1 /* $NetBSD: omap2_nand.c,v 1.4 2021/04/24 23:36:29 thorpej 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 /* Device driver for the NAND controller found in Texas Instruments OMAP2 35 * and later SOCs. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: omap2_nand.c,v 1.4 2021/04/24 23:36:29 thorpej Exp $"); 40 41 /* TODO move to opt_* */ 42 #undef OMAP2_NAND_HARDWARE_ECC 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/cdefs.h> 47 #include <sys/device.h> 48 49 #include <sys/bus.h> 50 51 #include <arm/ti/omap2_gpmcreg.h> 52 53 #include <dev/nand/nand.h> 54 #include <dev/nand/onfi.h> 55 56 #include <dev/fdt/fdtvar.h> 57 58 extern struct flash_interface nand_flash_if; 59 extern int flash_print(void *, const char *); 60 61 /* GPMC_STATUS */ 62 #define WAIT0 __BIT(8) /* active low */ 63 64 /* GPMC_ECC_CONTROL */ 65 #define ECCCLEAR __BIT(8) 66 #define ECCPOINTER __BITS(3,0) 67 68 /* GPMC_ECC_CONFIG */ 69 #define ECCALGORITHM __BIT(16) 70 #define ECCCS __BITS(3,1) 71 #define ECC16B __BIT(7) 72 #define ECCENABLE __BIT(0) 73 /* GPMC_ECC_SIZE_CONFIG */ 74 #define ECCSIZE1 __BITS(29,22) 75 76 /* GPMC_CONFIG1_i */ 77 #define DEVICETYPE __BITS(11,10) 78 #define DEVICESIZE __BITS(13,12) 79 80 #define MASKEDINT(mask, integer) ((integer) << (ffs(mask) - 1) & mask) 81 82 /* NAND status register */ 83 #define NAND_WP_BIT __BIT(4) 84 85 static int omap2_nand_match(device_t, cfdata_t, void *); 86 static void omap2_nand_attach(device_t, device_t, void *); 87 88 static void omap2_nand_command(device_t self, uint8_t command); 89 static void omap2_nand_address(device_t self, uint8_t address); 90 static void omap2_nand_busy(device_t self); 91 static void omap2_nand_read_1(device_t self, uint8_t *data); 92 static void omap2_nand_write_1(device_t self, uint8_t data); 93 static void omap2_nand_read_2(device_t self, uint16_t *data); 94 static void omap2_nand_write_2(device_t self, uint16_t data); 95 bool omap2_nand_isbusy(device_t self); 96 static void omap2_nand_read_buf_1(device_t self, void *buf, size_t len); 97 static void omap2_nand_read_buf_2(device_t self, void *buf, size_t len); 98 static void omap2_nand_write_buf_1(device_t self, const void *buf, size_t len); 99 static void omap2_nand_write_buf_2(device_t self, const void *buf, size_t len); 100 101 #ifdef OMAP2_NAND_HARDWARE_ECC 102 static int omap2_nand_ecc_init(device_t self); 103 static int omap2_nand_ecc_prepare(device_t self, int mode); 104 static int omap2_nand_ecc_compute(device_t self, const uint8_t *data, uint8_t *ecc); 105 static int omap2_nand_ecc_correct(device_t self, uint8_t *data, const uint8_t *oldecc, 106 const uint8_t *calcecc); 107 #endif 108 109 struct omap2_nand_softc { 110 device_t sc_dev; 111 device_t sc_nanddev; 112 113 int sc_cs; 114 int sc_buswidth; /* 0: 8bit, 1: 16bit */ 115 116 struct nand_interface sc_nand_if; 117 118 bus_space_tag_t sc_iot; 119 bus_space_handle_t sc_ioh; 120 bus_space_handle_t sc_gpmc_ioh; 121 122 bus_size_t sc_cmd_reg; 123 bus_size_t sc_addr_reg; 124 bus_size_t sc_data_reg; 125 }; 126 127 static const struct device_compatible_entry compat_data[] = { 128 { .compat = "ti,omap2-nand" }, 129 { .compat = "ti,omap2-onenand" }, 130 DEVICE_COMPAT_EOL 131 }; 132 133 CFATTACH_DECL_NEW(omapnand, sizeof(struct omap2_nand_softc), omap2_nand_match, 134 omap2_nand_attach, NULL, NULL); 135 136 static inline uint32_t 137 gpmc_register_read(struct omap2_nand_softc *sc, bus_size_t reg) 138 { 139 return bus_space_read_4(sc->sc_iot, sc->sc_gpmc_ioh, reg); 140 } 141 142 static inline void 143 gpmc_register_write(struct omap2_nand_softc *sc, bus_size_t reg, const uint32_t data) 144 { 145 bus_space_write_4(sc->sc_iot, sc->sc_gpmc_ioh, reg, data); 146 } 147 148 static void 149 omap2_nand_command(device_t self, uint8_t command) 150 { 151 struct omap2_nand_softc *sc = device_private(self); 152 153 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_cmd_reg, command); 154 }; 155 156 static void 157 omap2_nand_address(device_t self, uint8_t address) 158 { 159 struct omap2_nand_softc *sc = device_private(self); 160 161 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_addr_reg, address); 162 }; 163 164 bool 165 omap2_nand_isbusy(device_t self) 166 { 167 struct omap2_nand_softc *sc = device_private(self); 168 uint8_t status; 169 170 DELAY(1); /* just to be sure we are not early */ 171 172 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 173 sc->sc_cmd_reg, ONFI_READ_STATUS); 174 175 DELAY(1); 176 177 status = bus_space_read_1(sc->sc_iot, 178 sc->sc_ioh, sc->sc_data_reg); 179 180 return !(status & ONFI_STATUS_RDY); 181 }; 182 183 static int 184 omap2_nand_match(device_t parent, cfdata_t match, void *aux) 185 { 186 struct fdt_attach_args * const faa = aux; 187 188 return of_compatible_match(faa->faa_phandle, compat_data); 189 } 190 191 static void 192 omap2_nand_attach(device_t parent, device_t self, void *aux) 193 { 194 struct omap2_nand_softc *sc = device_private(self); 195 struct fdt_attach_args * const faa = aux; 196 const int phandle = faa->faa_phandle; 197 struct flash_attach_args flash; 198 bus_addr_t addr, part_addr; 199 bus_size_t size, part_size; 200 const u_int *prop; 201 uint32_t val; 202 int len, child; 203 204 if (fdtbus_get_reg(OF_parent(phandle), 0, &addr, &size) != 0) { 205 aprint_error(": couldn't get registers\n"); 206 return; 207 } 208 209 sc->sc_iot = faa->faa_bst; 210 sc->sc_dev = self; 211 212 prop = fdtbus_get_prop(phandle, "reg", &len); 213 if (prop == NULL || len < 4) { 214 aprint_error(": couldn't read reg property\n"); 215 return; 216 } 217 218 sc->sc_cs = be32toh(prop[0]); 219 220 /* map i/o space */ 221 if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_gpmc_ioh) != 0) { 222 aprint_error(": couldn't map registers\n"); 223 return; 224 } 225 if (bus_space_subregion(sc->sc_iot, sc->sc_gpmc_ioh, GPMC_CS_CONFIG(sc->sc_cs), 0x30, &sc->sc_ioh) != 0) { 226 aprint_error(": couldn't map cs registers\n"); 227 return; 228 } 229 230 aprint_naive("\n"); 231 aprint_normal(": CS%d\n", sc->sc_cs); 232 233 sc->sc_cmd_reg = GPMC_NAND_COMMAND_0 - GPMC_CONFIG1_0; 234 sc->sc_addr_reg = GPMC_NAND_ADDRESS_0 - GPMC_CONFIG1_0; 235 sc->sc_data_reg = GPMC_NAND_DATA_0 - GPMC_CONFIG1_0; 236 237 /* turn off write protection if enabled */ 238 val = gpmc_register_read(sc, GPMC_CONFIG); 239 val |= NAND_WP_BIT; 240 gpmc_register_write(sc, GPMC_CONFIG, val); 241 242 /* 243 * do the reset dance for NAND 244 */ 245 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 246 sc->sc_cmd_reg, ONFI_RESET); 247 248 omap2_nand_busy(self); 249 250 /* read GPMC_CONFIG1_i to get buswidth */ 251 val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPMC_CONFIG1_i); 252 253 if ((val & DEVICESIZE) == MASKEDINT(DEVICESIZE, 0x01)) { 254 /* 16bit */ 255 sc->sc_buswidth = 1; 256 } else if ((val & DEVICESIZE) == MASKEDINT(DEVICESIZE, 0x00)) { 257 /* 8bit */ 258 sc->sc_buswidth = 0; 259 } else { 260 panic("invalid buswidth reported by config1"); 261 } 262 263 nand_init_interface(&sc->sc_nand_if); 264 265 sc->sc_nand_if.command = &omap2_nand_command; 266 sc->sc_nand_if.address = &omap2_nand_address; 267 sc->sc_nand_if.read_buf_1 = &omap2_nand_read_buf_1; 268 sc->sc_nand_if.read_buf_2 = &omap2_nand_read_buf_2; 269 sc->sc_nand_if.read_1 = &omap2_nand_read_1; 270 sc->sc_nand_if.read_2 = &omap2_nand_read_2; 271 sc->sc_nand_if.write_buf_1 = &omap2_nand_write_buf_1; 272 sc->sc_nand_if.write_buf_2 = &omap2_nand_write_buf_2; 273 sc->sc_nand_if.write_1 = &omap2_nand_write_1; 274 sc->sc_nand_if.write_2 = &omap2_nand_write_2; 275 sc->sc_nand_if.busy = &omap2_nand_busy; 276 277 #ifdef OMAP2_NAND_HARDWARE_ECC 278 omap2_nand_ecc_init(self); 279 sc->sc_nand_if.ecc_compute = &omap2_nand_ecc_compute; 280 sc->sc_nand_if.ecc_correct = &omap2_nand_ecc_correct; 281 sc->sc_nand_if.ecc_prepare = &omap2_nand_ecc_prepare; 282 sc->sc_nand_if.ecc.necc_code_size = 3; 283 sc->sc_nand_if.ecc.necc_block_size = 512; 284 sc->sc_nand_if.ecc.necc_type = NAND_ECC_TYPE_HW; 285 #else 286 sc->sc_nand_if.ecc.necc_code_size = 3; 287 sc->sc_nand_if.ecc.necc_block_size = 256; 288 #endif /* OMAP2_NAND_HARDWARE_ECC */ 289 290 if (!pmf_device_register1(sc->sc_dev, NULL, NULL, NULL)) 291 aprint_error_dev(sc->sc_dev, 292 "couldn't establish power handler\n"); 293 294 sc->sc_nanddev = nand_attach_mi(&sc->sc_nand_if, sc->sc_dev); 295 if (sc->sc_nanddev == NULL) 296 return; 297 298 for (child = OF_child(phandle); child; child = OF_peer(child)) { 299 if (!fdtbus_status_okay(child)) 300 continue; 301 302 if (fdtbus_get_reg(child, 0, &part_addr, &part_size) != 0) { 303 aprint_error_dev(self, "couldn't parse partition %s\n", 304 fdtbus_get_string(child, "name")); 305 continue; 306 } 307 308 memset(&flash, 0, sizeof(flash)); 309 flash.flash_if = &nand_flash_if; 310 flash.partinfo.part_offset = part_addr; 311 flash.partinfo.part_size = part_size; 312 flash.partinfo.part_flags = 0; 313 flash.partinfo.part_name = fdtbus_get_string(child, "label"); 314 if (flash.partinfo.part_name == NULL) 315 flash.partinfo.part_name = fdtbus_get_string(child, "name"); 316 317 config_found(sc->sc_nanddev, &flash, flash_print, CFARG_EOL); 318 } 319 } 320 321 static void 322 omap2_nand_busy(device_t self) 323 { 324 struct omap2_nand_softc *sc = device_private(self); 325 326 while (!(gpmc_register_read(sc, GPMC_STATUS) & WAIT0)) { 327 DELAY(1); 328 } 329 } 330 331 static void 332 omap2_nand_read_1(device_t self, uint8_t *data) 333 { 334 struct omap2_nand_softc *sc = device_private(self); 335 336 *data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->sc_data_reg); 337 } 338 339 static void 340 omap2_nand_write_1(device_t self, uint8_t data) 341 { 342 struct omap2_nand_softc *sc = device_private(self); 343 344 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_data_reg, data); 345 } 346 347 static void 348 omap2_nand_read_2(device_t self, uint16_t *data) 349 { 350 struct omap2_nand_softc *sc = device_private(self); 351 352 *data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, sc->sc_data_reg); 353 } 354 355 static void 356 omap2_nand_write_2(device_t self, uint16_t data) 357 { 358 struct omap2_nand_softc *sc = device_private(self); 359 360 bus_space_write_2(sc->sc_iot, sc->sc_ioh, sc->sc_data_reg, data); 361 } 362 363 static void 364 omap2_nand_read_buf_1(device_t self, void *buf, size_t len) 365 { 366 struct omap2_nand_softc *sc = device_private(self); 367 368 KASSERT(buf != NULL); 369 KASSERT(len >= 1); 370 371 bus_space_read_multi_1(sc->sc_iot, sc->sc_ioh, 372 sc->sc_data_reg, buf, len); 373 } 374 375 static void 376 omap2_nand_read_buf_2(device_t self, void *buf, size_t len) 377 { 378 struct omap2_nand_softc *sc = device_private(self); 379 380 KASSERT(buf != NULL); 381 KASSERT(len >= 2); 382 KASSERT(!(len & 0x01)); 383 384 bus_space_read_multi_2(sc->sc_iot, sc->sc_ioh, 385 sc->sc_data_reg, buf, len / 2); 386 } 387 388 static void 389 omap2_nand_write_buf_1(device_t self, const void *buf, size_t len) 390 { 391 struct omap2_nand_softc *sc = device_private(self); 392 393 KASSERT(buf != NULL); 394 KASSERT(len >= 1); 395 396 bus_space_write_multi_1(sc->sc_iot, sc->sc_ioh, 397 sc->sc_data_reg, buf, len); 398 } 399 400 static void 401 omap2_nand_write_buf_2(device_t self, const void *buf, size_t len) 402 { 403 struct omap2_nand_softc *sc = device_private(self); 404 405 KASSERT(buf != NULL); 406 KASSERT(len >= 2); 407 KASSERT(!(len & 0x01)); 408 409 bus_space_write_multi_2(sc->sc_iot, sc->sc_ioh, 410 sc->sc_data_reg, buf, len / 2); 411 } 412 413 #ifdef OMAP2_NAND_HARDWARE_ECC 414 static uint32_t 415 convert_ecc(const uint8_t *ecc) 416 { 417 return ecc[0] | (ecc[1] << 16) | ((ecc[2] & 0xf0) << 20) | 418 ((ecc[2] & 0x0f) << 8); 419 } 420 421 static int 422 omap2_nand_ecc_init(device_t self) 423 { 424 struct omap2_nand_softc *sc = device_private(self); 425 uint32_t val; 426 427 val = gpmc_register_read(sc, GPMC_ECC_CONTROL); 428 /* clear ecc, select ecc register 1 */ 429 val &= ~ECCPOINTER; 430 val |= ECCCLEAR | MASKEDINT(ECCPOINTER, 1); 431 gpmc_register_write(sc, GPMC_ECC_CONTROL, val); 432 433 /* XXX too many MAGIC */ 434 /* set ecc size to 512, set all regs to eccsize1*/ 435 val = gpmc_register_read(sc, GPMC_ECC_SIZE_CONFIG); 436 val &= ~ECCSIZE1; 437 val |= MASKEDINT(ECCSIZE1, 512) | 0x0f; 438 gpmc_register_write(sc, GPMC_ECC_CONTROL, val); 439 440 return 0; 441 } 442 443 static int 444 omap2_nand_ecc_compute(device_t self, const uint8_t *data, uint8_t *ecc) 445 { 446 struct omap2_nand_softc *sc = device_private(self); 447 uint32_t val; 448 449 /* read ecc result register */ 450 val = gpmc_register_read(sc, GPMC_ECC1_RESULT); 451 452 ecc[0] = val & 0xff; 453 ecc[1] = (val >> 16) & 0xff; 454 ecc[2] = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0); 455 456 /* disable ecc engine */ 457 val = gpmc_register_read(sc, GPMC_ECC_CONFIG); 458 val &= ~ECCENABLE; 459 gpmc_register_write(sc, GPMC_ECC_CONFIG, val); 460 461 return 0; 462 } 463 464 static int 465 omap2_nand_ecc_prepare(device_t self, int mode) 466 { 467 struct omap2_nand_softc *sc = device_private(self); 468 uint32_t val; 469 470 /* same for read/write */ 471 switch (mode) { 472 case NAND_ECC_READ: 473 case NAND_ECC_WRITE: 474 val = gpmc_register_read(sc, GPMC_ECC_CONTROL); 475 /* clear ecc, select ecc register 1 */ 476 val &= ~ECCPOINTER; 477 val |= ECCCLEAR | MASKEDINT(ECCPOINTER, 1); 478 gpmc_register_write(sc, GPMC_ECC_CONTROL, val); 479 480 val = gpmc_register_read(sc, GPMC_ECC_CONFIG); 481 val &= ~ECCCS; 482 val |= ECCENABLE | MASKEDINT(ECCCS, sc->sc_cs); 483 if (sc->sc_buswidth == 1) 484 val |= ECC16B; 485 else 486 val &= ~ECC16B; 487 gpmc_register_write(sc, GPMC_ECC_CONFIG, val); 488 489 break; 490 default: 491 aprint_error_dev(self, "invalid i/o mode for ecc prepare\n"); 492 return -1; 493 } 494 495 return 0; 496 } 497 498 static int 499 omap2_nand_ecc_correct(device_t self, uint8_t *data, const uint8_t *oldecc, 500 const uint8_t *calcecc) 501 { 502 uint32_t oecc, cecc, xor; 503 uint16_t parity, offset; 504 uint8_t bit; 505 506 oecc = convert_ecc(oldecc); 507 cecc = convert_ecc(calcecc); 508 509 /* get the difference */ 510 xor = oecc ^ cecc; 511 512 /* the data was correct if all bits are zero */ 513 if (xor == 0x00) 514 return NAND_ECC_OK; 515 516 switch (popcount32(xor)) { 517 case 12: 518 /* single byte error */ 519 parity = xor >> 16; 520 bit = (parity & 0x07); 521 offset = (parity >> 3) & 0x01ff; 522 /* correct bit */ 523 data[offset] ^= (0x01 << bit); 524 return NAND_ECC_CORRECTED; 525 case 1: 526 return NAND_ECC_INVALID; 527 default: 528 /* erased page! */ 529 if ((oecc == 0x0fff0fff) && (cecc == 0x00000000)) 530 return NAND_ECC_OK; 531 532 return NAND_ECC_TWOBIT; 533 } 534 } 535 #endif /* !OMAP2_NAND_HARDWARE_ECC */ 536