1/* 2 * drivers/mtd/nand/toto.c 3 * 4 * Copyright (c) 2003 Texas Instruments 5 * 6 * Derived from drivers/mtd/autcpu12.c 7 * 8 * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * Overview: 15 * This is a device driver for the NAND flash device found on the 16 * TI fido board. It supports 32MiB and 64MiB cards 17 * 18 * $Id: toto.c,v 1.1.1.1 2007/08/03 18:52:44 Exp $ 19 */ 20 21#include <linux/slab.h> 22#include <linux/init.h> 23#include <linux/module.h> 24#include <linux/delay.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#include <asm/arch/hardware.h> 30#include <asm/sizes.h> 31#include <asm/arch/toto.h> 32#include <asm/arch-omap1510/hardware.h> 33#include <asm/arch/gpio.h> 34 35#define CONFIG_NAND_WORKAROUND 1 36 37/* 38 * MTD structure for TOTO board 39 */ 40static struct mtd_info *toto_mtd = NULL; 41 42static unsigned long toto_io_base = OMAP_FLASH_1_BASE; 43 44/* 45 * Define partitions for flash devices 46 */ 47 48static struct mtd_partition partition_info64M[] = { 49 { .name = "toto kernel partition 1", 50 .offset = 0, 51 .size = 2 * SZ_1M }, 52 { .name = "toto file sys partition 2", 53 .offset = 2 * SZ_1M, 54 .size = 14 * SZ_1M }, 55 { .name = "toto user partition 3", 56 .offset = 16 * SZ_1M, 57 .size = 16 * SZ_1M }, 58 { .name = "toto devboard extra partition 4", 59 .offset = 32 * SZ_1M, 60 .size = 32 * SZ_1M }, 61}; 62 63static struct mtd_partition partition_info32M[] = { 64 { .name = "toto kernel partition 1", 65 .offset = 0, 66 .size = 2 * SZ_1M }, 67 { .name = "toto file sys partition 2", 68 .offset = 2 * SZ_1M, 69 .size = 14 * SZ_1M }, 70 { .name = "toto user partition 3", 71 .offset = 16 * SZ_1M, 72 .size = 16 * SZ_1M }, 73}; 74 75#define NUM_PARTITIONS32M 3 76#define NUM_PARTITIONS64M 4 77 78/* 79 * hardware specific access to control-lines 80 * 81 * ctrl: 82 * NAND_NCE: bit 0 -> bit 14 (0x4000) 83 * NAND_CLE: bit 1 -> bit 12 (0x1000) 84 * NAND_ALE: bit 2 -> bit 1 (0x0002) 85 */ 86static void toto_hwcontrol(struct mtd_info *mtd, int cmd, 87 unsigned int ctrl) 88{ 89 struct nand_chip *chip = mtd->priv; 90 91 if (ctrl & NAND_CTRL_CHANGE) { 92 unsigned long bits; 93 94 /* hopefully enough time for tc make proceding write to clear */ 95 udelay(1); 96 97 bits = (~ctrl & NAND_NCE) << 14; 98 bits |= (ctrl & NAND_CLE) << 12; 99 bits |= (ctrl & NAND_ALE) >> 1; 100 101#warning Wild guess as gpiosetout() is nowhere defined in the kernel source - tglx 102 gpiosetout(0x5002, bits); 103 104#ifdef CONFIG_NAND_WORKAROUND 105 /* "some" dev boards busted, blue wired to rts2 :( */ 106 rts2setout(2, (ctrl & NAND_CLE) << 1); 107#endif 108 /* allow time to ensure gpio state to over take memory write */ 109 udelay(1); 110 } 111 112 if (cmd != NAND_CMD_NONE) 113 writeb(cmd, chip->IO_ADDR_W); 114} 115 116/* 117 * Main initialization routine 118 */ 119static int __init toto_init(void) 120{ 121 struct nand_chip *this; 122 int err = 0; 123 124 /* Allocate memory for MTD device structure and private data */ 125 toto_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); 126 if (!toto_mtd) { 127 printk(KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n"); 128 err = -ENOMEM; 129 goto out; 130 } 131 132 /* Get pointer to private data */ 133 this = (struct nand_chip *)(&toto_mtd[1]); 134 135 /* Initialize structures */ 136 memset(toto_mtd, 0, sizeof(struct mtd_info)); 137 memset(this, 0, sizeof(struct nand_chip)); 138 139 /* Link the private data with the MTD structure */ 140 toto_mtd->priv = this; 141 toto_mtd->owner = THIS_MODULE; 142 143 /* Set address of NAND IO lines */ 144 this->IO_ADDR_R = toto_io_base; 145 this->IO_ADDR_W = toto_io_base; 146 this->cmd_ctrl = toto_hwcontrol; 147 this->dev_ready = NULL; 148 /* 25 us command delay time */ 149 this->chip_delay = 30; 150 this->ecc.mode = NAND_ECC_SOFT; 151 152 /* Scan to find existance of the device */ 153 if (nand_scan(toto_mtd, 1)) { 154 err = -ENXIO; 155 goto out_mtd; 156 } 157 158 /* Register the partitions */ 159 switch (toto_mtd->size) { 160 case SZ_64M: 161 add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); 162 break; 163 case SZ_32M: 164 add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); 165 break; 166 default:{ 167 printk(KERN_WARNING "Unsupported Nand device\n"); 168 err = -ENXIO; 169 goto out_buf; 170 } 171 } 172 173 gpioreserve(NAND_MASK); /* claim our gpios */ 174 archflashwp(0, 0); /* open up flash for writing */ 175 176 goto out; 177 178 out_mtd: 179 kfree(toto_mtd); 180 out: 181 return err; 182} 183 184module_init(toto_init); 185 186/* 187 * Clean up routine 188 */ 189static void __exit toto_cleanup(void) 190{ 191 /* Release resources, unregister device */ 192 nand_release(toto_mtd); 193 194 /* Free the MTD device structure */ 195 kfree(toto_mtd); 196 197 /* stop flash writes */ 198 archflashwp(0, 1); 199 200 /* release gpios to system */ 201 gpiorelease(NAND_MASK); 202} 203 204module_exit(toto_cleanup); 205 206MODULE_LICENSE("GPL"); 207MODULE_AUTHOR("Richard Woodruff <r-woodruff2@ti.com>"); 208MODULE_DESCRIPTION("Glue layer for NAND flash on toto board"); 209