1258828Sian/*- 2258828Sian * Copyright (C) 2013 Ian Lepore. 3258828Sian * All rights reserved. 4258828Sian * 5258828Sian * Redistribution and use in source and binary forms, with or without 6258828Sian * modification, are permitted provided that the following conditions 7258828Sian * are met: 8258828Sian * 1. Redistributions of source code must retain the above copyright 9258828Sian * notice, this list of conditions and the following disclaimer. 10258828Sian * 2. Redistributions in binary form must reproduce the above copyright 11258828Sian * notice, this list of conditions and the following disclaimer in the 12258828Sian * documentation and/or other materials provided with the distribution. 13258828Sian * 14258828Sian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15258828Sian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16258828Sian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17258828Sian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18258828Sian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19258828Sian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20258828Sian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21258828Sian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22258828Sian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23258828Sian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24258828Sian * SUCH DAMAGE. 25258828Sian */ 26258828Sian 27258828Sian/* 28258828Sian * Atmel at91-family integrated NAND controller driver. 29258828Sian * 30258828Sian * This code relies on the board setup code (in at91/board_whatever.c) having 31258828Sian * set up the EBI and SMC registers appropriately for whatever type of nand part 32258828Sian * is on the board. 33258828Sian */ 34258828Sian 35266217Sian#include "opt_platform.h" 36266217Sian 37258828Sian#include <sys/cdefs.h> 38258828Sian__FBSDID("$FreeBSD: releng/10.2/sys/dev/nand/nfc_at91.c 266217 2014-05-16 12:43:45Z ian $"); 39258828Sian 40258828Sian#include <sys/param.h> 41258828Sian#include <sys/systm.h> 42258828Sian#include <sys/proc.h> 43258828Sian#include <sys/bus.h> 44258828Sian#include <sys/conf.h> 45258828Sian#include <sys/kernel.h> 46258828Sian#include <sys/module.h> 47258828Sian#include <sys/malloc.h> 48258828Sian#include <sys/rman.h> 49258828Sian#include <sys/lock.h> 50258828Sian#include <sys/mutex.h> 51258828Sian#include <sys/time.h> 52258828Sian 53258828Sian#include <machine/bus.h> 54258828Sian 55258828Sian#include <dev/nand/nand.h> 56258828Sian#include <dev/nand/nandbus.h> 57258828Sian#include "nfc_if.h" 58258828Sian 59266087Sian#include <dev/nand/nfc_at91.h> 60266087Sian#include <arm/at91/at91_smc.h> 61266087Sian 62266217Sian#ifdef FDT 63266217Sian#include <dev/fdt/fdt_common.h> 64266217Sian#include <dev/ofw/ofw_bus.h> 65266217Sian#include <dev/ofw/ofw_bus_subr.h> 66266217Sian#endif 67266217Sian 68258828Sian/* 69258828Sian * Data cycles are triggered by access to any address within the EBI CS3 region 70258828Sian * that has A21 and A22 clear. Command cycles are any access with bit A21 71266087Sian * asserted. Address cycles are any access with bit A22 asserted. Or vice versa. 72266087Sian * We get these parameters from the nand_param that the board is required to 73266087Sian * call at91_enable_nand, and enable the GPIO lines properly (that will be moved 74266087Sian * into at91_enable_nand when the great GPIO pin renumbering happens). We use 75266087Sian * ale (Address Latch Enable) and cle (Comand Latch Enable) to match the hardware 76266087Sian * names used in NAND. 77258828Sian */ 78258828Sian#define AT91_NAND_DATA 0 79258828Sian 80258828Sianstruct at91_nand_softc { 81258828Sian struct nand_softc nand_sc; 82258828Sian struct resource *res; 83266087Sian struct at91_nand_params *nand_param; 84258828Sian}; 85258828Sian 86266087Sianstatic struct at91_nand_params nand_param; 87266087Sian 88258828Sianstatic int at91_nand_attach(device_t); 89258828Sianstatic int at91_nand_probe(device_t); 90258828Sianstatic uint8_t at91_nand_read_byte(device_t); 91258828Sianstatic void at91_nand_read_buf(device_t, void *, uint32_t); 92258828Sianstatic int at91_nand_read_rnb(device_t); 93258828Sianstatic int at91_nand_select_cs(device_t, uint8_t); 94258828Sianstatic int at91_nand_send_command(device_t, uint8_t); 95258828Sianstatic int at91_nand_send_address(device_t, uint8_t); 96258828Sianstatic void at91_nand_write_buf(device_t, void *, uint32_t); 97258828Sian 98266087Sianvoid 99266087Sianat91_enable_nand(const struct at91_nand_params *np) 100266087Sian{ 101266087Sian nand_param = *np; 102266087Sian} 103266087Sian 104258828Sianstatic inline u_int8_t 105258828Siandev_read_1(struct at91_nand_softc *sc, bus_size_t offset) 106258828Sian{ 107258828Sian return bus_read_1(sc->res, offset); 108258828Sian} 109258828Sian 110258828Sianstatic inline void 111258828Siandev_write_1(struct at91_nand_softc *sc, bus_size_t offset, u_int8_t value) 112258828Sian{ 113258828Sian bus_write_1(sc->res, offset, value); 114258828Sian} 115258828Sian 116258828Sianstatic int 117258828Sianat91_nand_probe(device_t dev) 118258828Sian{ 119266217Sian#ifdef FDT 120266217Sian if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-nand")) 121266217Sian return (ENXIO); 122266217Sian#endif 123258828Sian device_set_desc(dev, "AT91 Integrated NAND controller"); 124258828Sian return (BUS_PROBE_DEFAULT); 125258828Sian} 126258828Sian 127258828Sianstatic int 128258828Sianat91_nand_attach(device_t dev) 129258828Sian{ 130258828Sian struct at91_nand_softc *sc; 131258828Sian int err, rid; 132258828Sian 133258828Sian sc = device_get_softc(dev); 134266087Sian sc->nand_param = &nand_param; 135266087Sian if (sc->nand_param->width != 8 && sc->nand_param->width != 16) { 136266087Sian device_printf(dev, "Bad bus width (%d) defaulting to 8 bits\n", 137266087Sian sc->nand_param->width); 138266087Sian sc->nand_param->width = 8; 139266087Sian } 140266087Sian at91_ebi_enable(sc->nand_param->cs); 141266087Sian 142258828Sian rid = 0; 143258828Sian sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 144258828Sian RF_ACTIVE); 145258828Sian if (sc->res == NULL) { 146258828Sian device_printf(dev, "could not allocate resources!\n"); 147258828Sian return (ENXIO); 148258828Sian } 149258828Sian 150258828Sian nand_init(&sc->nand_sc, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL); 151258828Sian 152258828Sian err = nandbus_create(dev); 153258828Sian 154258828Sian return (err); 155258828Sian} 156258828Sian 157258828Sianstatic int 158258828Sianat91_nand_send_command(device_t dev, uint8_t command) 159258828Sian{ 160258828Sian struct at91_nand_softc *sc; 161258828Sian 162266087Sian nand_debug(NDBG_DRV,"at91_nand_send_command: 0x%02x", command); 163258828Sian 164258828Sian sc = device_get_softc(dev); 165266087Sian dev_write_1(sc, sc->nand_param->cle, command); 166258828Sian return (0); 167258828Sian} 168258828Sian 169258828Sianstatic int 170258828Sianat91_nand_send_address(device_t dev, uint8_t addr) 171258828Sian{ 172258828Sian struct at91_nand_softc *sc; 173258828Sian 174266087Sian nand_debug(NDBG_DRV,"at91_nand_send_address: x%02x", addr); 175258828Sian 176258828Sian sc = device_get_softc(dev); 177266087Sian dev_write_1(sc, sc->nand_param->ale, addr); 178258828Sian return (0); 179258828Sian} 180258828Sian 181258828Sianstatic uint8_t 182258828Sianat91_nand_read_byte(device_t dev) 183258828Sian{ 184258828Sian struct at91_nand_softc *sc; 185258828Sian uint8_t data; 186258828Sian 187258828Sian sc = device_get_softc(dev); 188258828Sian data = dev_read_1(sc, AT91_NAND_DATA); 189258828Sian 190266087Sian nand_debug(NDBG_DRV,"at91_nand_read_byte: 0x%02x", data); 191258828Sian 192258828Sian return (data); 193258828Sian} 194258828Sian 195258828Sian 196258828Sianstatic void 197258828Sianat91_nand_dump_buf(const char *op, void* buf, uint32_t len) 198258828Sian{ 199258828Sian int i; 200258828Sian uint8_t *b = buf; 201258828Sian 202258828Sian printf("at91_nand_%s_buf (hex):", op); 203258828Sian for (i = 0; i < len; i++) { 204258828Sian if ((i & 0x01f) == 0) 205258828Sian printf("\n"); 206258828Sian printf(" %02x", b[i]); 207258828Sian } 208258828Sian printf("\n"); 209258828Sian} 210258828Sian 211258828Sianstatic void 212258828Sianat91_nand_read_buf(device_t dev, void* buf, uint32_t len) 213258828Sian{ 214258828Sian struct at91_nand_softc *sc; 215258828Sian 216258828Sian sc = device_get_softc(dev); 217258828Sian 218258828Sian bus_read_multi_1(sc->res, AT91_NAND_DATA, buf, len); 219258828Sian 220258828Sian if (nand_debug_flag & NDBG_DRV) 221258828Sian at91_nand_dump_buf("read", buf, len); 222258828Sian} 223258828Sian 224258828Sianstatic void 225258828Sianat91_nand_write_buf(device_t dev, void* buf, uint32_t len) 226258828Sian{ 227258828Sian struct at91_nand_softc *sc; 228258828Sian 229258828Sian sc = device_get_softc(dev); 230258828Sian 231258828Sian if (nand_debug_flag & NDBG_DRV) 232258828Sian at91_nand_dump_buf("write", buf, len); 233258828Sian 234258828Sian bus_write_multi_1(sc->res, AT91_NAND_DATA, buf, len); 235258828Sian} 236258828Sian 237258828Sianstatic int 238258828Sianat91_nand_select_cs(device_t dev, uint8_t cs) 239258828Sian{ 240258828Sian 241258828Sian if (cs > 0) 242258828Sian return (ENODEV); 243258828Sian 244258828Sian return (0); 245258828Sian} 246258828Sian 247258828Sianstatic int 248258828Sianat91_nand_read_rnb(device_t dev) 249258828Sian{ 250258828Sian#if 0 251258828Sian /* 252258828Sian * XXX There's no way for this code to know which GPIO pin (if any) is 253258828Sian * attached to the chip's RNB line. Not to worry, nothing calls this; 254258828Sian * at higher layers, all the nand code uses status commands. 255258828Sian */ 256258828Sian uint32_t bits; 257258828Sian 258258828Sian bits = at91_pio_gpio_get(AT91RM92_PIOD_BASE, AT91C_PIO_PD15); 259258828Sian nand_debug(NDBG_DRV,"at91_nand: read_rnb: %#x", bits); 260258828Sian return (bits != 0); /* ready */ 261258828Sian#endif 262258828Sian panic("at91_nand_read_rnb() is not implemented\n"); 263258828Sian return (0); 264258828Sian} 265258828Sian 266258828Sianstatic device_method_t at91_nand_methods[] = { 267258828Sian DEVMETHOD(device_probe, at91_nand_probe), 268258828Sian DEVMETHOD(device_attach, at91_nand_attach), 269258828Sian 270258828Sian DEVMETHOD(nfc_send_command, at91_nand_send_command), 271258828Sian DEVMETHOD(nfc_send_address, at91_nand_send_address), 272258828Sian DEVMETHOD(nfc_read_byte, at91_nand_read_byte), 273258828Sian DEVMETHOD(nfc_read_buf, at91_nand_read_buf), 274258828Sian DEVMETHOD(nfc_write_buf, at91_nand_write_buf), 275258828Sian DEVMETHOD(nfc_select_cs, at91_nand_select_cs), 276258828Sian DEVMETHOD(nfc_read_rnb, at91_nand_read_rnb), 277258828Sian 278258828Sian DEVMETHOD_END 279258828Sian}; 280258828Sian 281258828Sianstatic driver_t at91_nand_driver = { 282258828Sian "nand", 283258828Sian at91_nand_methods, 284258828Sian sizeof(struct at91_nand_softc), 285258828Sian}; 286258828Sian 287258828Sianstatic devclass_t at91_nand_devclass; 288266217Sian 289266217Sian#ifdef FDT 290266217SianDRIVER_MODULE(at91_nand, simplebus, at91_nand_driver, at91_nand_devclass, 0, 0); 291266217Sian#else 292258828SianDRIVER_MODULE(at91_nand, atmelarm, at91_nand_driver, at91_nand_devclass, 0, 0); 293266217Sian#endif 294