1 /* $NetBSD: efa.c,v 1.12 2014/01/03 00:33:06 rkujawa Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Radoslaw Kujawa. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Driver for FastATA 1200 EIDE controller, manufactured by ELBOX Computer. 34 * 35 * Gayle-related stuff inspired by wdc_amiga.c written by Michael L. Hitch 36 * and Aymeric Vincent. 37 */ 38 39 #include <sys/cdefs.h> 40 41 #include <sys/types.h> 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/malloc.h> 45 #include <sys/device.h> 46 #include <sys/bus.h> 47 #include <sys/proc.h> 48 #include <sys/kernel.h> 49 #include <sys/kthread.h> 50 51 #include <machine/cpu.h> 52 #include <machine/intr.h> 53 #include <sys/bswap.h> 54 55 #include <amiga/amiga/cia.h> 56 #include <amiga/amiga/custom.h> 57 #include <amiga/amiga/device.h> 58 #include <amiga/amiga/gayle.h> 59 #include <amiga/dev/zbusvar.h> 60 61 #include <dev/ata/atavar.h> 62 #include <dev/ic/wdcvar.h> 63 64 #include <amiga/dev/efareg.h> 65 #include <amiga/dev/efavar.h> 66 67 #define EFA_32BIT_IO 1 68 /* #define EFA_NO_INTR 1 */ 69 /* #define EFA_DEBUG 1 */ 70 71 int efa_probe(device_t, cfdata_t, void *); 72 void efa_attach(device_t, device_t, void *); 73 int efa_intr(void *); 74 int efa_intr_soft(void *arg); 75 static void efa_set_opts(struct efa_softc *sc); 76 static bool efa_mapbase(struct efa_softc *sc); 77 static bool efa_mapreg_gayle(struct efa_softc *sc); 78 static bool efa_mapreg_native(struct efa_softc *sc); 79 static void efa_fata_subregion_pio0(struct wdc_regs *wdr_fata); 80 static void efa_fata_subregion_pion(struct wdc_regs *wdr_fata, bool data32); 81 static void efa_setup_channel(struct ata_channel *chp); 82 static void efa_attach_channel(struct efa_softc *sc, int i); 83 static void efa_select_regset(struct efa_softc *sc, int chnum, 84 uint8_t piomode); 85 static void efa_poll_kthread(void *arg); 86 static bool efa_compare_status(void); 87 #ifdef EFA_DEBUG 88 static void efa_debug_print_regmapping(struct wdc_regs *wdr_fata); 89 #endif /* EFA_DEBUG */ 90 91 CFATTACH_DECL_NEW(efa, sizeof(struct efa_softc), 92 efa_probe, efa_attach, NULL, NULL); 93 94 #define PIO_NSUPP 0xFFFFFFFF 95 96 static const bus_addr_t pio_offsets[] = 97 { FATA1_PIO0_OFF, PIO_NSUPP, PIO_NSUPP, FATA1_PIO3_OFF, FATA1_PIO4_OFF, 98 FATA1_PIO5_OFF }; 99 static const unsigned int wdr_offsets_pio0[] = 100 { FATA1_PIO0_OFF_DATA, FATA1_PIO0_OFF_ERROR, FATA1_PIO0_OFF_SECCNT, 101 FATA1_PIO0_OFF_SECTOR, FATA1_PIO0_OFF_CYL_LO, FATA1_PIO0_OFF_CYL_HI, 102 FATA1_PIO0_OFF_SDH, FATA1_PIO0_OFF_COMMAND }; 103 static const unsigned int wdr_offsets_pion[] = 104 { FATA1_PION_OFF_DATA, FATA1_PION_OFF_ERROR, FATA1_PION_OFF_SECCNT, 105 FATA1_PION_OFF_SECTOR, FATA1_PION_OFF_CYL_LO, FATA1_PION_OFF_CYL_HI, 106 FATA1_PION_OFF_SDH, FATA1_PION_OFF_COMMAND }; 107 108 int 109 efa_probe(device_t parent, cfdata_t cfp, void *aux) 110 { 111 /* 112 * FastATA 1200 uses portions of Gayle IDE interface, and efa driver 113 * can't coexist with wdc_amiga. Match "wdc" on an A1200, because 114 * FastATA 1200 does not autoconfigure. 115 */ 116 if (!matchname(aux, "wdc") || !is_a1200()) 117 return(0); 118 119 if (!efa_compare_status()) 120 return(0); 121 122 #ifdef EFA_DEBUG 123 aprint_normal("efa_probe succeeded\n"); 124 #endif /* EFA_DEBUG */ 125 126 return 100; 127 } 128 129 void 130 efa_attach(device_t parent, device_t self, void *aux) 131 { 132 int i; 133 struct efa_softc *sc = device_private(self); 134 135 aprint_normal(": ELBOX FastATA 1200\n"); 136 137 gayle_init(); 138 139 sc->sc_dev = self; 140 141 efa_set_opts(sc); 142 143 if (!efa_mapbase(sc)) { 144 aprint_error_dev(self, "couldn't map base addresses\n"); 145 return; 146 } 147 if (!efa_mapreg_gayle(sc)) { 148 aprint_error_dev(self, "couldn't map Gayle registers\n"); 149 return; 150 } 151 if (!efa_mapreg_native(sc)) { 152 aprint_error_dev(self, "couldn't map FastATA regsters\n"); 153 return; 154 } 155 156 sc->sc_wdcdev.sc_atac.atac_pio_cap = 5; 157 sc->sc_wdcdev.sc_atac.atac_nchannels = FATA1_CHANNELS; 158 sc->sc_wdcdev.sc_atac.atac_set_modes = efa_setup_channel; 159 sc->sc_wdcdev.sc_atac.atac_dev = self; 160 sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanlist; 161 sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16; 162 sc->sc_wdcdev.wdc_maxdrives = 2; 163 164 if (sc->sc_32bit_io) 165 sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA32; 166 167 /* 168 * The following should work for polling mode, but it does not. 169 * if (sc->sc_no_intr) 170 * sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_NOIRQ; 171 */ 172 173 wdc_allocate_regs(&sc->sc_wdcdev); 174 175 for (i = 0; i < FATA1_CHANNELS; i++) 176 efa_attach_channel(sc, i); 177 178 if (sc->sc_no_intr) { 179 sc->sc_fata_softintr = softint_establish(SOFTINT_BIO, 180 (void (*)(void *))efa_intr_soft, sc); 181 if (sc->sc_fata_softintr == NULL) { 182 aprint_error_dev(self, "couldn't create soft intr\n"); 183 return; 184 } 185 if (kthread_create(PRI_NONE, 0, NULL, efa_poll_kthread, sc, 186 NULL, "efa")) { 187 aprint_error_dev(self, "couldn't create kthread\n"); 188 return; 189 } 190 } else { 191 sc->sc_isr.isr_intr = efa_intr; 192 sc->sc_isr.isr_arg = sc; 193 sc->sc_isr.isr_ipl = 2; 194 add_isr (&sc->sc_isr); 195 gayle_intr_enable_set(GAYLE_INT_IDE); 196 } 197 198 } 199 200 static void 201 efa_attach_channel(struct efa_softc *sc, int chnum) 202 { 203 sc->sc_chanlist[chnum] = &sc->sc_ports[chnum].chan; 204 205 sc->sc_ports[chnum].chan.ch_channel = chnum; 206 sc->sc_ports[chnum].chan.ch_atac = &sc->sc_wdcdev.sc_atac; 207 sc->sc_ports[chnum].chan.ch_queue = &sc->sc_ports[chnum].queue; 208 209 if (!sc->sc_32bit_io) 210 efa_select_regset(sc, chnum, 0); /* Start in PIO0. */ 211 else 212 efa_select_regset(sc, chnum, 3); 213 214 wdc_init_shadow_regs(&sc->sc_ports[chnum].chan); 215 216 wdcattach(&sc->sc_ports[chnum].chan); 217 218 #ifdef EFA_DEBUG 219 aprint_normal_dev(sc->sc_dev, "done init for channel %d\n", chnum); 220 #endif 221 222 } 223 224 /* TODO: convert to callout(9) */ 225 static void 226 efa_poll_kthread(void *arg) 227 { 228 struct efa_softc *sc = arg; 229 230 for (;;) { 231 /* TODO: actually check if interrupt status register is set */ 232 softint_schedule(sc->sc_fata_softintr); 233 /* TODO: convert to kpause */ 234 tsleep(arg, PWAIT, "efa_poll", hz); 235 } 236 } 237 238 static void 239 efa_set_opts(struct efa_softc *sc) 240 { 241 #ifdef EFA_32BIT_IO 242 sc->sc_32bit_io = true; 243 #else 244 sc->sc_32bit_io = false; 245 #endif /* EFA_32BIT_IO */ 246 247 #ifdef EFA_NO_INTR 248 sc->sc_no_intr = true; /* XXX: not yet! */ 249 #else 250 sc->sc_no_intr = false; 251 #endif /* EFA_NO_INTR */ 252 253 if (sc->sc_no_intr) 254 aprint_verbose_dev(sc->sc_dev, "hardware interrupt disabled\n"); 255 256 if (sc->sc_32bit_io) 257 aprint_verbose_dev(sc->sc_dev, "32-bit I/O enabled\n"); 258 } 259 260 int 261 efa_intr_soft(void *arg) 262 { 263 int ret = 0; 264 struct efa_softc *sc = (struct efa_softc *)arg; 265 266 /* TODO: check which channel needs servicing */ 267 /* 268 uint8_t fataintreq; 269 fataintreq = bus_space_read_1(sc->sc_ports[0].wdr[piom].cmd_iot, 270 sc->sc_ports[chnum].intst[piom], 0); 271 */ 272 273 ret = wdcintr(&sc->sc_ports[0].chan); 274 ret = wdcintr(&sc->sc_ports[1].chan); 275 276 return ret; 277 } 278 279 int 280 efa_intr(void *arg) 281 { 282 struct efa_softc *sc = (struct efa_softc *)arg; 283 int r1, r2, ret; 284 uint8_t intreq; 285 286 intreq = gayle_intr_status(); 287 ret = 0; 288 289 if (intreq & GAYLE_INT_IDE) { 290 gayle_intr_ack(0x7C | (intreq & 0x03)); 291 /* How to check which channel caused interrupt? 292 * Interrupt status register is not very useful here. */ 293 r1 = wdcintr(&sc->sc_ports[0].chan); 294 r2 = wdcintr(&sc->sc_ports[1].chan); 295 ret = r1 | r2; 296 } 297 298 return ret; 299 } 300 301 static bool 302 efa_mapbase(struct efa_softc *sc) 303 { 304 int i, j; 305 static struct bus_space_tag fata_cmd_iot; 306 static struct bus_space_tag gayle_cmd_iot; 307 308 gayle_cmd_iot.base = (bus_addr_t) ztwomap(GAYLE_IDE_BASE + 2); 309 gayle_cmd_iot.absm = &amiga_bus_stride_4swap; 310 fata_cmd_iot.base = (bus_addr_t) ztwomap(FATA1_BASE); 311 fata_cmd_iot.absm = &amiga_bus_stride_4swap; 312 313 #ifdef EFA_DEBUG 314 aprint_normal_dev(sc->sc_dev, "Gayle %x -> %x, FastATA %x -> %x\n", 315 GAYLE_IDE_BASE, gayle_cmd_iot.base, FATA1_BASE, fata_cmd_iot.base); 316 #endif 317 318 if (!gayle_cmd_iot.base) 319 return false; 320 if (!fata_cmd_iot.base) 321 return false; 322 323 sc->sc_gayle_wdc_regs.cmd_iot = &gayle_cmd_iot; 324 sc->sc_gayle_wdc_regs.ctl_iot = &gayle_cmd_iot; 325 326 for (i = 0; i < FATA1_CHANNELS; i++) { 327 for (j = 0; j < PIO_COUNT; j++) { 328 sc->sc_ports[i].wdr[j].cmd_iot = &fata_cmd_iot; 329 sc->sc_ports[i].wdr[j].data32iot = &fata_cmd_iot; 330 sc->sc_ports[i].wdr[j].ctl_iot = &gayle_cmd_iot; 331 } 332 } 333 334 return true; 335 } 336 337 338 /* Gayle IDE register mapping, we need it anyway. */ 339 static bool 340 efa_mapreg_gayle(struct efa_softc *sc) 341 { 342 int i; 343 344 struct wdc_regs *wdr = &sc->sc_gayle_wdc_regs; 345 346 if (bus_space_map(wdr->cmd_iot, 0, 0x40, 0, 347 &wdr->cmd_baseioh)) { 348 return false; 349 } 350 351 for (i = 0; i < WDC_NREG; i++) { 352 if (bus_space_subregion(wdr->cmd_iot, 353 wdr->cmd_baseioh, i, i == 0 ? 4 : 1, 354 &wdr->cmd_iohs[i]) != 0) { 355 356 bus_space_unmap(wdr->cmd_iot, 357 wdr->cmd_baseioh, 0x40); 358 return false; 359 } 360 } 361 362 if (bus_space_subregion(wdr->cmd_iot, 363 wdr->cmd_baseioh, 0x406, 1, &wdr->ctl_ioh)) 364 return false; 365 366 return true; 367 } 368 369 /* Native FastATA register mapping, suitable for PIO modes 0 to 5. */ 370 static bool 371 efa_mapreg_native(struct efa_softc *sc) 372 { 373 int i,j; 374 struct wdc_regs *wdr_gayle = &sc->sc_gayle_wdc_regs; 375 struct wdc_regs *wdr_fata; 376 377 for (i = 0; i < FATA1_CHANNELS; i++) { 378 379 for (j = 0; j < PIO_COUNT; j++) { 380 381 wdr_fata = &sc->sc_ports[i].wdr[j]; 382 sc->sc_ports[i].mode_ok[j] = false; 383 384 if (pio_offsets[j] == PIO_NSUPP) { 385 #ifdef EFA_DEBUG 386 aprint_normal_dev(sc->sc_dev, 387 "Skipping mapping for PIO mode %x\n", j); 388 #endif 389 continue; 390 } 391 392 if (bus_space_map(wdr_fata->cmd_iot, 393 pio_offsets[j] + FATA1_CHAN_SIZE * i, 394 FATA1_CHAN_SIZE, 0, &wdr_fata->cmd_baseioh)) { 395 return false; 396 } 397 #ifdef EFA_DEBUG 398 aprint_normal_dev(sc->sc_dev, 399 "Chan %x PIO mode %x mapped %x -> %x\n", 400 i, j, (bus_addr_t) kvtop((void*) 401 wdr_fata->cmd_baseioh), (unsigned int) 402 wdr_fata->cmd_baseioh); 403 #endif 404 405 sc->sc_ports[i].mode_ok[j] = true; 406 407 if (j == 0) 408 efa_fata_subregion_pio0(wdr_fata); 409 else { 410 if (sc->sc_32bit_io) 411 efa_fata_subregion_pion(wdr_fata, 412 true); 413 else 414 efa_fata_subregion_pion(wdr_fata, 415 false); 416 417 bus_space_subregion(wdr_fata->cmd_iot, 418 wdr_fata->cmd_baseioh, FATA1_PION_OFF_INTST, 419 1, &sc->sc_ports[i].intst[j]); 420 } 421 422 /* No 32-bit register for PIO0 ... */ 423 if (j == 0 && sc->sc_32bit_io) 424 sc->sc_ports[i].mode_ok[j] = false; 425 426 wdr_fata->ctl_ioh = wdr_gayle->ctl_ioh; 427 }; 428 } 429 return true; 430 } 431 432 433 static void 434 efa_fata_subregion_pio0(struct wdc_regs *wdr_fata) 435 { 436 int i; 437 438 for (i = 0; i < WDC_NREG; i++) 439 bus_space_subregion(wdr_fata->cmd_iot, 440 wdr_fata->cmd_baseioh, wdr_offsets_pio0[i], 441 i == 0 ? 4 : 1, &wdr_fata->cmd_iohs[i]); 442 } 443 444 static void 445 efa_fata_subregion_pion(struct wdc_regs *wdr_fata, bool data32) 446 { 447 int i; 448 449 if (data32) 450 bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 451 FATA1_PION_OFF_DATA32, 8, &wdr_fata->data32ioh); 452 453 for (i = 0; i < WDC_NREG; i++) 454 bus_space_subregion(wdr_fata->cmd_iot, 455 wdr_fata->cmd_baseioh, wdr_offsets_pion[i], 456 i == 0 ? 4 : 1, &wdr_fata->cmd_iohs[i]); 457 } 458 459 static void 460 efa_setup_channel(struct ata_channel *chp) 461 { 462 int drive, chnum; 463 uint8_t mode; 464 struct atac_softc *atac; 465 struct ata_drive_datas *drvp; 466 struct efa_softc *sc; 467 int ipl; 468 469 chnum = chp->ch_channel; 470 atac = chp->ch_atac; 471 sc = device_private(atac->atac_dev); 472 473 mode = 5; /* start with fastest possible setting */ 474 475 #ifdef EFA_DEBUG 476 aprint_normal_dev(sc->sc_dev, "efa_setup_channel for ch %d\n", 477 chnum); 478 #endif /* EFA_DEBUG */ 479 480 /* We might be in the middle of something... so raise IPL. */ 481 ipl = splvm(); 482 483 for (drive = 0; drive < 2; drive++) { 484 drvp = &chp->ch_drive[drive]; 485 486 if (drvp->drive_type == ATA_DRIVET_NONE) 487 continue; /* nothing to see here */ 488 489 if (drvp->PIO_cap < mode) 490 mode = drvp->PIO_cap; 491 492 /* TODO: check if sc_ports->mode_ok */ 493 494 #ifdef EFA_DEBUG 495 aprint_normal_dev(sc->sc_dev, "drive %d supports %d\n", 496 drive, drvp->PIO_cap); 497 #endif /* EFA_DEBUG */ 498 499 drvp->PIO_mode = mode; 500 } 501 502 /* Change FastATA register set. */ 503 efa_select_regset(sc, chnum, mode); 504 /* re-init shadow regs */ 505 wdc_init_shadow_regs(&sc->sc_ports[chnum].chan); 506 507 splx(ipl); 508 } 509 510 static void 511 efa_select_regset(struct efa_softc *sc, int chnum, uint8_t piomode) 512 { 513 struct wdc_softc *wdc; 514 515 wdc = CHAN_TO_WDC(&sc->sc_ports[chnum].chan); 516 wdc->regs[chnum] = sc->sc_ports[chnum].wdr[piomode]; 517 518 #ifdef EFA_DEBUG 519 aprint_normal_dev(sc->sc_dev, "switched ch %d to PIO %d\n", 520 chnum, piomode); 521 522 efa_debug_print_regmapping(&wdc->regs[chnum]); 523 #endif /* EFA_DEBUG */ 524 } 525 526 #ifdef EFA_DEBUG 527 static void 528 efa_debug_print_regmapping(struct wdc_regs *wdr_fata) 529 { 530 int i; 531 aprint_normal("base %x->%x", 532 (bus_addr_t) kvtop((void*) wdr_fata->cmd_baseioh), 533 (bus_addr_t) wdr_fata->cmd_baseioh); 534 for (i = 0; i < WDC_NREG; i++) { 535 aprint_normal("reg %x, %x->%x, ", i, 536 (bus_addr_t) kvtop((void*) wdr_fata->cmd_iohs[i]), 537 (bus_addr_t) wdr_fata->cmd_iohs[i]); 538 } 539 aprint_normal("\n"); 540 } 541 #endif /* EFA_DEBUG */ 542 543 /* Compare the values of (status) command register in PIO0, PIO3 sets. */ 544 static bool 545 efa_compare_status(void) 546 { 547 uint8_t cmd0, cmd3; 548 struct bus_space_tag fata_bst; 549 bus_space_tag_t fata_iot; 550 bus_space_handle_t cmd0_ioh, cmd3_ioh; 551 bool rv; 552 553 rv = false; 554 555 fata_bst.base = (bus_addr_t) ztwomap(FATA1_BASE); 556 fata_bst.absm = &amiga_bus_stride_4swap; 557 558 fata_iot = &fata_bst; 559 560 if (bus_space_map(fata_iot, pio_offsets[0], FATA1_CHAN_SIZE, 0, 561 &cmd0_ioh)) 562 return false; 563 if (bus_space_map(fata_iot, pio_offsets[3], FATA1_CHAN_SIZE, 0, 564 &cmd3_ioh)) 565 return false; 566 567 #ifdef EFA_DEBUG 568 aprint_normal("probing for FastATA at %x, %x: ", (bus_addr_t) cmd0_ioh, 569 (bus_addr_t) cmd3_ioh); 570 #endif /* EFA_DEBUG */ 571 572 cmd0 = bus_space_read_1(fata_iot, cmd0_ioh, FATA1_PIO0_OFF_COMMAND); 573 cmd3 = bus_space_read_1(fata_iot, cmd3_ioh, FATA1_PION_OFF_COMMAND); 574 575 if (cmd0 == cmd3) 576 rv = true; 577 578 if ( (cmd0 == 0xFF) || (cmd0 == 0x00) ) { 579 /* Assume there's nothing there... */ 580 rv = false; 581 } 582 583 #ifdef EFA_DEBUG 584 aprint_normal("cmd0 %x, cmd3 %x\n", cmd0, cmd3); 585 #endif /* EFA_DEBUG */ 586 587 bus_space_unmap(fata_iot, pio_offsets[0], FATA1_CHAN_SIZE); 588 bus_space_unmap(fata_iot, pio_offsets[3], FATA1_CHAN_SIZE); 589 590 return rv; 591 } 592 593