1/* 2 * arch/cris/arch-v32/drivers/nandflash.c 3 * 4 * Copyright (c) 2007 5 * 6 * Derived from drivers/mtd/nand/spia.c 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 */ 14 15#include <linux/slab.h> 16#include <linux/init.h> 17#include <linux/module.h> 18#include <linux/mtd/mtd.h> 19#include <linux/mtd/nand.h> 20#include <linux/mtd/partitions.h> 21#include <arch/memmap.h> 22#include <hwregs/reg_map.h> 23#include <hwregs/reg_rdwr.h> 24#include <hwregs/pio_defs.h> 25#include <pinmux.h> 26#include <asm/io.h> 27 28#define MANUAL_ALE_CLE_CONTROL 1 29 30#define regf_ALE a0 31#define regf_CLE a1 32#define regf_NCE ce0_n 33 34#define CLE_BIT 10 35#define ALE_BIT 11 36#define CE_BIT 12 37 38struct mtd_info_wrapper { 39 struct mtd_info info; 40 struct nand_chip chip; 41}; 42 43/* Bitmask for control pins */ 44#define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT)) 45 46static struct mtd_info *crisv32_mtd; 47/* 48 * hardware specific access to control-lines 49 */ 50static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd, 51 unsigned int ctrl) 52{ 53 unsigned long flags; 54 reg_pio_rw_dout dout; 55 struct nand_chip *this = mtd->priv; 56 57 local_irq_save(flags); 58 59 /* control bits change */ 60 if (ctrl & NAND_CTRL_CHANGE) { 61 dout = REG_RD(pio, regi_pio, rw_dout); 62 dout.regf_NCE = (ctrl & NAND_NCE) ? 0 : 1; 63 64#if !MANUAL_ALE_CLE_CONTROL 65 if (ctrl & NAND_ALE) { 66 /* A0 = ALE high */ 67 this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio, 68 regi_pio, rw_io_access1); 69 } else if (ctrl & NAND_CLE) { 70 /* A1 = CLE high */ 71 this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio, 72 regi_pio, rw_io_access2); 73 } else { 74 /* A1 = CLE and A0 = ALE low */ 75 this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio, 76 regi_pio, rw_io_access0); 77 } 78#else 79 80 dout.regf_CLE = (ctrl & NAND_CLE) ? 1 : 0; 81 dout.regf_ALE = (ctrl & NAND_ALE) ? 1 : 0; 82#endif 83 REG_WR(pio, regi_pio, rw_dout, dout); 84 } 85 86 /* command to chip */ 87 if (cmd != NAND_CMD_NONE) 88 writeb(cmd, this->IO_ADDR_W); 89 90 local_irq_restore(flags); 91} 92 93/* 94* read device ready pin 95*/ 96static int crisv32_device_ready(struct mtd_info *mtd) 97{ 98 reg_pio_r_din din = REG_RD(pio, regi_pio, r_din); 99 return din.rdy; 100} 101 102/* 103 * Main initialization routine 104 */ 105struct mtd_info *__init crisv32_nand_flash_probe(void) 106{ 107 void __iomem *read_cs; 108 void __iomem *write_cs; 109 110 struct mtd_info_wrapper *wrapper; 111 struct nand_chip *this; 112 int err = 0; 113 114 reg_pio_rw_man_ctrl man_ctrl = { 115 .regf_NCE = regk_pio_yes, 116#if MANUAL_ALE_CLE_CONTROL 117 .regf_ALE = regk_pio_yes, 118 .regf_CLE = regk_pio_yes 119#endif 120 }; 121 reg_pio_rw_oe oe = { 122 .regf_NCE = regk_pio_yes, 123#if MANUAL_ALE_CLE_CONTROL 124 .regf_ALE = regk_pio_yes, 125 .regf_CLE = regk_pio_yes 126#endif 127 }; 128 reg_pio_rw_dout dout = { .regf_NCE = 1 }; 129 130 /* Allocate pio pins to pio */ 131 crisv32_pinmux_alloc_fixed(pinmux_pio); 132 /* Set up CE, ALE, CLE (ce0_n, a0, a1) for manual control and output */ 133 REG_WR(pio, regi_pio, rw_man_ctrl, man_ctrl); 134 REG_WR(pio, regi_pio, rw_dout, dout); 135 REG_WR(pio, regi_pio, rw_oe, oe); 136 137 /* Allocate memory for MTD device structure and private data */ 138 wrapper = kzalloc(sizeof(struct mtd_info_wrapper), GFP_KERNEL); 139 if (!wrapper) { 140 printk(KERN_ERR "Unable to allocate CRISv32 NAND MTD " 141 "device structure.\n"); 142 err = -ENOMEM; 143 return NULL; 144 } 145 146 read_cs = write_cs = (void __iomem *)REG_ADDR(pio, regi_pio, 147 rw_io_access0); 148 149 /* Get pointer to private data */ 150 this = &wrapper->chip; 151 crisv32_mtd = &wrapper->info; 152 153 /* Link the private data with the MTD structure */ 154 crisv32_mtd->priv = this; 155 156 /* Set address of NAND IO lines */ 157 this->IO_ADDR_R = read_cs; 158 this->IO_ADDR_W = write_cs; 159 this->cmd_ctrl = crisv32_hwcontrol; 160 this->dev_ready = crisv32_device_ready; 161 /* 20 us command delay time */ 162 this->chip_delay = 20; 163 this->ecc.mode = NAND_ECC_SOFT; 164 165 /* Enable the following for a flash based bad block table */ 166 /* this->bbt_options = NAND_BBT_USE_FLASH; */ 167 168 /* Scan to find existence of the device */ 169 if (nand_scan(crisv32_mtd, 1)) { 170 err = -ENXIO; 171 goto out_mtd; 172 } 173 174 return crisv32_mtd; 175 176out_mtd: 177 kfree(wrapper); 178 return NULL; 179} 180 181