atiixp.c (5d75db4f00df60db6f30ae40772b52be2aebb1f8) | atiixp.c (8a7c4d36cbc18f5e379be650b345f04f6d0d083d) |
---|---|
1/*- 2 * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 60 unchanged lines hidden (view full) --- 69 70#define ATI_IXP_BUFSZ_MIN 4096 71#define ATI_IXP_BUFSZ_MAX 65536 72#define ATI_IXP_BUFSZ_DEFAULT 16384 73 74#define ATI_IXP_BLK_MIN 32 75#define ATI_IXP_BLK_ALIGN (~(ATI_IXP_BLK_MIN - 1)) 76 | 1/*- 2 * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 60 unchanged lines hidden (view full) --- 69 70#define ATI_IXP_BUFSZ_MIN 4096 71#define ATI_IXP_BUFSZ_MAX 65536 72#define ATI_IXP_BUFSZ_DEFAULT 16384 73 74#define ATI_IXP_BLK_MIN 32 75#define ATI_IXP_BLK_ALIGN (~(ATI_IXP_BLK_MIN - 1)) 76 |
77#define ATI_IXP_CHN_RUNNING 0x00000001 78#define ATI_IXP_CHN_SUSPEND 0x00000002 79 |
|
77struct atiixp_dma_op { 78 volatile uint32_t addr; 79 volatile uint16_t status; 80 volatile uint16_t size; 81 volatile uint32_t next; 82}; 83 84struct atiixp_info; 85 86struct atiixp_chinfo { 87 struct snd_dbuf *buffer; 88 struct pcm_channel *channel; 89 struct atiixp_info *parent; 90 struct atiixp_dma_op *sgd_table; 91 bus_addr_t sgd_addr; 92 uint32_t enable_bit, flush_bit, linkptr_bit, dt_cur_bit; 93 uint32_t blksz, blkcnt; 94 uint32_t ptr, prevptr; 95 uint32_t fmt; | 80struct atiixp_dma_op { 81 volatile uint32_t addr; 82 volatile uint16_t status; 83 volatile uint16_t size; 84 volatile uint32_t next; 85}; 86 87struct atiixp_info; 88 89struct atiixp_chinfo { 90 struct snd_dbuf *buffer; 91 struct pcm_channel *channel; 92 struct atiixp_info *parent; 93 struct atiixp_dma_op *sgd_table; 94 bus_addr_t sgd_addr; 95 uint32_t enable_bit, flush_bit, linkptr_bit, dt_cur_bit; 96 uint32_t blksz, blkcnt; 97 uint32_t ptr, prevptr; 98 uint32_t fmt; |
96 int caps_32bit, dir, active; | 99 uint32_t flags; 100 int caps_32bit, dir; |
97}; 98 99struct atiixp_info { 100 device_t dev; 101 102 bus_space_tag_t st; 103 bus_space_handle_t sh; 104 bus_dma_tag_t parent_dmat; --- 544 unchanged lines hidden (view full) --- 649} 650 651static __inline int 652atiixp_poll_channel(struct atiixp_chinfo *ch) 653{ 654 uint32_t sz, delta; 655 volatile uint32_t ptr; 656 | 101}; 102 103struct atiixp_info { 104 device_t dev; 105 106 bus_space_tag_t st; 107 bus_space_handle_t sh; 108 bus_dma_tag_t parent_dmat; --- 544 unchanged lines hidden (view full) --- 653} 654 655static __inline int 656atiixp_poll_channel(struct atiixp_chinfo *ch) 657{ 658 uint32_t sz, delta; 659 volatile uint32_t ptr; 660 |
657 if (ch->active == 0) | 661 if (!(ch->flags & ATI_IXP_CHN_RUNNING)) |
658 return (0); 659 660 sz = ch->blksz * ch->blkcnt; 661 ptr = atiixp_dmapos(ch); 662 ch->ptr = ptr; 663 ptr %= sz; 664 ptr &= ~(ch->blksz - 1); 665 delta = (sz + ptr - ch->prevptr) % sz; 666 667 if (delta < ch->blksz) 668 return (0); 669 670 ch->prevptr = ptr; 671 672 return (1); 673} 674 | 662 return (0); 663 664 sz = ch->blksz * ch->blkcnt; 665 ptr = atiixp_dmapos(ch); 666 ch->ptr = ptr; 667 ptr %= sz; 668 ptr &= ~(ch->blksz - 1); 669 delta = (sz + ptr - ch->prevptr) % sz; 670 671 if (delta < ch->blksz) 672 return (0); 673 674 ch->prevptr = ptr; 675 676 return (1); 677} 678 |
675#define atiixp_chan_active(sc) ((sc)->pch.active + (sc)->rch.active) | 679#define atiixp_chan_active(sc) (((sc)->pch.flags | (sc)->rch.flags) & \ 680 ATI_IXP_CHN_RUNNING) |
676 677static void 678atiixp_poll_callback(void *arg) 679{ 680 struct atiixp_info *sc = arg; 681 uint32_t trigger = 0; 682 683 if (sc == NULL) --- 65 unchanged lines hidden (view full) --- 749 __func__, sc->poll_ticks, 750 pollticks); 751 } 752 sc->poll_ticks = pollticks; 753 callout_reset(&sc->poll_timer, 1, 754 atiixp_poll_callback, sc); 755 } 756 } | 681 682static void 683atiixp_poll_callback(void *arg) 684{ 685 struct atiixp_info *sc = arg; 686 uint32_t trigger = 0; 687 688 if (sc == NULL) --- 65 unchanged lines hidden (view full) --- 754 __func__, sc->poll_ticks, 755 pollticks); 756 } 757 sc->poll_ticks = pollticks; 758 callout_reset(&sc->poll_timer, 1, 759 atiixp_poll_callback, sc); 760 } 761 } |
757 ch->active = 1; | 762 ch->flags |= ATI_IXP_CHN_RUNNING; |
758 break; 759 case PCMTRIG_STOP: 760 case PCMTRIG_ABORT: 761 atiixp_disable_dma(ch); 762 atiixp_flush_dma(ch); | 763 break; 764 case PCMTRIG_STOP: 765 case PCMTRIG_ABORT: 766 atiixp_disable_dma(ch); 767 atiixp_flush_dma(ch); |
763 ch->active = 0; | 768 ch->flags &= ~ATI_IXP_CHN_RUNNING; |
764 if (sc->polling != 0) { 765 if (atiixp_chan_active(sc) == 0) { 766 callout_stop(&sc->poll_timer); 767 sc->poll_ticks = 1; 768 } else { | 769 if (sc->polling != 0) { 770 if (atiixp_chan_active(sc) == 0) { 771 callout_stop(&sc->poll_timer); 772 sc->poll_ticks = 1; 773 } else { |
769 if (sc->pch.active != 0) | 774 if (sc->pch.flags & ATI_IXP_CHN_RUNNING) |
770 ch = &sc->pch; 771 else 772 ch = &sc->rch; 773 pollticks = ((uint64_t)hz * ch->blksz) / 774 ((uint64_t)sndbuf_getbps(ch->buffer) * 775 sndbuf_getspd(ch->buffer)); 776 pollticks >>= 2; 777 if (pollticks > hz) --- 91 unchanged lines hidden (view full) --- 869 } 870 status = atiixp_rd(sc, ATI_REG_ISR); 871 872 if (status == 0) { 873 atiixp_unlock(sc); 874 return; 875 } 876 | 775 ch = &sc->pch; 776 else 777 ch = &sc->rch; 778 pollticks = ((uint64_t)hz * ch->blksz) / 779 ((uint64_t)sndbuf_getbps(ch->buffer) * 780 sndbuf_getspd(ch->buffer)); 781 pollticks >>= 2; 782 if (pollticks > hz) --- 91 unchanged lines hidden (view full) --- 874 } 875 status = atiixp_rd(sc, ATI_REG_ISR); 876 877 if (status == 0) { 878 atiixp_unlock(sc); 879 return; 880 } 881 |
877 if ((status & ATI_REG_ISR_OUT_STATUS) && sc->pch.active != 0) | 882 if ((status & ATI_REG_ISR_OUT_STATUS) && 883 (sc->pch.flags & ATI_IXP_CHN_RUNNING)) |
878 trigger |= 1; | 884 trigger |= 1; |
879 if ((status & ATI_REG_ISR_IN_STATUS) && sc->rch.active != 0) | 885 if ((status & ATI_REG_ISR_IN_STATUS) && 886 (sc->rch.flags & ATI_IXP_CHN_RUNNING)) |
880 trigger |= 2; 881 882#if 0 883 if (status & ATI_REG_ISR_IN_XRUN) { 884 device_printf(sc->dev, 885 "Recieve IN XRUN interrupt\n"); 886 } 887 if (status & ATI_REG_ISR_OUT_XRUN) { --- 439 unchanged lines hidden (view full) --- 1327 uint32_t value; 1328 1329 /* quickly disable interrupts and save channels active state */ 1330 atiixp_lock(sc); 1331 atiixp_disable_interrupts(sc); 1332 atiixp_unlock(sc); 1333 1334 /* stop everything */ | 887 trigger |= 2; 888 889#if 0 890 if (status & ATI_REG_ISR_IN_XRUN) { 891 device_printf(sc->dev, 892 "Recieve IN XRUN interrupt\n"); 893 } 894 if (status & ATI_REG_ISR_OUT_XRUN) { --- 439 unchanged lines hidden (view full) --- 1334 uint32_t value; 1335 1336 /* quickly disable interrupts and save channels active state */ 1337 atiixp_lock(sc); 1338 atiixp_disable_interrupts(sc); 1339 atiixp_unlock(sc); 1340 1341 /* stop everything */ |
1335 if (sc->pch.active != 0) | 1342 if (sc->pch.flags & ATI_IXP_CHN_RUNNING) { |
1336 atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_STOP); | 1343 atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_STOP); |
1337 if (sc->rch.active != 0) | 1344 sc->pch.flags |= ATI_IXP_CHN_SUSPEND; 1345 } 1346 if (sc->rch.flags & ATI_IXP_CHN_RUNNING) { |
1338 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_STOP); | 1347 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_STOP); |
1348 sc->rch.flags |= ATI_IXP_CHN_SUSPEND; 1349 } |
|
1339 1340 /* power down aclink and pci bus */ 1341 atiixp_lock(sc); 1342 value = atiixp_rd(sc, ATI_REG_CMD); 1343 value |= ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET; 1344 atiixp_wr(sc, ATI_REG_CMD, ATI_REG_CMD_POWERDOWN); 1345 pci_set_powerstate(dev, PCI_POWERSTATE_D3); 1346 atiixp_unlock(sc); --- 22 unchanged lines hidden (view full) --- 1369 1370 /* 1371 * Resume channel activities. Reset channel format regardless 1372 * of its previous state. 1373 */ 1374 if (sc->pch.channel != NULL) { 1375 if (sc->pch.fmt != 0) 1376 atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt); | 1350 1351 /* power down aclink and pci bus */ 1352 atiixp_lock(sc); 1353 value = atiixp_rd(sc, ATI_REG_CMD); 1354 value |= ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET; 1355 atiixp_wr(sc, ATI_REG_CMD, ATI_REG_CMD_POWERDOWN); 1356 pci_set_powerstate(dev, PCI_POWERSTATE_D3); 1357 atiixp_unlock(sc); --- 22 unchanged lines hidden (view full) --- 1380 1381 /* 1382 * Resume channel activities. Reset channel format regardless 1383 * of its previous state. 1384 */ 1385 if (sc->pch.channel != NULL) { 1386 if (sc->pch.fmt != 0) 1387 atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt); |
1377 if (sc->pch.active != 0) | 1388 if (sc->pch.flags & ATI_IXP_CHN_SUSPEND) { 1389 sc->pch.flags &= ~ATI_IXP_CHN_SUSPEND; |
1378 atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_START); | 1390 atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_START); |
1391 } |
|
1379 } 1380 if (sc->rch.channel != NULL) { 1381 if (sc->rch.fmt != 0) 1382 atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt); | 1392 } 1393 if (sc->rch.channel != NULL) { 1394 if (sc->rch.fmt != 0) 1395 atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt); |
1383 if (sc->rch.active != 0) | 1396 if (sc->rch.flags & ATI_IXP_CHN_SUSPEND) { 1397 sc->rch.flags &= ~ATI_IXP_CHN_SUSPEND; |
1384 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START); | 1398 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START); |
1399 } |
|
1385 } 1386 1387 /* enable interrupts */ 1388 atiixp_lock(sc); 1389 if (sc->polling == 0) 1390 atiixp_enable_interrupts(sc); 1391 atiixp_unlock(sc); 1392 --- 21 unchanged lines hidden --- | 1400 } 1401 1402 /* enable interrupts */ 1403 atiixp_lock(sc); 1404 if (sc->polling == 0) 1405 atiixp_enable_interrupts(sc); 1406 atiixp_unlock(sc); 1407 --- 21 unchanged lines hidden --- |