zoukankan      html  css  js  c++  java
  • 第七章之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 ", 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 ");
    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) ", 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 ",
    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 ");
    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() ");

    /* 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 ");

    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.

  • 相关阅读:
    IT 已成为最疯狂的加班行业,没有之一
    编程和音乐真的很像吗?
    jquery:
    内存管理机制/垃圾回收机制:
    处理跨域:
    创建Djongo需要改url的地方:
    数据库连接池 DBUtils:
    C# 使用 SAP NCO3.0 调用SAP RFC函数接口
    java反射机制的原理与简单使用
    java反射机制的原理与简单使用
  • 原文地址:https://www.cnblogs.com/eeexu123/p/7326594.html
Copyright © 2011-2022 走看看