source: trunk/target/linux/brcm47xx/patches-3.2/030-bcm47xx-bcma-nandflash.patch @ 30943

Last change on this file since 30943 was 30943, checked in by hauke, 5 years ago

brcm47xx: add support for NAND flash on devices using bcma

This patch add support for the NAND flash on BCM5357 based devices like the WNR3500Lv2.

Thank you Tathagata Das <tathagata@…> for the patch

File size: 30.7 KB
  • arch/mips/bcm47xx/bus.c

    a b  
    22 * BCM947xx nvram variable access 
    33 * 
    44 * Copyright (C) 2011 Hauke Mehrtens <hauke@hauke-m.de> 
     5 * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> 
    56 * 
    67 * This program is free software; you can redistribute  it and/or modify it 
    78 * under  the terms of  the GNU General  Public License as published by the 
    void bcm47xx_sflash_struct_ssb_init(stru 
    9293        sflash->numblocks = scc->sflash.numblocks; 
    9394        sflash->size = scc->sflash.size; 
    9495} 
     96 
     97void bcm47xx_nflash_struct_bcma_init(struct bcm47xx_nflash *nflash, struct bcma_drv_cc *bcc) 
     98{ 
     99        nflash->nflash_type = BCM47XX_BUS_TYPE_BCMA; 
     100        nflash->bcc = bcc; 
     101} 
  • arch/mips/bcm47xx/nvram.c

    a b  
    44 * Copyright (C) 2005 Broadcom Corporation 
    55 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 
    66 * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de> 
     7 * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> 
    78 * 
    89 * This program is free software; you can redistribute  it and/or modify it 
    910 * under  the terms of  the GNU General  Public License as published by the 
     
    2122#include <asm/mach-bcm47xx/nvram.h> 
    2223#include <asm/mach-bcm47xx/bcm47xx.h> 
    2324#include <asm/mach-bcm47xx/bus.h> 
     25#include <linux/mtd/bcm47xx_nand.h> 
    2426 
    2527static char nvram_buf[NVRAM_SPACE]; 
    2628 
    found: 
    137139        return 0; 
    138140} 
    139141 
     142static int early_nvram_init_nflash(void) 
     143{ 
     144        struct nvram_header *header; 
     145        u32 off; 
     146        int ret; 
     147        int len; 
     148        u32 flash_size = bcm47xx_nflash.size; 
     149        u8 tmpbuf[NFL_SECTOR_SIZE]; 
     150        int i; 
     151        u32 *src, *dst; 
     152 
     153        /* check if the struct is already initilized */ 
     154        if (!flash_size) 
     155                return -1; 
     156         
     157        cfe_env = 0; 
     158 
     159        off = FLASH_MIN; 
     160        while (off <= flash_size) { 
     161                ret = bcma_nflash_read(bcm47xx_nflash.bcc, off, NFL_SECTOR_SIZE, tmpbuf); 
     162                if (ret != NFL_SECTOR_SIZE) 
     163                        goto done; 
     164                header = (struct nvram_header *)tmpbuf; 
     165                if (header->magic == NVRAM_HEADER) 
     166                        goto found; 
     167                off <<= 1; 
     168        } 
     169 
     170        ret = -1; 
     171        goto done; 
     172 
     173found: 
     174        len = header->len; 
     175        header = (struct nvram_header *) KSEG1ADDR(NAND_FLASH1 + off); 
     176        src = (u32 *) header; 
     177        dst = (u32 *) nvram_buf; 
     178        for (i = 0; i < sizeof(struct nvram_header); i += 4) 
     179                *dst++ = *src++; 
     180        for (; i < len && i < NVRAM_SPACE; i += 4) 
     181                *dst++ = *src++; 
     182        ret = 0; 
     183done: 
     184        return ret; 
     185} 
     186 
    140187static void early_nvram_init(void) 
    141188{ 
    142189        int err = 0; 
    static void early_nvram_init(void) 
    163210                        err = early_nvram_init_sflash(); 
    164211                        if (err < 0) 
    165212                                printk(KERN_WARNING "can not read from flash: %i\n", err); 
     213                } else if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_NFLASH) { 
     214                        err = early_nvram_init_nflash(); 
     215                        if (err < 0) 
     216                                printk(KERN_WARNING "can not read from nflash: %i\n", err); 
    166217                } else { 
    167218                        printk(KERN_WARNING "unknow flash type\n"); 
    168219                } 
  • arch/mips/bcm47xx/setup.c

    a b  
    44 *  Copyright (C) 2006 Michael Buesch <m@bues.ch> 
    55 *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> 
    66 *  Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de> 
     7 *  Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> 
    78 * 
    89 *  This program is free software; you can redistribute  it and/or modify it 
    910 *  under  the terms of  the GNU General  Public License as published by the 
    enum bcm47xx_bus_type bcm47xx_bus_type; 
    4647EXPORT_SYMBOL(bcm47xx_bus_type); 
    4748 
    4849struct bcm47xx_sflash bcm47xx_sflash; 
     50struct bcm47xx_nflash bcm47xx_nflash; 
    4951 
    5052static void bcm47xx_machine_restart(char *command) 
    5153{ 
    static void __init bcm47xx_register_bcma 
    325327 
    326328        if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_SFLASH) 
    327329                bcm47xx_sflash_struct_bcma_init(&bcm47xx_sflash, &bcm47xx_bus.bcma.bus.drv_cc); 
     330         
     331        if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_NFLASH) 
     332                bcm47xx_nflash_struct_bcma_init(&bcm47xx_nflash, &bcm47xx_bus.bcma.bus.drv_cc); 
    328333} 
    329334#endif 
    330335 
    static struct platform_device bcm47xx_sf 
    395400        .num_resources  = 1, 
    396401}; 
    397402 
     403static struct resource bcm47xx_nflash_resource = { 
     404        .name   = "bcm47xx_nflash", 
     405        .start  = 0, 
     406        .end    = 0, 
     407        .flags  = 0, 
     408}; 
     409 
     410static struct platform_device bcm47xx_nflash_dev = { 
     411        .name           = "bcm47xx_nflash", 
     412        .resource       = &bcm47xx_nflash_resource, 
     413        .num_resources  = 1, 
     414}; 
     415 
    398416static int __init bcm47xx_register_flash(void) 
    399417{ 
    400418#ifdef CONFIG_BCM47XX_SSB 
    static int __init bcm47xx_register_flash 
    429447                } else if (drv_cc->flash_type == BCMA_SFLASH) { 
    430448                        bcm47xx_sflash_dev.dev.platform_data = &bcm47xx_sflash; 
    431449                        return platform_device_register(&bcm47xx_sflash_dev); 
     450                } else if (drv_cc->flash_type == BCMA_NFLASH) { 
     451                        bcm47xx_nflash_dev.dev.platform_data = &bcm47xx_nflash; 
     452                        return platform_device_register(&bcm47xx_nflash_dev); 
    432453                } else { 
    433454                        printk(KERN_ERR "No flash device found\n"); 
    434455                        return -1; 
  • arch/mips/include/asm/mach-bcm47xx/bus.h

    a b  
    22 * BCM947xx nvram variable access 
    33 * 
    44 * Copyright (C) 2011 Hauke Mehrtens <hauke@hauke-m.de> 
     5 * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> 
    56 * 
    67 * This program is free software; you can redistribute  it and/or modify it 
    78 * under  the terms of  the GNU General  Public License as published by the 
     
    1314#include <linux/bcma/bcma.h> 
    1415#include <linux/mtd/mtd.h> 
    1516#include <bcm47xx.h> 
     17#include <linux/mtd/nand.h> 
    1618 
    1719struct bcm47xx_sflash { 
    1820        enum bcm47xx_bus_type sflash_type; 
    void bcm47xx_sflash_struct_bcma_init(str 
    3840void bcm47xx_sflash_struct_ssb_init(struct bcm47xx_sflash *sflash, struct ssb_chipcommon *scc); 
    3941 
    4042extern struct bcm47xx_sflash bcm47xx_sflash; 
     43 
     44struct bcm47xx_nflash { 
     45        enum bcm47xx_bus_type nflash_type; 
     46        struct bcma_drv_cc *bcc; 
     47 
     48        u32 size;               /* Total size in bytes */ 
     49        u32 next_opcode; /* Next expected command from upper NAND layer */ 
     50 
     51        struct mtd_info mtd; 
     52        struct nand_chip nand; 
     53}; 
     54 
     55void bcm47xx_nflash_struct_bcma_init(struct bcm47xx_nflash *nflash, struct bcma_drv_cc *bcc); 
     56 
     57extern struct bcm47xx_nflash bcm47xx_nflash; 
  • drivers/bcma/bcma_private.h

    a b u32 bcma_pmu_get_clockcpu(struct bcma_dr 
    4646int bcma_sflash_init(struct bcma_drv_cc *cc); 
    4747#endif /* CONFIG_BCMA_SFLASH */ 
    4848 
     49#ifdef CONFIG_BCMA_NFLASH 
     50/* driver_chipcommon_nflash.c */ 
     51int bcma_nflash_init(struct bcma_drv_cc *cc); 
     52#endif /* CONFIG_BCMA_NFLASH */ 
     53 
    4954#ifdef CONFIG_BCMA_HOST_PCI 
    5055/* host_pci.c */ 
    5156extern int __init bcma_host_pci_init(void); 
  • new file drivers/bcma/driver_chipcommon_nflash.c

    - +  
     1/* 
     2 * BCMA nand flash interface 
     3 * 
     4 * Copyright 2011, Tathagata Das <tathagata@alumnux.com> 
     5 * Copyright 2010, Broadcom Corporation 
     6 * 
     7 * Licensed under the GNU/GPL. See COPYING for details. 
     8 */ 
     9 
     10#include <linux/bcma/bcma.h> 
     11#include <linux/bcma/bcma_driver_chipcommon.h> 
     12#include <linux/delay.h> 
     13#include <linux/mtd/bcm47xx_nand.h> 
     14#include <linux/mtd/nand.h> 
     15 
     16#include "bcma_private.h" 
     17 
     18/* Issue a nand flash command */ 
     19static inline void bcma_nflash_cmd(struct bcma_drv_cc *cc, u32 opcode) 
     20{ 
     21        bcma_cc_write32(cc, NAND_CMD_START, opcode); 
     22        bcma_cc_read32(cc,  NAND_CMD_START); 
     23} 
     24 
     25/* Check offset and length */ 
     26static int bcma_nflash_offset_is_valid(struct bcma_drv_cc *cc, u32 offset, u32 len, u32 mask) 
     27{ 
     28        if ((offset & mask) != 0 || (len & mask) != 0) { 
     29                pr_err("%s(): Address is not aligned. offset: %x, len: %x, mask: %x\n", __func__, offset, len, mask); 
     30                return 1; 
     31        } 
     32 
     33        if ((((offset + len) >> 20) >= cc->nflash.size) && 
     34                (((offset + len) & ((1 << 20) - 1)) != 0)) { 
     35                pr_err("%s(): Address is outside Flash memory region. offset: %x, len: %x, mask: %x\n", __func__, offset, len, mask); 
     36                return 1; 
     37        } 
     38 
     39        return 0; 
     40} 
     41 
     42/* Read len bytes starting at offset into buf. Returns number of bytes read. */ 
     43int bcma_nflash_read(struct bcma_drv_cc *cc, u32 offset, u32 len, u8 *buf) 
     44{ 
     45        u32 mask; 
     46        int i; 
     47        u32 *to, val, res; 
     48 
     49        mask = NFL_SECTOR_SIZE - 1; 
     50        if (bcma_nflash_offset_is_valid(cc, offset, len, mask)) 
     51                return 0; 
     52 
     53        to = (u32 *)buf; 
     54        res = len; 
     55        while (res > 0) { 
     56                bcma_cc_write32(cc, NAND_CMD_ADDR, offset); 
     57                bcma_nflash_cmd(cc, NCMD_PAGE_RD); 
     58                if (bcma_nflash_poll(cc) < 0) 
     59                        break; 
     60                val = bcma_cc_read32(cc, NAND_INTFC_STATUS); 
     61                if ((val & NIST_CACHE_VALID) == 0) 
     62                        break; 
     63                bcma_cc_write32(cc, NAND_CACHE_ADDR, 0); 
     64                for (i = 0; i < NFL_SECTOR_SIZE; i += 4, to++) { 
     65                        *to = bcma_cc_read32(cc, NAND_CACHE_DATA); 
     66                } 
     67                res -= NFL_SECTOR_SIZE; 
     68                offset += NFL_SECTOR_SIZE; 
     69        } 
     70        return (len - res); 
     71} 
     72 
     73#define NF_RETRIES   1000000 
     74 
     75/* Poll for command completion. Returns zero when complete. */ 
     76int bcma_nflash_poll(struct bcma_drv_cc *cc) 
     77{ 
     78        u32 retries = NF_RETRIES; 
     79        u32 pollmask = NIST_CTRL_READY|NIST_FLASH_READY; 
     80        u32 mask; 
     81 
     82        while (retries--) { 
     83                mask = bcma_cc_read32(cc, NAND_INTFC_STATUS) & pollmask; 
     84                if (mask == pollmask) 
     85                        return 0; 
     86                cpu_relax(); 
     87        } 
     88 
     89        if (!retries) { 
     90                pr_err("bcma_nflash_poll: not ready\n"); 
     91                return -1; 
     92        } 
     93 
     94        return 0; 
     95} 
     96 
     97/* Write len bytes starting at offset into buf. Returns success (0) or failure (!0). 
     98 * Should poll for completion. 
     99 */ 
     100int bcma_nflash_write(struct bcma_drv_cc *cc, u32 offset, u32 len, 
     101                            const u8 *buf) 
     102{ 
     103        u32 mask; 
     104        int i; 
     105        u32 *from, res, reg; 
     106 
     107        mask = cc->nflash.pagesize - 1; 
     108        if (bcma_nflash_offset_is_valid(cc, offset, len, mask)) 
     109                return 1; 
     110         
     111        /* disable partial page enable */ 
     112        reg = bcma_cc_read32(cc, NAND_ACC_CONTROL); 
     113        reg &= ~NAC_PARTIAL_PAGE_EN; 
     114        bcma_cc_write32(cc, NAND_ACC_CONTROL, reg); 
     115 
     116        from = (u32 *)buf; 
     117        res = len; 
     118        while (res > 0) { 
     119                bcma_cc_write32(cc, NAND_CACHE_ADDR, 0); 
     120                for (i = 0; i < cc->nflash.pagesize; i += 4, from++) { 
     121                        if (i % 512 == 0) 
     122                                bcma_cc_write32(cc, NAND_CMD_ADDR, i); 
     123                        bcma_cc_write32(cc, NAND_CACHE_DATA, *from); 
     124                } 
     125                bcma_cc_write32(cc, NAND_CMD_ADDR, offset + cc->nflash.pagesize - 512); 
     126                bcma_nflash_cmd(cc, NCMD_PAGE_PROG); 
     127                if (bcma_nflash_poll(cc) < 0) 
     128                        break; 
     129                res -= cc->nflash.pagesize; 
     130                offset += cc->nflash.pagesize; 
     131        } 
     132 
     133        if (res <= 0) 
     134                return 0; 
     135        else 
     136                return (len - res); 
     137} 
     138 
     139/* Erase a region. Returns success (0) or failure (-1).  
     140 * Poll for completion. 
     141 */ 
     142int bcma_nflash_erase(struct bcma_drv_cc *cc, u32 offset) 
     143{ 
     144        if ((offset >> 20) >= cc->nflash.size) 
     145                return -1; 
     146        if ((offset & (cc->nflash.blocksize - 1)) != 0) 
     147                return -1; 
     148 
     149        bcma_cc_write32(cc, NAND_CMD_ADDR, offset); 
     150        bcma_nflash_cmd(cc, NCMD_BLOCK_ERASE); 
     151        if (bcma_nflash_poll(cc) < 0) 
     152                return -1; 
     153        return 0; 
     154} 
  • drivers/bcma/driver_mips.c

    a b  
    66 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de> 
    77 * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com> 
    88 * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de> 
     9 * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> 
    910 * 
    1011 * Licensed under the GNU/GPL. See COPYING for details. 
    1112 */ 
    static void bcma_core_mips_flash_detect( 
    182183{ 
    183184        struct bcma_bus *bus = mcore->core->bus; 
    184185 
     186        if (bus->drv_cc.core->id.rev == 38  
     187                && (bus->drv_cc.status & (1 << 4)) != 0) { 
     188#ifdef CONFIG_BCMA_NFLASH 
     189                pr_info("found nand flash.\n"); 
     190                bus->drv_cc.flash_type = BCMA_NFLASH; 
     191#else 
     192                pr_info("NAND flash not supported.\n"); 
     193#endif 
     194                return; 
     195        } 
     196 
    185197        switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) { 
    186198        case BCMA_CC_FLASHT_STSER: 
    187199        case BCMA_CC_FLASHT_ATSER: 
  • drivers/bcma/Kconfig

    a b config BCMA_SFLASH 
    4343        depends on BCMA_DRIVER_MIPS 
    4444        default y 
    4545 
     46config BCMA_NFLASH 
     47        bool 
     48        depends on BCMA_DRIVER_MIPS 
     49        default y 
     50 
    4651config BCMA_DRIVER_MIPS 
    4752        bool "BCMA Broadcom MIPS core driver" 
    4853        depends on BCMA && MIPS 
  • drivers/bcma/Makefile

    a b  
    11bcma-y                                  += main.o scan.o core.o sprom.o 
    22bcma-y                                  += driver_chipcommon.o driver_chipcommon_pmu.o 
    33bcma-$(CONFIG_BCMA_SFLASH)              += driver_chipcommon_sflash.o 
     4bcma-$(CONFIG_BCMA_NFLASH)              += driver_chipcommon_nflash.o 
    45bcma-y                                  += driver_pci.o 
    56bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o 
    67bcma-$(CONFIG_BCMA_DRIVER_MIPS)         += driver_mips.o 
  • new file drivers/mtd/nand/bcm47xx_nand.c

    - +  
     1/* 
     2 * BCMA nand flash interface 
     3 * 
     4 * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> 
     5 * Copyright 2010, Broadcom Corporation 
     6 * 
     7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
     8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
     9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
     10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
     11 * 
     12 */ 
     13 
     14#define pr_fmt(fmt) "bcm47xx_nflash: " fmt 
     15#include <linux/module.h> 
     16#include <linux/slab.h> 
     17#include <linux/ioport.h> 
     18#include <linux/sched.h> 
     19#include <linux/mtd/mtd.h> 
     20#include <linux/mtd/map.h> 
     21#include <linux/mtd/partitions.h> 
     22#include <linux/errno.h> 
     23#include <linux/delay.h> 
     24#include <linux/platform_device.h> 
     25#include <bcm47xx.h> 
     26#include <bus.h> 
     27#include <linux/cramfs_fs.h> 
     28#include <linux/romfs_fs.h> 
     29#include <linux/magic.h> 
     30#include <linux/byteorder/generic.h> 
     31#include <linux/mtd/bcm47xx_nand.h> 
     32#include <linux/mtd/nand.h> 
     33 
     34static int bcm47xx_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip); 
     35static int bcm47xx_erase(struct mtd_info *mtd, unsigned int addr, unsigned int len); 
     36 
     37/* Private Global variable */ 
     38static u32 read_offset = 0; 
     39static u32 write_offset; 
     40 
     41static int 
     42nflash_mtd_poll(struct bcm47xx_nflash *nflash, unsigned int offset, int timeout) 
     43{ 
     44        unsigned long now = jiffies; 
     45        int ret = 0; 
     46 
     47        for (;;) { 
     48                if (!bcma_nflash_poll(nflash->bcc)) { 
     49                        ret = 0; 
     50                        break; 
     51                } 
     52                if (time_after(jiffies, now + timeout)) { 
     53                        pr_err("timeout while polling\n"); 
     54                        ret = -ETIMEDOUT; 
     55                        break; 
     56                } 
     57                udelay(1); 
     58        } 
     59 
     60        return ret; 
     61} 
     62 
     63static int 
     64bcm47xx_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) 
     65{ 
     66        struct nand_chip *nchip = (struct nand_chip *)mtd->priv; 
     67        struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; 
     68        int bytes, ret = 0; 
     69        u32 extra = 0; 
     70        u8 *tmpbuf = NULL; 
     71        int size; 
     72        u32 offset, blocksize, mask, off; 
     73        u32 skip_bytes = 0; 
     74        int need_copy = 0; 
     75        u8 *ptr = NULL; 
     76 
     77        /* Check address range */ 
     78        if (!len) 
     79                return 0; 
     80        if ((from + len) > mtd->size) 
     81                return -EINVAL; 
     82        offset = from; 
     83        if ((offset & (NFL_SECTOR_SIZE - 1)) != 0) { 
     84                extra = offset & (NFL_SECTOR_SIZE - 1); 
     85                offset -= extra; 
     86                len += extra; 
     87                need_copy = 1; 
     88        } 
     89        size = (len + (NFL_SECTOR_SIZE - 1)) & ~(NFL_SECTOR_SIZE - 1); 
     90        if (size != len) { 
     91                need_copy = 1; 
     92        } 
     93        if (!need_copy) { 
     94                ptr = buf; 
     95        } else { 
     96                tmpbuf = (u8 *)kmalloc(size, GFP_KERNEL); 
     97                ptr = tmpbuf; 
     98        } 
     99 
     100        blocksize = mtd->erasesize; 
     101        mask = blocksize - 1; 
     102        *retlen = 0; 
     103        while (len > 0) { 
     104                off = offset + skip_bytes; 
     105                if ((bytes = bcma_nflash_read(nflash->bcc, off, NFL_SECTOR_SIZE, ptr)) < 0) { 
     106                        ret = bytes; 
     107                        goto done; 
     108                } 
     109                if (bytes > len) 
     110                        bytes = len; 
     111                offset += bytes; 
     112                len -= bytes; 
     113                ptr += bytes; 
     114                *retlen += bytes; 
     115        } 
     116 
     117done: 
     118        if (tmpbuf) { 
     119                *retlen -= extra; 
     120                memcpy(buf, tmpbuf+extra, *retlen); 
     121                kfree(tmpbuf); 
     122        } 
     123 
     124        return ret; 
     125} 
     126 
     127static void bcm47xx_write(struct mtd_info *mtd, u32 to, const u_char *buf, u32 len) 
     128{ 
     129        struct nand_chip *nchip = (struct nand_chip *)mtd->priv; 
     130        struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; 
     131        u32 offset, blocksize, mask, off; 
     132        int read_len; 
     133        u32 copy_len, write_len, from; 
     134        u_char *write_ptr, *block; 
     135        const u_char *ptr; 
     136        int ret, bytes; 
     137 
     138        /* Check address range */ 
     139        if (!len) { 
     140                pr_err("Error: Attempted to write too small data\n"); 
     141                return; 
     142        } 
     143 
     144        if (!to) 
     145                return; 
     146 
     147        if ((to + len) > mtd->size) { 
     148                pr_err("Error: Attempted to write too large data\n"); 
     149                return; 
     150        } 
     151 
     152        ptr = buf; 
     153        block = NULL; 
     154        offset = to; 
     155        blocksize = mtd->erasesize; 
     156        if (!(block = kmalloc(blocksize, GFP_KERNEL))) 
     157                return; 
     158        mask = blocksize - 1; 
     159        while (len) { 
     160                /* Align offset */ 
     161                from = offset & ~mask; 
     162                /* Copy existing data into holding block if necessary */ 
     163                if (((offset & (blocksize-1)) != 0) || (len < blocksize)) { 
     164                        if ((ret = bcm47xx_read(mtd, from, blocksize, &read_len, block))) 
     165                                goto done; 
     166                        if (read_len != blocksize) { 
     167                                ret = -EINVAL; 
     168                                goto done; 
     169                        } 
     170                } 
     171         
     172                /* Copy input data into holding block */ 
     173                copy_len = min(len, blocksize - (offset & mask)); 
     174                memcpy(block + (offset & mask), ptr, copy_len); 
     175                off = (uint) from; 
     176                /* Erase block */ 
     177                if ((ret = bcm47xx_erase(mtd, off, blocksize)) < 0) 
     178                        goto done; 
     179                /* Write holding block */ 
     180                write_ptr = block; 
     181                write_len = blocksize; 
     182                if ((bytes = bcma_nflash_write(nflash->bcc, (uint)from, (uint)write_len, (u8 *) write_ptr)) != 0) { 
     183                        ret = bytes; 
     184                        goto done; 
     185                } 
     186                offset += copy_len; 
     187                if (len < copy_len) 
     188                        len = 0; 
     189                else 
     190                        len -= copy_len; 
     191                ptr += copy_len; 
     192        } 
     193 
     194done: 
     195        if (block) 
     196                kfree(block); 
     197        return; 
     198} 
     199 
     200static int bcm47xx_erase(struct mtd_info *mtd, unsigned int addr, unsigned int len) 
     201{ 
     202        struct nand_chip *nchip = (struct nand_chip *)mtd->priv; 
     203        struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; 
     204 
     205        /* Check address range */ 
     206        if (!len) 
     207                return 1; 
     208        if ((addr + len) > mtd->size) 
     209                return 1; 
     210 
     211        if (bcma_nflash_erase(nflash->bcc, addr)) { 
     212                pr_err("ERASE: nflash erase error\n"); 
     213                return 1; 
     214        } 
     215 
     216        if (nflash_mtd_poll(nflash, addr, 10 * HZ)) { 
     217                pr_err("ERASE: nflash_mtd_poll error\n"); 
     218                return 1; 
     219        } 
     220         
     221        return 0; 
     222} 
     223 
     224/* This functions is used by upper layer to checks if device is ready */ 
     225static int bcm47xx_dev_ready(struct mtd_info *mtd) 
     226{ 
     227        return 1; 
     228} 
     229 
     230/* Issue a nand flash command */ 
     231static inline void bcm47xx_nflash_cmd(struct bcma_drv_cc *cc, u32 opcode) 
     232{ 
     233        bcma_cc_write32(cc, NAND_CMD_START, opcode); 
     234        bcma_cc_read32(cc,  NAND_CMD_START); 
     235} 
     236 
     237static void bcm47xx_command(struct mtd_info *mtd, unsigned command, 
     238                                int column, int page_addr) 
     239{ 
     240        struct nand_chip *nchip = (struct nand_chip *)mtd->priv; 
     241        struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; 
     242        u32 pagesize = 1 << nchip->page_shift; 
     243 
     244        /* Command pre-processing step */ 
     245        switch (command) { 
     246        case NAND_CMD_RESET: 
     247                bcm47xx_nflash_cmd(nflash->bcc, NCMD_FLASH_RESET); 
     248                break; 
     249 
     250        case NAND_CMD_STATUS: 
     251                nflash->next_opcode = NAND_CMD_STATUS; 
     252                read_offset = 0; 
     253                write_offset = 0; 
     254                break; 
     255 
     256        case NAND_CMD_READ0: 
     257                read_offset = page_addr * pagesize; 
     258                nflash->next_opcode = 0; 
     259                break; 
     260 
     261        case NAND_CMD_READOOB: 
     262                read_offset = page_addr * pagesize; 
     263                nflash->next_opcode = 0; 
     264                break; 
     265 
     266        case NAND_CMD_SEQIN: 
     267                write_offset = page_addr * pagesize; 
     268                nflash->next_opcode = 0; 
     269                break; 
     270 
     271        case NAND_CMD_PAGEPROG: 
     272                nflash->next_opcode = 0; 
     273                break; 
     274 
     275        case NAND_CMD_READID: 
     276                read_offset = column; 
     277                bcm47xx_nflash_cmd(nflash->bcc, NCMD_ID_RD); 
     278                nflash->next_opcode = NAND_DEVID; 
     279                break; 
     280 
     281        case NAND_CMD_ERASE1: 
     282                nflash->next_opcode = 0; 
     283                bcm47xx_erase(mtd, page_addr*pagesize, pagesize); 
     284                break; 
     285         
     286        case NAND_CMD_ERASE2: 
     287                break; 
     288 
     289        case NAND_CMD_RNDOUT: 
     290                if (column > mtd->writesize) 
     291                        read_offset += (column - mtd->writesize); 
     292                else  
     293                        read_offset += column; 
     294                break; 
     295 
     296        default: 
     297                pr_err("COMMAND not supported %x\n", command); 
     298                nflash->next_opcode = 0; 
     299                break; 
     300        } 
     301} 
     302 
     303/* This function is used by upper layer for select and 
     304 * deselect of the NAND chip. 
     305 * It is dummy function. */ 
     306static void bcm47xx_select_chip(struct mtd_info *mtd, int chip) 
     307{ 
     308} 
     309 
     310static u_char bcm47xx_read_byte(struct mtd_info *mtd) 
     311{ 
     312        struct nand_chip *nchip = mtd->priv; 
     313        struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; 
     314        uint8_t ret = 0; 
     315        static u32 id; 
     316 
     317        if (nflash->next_opcode == 0) 
     318                return ret; 
     319 
     320        if (nflash->next_opcode == NAND_CMD_STATUS) 
     321                return NAND_STATUS_WP;  
     322 
     323        id = bcma_cc_read32(nflash->bcc, nflash->next_opcode); 
     324 
     325        if (nflash->next_opcode == NAND_DEVID) { 
     326                ret = (id >> (8*read_offset)) & 0xff; 
     327                read_offset++; 
     328        } 
     329 
     330        return ret; 
     331} 
     332 
     333static uint16_t bcm47xx_read_word(struct mtd_info *mtd) 
     334{ 
     335        loff_t from = read_offset; 
     336        uint16_t buf = 0; 
     337        int bytes; 
     338 
     339        bcm47xx_read(mtd, from, sizeof(buf), &bytes, (u_char *)&buf); 
     340        return buf; 
     341} 
     342 
     343/* Write data of length len to buffer buf. The data to be 
     344 * written on NAND Flash is first copied to RAMbuffer. After the Data Input 
     345 * Operation by the NFC, the data is written to NAND Flash */ 
     346static void bcm47xx_write_buf(struct mtd_info *mtd, 
     347                                const u_char *buf, int len) 
     348{ 
     349        bcm47xx_write(mtd, write_offset, buf, len); 
     350} 
     351 
     352/* Read the data buffer from the NAND Flash. To read the data from NAND 
     353 * Flash first the data output cycle is initiated by the NFC, which copies 
     354 * the data to RAMbuffer. This data of length len is then copied to buffer buf. 
     355 */ 
     356static void bcm47xx_read_buf(struct mtd_info *mtd, u_char *buf, int len) 
     357{ 
     358        loff_t from = read_offset; 
     359        int bytes; 
     360 
     361        bcm47xx_read(mtd, from, len, &bytes, buf); 
     362} 
     363 
     364/* Used by the upper layer to verify the data in NAND Flash 
     365 * with the data in the buf. */ 
     366static int bcm47xx_verify_buf(struct mtd_info *mtd, 
     367                                const u_char *buf, int len) 
     368{ 
     369        return -EFAULT; 
     370} 
     371 
     372static int bcm47xx_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) 
     373{ 
     374        struct nand_chip *nchip = mtd->priv; 
     375        struct bcm47xx_nflash *nflash = (struct bcm47xx_nflash *)nchip->priv; 
     376        int i; 
     377        uint off; 
     378        u32 pagesize = 1 << nchip->page_shift; 
     379        u32 blocksize = mtd->erasesize; 
     380 
     381        if ((ofs >> 20) >= nflash->size) 
     382                return 1; 
     383        if ((ofs & (blocksize - 1)) != 0) 
     384                return 1; 
     385 
     386        for (i = 0; i < 2; i++) { 
     387                off = ofs + pagesize; 
     388                bcma_cc_write32(nflash->bcc, NAND_CMD_ADDR, off); 
     389                bcm47xx_nflash_cmd(nflash->bcc, NCMD_SPARE_RD); 
     390                if (bcma_nflash_poll(nflash->bcc) < 0) 
     391                        break; 
     392                if ((bcma_cc_read32(nflash->bcc, NAND_INTFC_STATUS) & NIST_SPARE_VALID) != NIST_SPARE_VALID) 
     393                        return 1; 
     394                if ((bcma_cc_read32(nflash->bcc, NAND_SPARE_RD0) & 0xff) != 0xff) 
     395                        return 1; 
     396        } 
     397        return 0; 
     398} 
     399 
     400const char *part_probes[] = { "cmdlinepart", NULL }; 
     401static int bcm47xx_probe(struct platform_device *pdev) 
     402{ 
     403        struct nand_chip *nchip; 
     404        struct mtd_info *mtd; 
     405        struct bcm47xx_nflash *nflash = dev_get_platdata(&pdev->dev); 
     406        int ret = 0; 
     407 
     408        mtd = &nflash->mtd; 
     409        nchip = &nflash->nand; 
     410 
     411        /* Register with MTD */ 
     412        mtd->priv = nchip; 
     413        mtd->owner = THIS_MODULE; 
     414        mtd->dev.parent = &pdev->dev; 
     415 
     416        /* 50 us command delay time */ 
     417        nchip->chip_delay = 50; 
     418 
     419        nchip->priv = nflash; 
     420        nchip->dev_ready = bcm47xx_dev_ready; 
     421        nchip->cmdfunc = bcm47xx_command; 
     422        nchip->select_chip = bcm47xx_select_chip; 
     423        nchip->read_byte = bcm47xx_read_byte; 
     424        nchip->read_word = bcm47xx_read_word; 
     425        nchip->write_buf = bcm47xx_write_buf; 
     426        nchip->read_buf = bcm47xx_read_buf; 
     427        nchip->verify_buf = bcm47xx_verify_buf; 
     428        nchip->block_bad = bcm47xx_block_bad; 
     429        nchip->options = NAND_SKIP_BBTSCAN; 
     430 
     431        /* Not known */ 
     432        nchip->ecc.mode = NAND_ECC_NONE; 
     433 
     434        /* first scan to find the device and get the page size */ 
     435        if (nand_scan_ident(mtd, 1, NULL)) { 
     436                pr_err("nand_scan_ident failed\n"); 
     437                ret = -ENXIO; 
     438                goto done; 
     439        } 
     440        nflash->bcc->nflash.size = mtd->size; 
     441        nflash->bcc->nflash.pagesize = 1 << nchip->page_shift; 
     442        nflash->bcc->nflash.blocksize = mtd->erasesize; 
     443        bcm47xx_nflash.size = mtd->size; 
     444 
     445        /* second phase scan */ 
     446        if (nand_scan_tail(mtd)) { 
     447                pr_err("nand_scan_tail failed\n"); 
     448                ret = -ENXIO; 
     449                goto done; 
     450        } 
     451 
     452        mtd->name = "bcm47xx-nflash"; 
     453        mtd->flags |= MTD_WRITEABLE; 
     454        ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); 
     455 
     456        if (ret) { 
     457                pr_err("mtd_device_register failed\n"); 
     458                return ret; 
     459        } 
     460         
     461        return 0; 
     462 
     463done: 
     464        return ret; 
     465} 
     466 
     467static int __devexit bcm47xx_remove(struct platform_device *pdev) 
     468{ 
     469        struct bcm47xx_nflash *nflash = dev_get_platdata(&pdev->dev); 
     470        struct mtd_info *mtd = &nflash->mtd; 
     471 
     472        if (nflash) { 
     473                /* Release resources, unregister device */ 
     474                nand_release(mtd); 
     475        } 
     476 
     477        return 0; 
     478} 
     479 
     480static struct platform_driver bcm47xx_driver = { 
     481        .remove = __devexit_p(bcm47xx_remove), 
     482        .driver = { 
     483                .name = "bcm47xx_nflash", 
     484                .owner = THIS_MODULE, 
     485        }, 
     486}; 
     487 
     488static int __init init_bcm47xx_nflash(void) 
     489{ 
     490        int ret = platform_driver_probe(&bcm47xx_driver, bcm47xx_probe); 
     491 
     492        if (ret) 
     493                pr_err("error registering platform driver: %i\n", ret); 
     494        return ret; 
     495} 
     496 
     497static void __exit exit_bcm47xx_nflash(void) 
     498{ 
     499        platform_driver_unregister(&bcm47xx_driver); 
     500} 
     501 
     502module_init(init_bcm47xx_nflash); 
     503module_exit(exit_bcm47xx_nflash); 
     504 
     505MODULE_LICENSE("GPL"); 
     506MODULE_DESCRIPTION("BCM47XX NAND flash driver"); 
  • drivers/mtd/nand/Kconfig

    a b config MTD_NAND_FSMC 
    537537          Enables support for NAND Flash chips on the ST Microelectronics 
    538538          Flexible Static Memory Controller (FSMC) 
    539539 
     540config MTD_NAND_BCM47XX 
     541        tristate "bcm47xx nand flash support" 
     542        default y 
     543        depends on BCM47XX 
     544        select MTD_PARTITIONS 
     545        help 
     546          Support for bcm47xx nand flash 
     547 
    540548endif # MTD_NAND 
  • drivers/mtd/nand/Makefile

    a b obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mp 
    4949obj-$(CONFIG_MTD_NAND_RICOH)            += r852.o 
    5050obj-$(CONFIG_MTD_NAND_JZ4740)           += jz4740_nand.o 
    5151obj-$(CONFIG_MTD_NAND_GPMI_NAND)        += gpmi-nand/ 
     52obj-$(CONFIG_MTD_NAND_BCM47XX)          += bcm47xx_nand.o 
    5253 
    5354nand-objs := nand_base.o nand_bbt.o 
  • include/linux/bcma/bcma_driver_chipcommon.h

    a b struct bcma_chipcommon_pmu { 
    376376enum bcma_flash_type { 
    377377        BCMA_PFLASH, 
    378378        BCMA_SFLASH, 
     379        BCMA_NFLASH, 
    379380}; 
    380381 
    381382struct bcma_pflash { 
    struct bcma_sflash { 
    392393}; 
    393394#endif /* CONFIG_BCMA_SFLASH */ 
    394395 
     396#ifdef CONFIG_BCMA_NFLASH 
     397struct bcma_nflash { 
     398        u32 blocksize;          /* Block size */ 
     399        u32 pagesize;           /* Page size */ 
     400        u32 size;               /* Total size in bytes */ 
     401}; 
     402#endif 
     403 
    395404struct bcma_serial_port { 
    396405        void *regs; 
    397406        unsigned long clockspeed; 
    struct bcma_drv_cc { 
    417426#ifdef CONFIG_BCMA_SFLASH 
    418427                struct bcma_sflash sflash; 
    419428#endif /* CONFIG_BCMA_SFLASH */ 
     429#ifdef CONFIG_BCMA_NFLASH 
     430                struct bcma_nflash nflash; 
     431#endif 
    420432        }; 
    421433 
    422434        int nr_serial_ports; 
    int bcma_sflash_commit(struct bcma_drv_c 
    483495                             const u8 *buf); 
    484496#endif /* CONFIG_BCMA_SFLASH */ 
    485497 
     498#ifdef CONFIG_BCMA_NFLASH 
     499/* Chipcommon nflash support. */ 
     500int bcma_nflash_read(struct bcma_drv_cc *cc, u32 offset, u32 len, u8 *buf); 
     501int bcma_nflash_poll(struct bcma_drv_cc *cc); 
     502int bcma_nflash_write(struct bcma_drv_cc *cc, u32 offset, u32 len, const u8 *buf); 
     503int bcma_nflash_erase(struct bcma_drv_cc *cc, u32 offset); 
     504int bcma_nflash_commit(struct bcma_drv_cc *cc, u32 offset, u32 len, const u8 *buf); 
     505#endif 
     506 
    486507#endif /* LINUX_BCMA_DRIVER_CC_H_ */ 
  • new file include/linux/mtd/bcm47xx_nand.h

    - +  
     1/* 
     2 * Broadcom chipcommon NAND flash interface 
     3 * 
     4 * Copyright (C) 2011-2012 Tathagata Das <tathagata@alumnux.com> 
     5 * Copyright (C) 2009, Broadcom Corporation 
     6 * All Rights Reserved. 
     7 *  
     8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
     9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
     10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
     11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
     12 * 
     13 */ 
     14 
     15#ifndef _nflash_h_ 
     16#define _nflash_h_ 
     17 
     18#define  NAND_FLASH1                                            0x1fc00000  /* MIPS Flash Region 1 */ 
     19 
     20/* nand_cmd_start commands */ 
     21#define NCMD_NULL                                               0 
     22#define NCMD_PAGE_RD                                    1 
     23#define NCMD_SPARE_RD                                   2 
     24#define NCMD_STATUS_RD                                  3 
     25#define NCMD_PAGE_PROG                                  4 
     26#define NCMD_SPARE_PROG                         5 
     27#define NCMD_COPY_BACK                                  6 
     28#define NCMD_ID_RD                                              7 
     29#define NCMD_BLOCK_ERASE                                8 
     30#define NCMD_FLASH_RESET                                9 
     31#define NCMD_LOCK                                               0xa 
     32#define NCMD_LOCK_DOWN                                  0xb 
     33#define NCMD_UNLOCK                                             0xc 
     34#define NCMD_LOCK_STATUS                                0xd 
     35 
     36/* nand_acc_control */ 
     37#define NAC_RD_ECC_EN                                   0x80000000 
     38#define NAC_WR_ECC_EN                                   0x40000000 
     39#define NAC_RD_ECC_BLK0_EN                      0x20000000 
     40#define NAC_FAST_PGM_RDIN                               0x10000000 
     41#define NAC_RD_ERASED_ECC_EN                    0x08000000 
     42#define NAC_PARTIAL_PAGE_EN                     0x04000000 
     43#define NAC_PAGE_HIT_EN                         0x01000000 
     44#define NAC_ECC_LEVEL0                                  0x00f00000 
     45#define NAC_ECC_LEVEL                                   0x000f0000 
     46#define NAC_SPARE_SIZE0                         0x00003f00 
     47#define NAC_SPARE_SIZE                                  0x0000003f 
     48 
     49/* nand_config */ 
     50#define NCF_CONFIG_LOCK                         0x80000000 
     51#define NCF_BLOCK_SIZE_MASK                     0x70000000 
     52#define NCF_BLOCK_SIZE_SHIFT                    28 
     53#define NCF_DEVICE_SIZE_MASK                    0x0f000000 
     54#define NCF_DEVICE_SIZE_SHIFT           24 
     55#define NCF_DEVICE_WIDTH                                0x00800000 
     56#define NCF_PAGE_SIZE_MASK                      0x00300000 
     57#define NCF_PAGE_SIZE_SHIFT                     20 
     58#define NCF_FULL_ADDR_BYTES_MASK        0x00070000 
     59#define NCF_FULL_ADDR_BYTES_SHIFT       16 
     60#define NCF_COL_ADDR_BYTES_MASK         0x00007000 
     61#define NCF_COL_ADDR_BYTES_SHIFT        12 
     62#define NCF_BLK_ADDR_BYTES_MASK         0x00000700 
     63#define NCF_BLK_ADDR_BYTES_SHIFT        8 
     64 
     65/* nand_intfc_status */ 
     66#define NIST_CTRL_READY                         0x80000000 
     67#define NIST_FLASH_READY                                0x40000000 
     68#define NIST_CACHE_VALID                                0x20000000 
     69#define NIST_SPARE_VALID                                0x10000000 
     70#define NIST_ERASED                                             0x08000000 
     71#define NIST_STATUS                                             0x000000ff 
     72 
     73#define NFL_SECTOR_SIZE                         512 
     74 
     75#define NFL_TABLE_END                                   0xffffffff 
     76#define NFL_BOOT_SIZE                                   0x200000 
     77#define NFL_BOOT_OS_SIZE                                0x2000000 
     78 
     79/* Nand flash MLC controller registers (corerev >= 38) */ 
     80#define NAND_REVISION                                   0xC00 
     81#define NAND_CMD_START                                  0xC04 
     82#define NAND_CMD_ADDR_X                         0xC08 
     83#define NAND_CMD_ADDR                                   0xC0C 
     84#define NAND_CMD_END_ADDR                               0xC10 
     85#define NAND_CS_NAND_SELECT                     0xC14 
     86#define NAND_CS_NAND_XOR                                0xC18 
     87#define NAND_SPARE_RD0                                  0xC20 
     88#define NAND_SPARE_RD4                                  0xC24 
     89#define NAND_SPARE_RD8                                  0xC28 
     90#define NAND_SPARE_RD12                         0xC2C 
     91#define NAND_SPARE_WR0                                  0xC30 
     92#define NAND_SPARE_WR4                                  0xC34 
     93#define NAND_SPARE_WR8                                  0xC38 
     94#define NAND_SPARE_WR12                         0xC3C 
     95#define NAND_ACC_CONTROL                                0xC40 
     96#define NAND_CONFIG                                             0xC48 
     97#define NAND_TIMING_1                                   0xC50 
     98#define NAND_TIMING_2                                   0xC54 
     99#define NAND_SEMAPHORE                                  0xC58 
     100#define NAND_DEVID                                              0xC60 
     101#define NAND_DEVID_X                                    0xC64 
     102#define NAND_BLOCK_LOCK_STATUS          0xC68 
     103#define NAND_INTFC_STATUS                               0xC6C 
     104#define NAND_ECC_CORR_ADDR_X                    0xC70 
     105#define NAND_ECC_CORR_ADDR                      0xC74 
     106#define NAND_ECC_UNC_ADDR_X                     0xC78 
     107#define NAND_ECC_UNC_ADDR                               0xC7C 
     108#define NAND_READ_ERROR_COUNT           0xC80 
     109#define NAND_CORR_STAT_THRESHOLD        0xC84 
     110#define NAND_READ_ADDR_X                                0xC90 
     111#define NAND_READ_ADDR                                  0xC94 
     112#define NAND_PAGE_PROGRAM_ADDR_X        0xC98 
     113#define NAND_PAGE_PROGRAM_ADDR          0xC9C 
     114#define NAND_COPY_BACK_ADDR_X           0xCA0 
     115#define NAND_COPY_BACK_ADDR                     0xCA4 
     116#define NAND_BLOCK_ERASE_ADDR_X         0xCA8 
     117#define NAND_BLOCK_ERASE_ADDR           0xCAC 
     118#define NAND_INV_READ_ADDR_X                    0xCB0 
     119#define NAND_INV_READ_ADDR                      0xCB4 
     120#define NAND_BLK_WR_PROTECT                     0xCC0 
     121#define NAND_ACC_CONTROL_CS1                    0xCD0 
     122#define NAND_CONFIG_CS1                         0xCD4 
     123#define NAND_TIMING_1_CS1                               0xCD8 
     124#define NAND_TIMING_2_CS1                               0xCDC 
     125#define NAND_SPARE_RD16                         0xD30 
     126#define NAND_SPARE_RD20                         0xD34 
     127#define NAND_SPARE_RD24                         0xD38 
     128#define NAND_SPARE_RD28                         0xD3C 
     129#define NAND_CACHE_ADDR                         0xD40 
     130#define NAND_CACHE_DATA                         0xD44 
     131#define NAND_CTRL_CONFIG                                0xD48 
     132#define NAND_CTRL_STATUS                                0xD4C 
     133 
     134#endif /* _nflash_h_ */ 
Note: See TracBrowser for help on using the repository browser.