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