1/*- 2 * Copyright (C) 2009-2012 Semihalf 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#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/socket.h> 34#include <sys/malloc.h> 35#include <sys/module.h> 36#include <sys/bus.h> 37#include <sys/proc.h> 38#include <sys/lock.h> 39#include <sys/mutex.h> 40#include <sys/condvar.h> 41 42#include <dev/nand/nand.h> 43#include <dev/nand/nandbus.h> 44#include "nand_if.h" 45#include "nandbus_if.h" 46#include "nfc_if.h" 47 48#define NAND_NCS 4 49 50static int nandbus_probe(device_t dev); 51static int nandbus_attach(device_t dev); 52static int nandbus_detach(device_t dev); 53 54static int nandbus_child_location_str(device_t, device_t, char *, size_t); 55static int nandbus_child_pnpinfo_str(device_t, device_t, char *, size_t); 56 57static int nandbus_get_status(device_t, uint8_t *); 58static void nandbus_read_buffer(device_t, void *, uint32_t); 59static int nandbus_select_cs(device_t, uint8_t); 60static int nandbus_send_command(device_t, uint8_t); 61static int nandbus_send_address(device_t, uint8_t); 62static int nandbus_start_command(device_t); 63static int nandbus_wait_ready(device_t, uint8_t *); 64static void nandbus_write_buffer(device_t, void *, uint32_t); 65static int nandbus_get_ecc(device_t, void *, uint32_t, void *, int *); 66static int nandbus_correct_ecc(device_t, void *, int, void *, void *); 67static void nandbus_lock(device_t); 68static void nandbus_unlock(device_t); 69 70static int nand_readid(device_t, uint8_t *, uint8_t *); 71static int nand_probe_onfi(device_t, uint8_t *); 72static int nand_reset(device_t); 73 74struct nandbus_softc { 75 device_t dev; 76 struct cv nandbus_cv; 77 struct mtx nandbus_mtx; 78 uint8_t busy; 79}; 80 81static device_method_t nandbus_methods[] = { 82 /* device interface */ 83 DEVMETHOD(device_probe, nandbus_probe), 84 DEVMETHOD(device_attach, nandbus_attach), 85 DEVMETHOD(device_detach, nandbus_detach), 86 DEVMETHOD(device_shutdown, bus_generic_shutdown), 87 88 /* bus interface */ 89 DEVMETHOD(bus_print_child, bus_generic_print_child), 90 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 91 DEVMETHOD(bus_child_pnpinfo_str, nandbus_child_pnpinfo_str), 92 DEVMETHOD(bus_child_location_str, nandbus_child_location_str), 93 94 /* nandbus interface */ 95 DEVMETHOD(nandbus_get_status, nandbus_get_status), 96 DEVMETHOD(nandbus_read_buffer, nandbus_read_buffer), 97 DEVMETHOD(nandbus_select_cs, nandbus_select_cs), 98 DEVMETHOD(nandbus_send_command, nandbus_send_command), 99 DEVMETHOD(nandbus_send_address, nandbus_send_address), 100 DEVMETHOD(nandbus_start_command,nandbus_start_command), 101 DEVMETHOD(nandbus_wait_ready, nandbus_wait_ready), 102 DEVMETHOD(nandbus_write_buffer, nandbus_write_buffer), 103 DEVMETHOD(nandbus_get_ecc, nandbus_get_ecc), 104 DEVMETHOD(nandbus_correct_ecc, nandbus_correct_ecc), 105 DEVMETHOD(nandbus_lock, nandbus_lock), 106 DEVMETHOD(nandbus_unlock, nandbus_unlock), 107 { 0, 0 } 108}; 109 110devclass_t nandbus_devclass; 111 112driver_t nandbus_driver = { 113 "nandbus", 114 nandbus_methods, 115 sizeof(struct nandbus_softc) 116}; 117 118DRIVER_MODULE(nandbus, nand, nandbus_driver, nandbus_devclass, 0, 0); 119 120int 121nandbus_create(device_t nfc) 122{ 123 device_t child; 124 125 child = device_add_child(nfc, "nandbus", -1); 126 if (!child) 127 return (ENODEV); 128 129 bus_generic_attach(nfc); 130 131 return(0); 132} 133 134void 135nandbus_destroy(device_t nfc) 136{ 137 device_t *children; 138 int nchildren, i; 139 140 mtx_lock(&Giant); 141 /* Detach & delete all children */ 142 if (!device_get_children(nfc, &children, &nchildren)) { 143 for (i = 0; i < nchildren; i++) 144 device_delete_child(nfc, children[i]); 145 146 free(children, M_TEMP); 147 } 148 mtx_unlock(&Giant); 149} 150 151static int 152nandbus_probe(device_t dev) 153{ 154 155 device_set_desc(dev, "NAND bus"); 156 157 return (0); 158} 159 160static int 161nandbus_attach(device_t dev) 162{ 163 device_t child, nfc; 164 struct nand_id chip_id; 165 struct nandbus_softc *sc; 166 struct nandbus_ivar *ivar; 167 struct nand_softc *nfc_sc; 168 struct nand_params *chip_params; 169 uint8_t cs, onfi; 170 171 sc = device_get_softc(dev); 172 sc->dev = dev; 173 174 nfc = device_get_parent(dev); 175 nfc_sc = device_get_softc(nfc); 176 177 mtx_init(&sc->nandbus_mtx, "nandbus lock", MTX_DEF, 0); 178 cv_init(&sc->nandbus_cv, "nandbus cv"); 179 180 /* Check each possible CS for existing nand devices */ 181 for (cs = 0; cs < NAND_NCS; cs++) { 182 nand_debug(NDBG_BUS,"probe chip select %x", cs); 183 184 /* Select & reset chip */ 185 if (nandbus_select_cs(dev, cs)) 186 break; 187 188 if (nand_reset(dev)) 189 continue; 190 191 /* Read manufacturer and device id */ 192 if (nand_readid(dev, &chip_id.man_id, &chip_id.dev_id)) 193 continue; 194 195 if (chip_id.man_id == 0xff) 196 continue; 197 198 /* Check if chip is ONFI compliant */ 199 if (nand_probe_onfi(dev, &onfi) != 0) { 200 continue; 201 } 202 203 ivar = malloc(sizeof(struct nandbus_ivar), 204 M_NAND, M_WAITOK); 205 206 if (onfi == 1) { 207 ivar->cs = cs; 208 ivar->cols = 0; 209 ivar->rows = 0; 210 ivar->params = NULL; 211 ivar->man_id = chip_id.man_id; 212 ivar->dev_id = chip_id.dev_id; 213 ivar->is_onfi = onfi; 214 ivar->chip_cdev_name = nfc_sc->chip_cdev_name; 215 216 child = device_add_child(dev, NULL, -1); 217 device_set_ivars(child, ivar); 218 continue; 219 } 220 221 chip_params = nand_get_params(&chip_id); 222 if (chip_params == NULL) { 223 nand_debug(NDBG_BUS,"Chip description not found! " 224 "(manuf: 0x%0x, chipid: 0x%0x)\n", 225 chip_id.man_id, chip_id.dev_id); 226 free(ivar, M_NAND); 227 continue; 228 } 229 230 ivar->cs = cs; 231 ivar->cols = 1; 232 ivar->rows = 2; 233 ivar->params = chip_params; 234 ivar->man_id = chip_id.man_id; 235 ivar->dev_id = chip_id.dev_id; 236 ivar->is_onfi = onfi; 237 ivar->chip_cdev_name = nfc_sc->chip_cdev_name; 238 239 /* 240 * Check what type of device we have. 241 * devices bigger than 32MiB have on more row (3) 242 */ 243 if (chip_params->chip_size > 32) 244 ivar->rows++; 245 /* Large page devices have one more col (2) */ 246 if (chip_params->chip_size >= 128 && 247 chip_params->page_size > 512) 248 ivar->cols++; 249 250 child = device_add_child(dev, NULL, -1); 251 device_set_ivars(child, ivar); 252 } 253 254 bus_generic_attach(dev); 255 return (0); 256} 257 258static int 259nandbus_detach(device_t dev) 260{ 261 struct nandbus_softc *sc; 262 263 sc = device_get_softc(dev); 264 265 bus_generic_detach(dev); 266 267 mtx_destroy(&sc->nandbus_mtx); 268 cv_destroy(&sc->nandbus_cv); 269 270 return (0); 271} 272 273static int 274nandbus_child_location_str(device_t bus, device_t child, char *buf, 275 size_t buflen) 276{ 277 struct nandbus_ivar *ivar = device_get_ivars(child); 278 279 snprintf(buf, buflen, "at cs#%d", ivar->cs); 280 return (0); 281} 282 283static int 284nandbus_child_pnpinfo_str(device_t bus, device_t child, char *buf, 285 size_t buflen) 286{ 287 // XXX man id, model id ???? 288 *buf = '\0'; 289 return (0); 290} 291 292static int 293nand_readid(device_t bus, uint8_t *man_id, uint8_t *dev_id) 294{ 295 device_t nfc; 296 297 if (!bus || !man_id || !dev_id) 298 return (EINVAL); 299 300 nand_debug(NDBG_BUS,"read id"); 301 302 nfc = device_get_parent(bus); 303 304 if (NFC_SEND_COMMAND(nfc, NAND_CMD_READ_ID)) { 305 nand_debug(NDBG_BUS,"Error : could not send READ ID command"); 306 return (ENXIO); 307 } 308 309 if (NFC_SEND_ADDRESS(nfc, 0)) { 310 nand_debug(NDBG_BUS,"Error : could not sent address to chip"); 311 return (ENXIO); 312 } 313 314 if (NFC_START_COMMAND(nfc) != 0) { 315 nand_debug(NDBG_BUS,"Error : could not start command"); 316 return (ENXIO); 317 } 318 319 DELAY(25); 320 321 *man_id = NFC_READ_BYTE(nfc); 322 *dev_id = NFC_READ_BYTE(nfc); 323 324 nand_debug(NDBG_BUS,"manufacturer id: %x chip id: %x", *man_id, 325 *dev_id); 326 327 return (0); 328} 329 330static int 331nand_probe_onfi(device_t bus, uint8_t *onfi_compliant) 332{ 333 device_t nfc; 334 char onfi_id[] = {'O', 'N', 'F', 'I', '\0'}; 335 int i; 336 337 nand_debug(NDBG_BUS,"probing ONFI"); 338 339 nfc = device_get_parent(bus); 340 341 if (NFC_SEND_COMMAND(nfc, NAND_CMD_READ_ID)) { 342 nand_debug(NDBG_BUS,"Error : could not sent READ ID command"); 343 return (ENXIO); 344 } 345 346 if (NFC_SEND_ADDRESS(nfc, ONFI_SIG_ADDR)) { 347 nand_debug(NDBG_BUS,"Error : could not sent address to chip"); 348 return (ENXIO); 349 } 350 351 if (NFC_START_COMMAND(nfc) != 0) { 352 nand_debug(NDBG_BUS,"Error : could not start command"); 353 return (ENXIO); 354 } 355 for (i = 0; onfi_id[i] != '\0'; i++) 356 if (NFC_READ_BYTE(nfc) != onfi_id[i]) { 357 nand_debug(NDBG_BUS,"ONFI non-compliant"); 358 *onfi_compliant = 0; 359 return (0); 360 } 361 362 nand_debug(NDBG_BUS,"ONFI compliant"); 363 *onfi_compliant = 1; 364 365 return (0); 366} 367 368static int 369nand_reset(device_t bus) 370{ 371 device_t nfc; 372 nand_debug(NDBG_BUS,"resetting..."); 373 374 nfc = device_get_parent(bus); 375 376 if (NFC_SEND_COMMAND(nfc, NAND_CMD_RESET) != 0) { 377 nand_debug(NDBG_BUS,"Error : could not sent RESET command"); 378 return (ENXIO); 379 } 380 381 if (NFC_START_COMMAND(nfc) != 0) { 382 nand_debug(NDBG_BUS,"Error : could not start RESET command"); 383 return (ENXIO); 384 } 385 386 DELAY(1000); 387 388 return (0); 389} 390 391void 392nandbus_lock(device_t dev) 393{ 394 struct nandbus_softc *sc; 395 396 sc = device_get_softc(dev); 397 398 mtx_lock(&sc->nandbus_mtx); 399 if (sc->busy) 400 cv_wait(&sc->nandbus_cv, &sc->nandbus_mtx); 401 sc->busy = 1; 402 mtx_unlock(&sc->nandbus_mtx); 403} 404 405void 406nandbus_unlock(device_t dev) 407{ 408 struct nandbus_softc *sc; 409 410 sc = device_get_softc(dev); 411 412 mtx_lock(&sc->nandbus_mtx); 413 sc->busy = 0; 414 cv_signal(&sc->nandbus_cv); 415 mtx_unlock(&sc->nandbus_mtx); 416} 417 418int 419nandbus_select_cs(device_t dev, uint8_t cs) 420{ 421 422 return (NFC_SELECT_CS(device_get_parent(dev), cs)); 423} 424 425int 426nandbus_send_command(device_t dev, uint8_t command) 427{ 428 int err; 429 430 if ((err = NFC_SEND_COMMAND(device_get_parent(dev), command))) 431 nand_debug(NDBG_BUS,"Err: Could not send command %x, err %x", 432 command, err); 433 434 return (err); 435} 436 437int 438nandbus_send_address(device_t dev, uint8_t address) 439{ 440 int err; 441 442 if ((err = NFC_SEND_ADDRESS(device_get_parent(dev), address))) 443 nand_debug(NDBG_BUS,"Err: Could not send address %x, err %x", 444 address, err); 445 446 return (err); 447} 448 449int 450nandbus_start_command(device_t dev) 451{ 452 int err; 453 454 if ((err = NFC_START_COMMAND(device_get_parent(dev)))) 455 nand_debug(NDBG_BUS,"Err: Could not start command, err %x", 456 err); 457 458 return (err); 459} 460 461void 462nandbus_read_buffer(device_t dev, void *buf, uint32_t len) 463{ 464 465 NFC_READ_BUF(device_get_parent(dev), buf, len); 466} 467 468void 469nandbus_write_buffer(device_t dev, void *buf, uint32_t len) 470{ 471 472 NFC_WRITE_BUF(device_get_parent(dev), buf, len); 473} 474 475int 476nandbus_get_status(device_t dev, uint8_t *status) 477{ 478 int err; 479 480 if ((err = NANDBUS_SEND_COMMAND(dev, NAND_CMD_STATUS))) 481 return (err); 482 if ((err = NANDBUS_START_COMMAND(dev))) 483 return (err); 484 485 *status = NFC_READ_BYTE(device_get_parent(dev)); 486 487 return (0); 488} 489 490int 491nandbus_wait_ready(device_t dev, uint8_t *status) 492{ 493 struct timeval tv, tv2; 494 495 tv2.tv_sec = 0; 496 tv2.tv_usec = 50 * 5000; /* 10ms */ 497 498 getmicrotime(&tv); 499 timevaladd(&tv, &tv2); 500 501 do { 502 if (NANDBUS_GET_STATUS(dev, status)) 503 return (ENXIO); 504 505 if (*status & NAND_STATUS_RDY) 506 return (0); 507 508 getmicrotime(&tv2); 509 } while (timevalcmp(&tv2, &tv, <=)); 510 511 return (EBUSY); 512} 513 514int 515nandbus_get_ecc(device_t dev, void *buf, uint32_t pagesize, void *ecc, 516 int *needwrite) 517{ 518 519 return (NFC_GET_ECC(device_get_parent(dev), buf, pagesize, ecc, needwrite)); 520} 521 522int 523nandbus_correct_ecc(device_t dev, void *buf, int pagesize, void *readecc, 524 void *calcecc) 525{ 526 527 return (NFC_CORRECT_ECC(device_get_parent(dev), buf, pagesize, 528 readecc, calcecc)); 529} 530 531