1 /* $OpenBSD: auixp.c,v 1.56 2024/09/20 02:20:44 jsg Exp $ */ 2 /* $NetBSD: auixp.c,v 1.9 2005/06/27 21:13:09 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 2004, 2005 Reinoud Zandijk <reinoud@netbsd.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 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 * Audio driver for ATI IXP-{150,200,...} audio driver hardware. 30 * 31 * Recording and playback has been tested OK on various sample rates and 32 * encodings. 33 * 34 * Known problems and issues : 35 * - SPDIF is untested and needs some work still (LED stays off) 36 * - 32 bit audio playback failed last time i tried but that might an AC'97 37 * codec support problem. 38 * - 32 bit recording works but can't try out playing: see above. 39 * - no suspend/resume support yet. 40 * - multiple codecs are `supported' but not tested; the implementation needs 41 * some cleaning up. 42 */ 43 44 /*#define DEBUG_AUIXP*/ 45 46 #include <sys/param.h> 47 #include <sys/errno.h> 48 #include <sys/systm.h> 49 #include <sys/malloc.h> 50 #include <sys/device.h> 51 #include <sys/audioio.h> 52 #include <sys/queue.h> 53 54 #include <machine/bus.h> 55 56 #include <dev/pci/pcidevs.h> 57 #include <dev/pci/pcivar.h> 58 59 #include <dev/audio_if.h> 60 #include <dev/ic/ac97.h> 61 62 #include <dev/pci/auixpreg.h> 63 #include <dev/pci/auixpvar.h> 64 65 /* codec detection constant indicating the interrupt flags */ 66 #define ALL_CODECS_NOT_READY \ 67 (ATI_REG_ISR_CODEC0_NOT_READY | ATI_REG_ISR_CODEC1_NOT_READY |\ 68 ATI_REG_ISR_CODEC2_NOT_READY) 69 #define CODEC_CHECK_BITS (ALL_CODECS_NOT_READY|ATI_REG_ISR_NEW_FRAME) 70 71 /* why isn't this base address register not in the headerfile? */ 72 #define PCI_CBIO 0x10 73 74 /* macro's used */ 75 #define KERNADDR(p) ((void *)((p)->addr)) 76 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 77 78 const struct pci_matchid auixp_pci_devices[] = { 79 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB200_AUDIO }, 80 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB300_AUDIO }, 81 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB400_AUDIO }, 82 { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB600_AUDIO } 83 }; 84 85 struct cfdriver auixp_cd = { 86 NULL, "auixp", DV_DULL 87 }; 88 89 int auixp_match( struct device *, void *, void *); 90 void auixp_attach(struct device *, struct device *, void *); 91 int auixp_detach(struct device *, int); 92 93 int auixp_activate(struct device *, int); 94 95 const struct cfattach auixp_ca = { 96 sizeof(struct auixp_softc), auixp_match, auixp_attach, 97 NULL, auixp_activate 98 }; 99 100 int auixp_open(void *v, int flags); 101 void auixp_close(void *v); 102 int auixp_set_params(void *, int, int, struct audio_params *, 103 struct audio_params *); 104 int auixp_commit_settings(void *); 105 int auixp_round_blocksize(void *, int); 106 int auixp_trigger_output(void *, void *, void *, int, 107 void (*)(void *), void *, struct audio_params *); 108 int auixp_trigger_input(void *, void *, void *, int, 109 void (*)(void *), void *, struct audio_params *); 110 int auixp_halt_output(void *); 111 int auixp_halt_input(void *); 112 int auixp_set_port(void *, mixer_ctrl_t *); 113 int auixp_get_port(void *, mixer_ctrl_t *); 114 int auixp_query_devinfo(void *, mixer_devinfo_t *); 115 void * auixp_malloc(void *, int, size_t, int, int); 116 void auixp_free(void *, void *, int); 117 int auixp_intr(void *); 118 int auixp_allocmem(struct auixp_softc *, size_t, size_t, 119 struct auixp_dma *); 120 int auixp_freemem(struct auixp_softc *, struct auixp_dma *); 121 122 /* Supporting subroutines */ 123 int auixp_init(struct auixp_softc *); 124 void auixp_autodetect_codecs(struct auixp_softc *); 125 void auixp_post_config(struct device *); 126 127 void auixp_reset_aclink(struct auixp_softc *); 128 int auixp_attach_codec(void *, struct ac97_codec_if *); 129 int auixp_read_codec(void *, u_int8_t, u_int16_t *); 130 int auixp_write_codec(void *, u_int8_t, u_int16_t); 131 int auixp_wait_for_codecs(struct auixp_softc *, const char *); 132 void auixp_reset_codec(void *); 133 enum ac97_host_flags auixp_flags_codec(void *); 134 135 void auixp_enable_dma(struct auixp_softc *, struct auixp_dma *); 136 void auixp_disable_dma(struct auixp_softc *, struct auixp_dma *); 137 void auixp_enable_interrupts(struct auixp_softc *); 138 void auixp_disable_interrupts(struct auixp_softc *); 139 140 void auixp_link_daisychain(struct auixp_softc *, 141 struct auixp_dma *, struct auixp_dma *, int, int); 142 int auixp_allocate_dma_chain(struct auixp_softc *, struct auixp_dma **); 143 void auixp_program_dma_chain(struct auixp_softc *, struct auixp_dma *); 144 void auixp_dma_update(struct auixp_softc *, struct auixp_dma *); 145 void auixp_update_busbusy(struct auixp_softc *); 146 147 #ifdef DEBUG_AUIXP 148 #define DPRINTF(x) printf x 149 #else 150 #define DPRINTF(x) 151 #endif 152 153 const struct audio_hw_if auixp_hw_if = { 154 .open = auixp_open, 155 .close = auixp_close, 156 .set_params = auixp_set_params, 157 .round_blocksize = auixp_round_blocksize, 158 .commit_settings = auixp_commit_settings, 159 .halt_output = auixp_halt_output, 160 .halt_input = auixp_halt_input, 161 .set_port = auixp_set_port, 162 .get_port = auixp_get_port, 163 .query_devinfo = auixp_query_devinfo, 164 .allocm = auixp_malloc, 165 .freem = auixp_free, 166 .trigger_output = auixp_trigger_output, 167 .trigger_input = auixp_trigger_input, 168 }; 169 170 int 171 auixp_open(void *v, int flags) 172 { 173 174 return 0; 175 } 176 177 void 178 auixp_close(void *v) 179 { 180 } 181 182 /* commit setting and program ATI IXP chip */ 183 int 184 auixp_commit_settings(void *hdl) 185 { 186 struct auixp_codec *co; 187 struct auixp_softc *sc; 188 bus_space_tag_t iot; 189 bus_space_handle_t ioh; 190 struct audio_params *params; 191 u_int32_t value; 192 193 /* XXX would it be better to stop interrupts first? XXX */ 194 co = (struct auixp_codec *) hdl; 195 sc = co->sc; 196 iot = sc->sc_iot; 197 ioh = sc->sc_ioh; 198 199 /* process input settings */ 200 params = &sc->sc_play_params; 201 202 /* set input interleaving (precision) */ 203 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 204 value &= ~ATI_REG_CMD_INTERLEAVE_IN; 205 if (params->precision <= 16) 206 value |= ATI_REG_CMD_INTERLEAVE_IN; 207 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 208 209 /* process output settings */ 210 params = &sc->sc_play_params; 211 212 value = bus_space_read_4(iot, ioh, ATI_REG_OUT_DMA_SLOT); 213 value &= ~ATI_REG_OUT_DMA_SLOT_MASK; 214 215 /* TODO SPDIF case for 8 channels */ 216 switch (params->channels) { 217 case 6: 218 value |= ATI_REG_OUT_DMA_SLOT_BIT(7) | 219 ATI_REG_OUT_DMA_SLOT_BIT(8); 220 /* FALLTHROUGH */ 221 case 4: 222 value |= ATI_REG_OUT_DMA_SLOT_BIT(6) | 223 ATI_REG_OUT_DMA_SLOT_BIT(9); 224 /* FALLTHROUGH */ 225 default: 226 value |= ATI_REG_OUT_DMA_SLOT_BIT(3) | 227 ATI_REG_OUT_DMA_SLOT_BIT(4); 228 break; 229 } 230 /* set output threshold */ 231 value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT; 232 bus_space_write_4(iot, ioh, ATI_REG_OUT_DMA_SLOT, value); 233 234 /* set output interleaving (precision) */ 235 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 236 value &= ~ATI_REG_CMD_INTERLEAVE_OUT; 237 if (params->precision <= 16) 238 value |= ATI_REG_CMD_INTERLEAVE_OUT; 239 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 240 241 /* enable 6 channel reordering */ 242 value = bus_space_read_4(iot, ioh, ATI_REG_6CH_REORDER); 243 value &= ~ATI_REG_6CH_REORDER_EN; 244 if (params->channels == 6) 245 value |= ATI_REG_6CH_REORDER_EN; 246 bus_space_write_4(iot, ioh, ATI_REG_6CH_REORDER, value); 247 248 if (sc->has_spdif) { 249 /* set SPDIF (if present) */ 250 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 251 value &= ~ATI_REG_CMD_SPDF_CONFIG_MASK; 252 value |= ATI_REG_CMD_SPDF_CONFIG_34; /* NetBSD AC'97 default */ 253 254 /* XXX this is probably not necessary unless split XXX */ 255 value &= ~ATI_REG_CMD_INTERLEAVE_SPDF; 256 if (params->precision <= 16) 257 value |= ATI_REG_CMD_INTERLEAVE_SPDF; 258 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 259 } 260 261 return 0; 262 } 263 264 265 /* set audio properties in desired setting */ 266 int 267 auixp_set_params(void *hdl, int setmode, int usemode, 268 struct audio_params *play, struct audio_params *rec) 269 { 270 struct auixp_codec *co; 271 int error; 272 u_int temprate; 273 274 co = (struct auixp_codec *) hdl; 275 if (setmode & AUMODE_PLAY) { 276 play->channels = 2; 277 play->precision = 16; 278 switch(play->encoding) { 279 case AUDIO_ENCODING_SLINEAR_LE: 280 break; 281 default: 282 return (EINVAL); 283 } 284 play->bps = AUDIO_BPS(play->precision); 285 play->msb = 1; 286 287 temprate = play->sample_rate; 288 error = ac97_set_rate(co->codec_if, 289 AC97_REG_PCM_LFE_DAC_RATE, &play->sample_rate); 290 if (error) 291 return (error); 292 293 play->sample_rate = temprate; 294 error = ac97_set_rate(co->codec_if, 295 AC97_REG_PCM_SURR_DAC_RATE, &play->sample_rate); 296 if (error) 297 return (error); 298 299 play->sample_rate = temprate; 300 error = ac97_set_rate(co->codec_if, 301 AC97_REG_PCM_FRONT_DAC_RATE, &play->sample_rate); 302 if (error) 303 return (error); 304 305 } 306 307 if (setmode & AUMODE_RECORD) { 308 rec->channels = 2; 309 rec->precision = 16; 310 switch(rec->encoding) { 311 case AUDIO_ENCODING_SLINEAR_LE: 312 break; 313 default: 314 return (EINVAL); 315 } 316 rec->bps = AUDIO_BPS(rec->precision); 317 rec->msb = 1; 318 319 error = ac97_set_rate(co->codec_if, AC97_REG_PCM_LR_ADC_RATE, 320 &rec->sample_rate); 321 if (error) 322 return (error); 323 } 324 325 return (0); 326 } 327 328 329 /* called to translate a requested blocksize to a hw-possible one */ 330 int 331 auixp_round_blocksize(void *v, int blk) 332 { 333 334 blk = (blk + 0x1f) & ~0x1f; 335 /* Be conservative; align to 32 bytes and maximise it to 64 kb */ 336 if (blk > 0x10000) 337 blk = 0x10000; 338 339 return blk; 340 } 341 342 343 /* 344 * allocate dma capable memory and record its information for later retrieval 345 * when we program the dma chain itself. The trigger routines passes on the 346 * kernel virtual address we return here as a reference to the mapping. 347 */ 348 void * 349 auixp_malloc(void *hdl, int direction, size_t size, int pool, int flags) 350 { 351 struct auixp_codec *co; 352 struct auixp_softc *sc; 353 struct auixp_dma *dma; 354 int error; 355 356 co = (struct auixp_codec *) hdl; 357 sc = co->sc; 358 /* get us a auixp_dma structure */ 359 dma = malloc(sizeof(*dma), pool, flags); 360 if (!dma) 361 return NULL; 362 363 /* get us a dma buffer itself */ 364 error = auixp_allocmem(sc, size, 16, dma); 365 if (error) { 366 free(dma, pool, sizeof(*dma)); 367 printf("%s: auixp_malloc: not enough memory\n", 368 sc->sc_dev.dv_xname); 369 return NULL; 370 } 371 SLIST_INSERT_HEAD(&sc->sc_dma_list, dma, dma_chain); 372 373 DPRINTF(("auixp_malloc: returning kern %p, hw 0x%08x for %zu bytes " 374 "in %d segs\n", KERNADDR(dma), (u_int32_t) DMAADDR(dma), dma->size, 375 dma->nsegs) 376 ); 377 378 return KERNADDR(dma); 379 } 380 381 /* 382 * free and release dma capable memory we allocated before and remove its 383 * recording 384 */ 385 void 386 auixp_free(void *hdl, void *addr, int pool) 387 { 388 struct auixp_codec *co; 389 struct auixp_softc *sc; 390 struct auixp_dma *dma; 391 392 co = (struct auixp_codec *) hdl; 393 sc = co->sc; 394 SLIST_FOREACH(dma, &sc->sc_dma_list, dma_chain) { 395 if (KERNADDR(dma) == addr) { 396 SLIST_REMOVE(&sc->sc_dma_list, dma, auixp_dma, 397 dma_chain); 398 auixp_freemem(sc, dma); 399 free(dma, pool, sizeof(*dma)); 400 return; 401 } 402 } 403 } 404 405 /* pass request to AC'97 codec code */ 406 int 407 auixp_set_port(void *hdl, mixer_ctrl_t *mc) 408 { 409 struct auixp_codec *co; 410 411 co = (struct auixp_codec *) hdl; 412 return co->codec_if->vtbl->mixer_set_port(co->codec_if, mc); 413 } 414 415 416 /* pass request to AC'97 codec code */ 417 int 418 auixp_get_port(void *hdl, mixer_ctrl_t *mc) 419 { 420 struct auixp_codec *co; 421 422 co = (struct auixp_codec *) hdl; 423 return co->codec_if->vtbl->mixer_get_port(co->codec_if, mc); 424 } 425 426 /* pass request to AC'97 codec code */ 427 int 428 auixp_query_devinfo(void *hdl, mixer_devinfo_t *di) 429 { 430 struct auixp_codec *co; 431 432 co = (struct auixp_codec *) hdl; 433 return co->codec_if->vtbl->query_devinfo(co->codec_if, di); 434 } 435 436 437 /* 438 * A dma descriptor has dma->nsegs segments defined in dma->segs set up when 439 * we claimed the memory. 440 * 441 * Due to our demand for one contiguous DMA area, we only have one segment. A 442 * c_dma structure is about 3 kb for the 256 entries we maximally program 443 * -arbitrary limit AFAIK- so all is most likely to be in one segment/page 444 * anyway. 445 * 446 * XXX ought to implement fragmented dma area XXX 447 * 448 * Note that _v variables depict kernel virtual addresses, _p variables depict 449 * physical addresses. 450 */ 451 void 452 auixp_link_daisychain(struct auixp_softc *sc, 453 struct auixp_dma *c_dma, struct auixp_dma *s_dma, 454 int blksize, int blocks) 455 { 456 atiixp_dma_desc_t *caddr_v, *next_caddr_v; 457 u_int32_t caddr_p, next_caddr_p, saddr_p; 458 int i; 459 460 /* just make sure we are not changing when its running */ 461 auixp_disable_dma(sc, c_dma); 462 463 /* setup dma chain start addresses */ 464 caddr_v = KERNADDR(c_dma); 465 caddr_p = DMAADDR(c_dma); 466 saddr_p = DMAADDR(s_dma); 467 468 /* program the requested number of blocks */ 469 for (i = 0; i < blocks; i++) { 470 /* clear the block just in case */ 471 bzero(caddr_v, sizeof(atiixp_dma_desc_t)); 472 473 /* round robin the chain dma addresses for its successor */ 474 next_caddr_v = caddr_v + 1; 475 next_caddr_p = caddr_p + sizeof(atiixp_dma_desc_t); 476 477 if (i == blocks-1) { 478 next_caddr_v = KERNADDR(c_dma); 479 next_caddr_p = DMAADDR(c_dma); 480 } 481 482 /* fill in the hardware dma chain descriptor in little-endian */ 483 caddr_v->addr = htole32(saddr_p); 484 caddr_v->status = htole16(0); 485 caddr_v->size = htole16((blksize >> 2)); /* in dwords (!!!) */ 486 caddr_v->next = htole32(next_caddr_p); 487 488 /* advance slot */ 489 saddr_p += blksize; /* XXX assuming contiguous XXX */ 490 caddr_v = next_caddr_v; 491 caddr_p = next_caddr_p; 492 } 493 } 494 495 496 int 497 auixp_allocate_dma_chain(struct auixp_softc *sc, struct auixp_dma **dmap) 498 { 499 struct auixp_dma *dma; 500 int error; 501 502 /* allocate keeper of dma area */ 503 *dmap = NULL; 504 dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT | M_ZERO); 505 if (!dma) 506 return ENOMEM; 507 508 /* allocate for daisychain of IXP hardware-dma descriptors */ 509 error = auixp_allocmem(sc, DMA_DESC_CHAIN * sizeof(atiixp_dma_desc_t), 510 16, dma); 511 if (error) { 512 printf("%s: can't malloc dma descriptor chain\n", 513 sc->sc_dev.dv_xname); 514 free(dma, M_DEVBUF, sizeof(*dma)); 515 return ENOMEM; 516 } 517 518 /* return info and initialise structure */ 519 dma->intr = NULL; 520 dma->intrarg = NULL; 521 522 *dmap = dma; 523 return 0; 524 } 525 526 527 /* program dma chain in its link address descriptor */ 528 void 529 auixp_program_dma_chain(struct auixp_softc *sc, struct auixp_dma *dma) 530 { 531 bus_space_tag_t iot; 532 bus_space_handle_t ioh; 533 u_int32_t value; 534 535 iot = sc->sc_iot; 536 ioh = sc->sc_ioh; 537 /* get hardware start address of DMA chain and set valid-flag in it */ 538 /* XXX always at start? XXX */ 539 value = DMAADDR(dma); 540 value = value | ATI_REG_LINKPTR_EN; 541 542 /* reset linkpointer */ 543 bus_space_write_4(iot, ioh, dma->linkptr, 0); 544 545 /* reset this DMA engine */ 546 auixp_disable_dma(sc, dma); 547 auixp_enable_dma(sc, dma); 548 549 /* program new DMA linkpointer */ 550 bus_space_write_4(iot, ioh, dma->linkptr, value); 551 } 552 553 554 /* called from interrupt code to signal end of one dma-slot */ 555 void 556 auixp_dma_update(struct auixp_softc *sc, struct auixp_dma *dma) 557 { 558 559 /* be very paranoid */ 560 if (!dma) 561 panic("auixp: update: dma = NULL"); 562 if (!dma->intr) 563 panic("auixp: update: dma->intr = NULL"); 564 565 /* request more input from upper layer */ 566 (*dma->intr)(dma->intrarg); 567 } 568 569 570 /* 571 * The magic `busbusy' bit that needs to be set when dma is active; allowing 572 * busmastering? 573 */ 574 void 575 auixp_update_busbusy(struct auixp_softc *sc) 576 { 577 bus_space_tag_t iot; 578 bus_space_handle_t ioh; 579 u_int32_t value; 580 int running; 581 582 iot = sc->sc_iot; 583 ioh = sc->sc_ioh; 584 /* set bus-busy flag when either recording or playing is performed */ 585 value = bus_space_read_4(iot, ioh, ATI_REG_IER); 586 value &= ~ATI_REG_IER_SET_BUS_BUSY; 587 588 running = ((sc->sc_output_dma->running) || (sc->sc_input_dma->running)); 589 if (running) 590 value |= ATI_REG_IER_SET_BUS_BUSY; 591 592 bus_space_write_4(iot, ioh, ATI_REG_IER, value); 593 594 } 595 596 597 /* 598 * Called from upper audio layer to request playing audio, only called once; 599 * audio is refilled by calling the intr() function when space is available 600 * again. 601 */ 602 /* XXX almost literally a copy of trigger-input; could be factorised XXX */ 603 int 604 auixp_trigger_output(void *hdl, void *start, void *end, int blksize, 605 void (*intr)(void *), void *intrarg, struct audio_params *param) 606 { 607 struct auixp_codec *co; 608 struct auixp_softc *sc; 609 struct auixp_dma *chain_dma; 610 struct auixp_dma *sound_dma; 611 u_int32_t blocks; 612 613 co = (struct auixp_codec *) hdl; 614 sc = co->sc; 615 chain_dma = sc->sc_output_dma; 616 /* add functions to call back */ 617 chain_dma->intr = intr; 618 chain_dma->intrarg = intrarg; 619 620 /* 621 * Program output DMA chain with blocks from [start...end] with 622 * blksize fragments. 623 * 624 * NOTE, we can assume its in one block since we asked for it to be in 625 * one contiguous blob; XXX change this? XXX 626 */ 627 blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize; 628 629 /* lookup `start' address in our list of DMA area's */ 630 SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) { 631 if (KERNADDR(sound_dma) == start) 632 break; 633 } 634 635 /* not ours ? then bail out */ 636 if (!sound_dma) { 637 printf("%s: auixp_trigger_output: bad sound addr %p\n", 638 sc->sc_dev.dv_xname, start); 639 return EINVAL; 640 } 641 642 /* link round-robin daisychain and program hardware */ 643 auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks); 644 auixp_program_dma_chain(sc, chain_dma); 645 646 /* mark we are now able to run now */ 647 mtx_enter(&audio_lock); 648 chain_dma->running = 1; 649 650 /* update bus-flags; XXX programs more flags XXX */ 651 auixp_update_busbusy(sc); 652 mtx_leave(&audio_lock); 653 654 /* callbacks happen in interrupt routine */ 655 return 0; 656 } 657 658 659 /* halt output of audio, just disable its dma and update bus state */ 660 int 661 auixp_halt_output(void *hdl) 662 { 663 struct auixp_codec *co; 664 struct auixp_softc *sc; 665 struct auixp_dma *dma; 666 667 mtx_enter(&audio_lock); 668 co = (struct auixp_codec *) hdl; 669 sc = co->sc; 670 dma = sc->sc_output_dma; 671 auixp_disable_dma(sc, dma); 672 673 dma->running = 0; 674 auixp_update_busbusy(sc); 675 mtx_leave(&audio_lock); 676 return 0; 677 } 678 679 680 /* XXX almost literally a copy of trigger-output; could be factorised XXX */ 681 int 682 auixp_trigger_input(void *hdl, void *start, void *end, int blksize, 683 void (*intr)(void *), void *intrarg, struct audio_params *param) 684 { 685 struct auixp_codec *co; 686 struct auixp_softc *sc; 687 struct auixp_dma *chain_dma; 688 struct auixp_dma *sound_dma; 689 u_int32_t blocks; 690 691 co = (struct auixp_codec *) hdl; 692 sc = co->sc; 693 chain_dma = sc->sc_input_dma; 694 /* add functions to call back */ 695 chain_dma->intr = intr; 696 chain_dma->intrarg = intrarg; 697 698 /* 699 * Program output DMA chain with blocks from [start...end] with 700 * blksize fragments. 701 * 702 * NOTE, we can assume its in one block since we asked for it to be in 703 * one contiguous blob; XXX change this? XXX 704 */ 705 blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize; 706 707 /* lookup `start' address in our list of DMA area's */ 708 SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) { 709 if (KERNADDR(sound_dma) == start) 710 break; 711 } 712 713 /* not ours ? then bail out */ 714 if (!sound_dma) { 715 printf("%s: auixp_trigger_input: bad sound addr %p\n", 716 sc->sc_dev.dv_xname, start); 717 return EINVAL; 718 } 719 720 /* link round-robin daisychain and program hardware */ 721 auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks); 722 auixp_program_dma_chain(sc, chain_dma); 723 724 /* mark we are now able to run now */ 725 mtx_enter(&audio_lock); 726 chain_dma->running = 1; 727 728 /* update bus-flags; XXX programs more flags XXX */ 729 auixp_update_busbusy(sc); 730 mtx_leave(&audio_lock); 731 732 /* callbacks happen in interrupt routine */ 733 return 0; 734 } 735 736 737 /* halt sampling audio, just disable its dma and update bus state */ 738 int 739 auixp_halt_input(void *hdl) 740 { 741 struct auixp_codec *co; 742 struct auixp_softc *sc; 743 struct auixp_dma *dma; 744 745 mtx_enter(&audio_lock); 746 co = (struct auixp_codec *) hdl; 747 sc = co->sc; 748 dma = sc->sc_input_dma; 749 auixp_disable_dma(sc, dma); 750 751 dma->running = 0; 752 auixp_update_busbusy(sc); 753 754 mtx_leave(&audio_lock); 755 return 0; 756 } 757 758 759 /* 760 * IXP audio interrupt handler 761 * 762 * note that we return the number of bits handled; the return value is not 763 * documented but I saw it implemented in other drivers. Probably returning a 764 * value > 0 means "I've dealt with it" 765 * 766 */ 767 int 768 auixp_intr(void *softc) 769 { 770 struct auixp_softc *sc; 771 bus_space_tag_t iot; 772 bus_space_handle_t ioh; 773 u_int32_t status, enable, detected_codecs; 774 int ret; 775 776 mtx_enter(&audio_lock); 777 sc = softc; 778 iot = sc->sc_iot; 779 ioh = sc->sc_ioh; 780 ret = 0; 781 /* get status from the interrupt status register */ 782 status = bus_space_read_4(iot, ioh, ATI_REG_ISR); 783 784 if (status == 0) { 785 mtx_leave(&audio_lock); 786 return 0; 787 } 788 789 DPRINTF(("%s: (status = %x)\n", sc->sc_dev.dv_xname, status)); 790 791 /* check DMA UPDATE flags for input & output */ 792 if (status & ATI_REG_ISR_IN_STATUS) { 793 ret++; DPRINTF(("IN_STATUS\n")); 794 auixp_dma_update(sc, sc->sc_input_dma); 795 } 796 if (status & ATI_REG_ISR_OUT_STATUS) { 797 ret++; DPRINTF(("OUT_STATUS\n")); 798 auixp_dma_update(sc, sc->sc_output_dma); 799 } 800 801 /* XXX XRUN flags not used/needed yet; should i implement it? XXX */ 802 /* acknowledge the interrupts nevertheless */ 803 if (status & ATI_REG_ISR_IN_XRUN) { 804 ret++; DPRINTF(("IN_XRUN\n")); 805 /* auixp_dma_xrun(sc, sc->sc_input_dma); */ 806 } 807 if (status & ATI_REG_ISR_OUT_XRUN) { 808 ret++; DPRINTF(("OUT_XRUN\n")); 809 /* auixp_dma_xrun(sc, sc->sc_output_dma); */ 810 } 811 812 /* check if we are looking for codec detection */ 813 if (status & CODEC_CHECK_BITS) { 814 ret++; 815 /* mark missing codecs as not ready */ 816 detected_codecs = status & CODEC_CHECK_BITS; 817 sc->sc_codec_not_ready_bits |= detected_codecs; 818 819 /* disable detected interrupt sources */ 820 enable = bus_space_read_4(iot, ioh, ATI_REG_IER); 821 enable &= ~detected_codecs; 822 bus_space_write_4(iot, ioh, ATI_REG_IER, enable); 823 } 824 825 /* acknowledge interrupt sources */ 826 bus_space_write_4(iot, ioh, ATI_REG_ISR, status); 827 mtx_leave(&audio_lock); 828 return ret; 829 } 830 831 832 /* allocate memory for dma purposes; on failure of any of the steps, roll back */ 833 int 834 auixp_allocmem(struct auixp_softc *sc, size_t size, 835 size_t align, struct auixp_dma *dma) 836 { 837 int error; 838 839 /* remember size */ 840 dma->size = size; 841 842 /* allocate DMA safe memory but in just one segment for now :( */ 843 error = bus_dmamem_alloc(sc->sc_dmat, dma->size, align, 0, 844 dma->segs, sizeof(dma->segs) / sizeof(dma->segs[0]), &dma->nsegs, 845 BUS_DMA_NOWAIT); 846 if (error) 847 return error; 848 849 /* 850 * map allocated memory into kernel virtual address space and keep it 851 * coherent with the CPU. 852 */ 853 error = bus_dmamem_map(sc->sc_dmat, dma->segs, dma->nsegs, dma->size, 854 &dma->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 855 if (error) 856 goto free; 857 858 /* allocate associated dma handle and initialize it. */ 859 error = bus_dmamap_create(sc->sc_dmat, dma->size, 1, dma->size, 0, 860 BUS_DMA_NOWAIT, &dma->map); 861 if (error) 862 goto unmap; 863 864 /* 865 * load the dma handle with mappings for a dma transfer; all pages 866 * need to be wired. 867 */ 868 error = bus_dmamap_load(sc->sc_dmat, dma->map, dma->addr, dma->size, NULL, 869 BUS_DMA_NOWAIT); 870 if (error) 871 goto destroy; 872 873 return 0; 874 875 destroy: 876 bus_dmamap_destroy(sc->sc_dmat, dma->map); 877 unmap: 878 bus_dmamem_unmap(sc->sc_dmat, dma->addr, dma->size); 879 free: 880 bus_dmamem_free(sc->sc_dmat, dma->segs, dma->nsegs); 881 882 return error; 883 } 884 885 886 /* undo dma mapping and release memory allocated */ 887 int 888 auixp_freemem(struct auixp_softc *sc, struct auixp_dma *p) 889 { 890 891 bus_dmamap_unload(sc->sc_dmat, p->map); 892 bus_dmamap_destroy(sc->sc_dmat, p->map); 893 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 894 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 895 896 return 0; 897 } 898 899 int 900 auixp_match(struct device *dev, void *match, void *aux) 901 { 902 return (pci_matchbyid((struct pci_attach_args *)aux, auixp_pci_devices, 903 sizeof(auixp_pci_devices)/sizeof(auixp_pci_devices[0]))); 904 } 905 906 int 907 auixp_activate(struct device *self, int act) 908 { 909 struct auixp_softc *sc = (struct auixp_softc *)self; 910 int rv = 0; 911 912 switch (act) { 913 case DVACT_SUSPEND: 914 rv = config_activate_children(self, act); 915 auixp_disable_interrupts(sc); 916 break; 917 case DVACT_RESUME: 918 auixp_init(sc); 919 ac97_resume(&sc->sc_codec.host_if, sc->sc_codec.codec_if); 920 rv = config_activate_children(self, act); 921 break; 922 default: 923 rv = config_activate_children(self, act); 924 break; 925 } 926 return (rv); 927 } 928 929 void 930 auixp_attach(struct device *parent, struct device *self, void *aux) 931 { 932 struct auixp_softc *sc; 933 struct pci_attach_args *pa; 934 pcitag_t tag; 935 pci_chipset_tag_t pc; 936 pci_intr_handle_t ih; 937 const char *intrstr; 938 939 sc = (struct auixp_softc *)self; 940 pa = (struct pci_attach_args *)aux; 941 tag = pa->pa_tag; 942 pc = pa->pa_pc; 943 944 /* map memory; its not sized -> what is the size? max PCI slot size? */ 945 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_MEM, 0, 946 &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios, 0)) { 947 printf(": can't map mem space\n"); 948 return; 949 } 950 951 /* Initialize softc */ 952 sc->sc_tag = tag; 953 sc->sc_pct = pc; 954 sc->sc_dmat = pa->pa_dmat; 955 SLIST_INIT(&sc->sc_dma_list); 956 957 /* get us the auixp_dma structures */ 958 auixp_allocate_dma_chain(sc, &sc->sc_output_dma); 959 auixp_allocate_dma_chain(sc, &sc->sc_input_dma); 960 961 /* when that fails we are dead in the water */ 962 if (!sc->sc_output_dma || !sc->sc_input_dma) 963 return; 964 965 #if 0 966 /* could preliminary program DMA chain */ 967 auixp_program_dma_chain(sc, sc->sc_output_dma); 968 auixp_program_dma_chain(sc, sc->sc_input_dma); 969 #endif 970 971 if (pci_intr_map(pa, &ih)) { 972 printf(": can't map interrupt\n"); 973 return; 974 } 975 intrstr = pci_intr_string(pc, ih); 976 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO | IPL_MPSAFE, 977 auixp_intr, sc, sc->sc_dev.dv_xname); 978 if (sc->sc_ih == NULL) { 979 printf(": can't establish interrupt"); 980 if (intrstr != NULL) 981 printf(" at %s", intrstr); 982 printf("\n"); 983 return; 984 } 985 printf(": %s\n", intrstr); 986 987 /* power up chip */ 988 pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D0); 989 990 /* init chip */ 991 if (auixp_init(sc) == -1) { 992 printf("%s: auixp_attach: unable to initialize the card\n", 993 sc->sc_dev.dv_xname); 994 return; 995 } 996 997 /* 998 * delay further configuration of codecs and audio after interrupts 999 * are enabled. 1000 */ 1001 config_mountroot(self, auixp_post_config); 1002 } 1003 1004 /* called from autoconfigure system when interrupts are enabled */ 1005 void 1006 auixp_post_config(struct device *self) 1007 { 1008 struct auixp_softc *sc = (struct auixp_softc *)self; 1009 1010 /* detect the AC97 codecs */ 1011 auixp_autodetect_codecs(sc); 1012 1013 /* Bail if no codecs attached. */ 1014 if (!sc->sc_codec.present) { 1015 printf("%s: no codecs detected or initialised\n", 1016 sc->sc_dev.dv_xname); 1017 return; 1018 } 1019 1020 audio_attach_mi(&auixp_hw_if, &sc->sc_codec, NULL, &sc->sc_dev); 1021 1022 if (sc->has_spdif) 1023 sc->has_spdif = 0; 1024 1025 /* fill in the missing details about the dma channels. */ 1026 /* for output */ 1027 sc->sc_output_dma->linkptr = ATI_REG_OUT_DMA_LINKPTR; 1028 sc->sc_output_dma->dma_enable_bit = ATI_REG_CMD_OUT_DMA_EN | 1029 ATI_REG_CMD_SEND_EN; 1030 /* have spdif? then this too! XXX not seeing LED yet! XXX */ 1031 if (sc->has_spdif) 1032 sc->sc_output_dma->dma_enable_bit |= ATI_REG_CMD_SPDF_OUT_EN; 1033 1034 /* and for input */ 1035 sc->sc_input_dma->linkptr = ATI_REG_IN_DMA_LINKPTR; 1036 sc->sc_input_dma->dma_enable_bit = ATI_REG_CMD_IN_DMA_EN | 1037 ATI_REG_CMD_RECEIVE_EN; 1038 1039 /* done! now enable all interrupts we can service */ 1040 auixp_enable_interrupts(sc); 1041 } 1042 1043 void 1044 auixp_enable_interrupts(struct auixp_softc *sc) 1045 { 1046 bus_space_tag_t iot; 1047 bus_space_handle_t ioh; 1048 u_int32_t value; 1049 1050 iot = sc->sc_iot; 1051 ioh = sc->sc_ioh; 1052 /* clear all pending */ 1053 bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff); 1054 1055 /* enable all relevant interrupt sources we can handle */ 1056 value = bus_space_read_4(iot, ioh, ATI_REG_IER); 1057 1058 value |= ATI_REG_IER_IO_STATUS_EN; 1059 1060 bus_space_write_4(iot, ioh, ATI_REG_IER, value); 1061 } 1062 1063 void 1064 auixp_disable_interrupts(struct auixp_softc *sc) 1065 { 1066 bus_space_tag_t iot; 1067 bus_space_handle_t ioh; 1068 1069 iot = sc->sc_iot; 1070 ioh = sc->sc_ioh; 1071 /* disable all interrupt sources */ 1072 bus_space_write_4(iot, ioh, ATI_REG_IER, 0); 1073 1074 /* clear all pending */ 1075 bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff); 1076 } 1077 1078 /* dismantle what we've set up by undoing setup */ 1079 int 1080 auixp_detach(struct device *self, int flags) 1081 { 1082 struct auixp_softc *sc; 1083 1084 sc = (struct auixp_softc *)self; 1085 /* XXX shouldn't we just reset the chip? XXX */ 1086 /* 1087 * should we explicitly disable interrupt generation and acknowledge 1088 * what's left on? better be safe than sorry. 1089 */ 1090 auixp_disable_interrupts(sc); 1091 1092 /* tear down .... */ 1093 config_detach(&sc->sc_dev, flags); /* XXX OK? XXX */ 1094 1095 if (sc->sc_ih != NULL) 1096 pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 1097 if (sc->sc_ios) 1098 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 1099 return 0; 1100 } 1101 1102 1103 /* 1104 * codec handling 1105 * 1106 * IXP audio support can have upto 3 codecs! are they chained ? or 1107 * alternative outlets with the same audio feed i.e. with different mixer 1108 * settings? XXX does NetBSD support more than one audio codec? XXX 1109 */ 1110 1111 1112 int 1113 auixp_attach_codec(void *aux, struct ac97_codec_if *codec_if) 1114 { 1115 struct auixp_codec *ixp_codec; 1116 1117 ixp_codec = aux; 1118 ixp_codec->codec_if = codec_if; 1119 1120 return 0; 1121 } 1122 1123 int 1124 auixp_read_codec(void *aux, u_int8_t reg, u_int16_t *result) 1125 { 1126 struct auixp_codec *co; 1127 struct auixp_softc *sc; 1128 bus_space_tag_t iot; 1129 bus_space_handle_t ioh; 1130 u_int32_t data; 1131 int timeout; 1132 1133 co = aux; 1134 sc = co->sc; 1135 iot = sc->sc_iot; 1136 ioh = sc->sc_ioh; 1137 if (auixp_wait_for_codecs(sc, "read_codec")) 1138 return 0xffff; 1139 1140 /* build up command for reading codec register */ 1141 data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) | 1142 ATI_REG_PHYS_OUT_ADDR_EN | 1143 ATI_REG_PHYS_OUT_RW | 1144 co->codec_nr; 1145 1146 bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, data); 1147 1148 if (auixp_wait_for_codecs(sc, "read_codec")) 1149 return 0xffff; 1150 1151 /* wait until codec info is clocked in */ 1152 timeout = 500; /* 500*2 usec -> 0.001 sec */ 1153 do { 1154 data = bus_space_read_4(iot, ioh, ATI_REG_PHYS_IN_ADDR); 1155 if (data & ATI_REG_PHYS_IN_READ_FLAG) { 1156 DPRINTF(("read ac'97 codec reg 0x%x = 0x%08x\n", 1157 reg, data >> ATI_REG_PHYS_IN_DATA_SHIFT)); 1158 *result = data >> ATI_REG_PHYS_IN_DATA_SHIFT; 1159 return 0; 1160 } 1161 DELAY(2); 1162 timeout--; 1163 } while (timeout > 0); 1164 1165 if (reg < 0x7c) 1166 printf("%s: codec read timeout! (reg %x)\n", 1167 sc->sc_dev.dv_xname, reg); 1168 1169 return 0xffff; 1170 } 1171 1172 int 1173 auixp_write_codec(void *aux, u_int8_t reg, u_int16_t data) 1174 { 1175 struct auixp_codec *co; 1176 struct auixp_softc *sc; 1177 bus_space_tag_t iot; 1178 bus_space_handle_t ioh; 1179 u_int32_t value; 1180 1181 DPRINTF(("write ac'97 codec reg 0x%x = 0x%08x\n", reg, data)); 1182 co = aux; 1183 sc = co->sc; 1184 iot = sc->sc_iot; 1185 ioh = sc->sc_ioh; 1186 if (auixp_wait_for_codecs(sc, "write_codec")) 1187 return -1; 1188 1189 /* build up command for writing codec register */ 1190 value = (((u_int32_t) data) << ATI_REG_PHYS_OUT_DATA_SHIFT) | 1191 (((u_int32_t) reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) | 1192 ATI_REG_PHYS_OUT_ADDR_EN | 1193 co->codec_nr; 1194 1195 bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, value); 1196 1197 return 0; 1198 } 1199 1200 void 1201 auixp_reset_codec(void *aux) 1202 { 1203 1204 /* nothing to be done? */ 1205 } 1206 1207 enum ac97_host_flags 1208 auixp_flags_codec(void *aux) 1209 { 1210 struct auixp_codec *ixp_codec; 1211 1212 ixp_codec = aux; 1213 return ixp_codec->codec_flags; 1214 } 1215 1216 int 1217 auixp_wait_for_codecs(struct auixp_softc *sc, const char *func) 1218 { 1219 bus_space_tag_t iot; 1220 bus_space_handle_t ioh; 1221 u_int32_t value; 1222 int timeout; 1223 1224 iot = sc->sc_iot; 1225 ioh = sc->sc_ioh; 1226 /* wait until all codec transfers are done */ 1227 timeout = 500; /* 500*2 usec -> 0.001 sec */ 1228 do { 1229 value = bus_space_read_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR); 1230 if ((value & ATI_REG_PHYS_OUT_ADDR_EN) == 0) 1231 return 0; 1232 1233 DELAY(2); 1234 timeout--; 1235 } while (timeout > 0); 1236 1237 printf("%s: %s: timed out\n", func, sc->sc_dev.dv_xname); 1238 return -1; 1239 } 1240 1241 void 1242 auixp_autodetect_codecs(struct auixp_softc *sc) 1243 { 1244 bus_space_tag_t iot; 1245 bus_space_handle_t ioh; 1246 pcireg_t subdev; 1247 struct auixp_codec *codec; 1248 int timeout; 1249 1250 iot = sc->sc_iot; 1251 ioh = sc->sc_ioh; 1252 subdev = pci_conf_read(sc->sc_pct, sc->sc_tag, PCI_SUBSYS_ID_REG); 1253 1254 /* ATI IXP can have upto 3 codecs; mark all codecs as not existing */ 1255 sc->sc_codec_not_ready_bits = 0; 1256 1257 /* enable all codecs to interrupt as well as the new frame interrupt */ 1258 bus_space_write_4(iot, ioh, ATI_REG_IER, CODEC_CHECK_BITS); 1259 1260 /* wait for the interrupts to happen */ 1261 timeout = 100; /* 100.000 usec -> 0.1 sec */ 1262 1263 while (timeout > 0) { 1264 DELAY(1000); 1265 if (sc->sc_codec_not_ready_bits) 1266 break; 1267 timeout--; 1268 } 1269 1270 if (timeout == 0) 1271 printf("%s: WARNING: timeout during codec detection; " 1272 "codecs might be present but haven't interrupted\n", 1273 sc->sc_dev.dv_xname); 1274 1275 /* disable all interrupts for now */ 1276 auixp_disable_interrupts(sc); 1277 1278 /* Attach AC97 host interfaces */ 1279 codec = &sc->sc_codec; 1280 bzero(codec, sizeof(struct auixp_codec)); 1281 1282 codec->sc = sc; 1283 1284 codec->host_if.arg = codec; 1285 codec->host_if.attach = auixp_attach_codec; 1286 codec->host_if.read = auixp_read_codec; 1287 codec->host_if.write = auixp_write_codec; 1288 codec->host_if.reset = auixp_reset_codec; 1289 codec->host_if.flags = auixp_flags_codec; 1290 switch (subdev) { 1291 case 0x1311462: /* MSI S270 */ 1292 case 0x1611462: /* LG K1 Express */ 1293 case 0x3511462: /* MSI L725 */ 1294 case 0x4711462: /* MSI L720 */ 1295 case 0x0611462: /* MSI S250 */ 1296 codec->codec_flags = AC97_HOST_ALC650_PIN47_IS_EAPD; 1297 break; 1298 } 1299 1300 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC0_NOT_READY)) { 1301 /* codec 0 present */ 1302 DPRINTF(("auixp : YAY! codec 0 present!\n")); 1303 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1304 sc->sc_codec.codec_nr = 0; 1305 sc->sc_codec.present = 1; 1306 return; 1307 } 1308 } 1309 1310 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC1_NOT_READY)) { 1311 /* codec 1 present */ 1312 DPRINTF(("auixp : YAY! codec 1 present!\n")); 1313 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1314 sc->sc_codec.codec_nr = 1; 1315 sc->sc_codec.present = 1; 1316 return; 1317 } 1318 } 1319 1320 if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC2_NOT_READY)) { 1321 /* codec 2 present */ 1322 DPRINTF(("auixp : YAY! codec 2 present!\n")); 1323 if (ac97_attach(&sc->sc_codec.host_if) == 0) { 1324 sc->sc_codec.codec_nr = 2; 1325 sc->sc_codec.present = 1; 1326 return; 1327 } 1328 } 1329 } 1330 1331 void 1332 auixp_disable_dma(struct auixp_softc *sc, struct auixp_dma *dma) 1333 { 1334 bus_space_tag_t iot; 1335 bus_space_handle_t ioh; 1336 u_int32_t value; 1337 1338 iot = sc->sc_iot; 1339 ioh = sc->sc_ioh; 1340 /* lets not stress the DMA engine more than necessary */ 1341 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1342 if (value & dma->dma_enable_bit) { 1343 value &= ~dma->dma_enable_bit; 1344 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1345 } 1346 } 1347 1348 void 1349 auixp_enable_dma(struct auixp_softc *sc, struct auixp_dma *dma) 1350 { 1351 bus_space_tag_t iot; 1352 bus_space_handle_t ioh; 1353 u_int32_t value; 1354 1355 iot = sc->sc_iot; 1356 ioh = sc->sc_ioh; 1357 /* lets not stress the DMA engine more than necessary */ 1358 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1359 if (!(value & dma->dma_enable_bit)) { 1360 value |= dma->dma_enable_bit; 1361 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1362 } 1363 } 1364 1365 void 1366 auixp_reset_aclink(struct auixp_softc *sc) 1367 { 1368 bus_space_tag_t iot; 1369 bus_space_handle_t ioh; 1370 u_int32_t value, timeout; 1371 1372 iot = sc->sc_iot; 1373 ioh = sc->sc_ioh; 1374 1375 /* if power is down, power it up */ 1376 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1377 if (value & ATI_REG_CMD_POWERDOWN) { 1378 printf("%s: powering up\n", sc->sc_dev.dv_xname); 1379 1380 /* explicitly enable power */ 1381 value &= ~ATI_REG_CMD_POWERDOWN; 1382 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1383 1384 /* have to wait at least 10 usec for it to initialise */ 1385 DELAY(20); 1386 } 1387 1388 printf("%s: soft resetting aclink\n", sc->sc_dev.dv_xname); 1389 1390 /* perform a soft reset */ 1391 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1392 value |= ATI_REG_CMD_AC_SOFT_RESET; 1393 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1394 1395 /* need to read the CMD reg and wait aprox. 10 usec to init */ 1396 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1397 DELAY(20); 1398 1399 /* clear soft reset flag again */ 1400 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1401 value &= ~ATI_REG_CMD_AC_SOFT_RESET; 1402 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1403 1404 /* check if the ac-link is working; reset device otherwise */ 1405 timeout = 10; 1406 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1407 while (!(value & ATI_REG_CMD_ACLINK_ACTIVE)) { 1408 printf("%s: not up; resetting aclink hardware\n", 1409 sc->sc_dev.dv_xname); 1410 1411 /* dip aclink reset but keep the acsync */ 1412 value &= ~ATI_REG_CMD_AC_RESET; 1413 value |= ATI_REG_CMD_AC_SYNC; 1414 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1415 1416 /* need to read CMD again and wait again (clocking in issue?) */ 1417 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1418 DELAY(20); 1419 1420 /* assert aclink reset again */ 1421 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1422 value |= ATI_REG_CMD_AC_RESET; 1423 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1424 1425 /* check if its active now */ 1426 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1427 1428 timeout--; 1429 if (timeout == 0) break; 1430 } 1431 1432 if (timeout == 0) { 1433 printf("%s: giving up aclink reset\n", sc->sc_dev.dv_xname); 1434 } 1435 if (timeout != 10) { 1436 printf("%s: aclink hardware reset successful\n", 1437 sc->sc_dev.dv_xname); 1438 } 1439 1440 /* assert reset and sync for safety */ 1441 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1442 value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET; 1443 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1444 } 1445 1446 /* chip hard init */ 1447 int 1448 auixp_init(struct auixp_softc *sc) 1449 { 1450 bus_space_tag_t iot; 1451 bus_space_handle_t ioh; 1452 u_int32_t value; 1453 1454 iot = sc->sc_iot; 1455 ioh = sc->sc_ioh; 1456 /* disable all interrupts and clear all sources */ 1457 auixp_disable_interrupts(sc); 1458 1459 /* clear all DMA enables (preserving rest of settings) */ 1460 value = bus_space_read_4(iot, ioh, ATI_REG_CMD); 1461 value &= ~( ATI_REG_CMD_IN_DMA_EN | 1462 ATI_REG_CMD_OUT_DMA_EN | 1463 ATI_REG_CMD_SPDF_OUT_EN ); 1464 bus_space_write_4(iot, ioh, ATI_REG_CMD, value); 1465 1466 /* Reset AC-link */ 1467 auixp_reset_aclink(sc); 1468 1469 /* 1470 * codecs get auto-detected later 1471 * 1472 * note: we are NOT enabling interrupts yet, no codecs have been 1473 * detected yet nor is anything else set up 1474 */ 1475 1476 return 0; 1477 } 1478