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 ---