第七章之S5PV210移植到Nandflash
1,之前的操作都是基于SD卡进行运行的,如今在Nandfalsh中运行u-boot.因为s5p_goni.h配置文件没有配置Nand相关文件,所以先配置Nand文件.
在include/configs/s5p_goni.h中添加一个:#define CONFIG_CMD_NAND
2,根据board_init_r函数中nand_init()如下图:
3,进行nand_init();
4,所以配置文件还需要添加#defnie CONFIG_SYS_MAX_NAND_DEVICE 1,及其 nand基地址#define CONFIG_SYS_NAND_BASE 0xB0E00000
5,查看common/Makefie如图:先把环境变量设成nand
6,在nand_init()中,发现drives/mtd/nand/没有相关的board_nand_init()函数.根据s3c2410修改成s5pv210nand.c:
/*************************************************************************
> File Name: s5pv210_nand.c
> Author:
> Mail:
> Created Time: Wed 09 Aug 2017 03:34:27 PM CST
************************************************************************/
/* name:Sourcelink
* (C) Copyright 2006 OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <nand.h>
#include <asm/arch/nand_reg.h>
#include <asm/io.h>
#define MP0_1CON (*(volatile unsigned long *)0xE02002E0)
#define MP0_3CON (*(volatile unsigned long *)0xE0200320)
#define MP0_6CON (*(volatile unsigned long *)0xE0200380)
/* Nand Flash Configuration Register */
#define AddrCycle 1 /* 5 address cycle */
#define PageSize 0 /* 2KBytes/Page */
#define MLCFlash 0 /* SLC NAND Flash */
#define TWRPH1 1 /* (0+1) * 7.5 > 5ns (tCLH/tALH) */
#define TWRPH0 2 /* (1+1) * 7.5ns > 12ns (tWP) */
#define TACLS 1 /* 7.5ns * 2 > 12ns tALS tCLS */
/* Control Register */
#define MODE 1 /* ENABLE NAND Flash Controller */
#define Reg_nCE0 1 /* Disable chip select */
/* modied by Sourcelink */
static void s5pv210_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
struct s5pv210_nand *nand = (struct s5pv210_nand *)s5pv210_get_base_nand();
debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
ulong IO_ADDR_W = (ulong)nand;
if (ctrl & NAND_CTRL_CHANGE) {
if (ctrl & NAND_CLE)
IO_ADDR_W = IO_ADDR_W | 0x8; /* Command Register */
else if (ctrl & NAND_ALE)
IO_ADDR_W = IO_ADDR_W | 0xC; /* Address Register */
chip->IO_ADDR_W = (void *)IO_ADDR_W;
if (ctrl & NAND_NCE) /* select */
writel(readl(&nand->nfcont) & ~(1 << 1), &nand->nfcont);
else /* deselect */
writel(readl(&nand->nfcont) | (1 << 1), &nand->nfcont);
}
if (cmd != NAND_CMD_NONE)
writeb(cmd, chip->IO_ADDR_W);
else
chip->IO_ADDR_W = &nand->nfdata;
}
static int s5pv210_dev_ready(struct mtd_info *mtd)
{
struct s5pv210_nand *nand = (struct s5pv210_nand *)s5pv210_get_base_nand();
debug("dev_ready\n");
return readl(&nand->nfstat) & 0x01;
}
#ifdef CONFIG_S3C2410_NAND_HWECC
void s5pv210_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct s5pv210_nand *nand = (struct s5pv210_nand *)s5pv210_get_base_nand();
debug("s5pv210_nand_enable_hwecc(%p, %d)\n", mtd, mode);
writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf);
}
static int s5pv210_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
u_char *ecc_code)
{
struct s5pv210_nand *nand = (struct s5pv210_nand *)s5pv210_get_base_nand();
ecc_code[0] = readb(&nand->nfecc);
ecc_code[1] = readb(&nand->nfecc + 1);
ecc_code[2] = readb(&nand->nfecc + 2);
debug("s5pv210_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
return 0;
}
static int s5pv210_nand_correct_data(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
{
if (read_ecc[0] == calc_ecc[0] &&
read_ecc[1] == calc_ecc[1] &&
read_ecc[2] == calc_ecc[2])
return 0;
printf("s5pv210_nand_correct_data: not implemented\n");
return -1;
}
#endif
/*
* add by Sourcelink
* nand_select_chip
* @mtd: MTD device structure
* @ctl: 0 to select, -1 for deselect
*
* Default select function for 1 chip devices.
*/
static void s5pv210_nand_select_chip(struct mtd_info *mtd, int ctl)
{
struct nand_chip *chip = mtd->priv;
switch (ctl) {
case -1: /* deselect the chip */
chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
break;
case 0: /* Select the chip */
chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
break;
default:
BUG();
}
}
/* modied by Sourcelink */
int board_nand_init(struct nand_chip *nand)
{
u32 cfg;
struct s5pv210_nand *nand_reg = (struct s5pv210_nand *)(struct s5pv210_nand *)s5pv210_get_base_nand();
debug("board_nand_init()\n");
/* initialize hardware */
/* HCLK_PSYS=133MHz(7.5ns) */
cfg = ((AddrCycle << 1) | (PageSize << 2) | (MLCFlash << 3) | (TWRPH1 << 4) | (TWRPH0 << 8) | (TACLS << 12));
writel(cfg, &nand_reg->nfconf);
writel((Reg_nCE0 << 1) | (MODE << 0), &nand_reg->nfcont);
/* Disable chip select and Enable NAND Flash Controller */
/*
* port map
* CE1-> Xm0CSn2 -> MP01_2
* CLE-> Xm0FCLE -> MP03_0
* ALE-> Xm0FALE -> MP03_1
* WE -> Xm0FWEn -> MP03_2
* RE -> Xm0FREn -> MP03_3
* R/B1->Xm0FRnB0-> MP03_4
* IO[7:0]->Xm0DATA[7:0]->MP0_6[7:0]
* */
/* 设置片选引脚 CSN[0] */
MP0_1CON &= ~(0x00000F00);
MP0_1CON |= (3 << 8);
/* CLE,ALE,WE,RE,R/B1 */
MP0_3CON &= ~(0x000FFFFF);
MP0_3CON |= 0x00022222;
/* DATA */
MP0_6CON = 0x22222222;
/* initialize nand_chip data structure */
nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
nand->select_chip = s5pv210_nand_select_chip;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
/* hwcontrol always must be implemented */
nand->cmd_ctrl = s5pv210_hwcontrol;
nand->dev_ready = s5pv210_dev_ready;
#ifdef CONFIG_S3C2410_NAND_HWECC
nand->ecc.hwctl = s5pv210_nand_enable_hwecc;
nand->ecc.calculate = s5pv210_nand_calculate_ecc;
nand->ecc.correct = s5pv210_nand_correct_data;
nand->ecc.mode = NAND_ECC_HW;
nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
nand->ecc.strength = 1;
#else
nand->ecc.mode = NAND_ECC_SOFT;
#endif
#ifdef CONFIG_S3C2410_NAND_BBT
nand->bbt_options |= NAND_BBT_USE_FLASH;
#endif
debug("end of nand_init\n");
return 0;
}
7,在vim arch/arm/include/asm/arch-s5pc1xx/cpu.h 下添加:
在62行添加#define S5PV210_NAND_BASE 0xB0E00000
8,然后在arch/arm/include/asm/arch-s5pc1xx/下创建文件nand_reg.h,定义 NAND 的寄存器结构体
/*************************************************************************
> File Name: nand_reg.h
> Author:
> Mail:
> Created Time: Wed 09 Aug 2017 04:11:49 PM CST
************************************************************************/
#ifndef _NAND_REG_H
#define _NAND_REG_H
#ifndef __ASSEMBLY__
static inline struct s5pv210_nand *s5pv210_get_base_nand(void)
{
return (struct s5pv210_nand *)S5PV210_NAND_BASE;
}
struct s5pv210_nand {
unsigned int nfconf;
unsigned int nfcont;
unsigned int nfcmmd;
unsigned int nfaddr;
unsigned int nfdata;
unsigned int nfmeccd0;
unsigned int nfmeccd1;
unsigned int nfseccd;
unsigned int nfsblk;
unsigned int nfeblk;
unsigned int nfstat;
unsigned int nfeccerr0;
unsigned int nfeccerr1;
unsigned int nfmecc0;
unsigned int nfmecc1;
unsigned int nfsecc;
unsigned int nfmlcbitpt;
};
#endif
#endif
9,修改drivers/mtd/nand/Makefile,将s5pv210_nand.c编译进uboot
10,添加环境变量偏移量,在配置文件里添加:#define CONFIG_ENV_OFFSET,移植NAND,必需要OFFSET
11,然后,再make,生成可以移值到Nand falsh的u-boot.
第七章之S5PV210移植到Nandflash的更多相关文章
- 第七章 LED将为我们闪烁:控制发光二极管
第七章 LED将为我们闪烁:控制发光二极管 本章我们将会看到一个完整的linux驱动程序,通过linux驱动程序控制LED的四个小灯,通俗的说就是通过向linux驱动程序来控制LED小灯的开关.用到 ...
- [学习笔记—Objective-C]《Objective-C-基础教程 第2版》第二章~第七章
在看完<Objective-C 程序设计 第6版>之后,看了一些关于iOS开发职位的面试题,发现自身基础非常是不牢,于是打算以查缺补漏的方式阅读还有一本关于Objective-C的基础书籍 ...
- 精通Web Analytics 2.0 (9) 第七章:失败更快:爆发测试与实验的能量
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第七章:失败更快:爆发测试与实验的能量 欢迎来到实验和测试这个棒极了的世界! 如果Web拥有一个超越所有其他渠道的巨大优势,它就 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (38) ------ 第七章 使用对象服务之动态创建连接字符串和从数据库读取模型
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第七章 使用对象服务 本章篇幅适中,对真实应用中的常见问题提供了切实可行的解决方案. ...
- 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7 标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...
- Java语言程序设计(基础篇) 第七章 一维数组
第七章 一维数组 7.2 数组的基础知识 1.一旦数组被创建,它的大小是固定的.使用一个数组引用变量,通过下标来访问数组中的元素. 2.数组是用来存储数据的集合,但是,通常我们会发现把数组看作一个存储 ...
- objective-c第七章课后练习2
题:改变第七章例子中print方法,增加bool参数,判断如果是YES则对分数进行约简 @interface Fraction : NSObject { //int num,den; } @prope ...
- 读《编写可维护的JavaScript》第七章总结
第七章 事件处理 7.1 典型用法 作者首先给了个我们一个处理事件的方法.看起来也没啥俩样,不过后来给出的优化方法很值得学习: // 不好的写法 function handleClick(even ...
- 第一章 Andorid系统移植与驱动开发概述 - 读书笔记
Android驱动月考1 第一章 Andorid系统移植与驱动开发概述 - 读书笔记 1.Android系统的架构: (1)Linux内核,Android是基于Linux内核的操作系统,并且开源,所以 ...
随机推荐
- 使用OC和Swift两种语言写一个发射烟花的小项目
OC与Swift两种实现方式基本上区别不大,主要是在一些对象或方法的调用方式不同,附带源码. OC代码样式: self.view.backgroundColor = [UIColor blackCol ...
- [WinForm]dataGridView背景色交替
方法一: //设置表格背景色 dgvSaleOrder.RowsDefaultCellStyle.BackColor = Color.Ivory; //设置交替行的背景色 dgvSaleOrder.A ...
- VS2010安装Boost库
source URL: http://stackoverflow.com/questions/2629421/how-to-use-boost-in-visual-studio-2010 While ...
- Notepad++ 使用探索
一.更换主题,视觉享受 1,http://wiki.macromates.com/Themes/UserSubmittedThemes,从网站上下载自己喜欢的主题,解压 2,复制Black Pearl ...
- Spring AOP (二)
下面介绍@AspectJ语法基础 一.切点表达式函数 AspectJ的切点表达式由关键字和操作参数组成,如execution(* greetTo(..)) 的切点表达式,execution为关键字,而 ...
- struts ajax多级下拉菜单
先看项目截图: 看看要加入的jar包 除了struts核心的那个几个之外,我们还需要这两个 OK先看struts.xml <?xml version="1.0" encodi ...
- PS图像特效算法——镜像渐隐
这个特效的实现,可以先利用前面提到的渐变特效,做一个图像的渐变, 然后将原图与渐变图对称放置,将背景设置成黑色. clc; clear all; close all; Image=imread('4. ...
- iOS下如何获取一个类的所有子类
因为项目中,不同用户切换时,用的是不同数据库,路径不同,而JKDBModel,数据库创建和字段检测,在app一次生命周期里,只会执行一次,所以得考虑账号切换时,创建数据库,需要获取所有JKDBMode ...
- How tomcat works 读书笔记十三 Host和Engine
Host Host是Context的父容器.如果想在一个tomcat上部署多个context就需要使用Host了.上下文容器的父容器是主机,但是可能有一些其它实现,没有必要的时候也可以忽略.不过在实践 ...
- JVM学习--(六)类加载器原理
我们知道我们编写的java代码,会经过编译器编译成字节码文件(class文件),再把字节码文件装载到JVM中,映射到各个内存区域中,我们的程序就可以在内存中运行了.那么字节码文件是怎样装载到JVM中的 ...