ppcboot添加nandflash支持

从uboot中 copy -rf 以下目录或文件至ppcboot相应目录
drivers/nand
include/linux/mtd
include/nand.h
include/asm-arm/io.h
在 include/cmd_confdefs.h 中添加
#define min(X, Y)    /
 ({ typeof (X) __x = (X), __y = (Y); /
  (__x < __y) ? __x : __y; })

#define max(X, Y)    /
 ({ typeof (X) __x = (X), __y = (Y); /
  (__x > __y) ? __x : __y; })
#define CFG_CMD_NAND 0x0000100000000000 /* NAND support*/
在 include/comfigs/smdk2410.h 中添加
#define CFG_NAND_BASE 0x4e00000C
#define CFG_MAX_NAND_DEVICE 1

还有一些修改就等着编译出错了再修改就是了

主要的工作就是添加命令和对驱动的修改
暂时添加一个简单的命令,nandinit来初始化nandflash
在 include 下添加 cmd_nand.h
#ifndef _CMD_NAND_H
#define _CMD_NAND_H

#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#define CMD_TBL_NANDINIT MK_CMD_TBL_ENTRY(     /
 "nandinit", 5, 1, 1, do_nandinit,   /
 "nandinit  - init nand flash/n",    /
 "/n  nandinit  - init nand flash/n"  /
),
int do_nandinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#else
#define CMD_TBL_NANDINIT
#endif /* CFG_CMD_NAND */
#endif /* _CMD_NAND_H */

然后再 common 中添加相应的 cmd_nand.c文件,来实现这个命令

#include <common.h>
#include <command.h>
 
extern void nand_init(void);

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

int do_nandinit ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
 ulong bank;
 nand_init();
 return 0;
}

#endif /* CFG_CMD_FLASH */

修改下Makefile,并在 common/command.c 中添加
#include <cmd_nand.h>
在 cmd_tbl 命令宏数组中加入 CMD_TBL_NANDINIT,使得run_command能找到命令

来自uboot的Nandflash的驱动基本就是2.6内核中的驱动
我们只需要实现几个更底层的接口函数,而且ppcboot中没有用到
MMU,这样直接对nandflash控制器的寄存器进行操作.
原本需要把这些函数放在 board/smdk2410 目录中,不过为了方便一点就直接修改驱动
的nand.c文件,以下是代码.
#include <common.h>
#include <asm/io.h>

#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)

#include <nand.h>

#ifndef CFG_NAND_BASE_LIST
#define CFG_NAND_BASE_LIST { CFG_NAND_BASE }
#endif

#define S3C2410_NFREG(x) (x+0x4e000000)

#define S3C2410_NFCONF  S3C2410_NFREG(0x00)
#define S3C2410_NFCMD   S3C2410_NFREG(0x04)
#define S3C2410_NFADDR  S3C2410_NFREG(0x08)
#define S3C2410_NFDATA  S3C2410_NFREG(0x0C)
#define S3C2410_NFSTAT  S3C2410_NFREG(0x10)
#define S3C2410_NFECC   S3C2410_NFREG(0x14)

#define S3C2410_NFCONF_EN          (1<<15)
#define S3C2410_NFCONF_512BYTE     (1<<14)
#define S3C2410_NFCONF_4STEP       (1<<13)
#define S3C2410_NFCONF_INITECC     (1<<12)
#define S3C2410_NFCONF_nFCE        (1<<11)
#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)

#define S3C2410_NFSTAT_BUSY        (1<<0)

void s3c2410_nand_inithw(void)
{
 u16 tacls, twrph0, twrph1;
 u16 cfg = 0;
 tacls = 4;
 twrph0 = 8;
 twrph1 = 8;
 cfg  = S3C2410_NFCONF_EN;
 cfg |= S3C2410_NFCONF_TACLS(tacls-1);
 cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
 cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
 writew(cfg,S3C2410_NFCONF);
}


static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
 struct nand_chip *chip = mtd->priv;

 switch (cmd) {
 case NAND_CTL_SETNCE:
  writew(readw(S3C2410_NFCONF) & ~S3C2410_NFCONF_nFCE , S3C2410_NFCONF);
  break;
 case NAND_CTL_CLRNCE:
  writew(readw(S3C2410_NFCONF) | S3C2410_NFCONF_nFCE , S3C2410_NFCONF);
  break;

 case NAND_CTL_SETCLE:
  chip->IO_ADDR_W = (void __iomem *)S3C2410_NFCMD;
  break;

 case NAND_CTL_SETALE:
  chip->IO_ADDR_W = (void __iomem *)S3C2410_NFADDR;
  break;

  /* NAND_CTL_CLRCLE: */
  /* NAND_CTL_CLRALE: */
 default:
  chip->IO_ADDR_W = (void __iomem *)S3C2410_NFDATA;
  break;
 }
}

static int s3c2410_nand_devready(struct mtd_info *mtd)
{
 return readb(S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
}


void board_nand_init(struct nand_chip *nand)
{
 s3c2410_nand_inithw();
 nand->hwcontrol    = s3c2410_nand_hwcontrol;
 nand->dev_ready    = s3c2410_nand_devready;
 nand->chip_delay   = 50;
 nand->options    = 0;
 nand->eccmode    = NAND_ECC_SOFT;
}


int nand_curr_device = -1;
nand_info_t nand_info[CFG_MAX_NAND_DEVICE];

static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE];
static ulong base_address[CFG_MAX_NAND_DEVICE] = CFG_NAND_BASE_LIST;

static const char default_nand_name[] = "nand";


static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
      ulong base_addr)
{
 mtd->priv = nand;

 nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
 board_nand_init(nand);

 if (nand_scan(mtd, 1) == 0) {
  if (!mtd->name)
   mtd->name = (char *)default_nand_name;
 } else
  mtd->name = NULL;

}

void nand_init(void)
{
 int i;
 unsigned int size = 0;
 for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
  nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
  size += nand_info[i].size;
  if (nand_curr_device == -1)
   nand_curr_device = i;
 }
 printf("Nand flash %dM/n", size / (1024 * 1024));
}

#endif

很容易就能读懂了,以后就可以在这基础上再加入烧写nandflash的命令
还可以加入启动wince的命令,来实现linux和wince的双系统.
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值