You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.2 KiB
132 lines
3.2 KiB
/*
|
|
* drivers/mtd/nand/fcr_soc.c
|
|
*/
|
|
|
|
#include <machine/types.h>
|
|
#include <linux/mtd/mtd.h>
|
|
#include <linux/mtd/nand.h>
|
|
#include <linux/mtd/partitions.h>
|
|
#include "fcr-nand.h"
|
|
/*
|
|
* MTD structure for fcr_soc board
|
|
*/
|
|
static struct mtd_info *fcr_soc_mtd = NULL;
|
|
/*
|
|
* Define partitions for flash device
|
|
*/
|
|
static const struct mtd_partition partition_info[] = {
|
|
{
|
|
.name = "fcr_soc flash partition 1",
|
|
.offset = 12*1024*1024,
|
|
.size = 32 * 1024 * 1024}
|
|
};
|
|
|
|
#define NUM_PARTITIONS 1
|
|
|
|
static void fcr_soc_hwcontrol(struct mtd_info *mtd, int dat,unsigned int ctrl)
|
|
{
|
|
struct nand_chip *chip = mtd->priv;
|
|
|
|
if((ctrl & NAND_CTRL_ALE)==NAND_CTRL_ALE)
|
|
*(volatile unsigned int *)(0xbf000014) = dat;
|
|
if ((ctrl & NAND_CTRL_CLE)==NAND_CTRL_CLE)
|
|
*(volatile unsigned int *)(0xbf000010) = dat;
|
|
}
|
|
|
|
|
|
//Main initialization for yaffs ----- by zhly
|
|
int fcr_soc_foryaffs_init(struct mtd_info *mtd)
|
|
{
|
|
struct nand_chip *this;
|
|
|
|
if(!mtd)
|
|
{
|
|
if(!(mtd = kmalloc(sizeof(struct mtd_info),GFP_KERNEL)))
|
|
{
|
|
printk("unable to allocate mtd_info structure!\n");
|
|
return -ENOMEM;
|
|
}
|
|
memset(mtd, 0, sizeof(struct mtd_info));
|
|
}
|
|
|
|
this = kmalloc(sizeof(struct nand_chip),GFP_KERNEL);
|
|
if(!this)
|
|
{
|
|
printk("Unable to allocate nand_chip structure!\n");
|
|
return -ENOMEM;
|
|
}
|
|
memset(this,0,sizeof(struct nand_chip));
|
|
|
|
fcr_soc_mtd=mtd;
|
|
fcr_soc_mtd->priv = this;
|
|
|
|
this->IO_ADDR_R = (void *)0xbf000040;
|
|
this->IO_ADDR_W = (void *)0xbf000040;
|
|
this->cmd_ctrl = fcr_soc_hwcontrol;
|
|
this->ecc.mode = NAND_ECC_SOFT;
|
|
|
|
if(nand_scan(fcr_soc_mtd,1))
|
|
{
|
|
kfree(fcr_soc_mtd);
|
|
printk("nand_scan failed!\n");
|
|
return -1;
|
|
}
|
|
fcr_soc_mtd->size=0x04000000;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Main initialization routine
|
|
*/
|
|
int fcr_soc_nand_init(void)
|
|
{
|
|
struct nand_chip *this;
|
|
|
|
/* Allocate memory for MTD device structure and private data */
|
|
fcr_soc_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
|
|
if (!fcr_soc_mtd) {
|
|
printk("Unable to allocate fcr_soc NAND MTD device structure.\n");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
/* Get pointer to private data */
|
|
this = (struct nand_chip *)(&fcr_soc_mtd[1]);
|
|
|
|
/* Initialize structures */
|
|
memset(fcr_soc_mtd, 0, sizeof(struct mtd_info));
|
|
memset(this, 0, sizeof(struct nand_chip));
|
|
|
|
/* Link the private data with the MTD structure */
|
|
fcr_soc_mtd->priv = this;
|
|
|
|
|
|
/* Set address of NAND IO lines */
|
|
this->IO_ADDR_R = (void *)0xbf000040;
|
|
this->IO_ADDR_W = (void *)0xbf000040;
|
|
/* Set address of hardware control function */
|
|
this->cmd_ctrl = fcr_soc_hwcontrol;
|
|
/* 15 us command delay time */
|
|
this->chip_delay = 15;
|
|
this->ecc.mode = NAND_ECC_SOFT;
|
|
|
|
/* Scan to find existence of the device */
|
|
if (nand_scan(fcr_soc_mtd, 1)) {
|
|
kfree(fcr_soc_mtd);
|
|
return -ENXIO;
|
|
}
|
|
|
|
/* Register the partitions */
|
|
// add_mtd_partitions(fcr_soc_mtd, partition_info, NUM_PARTITIONS);
|
|
add_mtd_device(fcr_soc_mtd,0,0,"total flash");
|
|
add_mtd_device(fcr_soc_mtd,0,0x02000000,"kernel");
|
|
add_mtd_device(fcr_soc_mtd,0x02000000,0x04000000,"squashfs");
|
|
add_mtd_device(fcr_soc_mtd,0x02000000+0x04000000,0x04000000,"jffs2");
|
|
add_mtd_device(fcr_soc_mtd,0x02000000+0x04000000+0x04000000,0x04000000,"yaffs2");
|
|
add_mtd_device(fcr_soc_mtd,0x02000000+0x04000000+0x04000000+0x04000000,0x02000000,"cramfs");
|
|
|
|
/* Return happy */
|
|
return 0;
|
|
}
|
|
|
|
|
|
|