nfc_at91.c revision 266087
1/*- 2 * Copyright (C) 2013 Ian Lepore. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Atmel at91-family integrated NAND controller driver. 29 * 30 * This code relies on the board setup code (in at91/board_whatever.c) having 31 * set up the EBI and SMC registers appropriately for whatever type of nand part 32 * is on the board. 33 */ 34 35#include <sys/cdefs.h> 36__FBSDID("$FreeBSD: stable/10/sys/dev/nand/nfc_at91.c 266087 2014-05-14 20:31:54Z ian $"); 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/proc.h> 41#include <sys/bus.h> 42#include <sys/conf.h> 43#include <sys/kernel.h> 44#include <sys/module.h> 45#include <sys/malloc.h> 46#include <sys/rman.h> 47#include <sys/lock.h> 48#include <sys/mutex.h> 49#include <sys/time.h> 50 51#include <machine/bus.h> 52 53#include <dev/nand/nand.h> 54#include <dev/nand/nandbus.h> 55#include "nfc_if.h" 56 57#include <dev/nand/nfc_at91.h> 58#include <arm/at91/at91_smc.h> 59 60/* 61 * Data cycles are triggered by access to any address within the EBI CS3 region 62 * that has A21 and A22 clear. Command cycles are any access with bit A21 63 * asserted. Address cycles are any access with bit A22 asserted. Or vice versa. 64 * We get these parameters from the nand_param that the board is required to 65 * call at91_enable_nand, and enable the GPIO lines properly (that will be moved 66 * into at91_enable_nand when the great GPIO pin renumbering happens). We use 67 * ale (Address Latch Enable) and cle (Comand Latch Enable) to match the hardware 68 * names used in NAND. 69 */ 70#define AT91_NAND_DATA 0 71 72struct at91_nand_softc { 73 struct nand_softc nand_sc; 74 struct resource *res; 75 struct at91_nand_params *nand_param; 76}; 77 78static struct at91_nand_params nand_param; 79 80static int at91_nand_attach(device_t); 81static int at91_nand_probe(device_t); 82static uint8_t at91_nand_read_byte(device_t); 83static void at91_nand_read_buf(device_t, void *, uint32_t); 84static int at91_nand_read_rnb(device_t); 85static int at91_nand_select_cs(device_t, uint8_t); 86static int at91_nand_send_command(device_t, uint8_t); 87static int at91_nand_send_address(device_t, uint8_t); 88static void at91_nand_write_buf(device_t, void *, uint32_t); 89 90void 91at91_enable_nand(const struct at91_nand_params *np) 92{ 93 nand_param = *np; 94} 95 96static inline u_int8_t 97dev_read_1(struct at91_nand_softc *sc, bus_size_t offset) 98{ 99 return bus_read_1(sc->res, offset); 100} 101 102static inline void 103dev_write_1(struct at91_nand_softc *sc, bus_size_t offset, u_int8_t value) 104{ 105 bus_write_1(sc->res, offset, value); 106} 107 108static int 109at91_nand_probe(device_t dev) 110{ 111 112 device_set_desc(dev, "AT91 Integrated NAND controller"); 113 return (BUS_PROBE_DEFAULT); 114} 115 116static int 117at91_nand_attach(device_t dev) 118{ 119 struct at91_nand_softc *sc; 120 int err, rid; 121 122 sc = device_get_softc(dev); 123 sc->nand_param = &nand_param; 124 if (sc->nand_param->width != 8 && sc->nand_param->width != 16) { 125 device_printf(dev, "Bad bus width (%d) defaulting to 8 bits\n", 126 sc->nand_param->width); 127 sc->nand_param->width = 8; 128 } 129 at91_ebi_enable(sc->nand_param->cs); 130 131 rid = 0; 132 sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 133 RF_ACTIVE); 134 if (sc->res == NULL) { 135 device_printf(dev, "could not allocate resources!\n"); 136 return (ENXIO); 137 } 138 139 nand_init(&sc->nand_sc, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL); 140 141 err = nandbus_create(dev); 142 143 return (err); 144} 145 146static int 147at91_nand_send_command(device_t dev, uint8_t command) 148{ 149 struct at91_nand_softc *sc; 150 151 nand_debug(NDBG_DRV,"at91_nand_send_command: 0x%02x", command); 152 153 sc = device_get_softc(dev); 154 dev_write_1(sc, sc->nand_param->cle, command); 155 return (0); 156} 157 158static int 159at91_nand_send_address(device_t dev, uint8_t addr) 160{ 161 struct at91_nand_softc *sc; 162 163 nand_debug(NDBG_DRV,"at91_nand_send_address: x%02x", addr); 164 165 sc = device_get_softc(dev); 166 dev_write_1(sc, sc->nand_param->ale, addr); 167 return (0); 168} 169 170static uint8_t 171at91_nand_read_byte(device_t dev) 172{ 173 struct at91_nand_softc *sc; 174 uint8_t data; 175 176 sc = device_get_softc(dev); 177 data = dev_read_1(sc, AT91_NAND_DATA); 178 179 nand_debug(NDBG_DRV,"at91_nand_read_byte: 0x%02x", data); 180 181 return (data); 182} 183 184 185static void 186at91_nand_dump_buf(const char *op, void* buf, uint32_t len) 187{ 188 int i; 189 uint8_t *b = buf; 190 191 printf("at91_nand_%s_buf (hex):", op); 192 for (i = 0; i < len; i++) { 193 if ((i & 0x01f) == 0) 194 printf("\n"); 195 printf(" %02x", b[i]); 196 } 197 printf("\n"); 198} 199 200static void 201at91_nand_read_buf(device_t dev, void* buf, uint32_t len) 202{ 203 struct at91_nand_softc *sc; 204 205 sc = device_get_softc(dev); 206 207 bus_read_multi_1(sc->res, AT91_NAND_DATA, buf, len); 208 209 if (nand_debug_flag & NDBG_DRV) 210 at91_nand_dump_buf("read", buf, len); 211} 212 213static void 214at91_nand_write_buf(device_t dev, void* buf, uint32_t len) 215{ 216 struct at91_nand_softc *sc; 217 218 sc = device_get_softc(dev); 219 220 if (nand_debug_flag & NDBG_DRV) 221 at91_nand_dump_buf("write", buf, len); 222 223 bus_write_multi_1(sc->res, AT91_NAND_DATA, buf, len); 224} 225 226static int 227at91_nand_select_cs(device_t dev, uint8_t cs) 228{ 229 230 if (cs > 0) 231 return (ENODEV); 232 233 return (0); 234} 235 236static int 237at91_nand_read_rnb(device_t dev) 238{ 239#if 0 240 /* 241 * XXX There's no way for this code to know which GPIO pin (if any) is 242 * attached to the chip's RNB line. Not to worry, nothing calls this; 243 * at higher layers, all the nand code uses status commands. 244 */ 245 uint32_t bits; 246 247 bits = at91_pio_gpio_get(AT91RM92_PIOD_BASE, AT91C_PIO_PD15); 248 nand_debug(NDBG_DRV,"at91_nand: read_rnb: %#x", bits); 249 return (bits != 0); /* ready */ 250#endif 251 panic("at91_nand_read_rnb() is not implemented\n"); 252 return (0); 253} 254 255static device_method_t at91_nand_methods[] = { 256 DEVMETHOD(device_probe, at91_nand_probe), 257 DEVMETHOD(device_attach, at91_nand_attach), 258 259 DEVMETHOD(nfc_send_command, at91_nand_send_command), 260 DEVMETHOD(nfc_send_address, at91_nand_send_address), 261 DEVMETHOD(nfc_read_byte, at91_nand_read_byte), 262 DEVMETHOD(nfc_read_buf, at91_nand_read_buf), 263 DEVMETHOD(nfc_write_buf, at91_nand_write_buf), 264 DEVMETHOD(nfc_select_cs, at91_nand_select_cs), 265 DEVMETHOD(nfc_read_rnb, at91_nand_read_rnb), 266 267 DEVMETHOD_END 268}; 269 270static driver_t at91_nand_driver = { 271 "nand", 272 at91_nand_methods, 273 sizeof(struct at91_nand_softc), 274}; 275 276static devclass_t at91_nand_devclass; 277DRIVER_MODULE(at91_nand, atmelarm, at91_nand_driver, at91_nand_devclass, 0, 0); 278 279