1/* 2 * drivers/mtd/nand/spia.c 3 * 4 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 5 * 6 * 7 * 10-29-2001 TG change to support hardwarespecific access 8 * to controllines (due to change in nand.c) 9 * page_cache added 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 * 15 * Overview: 16 * This is a device driver for the NAND flash device found on the 17 * SPIA board which utilizes the Toshiba TC58V64AFT part. This is 18 * a 64Mibit (8MiB x 8 bits) NAND flash device. 19 */ 20 21#include <linux/kernel.h> 22#include <linux/init.h> 23#include <linux/slab.h> 24#include <linux/module.h> 25#include <linux/mtd/mtd.h> 26#include <linux/mtd/nand.h> 27#include <linux/mtd/partitions.h> 28#include <asm/io.h> 29 30/* 31 * MTD structure for SPIA board 32 */ 33static struct mtd_info *spia_mtd = NULL; 34 35/* 36 * Values specific to the SPIA board (used with EP7212 processor) 37 */ 38#define SPIA_IO_BASE 0xd0000000 /* Start of EP7212 IO address space */ 39#define SPIA_FIO_BASE 0xf0000000 /* Address where flash is mapped */ 40#define SPIA_PEDR 0x0080 /* 41 * IO offset to Port E data register 42 * where the CLE, ALE and NCE pins 43 * are wired to. 44 */ 45#define SPIA_PEDDR 0x00c0 /* 46 * IO offset to Port E data direction 47 * register so we can control the IO 48 * lines. 49 */ 50 51/* 52 * Module stuff 53 */ 54 55static int spia_io_base = SPIA_IO_BASE; 56static int spia_fio_base = SPIA_FIO_BASE; 57static int spia_pedr = SPIA_PEDR; 58static int spia_peddr = SPIA_PEDDR; 59 60module_param(spia_io_base, int, 0); 61module_param(spia_fio_base, int, 0); 62module_param(spia_pedr, int, 0); 63module_param(spia_peddr, int, 0); 64 65/* 66 * Define partitions for flash device 67 */ 68static const struct mtd_partition partition_info[] = { 69 { 70 .name = "SPIA flash partition 1", 71 .offset = 0, 72 .size = 2 * 1024 * 1024}, 73 { 74 .name = "SPIA flash partition 2", 75 .offset = 2 * 1024 * 1024, 76 .size = 6 * 1024 * 1024} 77}; 78 79#define NUM_PARTITIONS 2 80 81/* 82 * hardware specific access to control-lines 83 * 84 * ctrl: 85 * NAND_CNE: bit 0 -> bit 2 86 * NAND_CLE: bit 1 -> bit 0 87 * NAND_ALE: bit 2 -> bit 1 88 */ 89static void spia_hwcontrol(struct mtd_info *mtd, int cmd) 90{ 91 struct nand_chip *chip = mtd->priv; 92 93 if (ctrl & NAND_CTRL_CHANGE) { 94 void __iomem *addr = spia_io_base + spia_pedr; 95 unsigned char bits; 96 97 bits = (ctrl & NAND_CNE) << 2; 98 bits |= (ctrl & NAND_CLE | NAND_ALE) >> 1; 99 writeb((readb(addr) & ~0x7) | bits, addr); 100 } 101 102 if (cmd != NAND_CMD_NONE) 103 writeb(cmd, chip->IO_ADDR_W); 104} 105 106/* 107 * Main initialization routine 108 */ 109static int __init spia_init(void) 110{ 111 struct nand_chip *this; 112 113 /* Allocate memory for MTD device structure and private data */ 114 spia_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); 115 if (!spia_mtd) { 116 printk("Unable to allocate SPIA NAND MTD device structure.\n"); 117 return -ENOMEM; 118 } 119 120 /* Get pointer to private data */ 121 this = (struct nand_chip *)(&spia_mtd[1]); 122 123 /* Initialize structures */ 124 memset(spia_mtd, 0, sizeof(struct mtd_info)); 125 memset(this, 0, sizeof(struct nand_chip)); 126 127 /* Link the private data with the MTD structure */ 128 spia_mtd->priv = this; 129 spia_mtd->owner = THIS_MODULE; 130 131 /* 132 * Set GPIO Port E control register so that the pins are configured 133 * to be outputs for controlling the NAND flash. 134 */ 135 (*(volatile unsigned char *)(spia_io_base + spia_peddr)) = 0x07; 136 137 /* Set address of NAND IO lines */ 138 this->IO_ADDR_R = (void __iomem *)spia_fio_base; 139 this->IO_ADDR_W = (void __iomem *)spia_fio_base; 140 /* Set address of hardware control function */ 141 this->cmd_ctrl = spia_hwcontrol; 142 /* 15 us command delay time */ 143 this->chip_delay = 15; 144 145 /* Scan to find existence of the device */ 146 if (nand_scan(spia_mtd, 1)) { 147 kfree(spia_mtd); 148 return -ENXIO; 149 } 150 151 /* Register the partitions */ 152 add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS); 153 154 /* Return happy */ 155 return 0; 156} 157 158module_init(spia_init); 159 160/* 161 * Clean up routine 162 */ 163static void __exit spia_cleanup(void) 164{ 165 /* Release resources, unregister device */ 166 nand_release(spia_mtd); 167 168 /* Free the MTD device structure */ 169 kfree(spia_mtd); 170} 171 172module_exit(spia_cleanup); 173 174MODULE_LICENSE("GPL"); 175MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com"); 176MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on SPIA board"); 177