edb7312.c 5.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 *  drivers/mtd/nand/edb7312.c
 *
4
 *  Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
L
Linus Torvalds 已提交
5 6 7 8
 *
 *  Derived from drivers/mtd/nand/autcpu12.c
 *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
 *
9
 * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $
L
Linus Torvalds 已提交
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *  Overview:
 *   This is a device driver for the NAND flash device found on the
 *   CLEP7312 board which utilizes the Toshiba TC58V64AFT part. This is
 *   a 64Mibit (8MiB x 8 bits) NAND flash device.
 */

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
28
#include <asm/arch/hardware.h>	/* for CLPS7111_VIRT_BASE */
L
Linus Torvalds 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#include <asm/sizes.h>
#include <asm/hardware/clps7111.h>

/*
 * MTD structure for EDB7312 board
 */
static struct mtd_info *ep7312_mtd = NULL;

/*
 * Values specific to the EDB7312 board (used with EP7312 processor)
 */
#define EP7312_FIO_PBASE 0x10000000	/* Phys address of flash */
#define EP7312_PXDR	0x0001	/*
				 * IO offset to Port B data register
				 * where the CLE, ALE and NCE pins
				 * are wired to.
				 */
#define EP7312_PXDDR	0x0041	/*
				 * IO offset to Port B data direction
				 * register so we can control the IO
				 * lines.
				 */

/*
 * Module stuff
 */

static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE;
57 58
static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR;
static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR;
L
Linus Torvalds 已提交
59 60 61 62 63 64

#ifdef CONFIG_MTD_PARTITIONS
/*
 * Define static partitions for flash device
 */
static struct mtd_partition partition_info[] = {
65 66 67
	{.name = "EP7312 Nand Flash",
	 .offset = 0,
	 .size = 8 * 1024 * 1024}
L
Linus Torvalds 已提交
68
};
69

L
Linus Torvalds 已提交
70 71 72 73
#define NUM_PARTITIONS 1

#endif

74
/*
L
Linus Torvalds 已提交
75
 *	hardware specific access to control-lines
76
 *
77
 *	NAND_NCE: bit 0 -> bit 6 (bit 7 = 1)
78 79
 *	NAND_CLE: bit 1 -> bit 4
 *	NAND_ALE: bit 2 -> bit 5
L
Linus Torvalds 已提交
80
 */
81
static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
L
Linus Torvalds 已提交
82
{
83 84 85
	struct nand_chip *chip = mtd->priv;

	if (ctrl & NAND_CTRL_CHANGE) {
86
		unsigned char bits = 0x80;
87

88 89
		bits |= (ctrl & (NAND_CLE | NAND_ALE)) << 3;
		bits |= (ctrl & NAND_NCE) ? 0x00 : 0x40;
90

91
		clps_writeb((clps_readb(ep7312_pxdr)  & 0xF0) | bits,
92
			    ep7312_pxdr);
L
Linus Torvalds 已提交
93
	}
94 95
	if (cmd != NAND_CMD_NONE)
		writeb(cmd, chip->IO_ADDR_W);
L
Linus Torvalds 已提交
96 97 98 99 100 101 102 103 104
}

/*
 *	read device ready pin
 */
static int ep7312_device_ready(struct mtd_info *mtd)
{
	return 1;
}
105

L
Linus Torvalds 已提交
106 107 108 109 110 111 112
#ifdef CONFIG_MTD_PARTITIONS
const char *part_probes[] = { "cmdlinepart", NULL };
#endif

/*
 * Main initialization routine
 */
113
static int __init ep7312_init(void)
L
Linus Torvalds 已提交
114 115 116 117 118
{
	struct nand_chip *this;
	const char *part_type = 0;
	int mtd_parts_nb = 0;
	struct mtd_partition *mtd_parts = 0;
119
	void __iomem *ep7312_fio_base;
120

L
Linus Torvalds 已提交
121
	/* Allocate memory for MTD device structure and private data */
122
	ep7312_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
L
Linus Torvalds 已提交
123 124 125 126
	if (!ep7312_mtd) {
		printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
		return -ENOMEM;
	}
127

L
Linus Torvalds 已提交
128 129
	/* map physical adress */
	ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
130
	if (!ep7312_fio_base) {
L
Linus Torvalds 已提交
131 132 133 134
		printk("ioremap EDB7312 NAND flash failed\n");
		kfree(ep7312_mtd);
		return -EIO;
	}
135

L
Linus Torvalds 已提交
136
	/* Get pointer to private data */
137
	this = (struct nand_chip *)(&ep7312_mtd[1]);
138

L
Linus Torvalds 已提交
139
	/* Initialize structures */
140 141
	memset(ep7312_mtd, 0, sizeof(struct mtd_info));
	memset(this, 0, sizeof(struct nand_chip));
142

L
Linus Torvalds 已提交
143 144
	/* Link the private data with the MTD structure */
	ep7312_mtd->priv = this;
145
	ep7312_mtd->owner = THIS_MODULE;
146

L
Linus Torvalds 已提交
147 148 149 150 151
	/*
	 * Set GPIO Port B control register so that the pins are configured
	 * to be outputs for controlling the NAND flash.
	 */
	clps_writeb(0xf0, ep7312_pxddr);
152

L
Linus Torvalds 已提交
153 154 155
	/* insert callbacks */
	this->IO_ADDR_R = ep7312_fio_base;
	this->IO_ADDR_W = ep7312_fio_base;
156
	this->cmd_ctrl = ep7312_hwcontrol;
L
Linus Torvalds 已提交
157 158 159
	this->dev_ready = ep7312_device_ready;
	/* 15 us command delay time */
	this->chip_delay = 15;
160

L
Linus Torvalds 已提交
161
	/* Scan to find existence of the device */
162
	if (nand_scan(ep7312_mtd, 1)) {
L
Linus Torvalds 已提交
163
		iounmap((void *)ep7312_fio_base);
164
		kfree(ep7312_mtd);
L
Linus Torvalds 已提交
165 166 167 168
		return -ENXIO;
	}
#ifdef CONFIG_MTD_PARTITIONS
	ep7312_mtd->name = "edb7312-nand";
169
	mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0);
L
Linus Torvalds 已提交
170 171 172 173 174 175 176 177 178 179
	if (mtd_parts_nb > 0)
		part_type = "command line";
	else
		mtd_parts_nb = 0;
#endif
	if (mtd_parts_nb == 0) {
		mtd_parts = partition_info;
		mtd_parts_nb = NUM_PARTITIONS;
		part_type = "static";
	}
180

L
Linus Torvalds 已提交
181 182 183
	/* Register the partitions */
	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
	add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb);
184

L
Linus Torvalds 已提交
185 186 187
	/* Return happy */
	return 0;
}
188

L
Linus Torvalds 已提交
189 190 191 192 193
module_init(ep7312_init);

/*
 * Clean up routine
 */
194
static void __exit ep7312_cleanup(void)
L
Linus Torvalds 已提交
195
{
196
	struct nand_chip *this = (struct nand_chip *)&ep7312_mtd[1];
197

L
Linus Torvalds 已提交
198
	/* Release resources, unregister device */
199
	nand_release(ap7312_mtd);
200

201
	/* Release io resource */
202
	iounmap(this->IO_ADDR_R);
203

L
Linus Torvalds 已提交
204
	/* Free the MTD device structure */
205
	kfree(ep7312_mtd);
L
Linus Torvalds 已提交
206
}
207

L
Linus Torvalds 已提交
208 209 210 211 212
module_exit(ep7312_cleanup);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
MODULE_DESCRIPTION("MTD map driver for Cogent EDB7312 board");