1 /* $NetBSD: nand.h,v 1.1 2011/02/26 18:07:31 ahoka Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 Department of Software Engineering, 5 * University of Szeged, Hungary 6 * Copyright (c) 2010 Adam Hoka <ahoka@NetBSD.org> 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to The NetBSD Foundation 10 * by the Department of Software Engineering, University of Szeged, Hungary 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef _NAND_H_ 35 #define _NAND_H_ 36 37 #include <sys/param.h> 38 #include <sys/cdefs.h> 39 40 #include <sys/bufq.h> 41 #include <sys/buf.h> 42 #include <sys/time.h> 43 44 #include <dev/flash/flash.h> 45 46 /* flash interface implementation */ 47 int nand_flash_isbad(device_t, uint64_t); 48 int nand_flash_markbad(device_t, uint64_t); 49 int nand_flash_write(device_t, off_t, size_t, size_t *, const u_char *); 50 int nand_flash_read(device_t, off_t, size_t, size_t *, uint8_t *); 51 int nand_flash_erase(device_t, struct flash_erase_instruction *); 52 53 /* nand specific functions */ 54 int nand_erase_block(device_t, size_t); 55 56 int nand_io_submit(device_t, struct buf *); 57 void nand_sync_thread(void *); 58 int nand_sync_thread_start(device_t); 59 void nand_sync_thread_stop(device_t); 60 61 bool nand_isfactorybad(device_t, flash_addr_t); 62 bool nand_iswornoutbad(device_t, flash_addr_t); 63 bool nand_isbad(device_t, flash_addr_t); 64 void nand_markbad(device_t, size_t); 65 66 int nand_read_page(device_t, size_t, uint8_t *); 67 int nand_read_oob(device_t self, size_t page, void *oob); 68 69 /* 70 * default functions for driver development 71 */ 72 void nand_default_select(device_t, bool); 73 int nand_default_ecc_compute(device_t, const uint8_t *, uint8_t *); 74 int nand_default_ecc_correct(device_t, uint8_t *, const uint8_t *, 75 const uint8_t *); 76 77 static inline void nand_busy(device_t); 78 static inline void nand_select(device_t, bool); 79 static inline void nand_command(device_t, uint8_t); 80 static inline void nand_address(device_t, uint32_t); 81 static inline void nand_read_buf_byte(device_t, void *, size_t); 82 static inline void nand_read_buf_word(device_t, void *, size_t); 83 static inline void nand_read_byte(device_t, uint8_t *); 84 static inline void nand_write_buf_byte(device_t, const void *, size_t); 85 static inline void nand_write_buf_word(device_t, const void *, size_t); 86 //static inline bool nand_block_isbad(device_t, off_t); 87 //static inline void nand_block_markbad(device_t, off_t); 88 //static inline bool nand_isbusy(device_t); 89 90 //#define NAND_DEBUG 1 91 #ifdef NAND_DEBUG 92 #define DPRINTF(x) if (nanddebug) printf x 93 #define DPRINTFN(n,x) if (nanddebug>(n)) printf x 94 #else 95 #define DPRINTF(x) 96 #define DPRINTFN(n,x) 97 #endif 98 99 #define NAND_VERBOSE 100 101 /* same as in linux for compatibility */ 102 enum { 103 NAND_BAD_MARKER_OFFSET = 0, 104 NAND_BAD_MARKER_OFFSET_SMALL = 5 105 }; 106 107 /* feature flags use in nc_flags */ 108 enum { 109 NC_BUSWIDTH_16 = (1<<0), 110 NC_SOURCE_SYNC = (1<<2), 111 NC_INTERLEAVED_PE = (1<<1), 112 NC_INTERLEAVED_R = (1<<3), 113 NC_EXTENDED_PARAM = (1<<4) 114 }; 115 116 /* various quirks used in nc_quirks */ 117 enum { 118 NC_QUIRK_NO_READ_START = (1<<0) 119 }; 120 121 enum { 122 NAND_ECC_READ, 123 NAND_ECC_WRITE 124 }; 125 126 enum { 127 NAND_ECC_OK, 128 NAND_ECC_CORRECTED, 129 NAND_ECC_INVALID, 130 NAND_ECC_TWOBIT 131 }; 132 133 enum { 134 NAND_ECC_TYPE_HW, 135 NAND_ECC_TYPE_SW 136 }; 137 138 struct nand_bbt { 139 uint8_t *nbbt_bitmap; 140 size_t nbbt_size; 141 }; 142 143 struct nand_ecc { 144 size_t necc_offset; /* offset of ecc data in oob */ 145 size_t necc_size; /* size of ecc data in oob */ 146 size_t necc_block_size; /* block size used in ecc calc */ 147 size_t necc_code_size; /* reduntant bytes per block */ 148 int necc_steps; /* pagesize / code size */ 149 int necc_type; /* type of the ecc engine */ 150 }; 151 152 /** 153 * nand_chip: structure containing the required information 154 * about the NAND chip. 155 */ 156 struct nand_chip { 157 uint8_t *nc_oob_cache; /* buffer for oob cache */ 158 uint8_t *nc_page_cache; /* buffer for page cache */ 159 uint8_t *nc_ecc_cache; 160 size_t nc_size; /* storage size in bytes */ 161 size_t nc_page_size; /* page size in bytes */ 162 size_t nc_block_pages; /* block size in pages */ 163 size_t nc_block_size; /* block size in bytes */ 164 size_t nc_spare_size; /* spare (oob) size in bytes */ 165 uint32_t nc_flags; /* bitfield flags */ 166 uint32_t nc_quirks; /* bitfield quirks */ 167 unsigned int nc_page_shift; /* page shift for page alignment */ 168 unsigned int nc_page_mask; /* page mask for page alignment */ 169 unsigned int nc_block_shift; /* write shift */ 170 unsigned int nc_block_mask; /* write mask */ 171 uint8_t nc_manf_id; /* manufacturer id */ 172 uint8_t nc_dev_id; /* device id */ 173 uint8_t nc_addr_cycles_row; /* row cycles for addressing */ 174 uint8_t nc_addr_cycles_column; /* column cycles for addressing */ 175 uint8_t nc_badmarker_offs; /* offset for marking bad blocks */ 176 177 struct nand_ecc *nc_ecc; 178 }; 179 180 struct nand_write_cache { 181 struct bintime nwc_creation; 182 struct bintime nwc_last_write; 183 struct bufq_state *nwc_bufq; 184 uint8_t *nwc_data; 185 daddr_t nwc_block; 186 kmutex_t nwc_lock; 187 bool nwc_write_pending; 188 }; 189 190 /* driver softc for nand */ 191 struct nand_softc { 192 device_t sc_dev; 193 device_t nand_dev; 194 struct nand_interface *nand_if; 195 void *nand_softc; 196 struct nand_chip sc_chip; 197 struct nand_bbt sc_bbt; 198 size_t sc_part_offset; 199 size_t sc_part_size; 200 kmutex_t sc_device_lock; /* serialize access to chip */ 201 202 /* for the i/o thread */ 203 struct lwp *sc_sync_thread; 204 struct nand_write_cache sc_cache; 205 kmutex_t sc_io_lock; 206 kmutex_t sc_waitq_lock; 207 kcondvar_t sc_io_cv; 208 bool sc_io_running; 209 }; 210 211 /* structure holding the nand api */ 212 struct nand_interface 213 { 214 void (*select) (device_t, bool); 215 void (*command) (device_t, uint8_t); 216 void (*address) (device_t, uint8_t); 217 void (*read_buf_byte) (device_t, void *, size_t); 218 void (*read_buf_word) (device_t, void *, size_t); 219 void (*read_byte) (device_t, uint8_t *); 220 void (*read_word) (device_t, uint16_t *); 221 void (*write_buf_byte) (device_t, const void *, size_t); 222 void (*write_buf_word) (device_t, const void *, size_t); 223 void (*write_byte) (device_t, uint8_t); 224 void (*write_word) (device_t, uint16_t); 225 void (*busy) (device_t); 226 227 /* functions specific to ecc computation */ 228 int (*ecc_prepare)(device_t, int); 229 int (*ecc_compute)(device_t, const uint8_t *, uint8_t *); 230 int (*ecc_correct)(device_t, uint8_t *, const uint8_t *, 231 const uint8_t *); 232 233 struct nand_ecc ecc; 234 235 /* flash partition information */ 236 const struct flash_partition *part_info; 237 int part_num; 238 }; 239 240 /* attach args */ 241 struct nand_attach_args { 242 struct nand_interface *naa_nand_if; 243 }; 244 245 device_t nand_attach_mi(struct nand_interface *nand_if, device_t dev); 246 247 static inline void 248 nand_busy(device_t device) 249 { 250 struct nand_softc *sc = device_private(device); 251 252 KASSERT(sc->nand_if->select != NULL); 253 KASSERT(sc->nand_dev != NULL); 254 255 sc->nand_if->select(sc->nand_dev, true); 256 257 if (sc->nand_if->busy != NULL) { 258 sc->nand_if->busy(sc->nand_dev); 259 } 260 261 sc->nand_if->select(sc->nand_dev, false); 262 } 263 264 static inline void 265 nand_select(device_t self, bool enable) 266 { 267 struct nand_softc *sc = device_private(self); 268 269 KASSERT(sc->nand_if->select != NULL); 270 KASSERT(sc->nand_dev != NULL); 271 272 sc->nand_if->select(sc->nand_dev, enable); 273 } 274 275 static inline void 276 nand_address(device_t self, uint32_t address) 277 { 278 struct nand_softc *sc = device_private(self); 279 280 KASSERT(sc->nand_if->address != NULL); 281 KASSERT(sc->nand_dev != NULL); 282 283 sc->nand_if->address(sc->nand_dev, address); 284 } 285 286 static inline void 287 nand_command(device_t self, uint8_t command) 288 { 289 struct nand_softc *sc = device_private(self); 290 291 KASSERT(sc->nand_if->command != NULL); 292 KASSERT(sc->nand_dev != NULL); 293 294 sc->nand_if->command(sc->nand_dev, command); 295 } 296 297 static inline void 298 nand_read_byte(device_t self, uint8_t *data) 299 { 300 struct nand_softc *sc = device_private(self); 301 302 KASSERT(sc->nand_if->read_byte != NULL); 303 KASSERT(sc->nand_dev != NULL); 304 305 sc->nand_if->read_byte(sc->nand_dev, data); 306 } 307 308 static inline void 309 nand_write_byte(device_t self, uint8_t data) 310 { 311 struct nand_softc *sc = device_private(self); 312 313 KASSERT(sc->nand_if->write_byte != NULL); 314 KASSERT(sc->nand_dev != NULL); 315 316 sc->nand_if->write_byte(sc->nand_dev, data); 317 } 318 319 static inline void 320 nand_read_word(device_t self, uint16_t *data) 321 { 322 struct nand_softc *sc = device_private(self); 323 324 KASSERT(sc->nand_if->read_word != NULL); 325 KASSERT(sc->nand_dev != NULL); 326 327 sc->nand_if->read_word(sc->nand_dev, data); 328 } 329 330 static inline void 331 nand_write_word(device_t self, uint16_t data) 332 { 333 struct nand_softc *sc = device_private(self); 334 335 KASSERT(sc->nand_if->write_word != NULL); 336 KASSERT(sc->nand_dev != NULL); 337 338 sc->nand_if->write_word(sc->nand_dev, data); 339 } 340 341 static inline void 342 nand_read_buf_byte(device_t self, void *buf, size_t size) 343 { 344 struct nand_softc *sc = device_private(self); 345 346 KASSERT(sc->nand_if->read_buf_byte != NULL); 347 KASSERT(sc->nand_dev != NULL); 348 349 sc->nand_if->read_buf_byte(sc->nand_dev, buf, size); 350 } 351 352 static inline void 353 nand_read_buf_word(device_t self, void *buf, size_t size) 354 { 355 struct nand_softc *sc = device_private(self); 356 357 KASSERT(sc->nand_if->read_buf_word != NULL); 358 KASSERT(sc->nand_dev != NULL); 359 360 sc->nand_if->read_buf_word(sc->nand_dev, buf, size); 361 } 362 363 static inline void 364 nand_write_buf_byte(device_t self, const void *buf, size_t size) 365 { 366 struct nand_softc *sc = device_private(self); 367 368 KASSERT(sc->nand_if->write_buf_byte != NULL); 369 KASSERT(sc->nand_dev != NULL); 370 371 sc->nand_if->write_buf_byte(sc->nand_dev, buf, size); 372 } 373 374 static inline void 375 nand_write_buf_word(device_t self, const void *buf, size_t size) 376 { 377 struct nand_softc *sc = device_private(self); 378 379 KASSERT(sc->nand_if->write_buf_word != NULL); 380 KASSERT(sc->nand_dev != NULL); 381 382 sc->nand_if->write_buf_word(sc->nand_dev, buf, size); 383 } 384 385 static inline int 386 nand_ecc_correct(device_t self, uint8_t *data, const uint8_t *oldcode, 387 const uint8_t *newcode) 388 { 389 struct nand_softc *sc = device_private(self); 390 391 KASSERT(sc->nand_if->ecc_correct != NULL); 392 KASSERT(sc->nand_dev != NULL); 393 394 return sc->nand_if->ecc_correct(sc->nand_dev, data, oldcode, newcode); 395 } 396 397 static inline void 398 nand_ecc_compute(device_t self, const uint8_t *data, uint8_t *code) 399 { 400 struct nand_softc *sc = device_private(self); 401 402 KASSERT(sc->nand_if->ecc_compute != NULL); 403 KASSERT(sc->nand_dev != NULL); 404 405 sc->nand_if->ecc_compute(sc->nand_dev, data, code); 406 } 407 408 static inline void 409 nand_ecc_prepare(device_t self, int mode) 410 { 411 struct nand_softc *sc = device_private(self); 412 413 KASSERT(sc->nand_dev != NULL); 414 415 if (sc->nand_if->ecc_prepare != NULL) 416 sc->nand_if->ecc_prepare(sc->nand_dev, mode); 417 } 418 419 #if 0 420 static inline bool 421 nand_block_isbad(device_t self, off_t block) 422 { 423 struct nand_softc *sc = device_private(self); 424 425 KASSERT(sc->nand_if->block_isbad != NULL); 426 KASSERT(sc->nand_dev != NULL); 427 428 return sc->nand_if->block_isbad(sc->nand_dev, block); 429 } 430 #endif 431 432 /* Manufacturer IDs defined by JEDEC */ 433 enum { 434 NAND_MFR_UNKNOWN = 0x00, 435 NAND_MFR_AMD = 0x01, 436 NAND_MFR_FUJITSU = 0x04, 437 NAND_MFR_RENESAS = 0x07, 438 NAND_MFR_STMICRO = 0x20, 439 NAND_MFR_MICRON = 0x2c, 440 NAND_MFR_NATIONAL = 0x8f, 441 NAND_MFR_TOSHIBA = 0x98, 442 NAND_MFR_HYNIX = 0xad, 443 NAND_MFR_SAMSUNG = 0xec 444 }; 445 446 struct nand_manufacturer { 447 int id; 448 const char *name; 449 }; 450 451 extern const struct nand_manufacturer nand_mfrs[]; 452 453 static inline void 454 nand_dump_data(const char *name, void *data, size_t len) 455 { 456 printf("dumping %s\n--------------\n", name); 457 uint8_t *dump = data; 458 for (int i = 0; i < len; i++) { 459 printf("0x%.2hhx ", *dump); 460 dump++; 461 } 462 printf("\n--------------\n"); 463 } 464 465 #endif /* _NAND_H_ */ 466