1 /* $NetBSD: sunxi_nand.c,v 1.10 2021/01/27 03:10:20 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca> 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 ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * 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 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: sunxi_nand.c,v 1.10 2021/01/27 03:10:20 thorpej Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/device.h> 35 #include <sys/intr.h> 36 #include <sys/systm.h> 37 38 #include <dev/fdt/fdtvar.h> 39 40 #include <dev/nand/nand.h> 41 #include <dev/nand/onfi.h> 42 43 #include <arm/bootconfig.h> 44 45 #define NDFC_CTL 0x00 46 #define NDFC_CTL_CE_SEL __BITS(27,24) 47 #define NDFC_CTL_PAGE_SIZE __BITS(11,8) 48 #define NDFC_CTL_RB_SEL __BITS(4,3) 49 #define NDFC_CTL_BUS_WIDTH __BIT(2) 50 #define NDFC_CTL_RESET __BIT(1) 51 #define NDFC_CTL_EN __BIT(0) 52 #define NDFC_ST 0x04 53 #define NDFC_ST_RB_STATE(n) __BIT(8 + (n)) 54 #define NDFC_ST_CMD_FIFO_STATUS __BIT(3) 55 #define NDFC_ST_DMA_INT_FLAG __BIT(2) 56 #define NDFC_ST_CMD_INT_FLAG __BIT(1) 57 #define NDFC_ST_INT_MASK __BITS(2,0) 58 #define NDFC_INT 0x08 59 #define NDFC_INT_CMD_INT_ENABLE __BIT(1) 60 #define NDFC_TIMING_CTL 0x0c 61 #define NDFC_TIMING_CFG 0x10 62 #define NDFC_ADDR_LOW 0x14 63 #define NDFC_ADDR_HIGH 0x18 64 #define NDFC_BLOCK_NUM 0x1c 65 #define NDFC_CNT 0x20 66 #define NDFC_CNT_DATA_CNT __BITS(9,0) 67 #define NDFC_CMD 0x24 68 #define NDFC_CMD_DATA_METHOD __BIT(26) 69 #define NDFC_CMD_SEND_FIRST_CMD __BIT(22) 70 #define NDFC_CMD_DATA_TRANS __BIT(21) 71 #define NDFC_CMD_ACCESS_DIR __BIT(20) 72 #define NDFC_CMD_SEND_ADR __BIT(19) 73 #define NDFC_CMD_ADR_NUM __BITS(18,16) 74 #define NDFC_RCMD_SET 0x28 75 #define NDFC_WCMD_SET 0x2c 76 #define NDFC_IO_DATA 0x30 77 #define NDFC_ECC_CTL 0x34 78 #define NDFC_ECC_ST 0x38 79 #define NDFC_EFR 0x3c 80 #define NDFC_ERR_CNT0 0x40 81 #define NDFC_ERR_CNT1 0x44 82 #define NDFC_USER_DATA(n) (0x50 + 4 * (n)) 83 #define NDFC_EFNAND_STA 0x90 84 #define NDFC_SPARE_AREA 0xa0 85 #define NDFC_PAT_ID 0xa4 86 #define NDFC_RDATA_STA_CTL 0xa8 87 #define NDFC_RDATA_STA_0 0xac 88 #define NDFC_RDATA_STA_1 0xb0 89 #define NDFC_MDMA_ADDR 0xc0 90 #define NDFC_MDMA_CNT 0xc4 91 #define NDFC_RAM0_BASE 0x400 92 #define NDFC_RAM1_BASE 0x800 93 94 #define NDFC_RAM_SIZE 1024 95 96 static const struct device_compatible_entry compat_data[] = { 97 { .compat = "allwinner,sun4i-a10-nand" }, 98 DEVICE_COMPAT_EOL 99 }; 100 101 struct sunxi_nand_softc; 102 103 enum sunxi_nand_eccmode { 104 ECC_MODE_UNKNOWN, 105 ECC_MODE_HW, 106 ECC_MODE_HW_SYNDROME, 107 ECC_MODE_SOFT, 108 ECC_MODE_SOFT_BCH, 109 ECC_MODE_NONE 110 }; 111 112 struct sunxi_nand_softc; 113 114 struct sunxi_nand_chip { 115 struct sunxi_nand_softc *chip_sc; 116 int chip_phandle; 117 device_t chip_dev; 118 119 u_int chip_cs; 120 enum sunxi_nand_eccmode chip_eccmode; 121 u_int chip_rb; 122 struct fdtbus_gpio_pin *chip_rb_pin; 123 124 struct nand_interface chip_nand; 125 126 bool chip_addr_pending; 127 u_int chip_addr_count; 128 uint32_t chip_addr[2]; 129 }; 130 131 struct sunxi_nand_softc { 132 device_t sc_dev; 133 int sc_phandle; 134 bus_space_tag_t sc_bst; 135 bus_space_handle_t sc_bsh; 136 void *sc_ih; 137 138 kmutex_t sc_lock; 139 kcondvar_t sc_cv; 140 141 uint32_t sc_intr; 142 143 struct clk *sc_clk_mod; 144 struct clk *sc_clk_ahb; 145 struct fdtbus_reset *sc_rst_ahb; 146 147 struct sunxi_nand_chip sc_chip; 148 }; 149 150 #define NAND_READ(sc, reg) \ 151 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 152 #define NAND_WRITE(sc, reg, val) \ 153 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 154 155 static int 156 sunxi_nand_rb_state(struct sunxi_nand_softc *sc, struct sunxi_nand_chip *chip) 157 { 158 if (chip->chip_rb_pin != NULL) 159 return fdtbus_gpio_read(chip->chip_rb_pin); 160 161 const uint32_t status = NAND_READ(sc, NDFC_ST); 162 return __SHIFTOUT(status, NDFC_ST_RB_STATE(chip->chip_rb)); 163 } 164 165 static int 166 sunxi_nand_wait_status(struct sunxi_nand_softc *sc, uint32_t mask, uint32_t val) 167 { 168 uint32_t status; 169 int retry, error = 0; 170 171 for (retry = 1000000; retry > 0; retry--) { 172 status = NAND_READ(sc, NDFC_ST); 173 if ((status & mask) == val) 174 break; 175 delay(1); 176 } 177 if (retry == 0) { 178 #ifdef SUNXI_NAND_DEBUG 179 device_printf(sc->sc_dev, 180 "device timeout; status=%x mask=%x val=%x\n", 181 status, mask, val); 182 #endif 183 error = ETIMEDOUT; 184 } 185 186 if (mask == NDFC_ST_CMD_INT_FLAG) 187 NAND_WRITE(sc, NDFC_ST, NDFC_ST_CMD_INT_FLAG); 188 189 return error; 190 } 191 192 static int 193 sunxi_nand_wait_intr(struct sunxi_nand_softc *sc, uint32_t mask) 194 { 195 struct bintime timeo, epsilon; 196 int error = 0; 197 198 KASSERT(mutex_owned(&sc->sc_lock)); 199 200 sc->sc_intr = 0; 201 202 /* Enable interrupts */ 203 NAND_WRITE(sc, NDFC_INT, mask); 204 205 /* Wait for the command to complete */ 206 timeo = ms2bintime(1000); 207 epsilon = ms2bintime(1000); 208 do { 209 if (sc->sc_intr & mask) 210 break; 211 error = cv_timedwaitbt(&sc->sc_cv, &sc->sc_lock, &timeo, 212 &epsilon); 213 } while (error == 0); 214 215 /* Disable interrupts */ 216 NAND_WRITE(sc, NDFC_INT, 0); 217 218 return error; 219 } 220 221 static void 222 sunxi_nand_send_address(struct sunxi_nand_softc *sc, 223 struct sunxi_nand_chip *chip) 224 { 225 if (chip->chip_addr_count == 0) 226 return; 227 228 /* Wait for space in the command FIFO */ 229 sunxi_nand_wait_status(sc, NDFC_ST_CMD_FIFO_STATUS, 0); 230 231 NAND_WRITE(sc, NDFC_ADDR_LOW, chip->chip_addr[0]); 232 NAND_WRITE(sc, NDFC_ADDR_HIGH, chip->chip_addr[1]); 233 NAND_WRITE(sc, NDFC_CMD, 234 NDFC_CMD_SEND_ADR | 235 __SHIFTIN(chip->chip_addr_count - 1, NDFC_CMD_ADR_NUM)); 236 237 /* Wait for the command to finish */ 238 sunxi_nand_wait_status(sc, NDFC_ST_CMD_INT_FLAG, NDFC_ST_CMD_INT_FLAG); 239 240 chip->chip_addr[0] = 0; 241 chip->chip_addr[1] = 0; 242 chip->chip_addr_count = 0; 243 } 244 245 static int 246 sunxi_nand_read_buf_n(device_t dev, void *data, size_t len, int n) 247 { 248 struct sunxi_nand_softc * const sc = device_private(dev); 249 struct sunxi_nand_chip * const chip = &sc->sc_chip; 250 uint8_t *xfer_buf = data; 251 size_t resid = len; 252 int error; 253 254 KASSERT(n == 1 || n == 2); 255 KASSERT(len % n == 0); 256 257 sunxi_nand_send_address(sc, chip); 258 259 while (resid > 0) { 260 const size_t xfer = uimin(resid, NDFC_RAM_SIZE); 261 262 /* Wait for space in the command FIFO */ 263 error = sunxi_nand_wait_status(sc, NDFC_ST_CMD_FIFO_STATUS, 0); 264 if (error != 0) 265 return error; 266 267 /* Start the transfer. */ 268 NAND_WRITE(sc, NDFC_CNT, xfer); 269 NAND_WRITE(sc, NDFC_CMD, 270 NDFC_CMD_DATA_TRANS | NDFC_CMD_DATA_METHOD); 271 272 /* Wait for the command to finish */ 273 if (cold) { 274 error = sunxi_nand_wait_status(sc, NDFC_ST_CMD_INT_FLAG, 275 NDFC_ST_CMD_INT_FLAG); 276 } else { 277 mutex_enter(&sc->sc_lock); 278 error = sunxi_nand_wait_intr(sc, NDFC_ST_CMD_INT_FLAG); 279 mutex_exit(&sc->sc_lock); 280 } 281 282 if (error != 0) 283 return error; 284 285 /* Transfer data from FIFO RAM to buffer */ 286 const int count = xfer / n; 287 if (n == 1) { 288 bus_space_read_region_1(sc->sc_bst, sc->sc_bsh, 289 NDFC_RAM0_BASE, (uint8_t *)xfer_buf, count); 290 } else if (n == 2) { 291 bus_space_read_region_2(sc->sc_bst, sc->sc_bsh, 292 NDFC_RAM0_BASE, (uint16_t *)xfer_buf, count); 293 } 294 295 resid -= xfer; 296 xfer_buf += xfer; 297 } 298 299 return 0; 300 } 301 302 static int 303 sunxi_nand_write_buf_n(device_t dev, const void *data, size_t len, int n) 304 { 305 struct sunxi_nand_softc * const sc = device_private(dev); 306 struct sunxi_nand_chip * const chip = &sc->sc_chip; 307 const uint8_t *xfer_buf = data; 308 size_t resid = len; 309 int error; 310 311 KASSERT(n == 1 || n == 2); 312 KASSERT(len % n == 0); 313 314 sunxi_nand_send_address(sc, chip); 315 316 while (resid > 0) { 317 const size_t xfer = uimin(resid, NDFC_RAM_SIZE); 318 319 /* Wait for space in the command FIFO */ 320 error = sunxi_nand_wait_status(sc, NDFC_ST_CMD_FIFO_STATUS, 0); 321 if (error != 0) 322 return error; 323 324 /* Transfer data from buffer to FIFO RAM */ 325 const int count = xfer / n; 326 if (n == 1) { 327 bus_space_write_region_1(sc->sc_bst, sc->sc_bsh, 328 NDFC_RAM0_BASE, (const uint8_t *)xfer_buf, count); 329 } else if (n == 2) { 330 bus_space_write_region_2(sc->sc_bst, sc->sc_bsh, 331 NDFC_RAM0_BASE, (const uint16_t *)xfer_buf, count); 332 } 333 334 /* Start the transfer. */ 335 NAND_WRITE(sc, NDFC_CNT, xfer); 336 NAND_WRITE(sc, NDFC_CMD, 337 NDFC_CMD_DATA_TRANS | NDFC_CMD_DATA_METHOD | 338 NDFC_CMD_ACCESS_DIR); 339 340 /* Wait for the command to finish */ 341 if (cold) { 342 error = sunxi_nand_wait_status(sc, NDFC_ST_CMD_INT_FLAG, 343 NDFC_ST_CMD_INT_FLAG); 344 } else { 345 mutex_enter(&sc->sc_lock); 346 error = sunxi_nand_wait_intr(sc, NDFC_ST_CMD_INT_FLAG); 347 mutex_exit(&sc->sc_lock); 348 } 349 if (error != 0) 350 return error; 351 352 resid -= xfer; 353 xfer_buf += xfer; 354 } 355 356 return 0; 357 } 358 359 /* 360 * NAND interface 361 */ 362 363 static void 364 sunxi_nand_select(device_t dev, bool enable) 365 { 366 struct sunxi_nand_softc * const sc = device_private(dev); 367 struct sunxi_nand_chip * const chip = &sc->sc_chip; 368 struct nand_softc * const nand_sc = device_private(chip->chip_dev); 369 struct nand_chip * const nc = nand_sc ? &nand_sc->sc_chip : NULL; 370 uint32_t ctl; 371 372 ctl = NAND_READ(sc, NDFC_CTL); 373 if (enable) { 374 ctl &= ~NDFC_CTL_CE_SEL; 375 ctl |= __SHIFTIN(chip->chip_cs, NDFC_CTL_CE_SEL); 376 ctl &= ~NDFC_CTL_RB_SEL; 377 ctl |= __SHIFTIN(chip->chip_rb, NDFC_CTL_RB_SEL); 378 ctl &= ~NDFC_CTL_PAGE_SIZE; 379 ctl &= ~NDFC_CTL_BUS_WIDTH; 380 ctl |= NDFC_CTL_EN; 381 382 if (nc) { 383 ctl |= __SHIFTIN(__builtin_ffs(nc->nc_page_size) - 11, 384 NDFC_CTL_PAGE_SIZE); 385 if (ISSET(nc->nc_flags, NC_BUSWIDTH_16)) 386 ctl |= NDFC_CTL_BUS_WIDTH; 387 388 NAND_WRITE(sc, NDFC_SPARE_AREA, nc->nc_page_size); 389 } 390 } 391 NAND_WRITE(sc, NDFC_CTL, ctl); 392 } 393 394 static void 395 sunxi_nand_command(device_t dev, uint8_t command) 396 { 397 struct sunxi_nand_softc * const sc = device_private(dev); 398 struct sunxi_nand_chip * const chip = &sc->sc_chip; 399 400 sunxi_nand_send_address(sc, chip); 401 402 /* Wait for space in the command FIFO */ 403 sunxi_nand_wait_status(sc, NDFC_ST_CMD_FIFO_STATUS, 0); 404 405 NAND_WRITE(sc, NDFC_CMD, NDFC_CMD_SEND_FIRST_CMD | command); 406 407 /* Wait for the command to finish */ 408 sunxi_nand_wait_status(sc, NDFC_ST_CMD_INT_FLAG, NDFC_ST_CMD_INT_FLAG); 409 } 410 411 static void 412 sunxi_nand_address(device_t dev, uint8_t address) 413 { 414 struct sunxi_nand_softc * const sc = device_private(dev); 415 struct sunxi_nand_chip * const chip = &sc->sc_chip; 416 const u_int index = chip->chip_addr_count / 4; 417 const u_int shift = (chip->chip_addr_count & 3) * 8; 418 419 KASSERT(index < 2); 420 421 chip->chip_addr[index] |= ((uint32_t)address << shift); 422 chip->chip_addr_count++; 423 } 424 425 static void 426 sunxi_nand_busy(device_t dev) 427 { 428 struct sunxi_nand_softc * const sc = device_private(dev); 429 struct sunxi_nand_chip * const chip = &sc->sc_chip; 430 431 while (!sunxi_nand_rb_state(sc, chip)) 432 delay(1); 433 } 434 435 static void 436 sunxi_nand_read_1(device_t dev, uint8_t *data) 437 { 438 sunxi_nand_read_buf_n(dev, data, 1, 1); 439 } 440 441 static void 442 sunxi_nand_read_2(device_t dev, uint16_t *data) 443 { 444 sunxi_nand_read_buf_n(dev, data, 2, 2); 445 } 446 447 static void 448 sunxi_nand_read_buf_1(device_t dev, void *data, size_t len) 449 { 450 sunxi_nand_read_buf_n(dev, data, len, 1); 451 } 452 453 static void 454 sunxi_nand_read_buf_2(device_t dev, void *data, size_t len) 455 { 456 sunxi_nand_read_buf_n(dev, data, len, 2); 457 } 458 459 static void 460 sunxi_nand_write_1(device_t dev, uint8_t data) 461 { 462 sunxi_nand_write_buf_n(dev, &data, 1, 1); 463 } 464 465 static void 466 sunxi_nand_write_2(device_t dev, uint16_t data) 467 { 468 sunxi_nand_write_buf_n(dev, &data, 2, 2); 469 } 470 471 static void 472 sunxi_nand_write_buf_1(device_t dev, const void *data, size_t len) 473 { 474 sunxi_nand_write_buf_n(dev, data, len, 1); 475 } 476 477 static void 478 sunxi_nand_write_buf_2(device_t dev, const void *data, size_t len) 479 { 480 sunxi_nand_write_buf_n(dev, data, len, 2); 481 } 482 483 static int 484 sunxi_nand_intr(void *priv) 485 { 486 struct sunxi_nand_softc * const sc = priv; 487 uint32_t status; 488 int rv = 0; 489 490 mutex_enter(&sc->sc_lock); 491 status = NAND_READ(sc, NDFC_ST) & NDFC_ST_INT_MASK; 492 if (status) { 493 sc->sc_intr |= status; 494 NAND_WRITE(sc, NDFC_ST, status); 495 cv_signal(&sc->sc_cv); 496 rv = 1; 497 } 498 mutex_exit(&sc->sc_lock); 499 500 return rv; 501 } 502 503 static void 504 sunxi_nand_attach_chip(struct sunxi_nand_softc *sc, 505 struct sunxi_nand_chip *chip, int phandle) 506 { 507 struct nand_interface *nand = &chip->chip_nand; 508 const char *ecc_mode, *mtdparts; 509 510 chip->chip_sc = sc; 511 chip->chip_phandle = phandle; 512 513 if (of_getprop_uint32(phandle, "reg", &chip->chip_cs) != 0) { 514 aprint_error_dev(sc->sc_dev, 515 "missing 'reg' property on chip node\n"); 516 return; 517 } 518 519 if (of_getprop_uint32(phandle, "allwinner,rb", &chip->chip_rb) != 0) { 520 aprint_error_dev(sc->sc_dev, 521 "chip #%u: missing 'allwinner,rb' property\n", 522 chip->chip_cs); 523 return; 524 } 525 526 ecc_mode = fdtbus_get_string(phandle, "nand-ecc-mode"); 527 if (ecc_mode == NULL) 528 ecc_mode = "none"; 529 530 if (strcmp(ecc_mode, "none") == 0) 531 chip->chip_eccmode = ECC_MODE_NONE; 532 else if (strcmp(ecc_mode, "hw") == 0) 533 chip->chip_eccmode = ECC_MODE_HW; 534 else if (strcmp(ecc_mode, "hw_syndrome") == 0) 535 chip->chip_eccmode = ECC_MODE_HW_SYNDROME; 536 else if (strcmp(ecc_mode, "soft") == 0) 537 chip->chip_eccmode = ECC_MODE_SOFT; 538 else if (strcmp(ecc_mode, "soft_bch") == 0) 539 chip->chip_eccmode = ECC_MODE_SOFT_BCH; 540 else 541 chip->chip_eccmode = ECC_MODE_UNKNOWN; 542 543 /* Only HW mode is supported for now */ 544 switch (chip->chip_eccmode) { 545 case ECC_MODE_HW: 546 break; 547 default: 548 return; 549 } 550 551 aprint_normal_dev(sc->sc_dev, "chip #%u: RB %u, ECC mode '%s'\n", 552 chip->chip_cs, chip->chip_rb, ecc_mode); 553 554 nand_init_interface(nand); 555 nand->select = sunxi_nand_select; 556 nand->command = sunxi_nand_command; 557 nand->address = sunxi_nand_address; 558 nand->read_buf_1 = sunxi_nand_read_buf_1; 559 nand->read_buf_2 = sunxi_nand_read_buf_2; 560 nand->read_1 = sunxi_nand_read_1; 561 nand->read_2 = sunxi_nand_read_2; 562 nand->write_buf_1 = sunxi_nand_write_buf_1; 563 nand->write_buf_2 = sunxi_nand_write_buf_2; 564 nand->write_1 = sunxi_nand_write_1; 565 nand->write_2 = sunxi_nand_write_2; 566 nand->busy = sunxi_nand_busy; 567 568 #if notyet 569 switch (chip->chip_eccmode) { 570 case ECC_MODE_HW: 571 nand->ecc_compute = sunxi_nand_ecc_compute; 572 nand->ecc_correct = sunxi_nand_ecc_correct; 573 nand->ecc_prepare = sunxi_nand_ecc_prepare; 574 nand->ecc.necc_code_size = 3; 575 nand->ecc.necc_block_size = 512; 576 nand->ecc.necc_type = NAND_ECC_TYPE_HW; 577 break; 578 default: 579 aprint_error_dev(sc->sc_dev, 580 "chip #%u: ECC mode not supported by driver\n", 581 chip->chip_cs); 582 return; 583 } 584 #else 585 nand->ecc.necc_code_size = 3; 586 nand->ecc.necc_block_size = 256; 587 #endif 588 589 chip->chip_dev = nand_attach_mi(nand, sc->sc_dev); 590 if (chip->chip_dev == NULL) 591 return; 592 593 mtdparts = get_bootconf_string(boot_args, "mtdparts"); 594 if (mtdparts != NULL) { 595 char mtd_id[] = "sunxi-nand.XX"; 596 snprintf(mtd_id, sizeof(mtd_id), "sunxi-nand.%u", 597 device_unit(sc->sc_dev)); 598 599 nand_attach_mtdparts(chip->chip_dev, mtd_id, mtdparts); 600 } 601 } 602 603 static int 604 sunxi_nand_init_resources(struct sunxi_nand_softc *sc) 605 { 606 int error; 607 608 /* Both "mod" and "ahb" clocks are required */ 609 sc->sc_clk_mod = fdtbus_clock_get(sc->sc_phandle, "mod"); 610 sc->sc_clk_ahb = fdtbus_clock_get(sc->sc_phandle, "ahb"); 611 if (sc->sc_clk_mod == NULL || sc->sc_clk_ahb == NULL) 612 return ENXIO; 613 614 if ((error = clk_enable(sc->sc_clk_ahb)) != 0) 615 return error; 616 if ((error = clk_enable(sc->sc_clk_mod)) != 0) 617 return error; 618 619 /* Reset is optional */ 620 sc->sc_rst_ahb = fdtbus_reset_get(sc->sc_phandle, "ahb"); 621 if (sc->sc_rst_ahb != NULL) { 622 if ((error = fdtbus_reset_deassert(sc->sc_rst_ahb)) != 0) 623 return error; 624 } 625 626 return 0; 627 } 628 629 static int 630 sunxi_nand_match(device_t parent, cfdata_t cf, void *aux) 631 { 632 struct fdt_attach_args * const faa = aux; 633 634 return of_compatible_match(faa->faa_phandle, compat_data); 635 } 636 637 static void 638 sunxi_nand_attach(device_t parent, device_t self, void *aux) 639 { 640 struct sunxi_nand_softc * const sc = device_private(self); 641 struct fdt_attach_args * const faa = aux; 642 const int phandle = faa->faa_phandle; 643 char intrstr[128]; 644 bus_addr_t addr; 645 bus_size_t size; 646 int child; 647 648 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 649 aprint_error(": couldn't get registers\n"); 650 return; 651 } 652 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 653 aprint_error(": couldn't decode interrupt\n"); 654 return; 655 } 656 657 sc->sc_dev = self; 658 sc->sc_phandle = phandle; 659 sc->sc_bst = faa->faa_bst; 660 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 661 aprint_error(": couldn't map registers\n"); 662 return; 663 } 664 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 665 cv_init(&sc->sc_cv, "nandxfer"); 666 667 aprint_naive("\n"); 668 aprint_normal(": NAND Flash Controller\n"); 669 670 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, 671 FDT_INTR_MPSAFE, sunxi_nand_intr, sc, device_xname(self)); 672 if (sc->sc_ih == NULL) { 673 aprint_error_dev(self, "couldn't establish interrupt on %s\n", 674 intrstr); 675 return; 676 } 677 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 678 679 if (sunxi_nand_init_resources(sc) != 0) { 680 aprint_error_dev(self, "couldn't initialize resources\n"); 681 return; 682 } 683 684 /* DT bindings allow for multiple chips but we only use the first */ 685 child = OF_child(phandle); 686 if (!child) 687 return; 688 689 sunxi_nand_attach_chip(sc, &sc->sc_chip, child); 690 } 691 692 CFATTACH_DECL_NEW(sunxi_nand, sizeof(struct sunxi_nand_softc), 693 sunxi_nand_match, sunxi_nand_attach, NULL, NULL); 694 695