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