Implement a "sndbuf_getbufaddr" function and use it instead of vtophys().
Reviewed by: orion
This commit is contained in:
parent
93664efadd
commit
38cc994207
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=111183
@ -334,7 +334,7 @@ als_playback_start(struct sc_chinfo *ch)
|
|||||||
struct sc_info *sc = ch->parent;
|
struct sc_info *sc = ch->parent;
|
||||||
u_int32_t buf, bufsz, count, dma_prog;
|
u_int32_t buf, bufsz, count, dma_prog;
|
||||||
|
|
||||||
buf = vtophys(sndbuf_getbuf(ch->buffer));
|
buf = sndbuf_getbufaddr(ch->buffer);
|
||||||
bufsz = sndbuf_getsize(ch->buffer);
|
bufsz = sndbuf_getsize(ch->buffer);
|
||||||
count = bufsz / 2;
|
count = bufsz / 2;
|
||||||
if (ch->format & AFMT_16BIT)
|
if (ch->format & AFMT_16BIT)
|
||||||
@ -428,7 +428,7 @@ als_capture_start(struct sc_chinfo *ch)
|
|||||||
struct sc_info *sc = ch->parent;
|
struct sc_info *sc = ch->parent;
|
||||||
u_int32_t buf, bufsz, count, dma_prog;
|
u_int32_t buf, bufsz, count, dma_prog;
|
||||||
|
|
||||||
buf = vtophys(sndbuf_getbuf(ch->buffer));
|
buf = sndbuf_getbufaddr(ch->buffer);
|
||||||
bufsz = sndbuf_getsize(ch->buffer);
|
bufsz = sndbuf_getsize(ch->buffer);
|
||||||
count = bufsz / 2;
|
count = bufsz / 2;
|
||||||
if (ch->format & AFMT_16BIT)
|
if (ch->format & AFMT_16BIT)
|
||||||
|
@ -243,7 +243,7 @@ au_prepareoutput(struct au_chinfo *ch, u_int32_t format)
|
|||||||
{
|
{
|
||||||
struct au_info *au = ch->parent;
|
struct au_info *au = ch->parent;
|
||||||
int i, stereo = (format & AFMT_STEREO)? 1 : 0;
|
int i, stereo = (format & AFMT_STEREO)? 1 : 0;
|
||||||
u_int32_t baseaddr = vtophys(sndbuf_getbuf(ch->buffer));
|
u_int32_t baseaddr = sndbuf_getbufaddr(ch->buffer);
|
||||||
|
|
||||||
au_wr(au, 0, 0x1061c, 0, 4);
|
au_wr(au, 0, 0x1061c, 0, 4);
|
||||||
au_wr(au, 0, 0x10620, 0, 4);
|
au_wr(au, 0, 0x10620, 0, 4);
|
||||||
|
@ -239,7 +239,7 @@ cmi_dma_prog(struct sc_info *sc, struct sc_chinfo *ch, u_int32_t base)
|
|||||||
{
|
{
|
||||||
u_int32_t s, i, sz;
|
u_int32_t s, i, sz;
|
||||||
|
|
||||||
ch->phys_buf = vtophys(sndbuf_getbuf(ch->buffer));
|
ch->phys_buf = sndbuf_getbufaddr(ch->buffer);
|
||||||
|
|
||||||
cmi_wr(sc, base, ch->phys_buf, 4);
|
cmi_wr(sc, base, ch->phys_buf, 4);
|
||||||
sz = (u_int32_t)sndbuf_getsize(ch->buffer);
|
sz = (u_int32_t)sndbuf_getsize(ch->buffer);
|
||||||
|
@ -487,7 +487,7 @@ adcdac_prog(struct sc_chinfo *ch)
|
|||||||
if (!ch->dma_setup) {
|
if (!ch->dma_setup) {
|
||||||
go = adcdac_go(ch, 0);
|
go = adcdac_go(ch, 0);
|
||||||
cs4281_wr(sc, CS4281PCI_DBA(ch->dma_chan),
|
cs4281_wr(sc, CS4281PCI_DBA(ch->dma_chan),
|
||||||
vtophys(sndbuf_getbuf(ch->buffer)));
|
sndbuf_getbufaddr(ch->buffer));
|
||||||
cs4281_wr(sc, CS4281PCI_DBC(ch->dma_chan),
|
cs4281_wr(sc, CS4281PCI_DBC(ch->dma_chan),
|
||||||
sndbuf_getsize(ch->buffer) / ch->bps - 1);
|
sndbuf_getsize(ch->buffer) / ch->bps - 1);
|
||||||
ch->dma_setup = 1;
|
ch->dma_setup = 1;
|
||||||
|
@ -463,7 +463,7 @@ csa_setupchan(struct csa_chinfo *ch)
|
|||||||
|
|
||||||
if (ch->dir == PCMDIR_PLAY) {
|
if (ch->dir == PCMDIR_PLAY) {
|
||||||
/* direction */
|
/* direction */
|
||||||
csa_writemem(resp, BA1_PBA, vtophys(sndbuf_getbuf(ch->buffer)));
|
csa_writemem(resp, BA1_PBA, sndbuf_getbufaddr(ch->buffer));
|
||||||
|
|
||||||
/* format */
|
/* format */
|
||||||
csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f;
|
csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f;
|
||||||
@ -492,7 +492,7 @@ csa_setupchan(struct csa_chinfo *ch)
|
|||||||
csa_setplaysamplerate(resp, ch->spd);
|
csa_setplaysamplerate(resp, ch->spd);
|
||||||
} else if (ch->dir == PCMDIR_REC) {
|
} else if (ch->dir == PCMDIR_REC) {
|
||||||
/* direction */
|
/* direction */
|
||||||
csa_writemem(resp, BA1_CBA, vtophys(sndbuf_getbuf(ch->buffer)));
|
csa_writemem(resp, BA1_CBA, sndbuf_getbufaddr(ch->buffer));
|
||||||
|
|
||||||
/* format */
|
/* format */
|
||||||
csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
|
csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
|
||||||
@ -581,11 +581,11 @@ csachan_getptr(kobj_t obj, void *data)
|
|||||||
resp = &csa->res;
|
resp = &csa->res;
|
||||||
|
|
||||||
if (ch->dir == PCMDIR_PLAY) {
|
if (ch->dir == PCMDIR_PLAY) {
|
||||||
ptr = csa_readmem(resp, BA1_PBA) - vtophys(sndbuf_getbuf(ch->buffer));
|
ptr = csa_readmem(resp, BA1_PBA) - sndbuf_getbufaddr(ch->buffer);
|
||||||
if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0)
|
if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0)
|
||||||
ptr >>= 1;
|
ptr >>= 1;
|
||||||
} else {
|
} else {
|
||||||
ptr = csa_readmem(resp, BA1_CBA) - vtophys(sndbuf_getbuf(ch->buffer));
|
ptr = csa_readmem(resp, BA1_CBA) - sndbuf_getbufaddr(ch->buffer);
|
||||||
if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0)
|
if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0)
|
||||||
ptr >>= 1;
|
ptr >>= 1;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +361,7 @@ ds_allocpslot(struct sc_info *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ds_initpbank(volatile struct pbank *pb, int ch, int b16, int stereo, u_int32_t rate, void *base, u_int32_t len)
|
ds_initpbank(volatile struct pbank *pb, int ch, int b16, int stereo, u_int32_t rate, bus_addr_t base, u_int32_t len)
|
||||||
{
|
{
|
||||||
u_int32_t lv[] = {1, 1, 0, 0, 0};
|
u_int32_t lv[] = {1, 1, 0, 0, 0};
|
||||||
u_int32_t rv[] = {1, 0, 1, 0, 0};
|
u_int32_t rv[] = {1, 0, 1, 0, 0};
|
||||||
@ -396,7 +396,7 @@ ds_initpbank(volatile struct pbank *pb, int ch, int b16, int stereo, u_int32_t r
|
|||||||
pb->Format |= b16? 0 : 0x80000000;
|
pb->Format |= b16? 0 : 0x80000000;
|
||||||
pb->Format |= (stereo && (ch == 2 || ch == 4))? 0x00000001 : 0;
|
pb->Format |= (stereo && (ch == 2 || ch == 4))? 0x00000001 : 0;
|
||||||
pb->LoopDefault = 0;
|
pb->LoopDefault = 0;
|
||||||
pb->PgBase = base? vtophys(base) : 0;
|
pb->PgBase = base? base : 0;
|
||||||
pb->PgLoop = 0;
|
pb->PgLoop = 0;
|
||||||
pb->PgLoopEnd = len >> ss;
|
pb->PgLoopEnd = len >> ss;
|
||||||
pb->PgLoopFrac = 0;
|
pb->PgLoopFrac = 0;
|
||||||
@ -430,18 +430,18 @@ static void
|
|||||||
ds_setuppch(struct sc_pchinfo *ch)
|
ds_setuppch(struct sc_pchinfo *ch)
|
||||||
{
|
{
|
||||||
int stereo, b16, c, sz;
|
int stereo, b16, c, sz;
|
||||||
void *buf;
|
bus_addr_t addr;
|
||||||
|
|
||||||
stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
|
stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
|
||||||
b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
|
b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
|
||||||
c = stereo? 1 : 0;
|
c = stereo? 1 : 0;
|
||||||
buf = sndbuf_getbuf(ch->buffer);
|
addr = sndbuf_getbufaddr(ch->buffer);
|
||||||
sz = sndbuf_getsize(ch->buffer);
|
sz = sndbuf_getsize(ch->buffer);
|
||||||
|
|
||||||
ds_initpbank(ch->lslot, c, stereo, b16, ch->spd, buf, sz);
|
ds_initpbank(ch->lslot, c, stereo, b16, ch->spd, addr, sz);
|
||||||
ds_initpbank(ch->lslot + 1, c, stereo, b16, ch->spd, buf, sz);
|
ds_initpbank(ch->lslot + 1, c, stereo, b16, ch->spd, addr, sz);
|
||||||
ds_initpbank(ch->rslot, 2, stereo, b16, ch->spd, buf, sz);
|
ds_initpbank(ch->rslot, 2, stereo, b16, ch->spd, addr, sz);
|
||||||
ds_initpbank(ch->rslot + 1, 2, stereo, b16, ch->spd, buf, sz);
|
ds_initpbank(ch->rslot + 1, 2, stereo, b16, ch->spd, addr, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -450,16 +450,16 @@ ds_setuprch(struct sc_rchinfo *ch)
|
|||||||
struct sc_info *sc = ch->parent;
|
struct sc_info *sc = ch->parent;
|
||||||
int stereo, b16, i, sz, pri;
|
int stereo, b16, i, sz, pri;
|
||||||
u_int32_t x, y;
|
u_int32_t x, y;
|
||||||
void *buf;
|
bus_addr_t addr;
|
||||||
|
|
||||||
stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
|
stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
|
||||||
b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
|
b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
|
||||||
buf = sndbuf_getbuf(ch->buffer);
|
addr = sndbuf_getbufaddr(ch->buffer);
|
||||||
sz = sndbuf_getsize(ch->buffer);
|
sz = sndbuf_getsize(ch->buffer);
|
||||||
pri = (ch->num == DS1_RECPRIMARY)? 1 : 0;
|
pri = (ch->num == DS1_RECPRIMARY)? 1 : 0;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
ch->slot[i].PgBase = vtophys(buf);
|
ch->slot[i].PgBase = addr;
|
||||||
ch->slot[i].PgLoopEnd = sz;
|
ch->slot[i].PgLoopEnd = sz;
|
||||||
ch->slot[i].PgStart = 0;
|
ch->slot[i].PgStart = 0;
|
||||||
ch->slot[i].NumOfLoops = 0;
|
ch->slot[i].NumOfLoops = 0;
|
||||||
|
@ -45,6 +45,7 @@ SND_DECLARE_FILE("$FreeBSD$");
|
|||||||
struct emu_memblk {
|
struct emu_memblk {
|
||||||
SLIST_ENTRY(emu_memblk) link;
|
SLIST_ENTRY(emu_memblk) link;
|
||||||
void *buf;
|
void *buf;
|
||||||
|
bus_addr_t buf_addr;
|
||||||
u_int32_t pte_start, pte_size;
|
u_int32_t pte_start, pte_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,6 +53,8 @@ struct emu_mem {
|
|||||||
u_int8_t bmap[MAXPAGES / 8];
|
u_int8_t bmap[MAXPAGES / 8];
|
||||||
u_int32_t *ptb_pages;
|
u_int32_t *ptb_pages;
|
||||||
void *silent_page;
|
void *silent_page;
|
||||||
|
bus_addr_t silent_page_addr;
|
||||||
|
bus_addr_t ptb_pages_addr;
|
||||||
SLIST_HEAD(, emu_memblk) blocks;
|
SLIST_HEAD(, emu_memblk) blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -116,8 +119,8 @@ struct sc_info {
|
|||||||
/* stuff */
|
/* stuff */
|
||||||
static int emu_init(struct sc_info *);
|
static int emu_init(struct sc_info *);
|
||||||
static void emu_intr(void *);
|
static void emu_intr(void *);
|
||||||
static void *emu_malloc(struct sc_info *sc, u_int32_t sz);
|
static void *emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr);
|
||||||
static void *emu_memalloc(struct sc_info *sc, u_int32_t sz);
|
static void *emu_memalloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr);
|
||||||
static int emu_memfree(struct sc_info *sc, void *buf);
|
static int emu_memfree(struct sc_info *sc, void *buf);
|
||||||
static int emu_memstart(struct sc_info *sc, void *buf);
|
static int emu_memstart(struct sc_info *sc, void *buf);
|
||||||
#ifdef EMUDEBUG
|
#ifdef EMUDEBUG
|
||||||
@ -426,8 +429,9 @@ emu_vinit(struct sc_info *sc, struct emu_voice *m, struct emu_voice *s,
|
|||||||
u_int32_t sz, struct snd_dbuf *b)
|
u_int32_t sz, struct snd_dbuf *b)
|
||||||
{
|
{
|
||||||
void *buf;
|
void *buf;
|
||||||
|
bus_addr_t tmp_addr;
|
||||||
|
|
||||||
buf = emu_memalloc(sc, sz);
|
buf = emu_memalloc(sc, sz, &tmp_addr);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (b != NULL)
|
if (b != NULL)
|
||||||
@ -441,7 +445,7 @@ emu_vinit(struct sc_info *sc, struct emu_voice *m, struct emu_voice *s,
|
|||||||
m->running = 0;
|
m->running = 0;
|
||||||
m->ismaster = 1;
|
m->ismaster = 1;
|
||||||
m->vol = 0xff;
|
m->vol = 0xff;
|
||||||
m->buf = vtophys(buf);
|
m->buf = tmp_addr;
|
||||||
m->slave = s;
|
m->slave = s;
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
s->start = m->start;
|
s->start = m->start;
|
||||||
@ -512,7 +516,7 @@ emu_vwrite(struct sc_info *sc, struct emu_voice *v)
|
|||||||
emu_wrptr(sc, v->vnum, Z1, 0);
|
emu_wrptr(sc, v->vnum, Z1, 0);
|
||||||
emu_wrptr(sc, v->vnum, Z2, 0);
|
emu_wrptr(sc, v->vnum, Z2, 0);
|
||||||
|
|
||||||
silent_page = ((u_int32_t)vtophys(sc->mem.silent_page) << 1) | MAP_PTI_MASK;
|
silent_page = ((u_int32_t)(sc->mem.silent_page_addr) << 1) | MAP_PTI_MASK;
|
||||||
emu_wrptr(sc, v->vnum, MAPA, silent_page);
|
emu_wrptr(sc, v->vnum, MAPA, silent_page);
|
||||||
emu_wrptr(sc, v->vnum, MAPB, silent_page);
|
emu_wrptr(sc, v->vnum, MAPB, silent_page);
|
||||||
|
|
||||||
@ -799,7 +803,7 @@ emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel
|
|||||||
return NULL;
|
return NULL;
|
||||||
else {
|
else {
|
||||||
snd_mtxlock(sc->lock);
|
snd_mtxlock(sc->lock);
|
||||||
emu_wrptr(sc, 0, ch->basereg, vtophys(sndbuf_getbuf(ch->buffer)));
|
emu_wrptr(sc, 0, ch->basereg, sndbuf_getbufaddr(ch->buffer));
|
||||||
emu_wrptr(sc, 0, ch->sizereg, 0); /* off */
|
emu_wrptr(sc, 0, ch->sizereg, 0); /* off */
|
||||||
snd_mtxunlock(sc->lock);
|
snd_mtxunlock(sc->lock);
|
||||||
return ch;
|
return ch;
|
||||||
@ -1030,15 +1034,16 @@ emu_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
emu_malloc(struct sc_info *sc, u_int32_t sz)
|
emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
|
||||||
{
|
{
|
||||||
void *buf, *phys = 0;
|
void *buf;
|
||||||
bus_dmamap_t map;
|
bus_dmamap_t map;
|
||||||
|
|
||||||
|
*addr = 0;
|
||||||
if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map))
|
if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, &phys, 0)
|
if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, addr, 0)
|
||||||
|| !phys)
|
|| !addr)
|
||||||
return NULL;
|
return NULL;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -1050,7 +1055,7 @@ emu_free(struct sc_info *sc, void *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
emu_memalloc(struct sc_info *sc, u_int32_t sz)
|
emu_memalloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
|
||||||
{
|
{
|
||||||
u_int32_t blksz, start, idx, ofs, tmp, found;
|
u_int32_t blksz, start, idx, ofs, tmp, found;
|
||||||
struct emu_mem *mem = &sc->mem;
|
struct emu_mem *mem = &sc->mem;
|
||||||
@ -1076,7 +1081,8 @@ emu_memalloc(struct sc_info *sc, u_int32_t sz)
|
|||||||
blk = malloc(sizeof(*blk), M_DEVBUF, M_NOWAIT);
|
blk = malloc(sizeof(*blk), M_DEVBUF, M_NOWAIT);
|
||||||
if (blk == NULL)
|
if (blk == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
buf = emu_malloc(sc, sz);
|
buf = emu_malloc(sc, sz, &blk->buf_addr);
|
||||||
|
*addr = blk->buf_addr;
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
free(blk, M_DEVBUF);
|
free(blk, M_DEVBUF);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1088,7 +1094,7 @@ emu_memalloc(struct sc_info *sc, u_int32_t sz)
|
|||||||
ofs = 0;
|
ofs = 0;
|
||||||
for (idx = start; idx < start + blksz; idx++) {
|
for (idx = start; idx < start + blksz; idx++) {
|
||||||
mem->bmap[idx >> 3] |= 1 << (idx & 7);
|
mem->bmap[idx >> 3] |= 1 << (idx & 7);
|
||||||
tmp = (u_int32_t)vtophys((u_int8_t *)buf + ofs);
|
tmp = (u_int32_t)((u_int8_t *)&blk->buf_addr + ofs);
|
||||||
/* printf("pte[%d] -> %x phys, %x virt\n", idx, tmp, ((u_int32_t)buf) + ofs); */
|
/* printf("pte[%d] -> %x phys, %x virt\n", idx, tmp, ((u_int32_t)buf) + ofs); */
|
||||||
mem->ptb_pages[idx] = (tmp << 1) | idx;
|
mem->ptb_pages[idx] = (tmp << 1) | idx;
|
||||||
ofs += EMUPAGESIZE;
|
ofs += EMUPAGESIZE;
|
||||||
@ -1113,7 +1119,7 @@ emu_memfree(struct sc_info *sc, void *buf)
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
|
SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
|
||||||
emu_free(sc, buf);
|
emu_free(sc, buf);
|
||||||
tmp = (u_int32_t)vtophys(sc->mem.silent_page) << 1;
|
tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
|
||||||
for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) {
|
for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) {
|
||||||
mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
|
mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
|
||||||
mem->ptb_pages[idx] = tmp | idx;
|
mem->ptb_pages[idx] = tmp | idx;
|
||||||
@ -1326,22 +1332,22 @@ emu_init(struct sc_info *sc)
|
|||||||
emu_initefx(sc);
|
emu_initefx(sc);
|
||||||
|
|
||||||
SLIST_INIT(&sc->mem.blocks);
|
SLIST_INIT(&sc->mem.blocks);
|
||||||
sc->mem.ptb_pages = emu_malloc(sc, MAXPAGES * sizeof(u_int32_t));
|
sc->mem.ptb_pages = emu_malloc(sc, MAXPAGES * sizeof(u_int32_t), &sc->mem.ptb_pages_addr);
|
||||||
if (sc->mem.ptb_pages == NULL)
|
if (sc->mem.ptb_pages == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
sc->mem.silent_page = emu_malloc(sc, EMUPAGESIZE);
|
sc->mem.silent_page = emu_malloc(sc, EMUPAGESIZE, &sc->mem.silent_page_addr);
|
||||||
if (sc->mem.silent_page == NULL) {
|
if (sc->mem.silent_page == NULL) {
|
||||||
emu_free(sc, sc->mem.ptb_pages);
|
emu_free(sc, sc->mem.ptb_pages);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Clear page with silence & setup all pointers to this page */
|
/* Clear page with silence & setup all pointers to this page */
|
||||||
bzero(sc->mem.silent_page, EMUPAGESIZE);
|
bzero(sc->mem.silent_page, EMUPAGESIZE);
|
||||||
tmp = (u_int32_t)vtophys(sc->mem.silent_page) << 1;
|
tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
|
||||||
for (i = 0; i < MAXPAGES; i++)
|
for (i = 0; i < MAXPAGES; i++)
|
||||||
sc->mem.ptb_pages[i] = tmp | i;
|
sc->mem.ptb_pages[i] = tmp | i;
|
||||||
|
|
||||||
emu_wrptr(sc, 0, PTB, vtophys(sc->mem.ptb_pages));
|
emu_wrptr(sc, 0, PTB, (sc->mem.ptb_pages_addr));
|
||||||
emu_wrptr(sc, 0, TCB, 0); /* taken from original driver */
|
emu_wrptr(sc, 0, TCB, 0); /* taken from original driver */
|
||||||
emu_wrptr(sc, 0, TCBS, 0); /* taken from original driver */
|
emu_wrptr(sc, 0, TCBS, 0); /* taken from original driver */
|
||||||
|
|
||||||
|
@ -283,11 +283,11 @@ eschan_setdir(kobj_t obj, void *data, int dir)
|
|||||||
|
|
||||||
if (dir == PCMDIR_PLAY) {
|
if (dir == PCMDIR_PLAY) {
|
||||||
bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_DAC2_FRAMEADR >> 8);
|
bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_DAC2_FRAMEADR >> 8);
|
||||||
bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMEADR & 0xff, vtophys(sndbuf_getbuf(ch->buffer)));
|
bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMEADR & 0xff, sndbuf_getbufaddr(ch->buffer));
|
||||||
bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMECNT & 0xff, (ch->bufsz >> 2) - 1);
|
bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMECNT & 0xff, (ch->bufsz >> 2) - 1);
|
||||||
} else {
|
} else {
|
||||||
bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_ADC_FRAMEADR >> 8);
|
bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_ADC_FRAMEADR >> 8);
|
||||||
bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMEADR & 0xff, vtophys(sndbuf_getbuf(ch->buffer)));
|
bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMEADR & 0xff, sndbuf_getbufaddr(ch->buffer));
|
||||||
bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMECNT & 0xff, (ch->bufsz >> 2) - 1);
|
bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMECNT & 0xff, (ch->bufsz >> 2) - 1);
|
||||||
}
|
}
|
||||||
ch->dir = dir;
|
ch->dir = dir;
|
||||||
|
@ -436,7 +436,7 @@ fm801ch_trigger(kobj_t obj, void *data, int go)
|
|||||||
{
|
{
|
||||||
struct fm801_chinfo *ch = data;
|
struct fm801_chinfo *ch = data;
|
||||||
struct fm801_info *fm801 = ch->parent;
|
struct fm801_info *fm801 = ch->parent;
|
||||||
u_int32_t baseaddr = vtophys(sndbuf_getbuf(ch->buffer));
|
u_int32_t baseaddr = sndbuf_getbufaddr(ch->buffer);
|
||||||
u_int32_t k1;
|
u_int32_t k1;
|
||||||
|
|
||||||
DPRINT("fm801ch_trigger go %d , ", go);
|
DPRINT("fm801ch_trigger go %d , ", go);
|
||||||
|
@ -65,6 +65,7 @@ struct sc_chinfo {
|
|||||||
struct sc_info *parent;
|
struct sc_info *parent;
|
||||||
|
|
||||||
struct ich_desc *dtbl;
|
struct ich_desc *dtbl;
|
||||||
|
bus_addr_t desc_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* device private data */
|
/* device private data */
|
||||||
@ -86,6 +87,7 @@ struct sc_info {
|
|||||||
struct sc_chinfo ch[3];
|
struct sc_chinfo ch[3];
|
||||||
int ac97rate;
|
int ac97rate;
|
||||||
struct ich_desc *dtbl;
|
struct ich_desc *dtbl;
|
||||||
|
bus_addr_t desc_addr;
|
||||||
struct intr_config_hook intrhook;
|
struct intr_config_hook intrhook;
|
||||||
int use_intrhook;
|
int use_intrhook;
|
||||||
};
|
};
|
||||||
@ -188,7 +190,7 @@ ich_filldtbl(struct sc_chinfo *ch)
|
|||||||
u_int32_t base;
|
u_int32_t base;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
base = vtophys(sndbuf_getbuf(ch->buffer));
|
base = sndbuf_getbufaddr(ch->buffer);
|
||||||
ch->blkcnt = sndbuf_getsize(ch->buffer) / ch->blksz;
|
ch->blkcnt = sndbuf_getsize(ch->buffer) / ch->blksz;
|
||||||
if (ch->blkcnt != 2 && ch->blkcnt != 4 && ch->blkcnt != 8 && ch->blkcnt != 16 && ch->blkcnt != 32) {
|
if (ch->blkcnt != 2 && ch->blkcnt != 4 && ch->blkcnt != 8 && ch->blkcnt != 16 && ch->blkcnt != 32) {
|
||||||
ch->blkcnt = 2;
|
ch->blkcnt = 2;
|
||||||
@ -247,6 +249,7 @@ ichchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *
|
|||||||
ch->parent = sc;
|
ch->parent = sc;
|
||||||
ch->run = 0;
|
ch->run = 0;
|
||||||
ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH);
|
ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH);
|
||||||
|
ch->desc_addr = sc->desc_addr + (ch->num * ICH_DTBL_LENGTH);
|
||||||
ch->blkcnt = 2;
|
ch->blkcnt = 2;
|
||||||
ch->blksz = sc->bufsz / ch->blkcnt;
|
ch->blksz = sc->bufsz / ch->blkcnt;
|
||||||
|
|
||||||
@ -279,7 +282,7 @@ ichchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *
|
|||||||
if (sndbuf_alloc(ch->buffer, sc->dmat, sc->bufsz))
|
if (sndbuf_alloc(ch->buffer, sc->dmat, sc->bufsz))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
|
ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)(ch->desc_addr), 4);
|
||||||
|
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
@ -335,7 +338,7 @@ ichchan_trigger(kobj_t obj, void *data, int go)
|
|||||||
switch (go) {
|
switch (go) {
|
||||||
case PCMTRIG_START:
|
case PCMTRIG_START:
|
||||||
ch->run = 1;
|
ch->run = 1;
|
||||||
ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
|
ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)(ch->desc_addr), 4);
|
||||||
ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE, 1);
|
ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -499,7 +502,7 @@ void ich_calibrate(void *arg)
|
|||||||
/* prepare */
|
/* prepare */
|
||||||
ociv = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1);
|
ociv = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1);
|
||||||
nciv = ociv;
|
nciv = ociv;
|
||||||
ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
|
ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)(ch->desc_addr), 4);
|
||||||
|
|
||||||
/* start */
|
/* start */
|
||||||
microtime(&t1);
|
microtime(&t1);
|
||||||
@ -553,6 +556,8 @@ void ich_calibrate(void *arg)
|
|||||||
static void
|
static void
|
||||||
ich_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
ich_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||||
{
|
{
|
||||||
|
struct sc_info *sc = (struct sc_info *)arg;
|
||||||
|
sc->desc_addr = segs->ds_addr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,7 +589,7 @@ ich_init(struct sc_info *sc)
|
|||||||
return ENOSPC;
|
return ENOSPC;
|
||||||
|
|
||||||
sz = sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3;
|
sz = sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3;
|
||||||
if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, sz, ich_setmap, NULL, 0)) {
|
if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, sz, ich_setmap, sc, 0)) {
|
||||||
bus_dmamem_free(sc->dmat, (void **)&sc->dtbl, sc->dtmap);
|
bus_dmamem_free(sc->dmat, (void **)&sc->dtbl, sc->dtmap);
|
||||||
return ENOSPC;
|
return ENOSPC;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ m3_pchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel
|
|||||||
ch->bufsize = sndbuf_getsize(ch->buffer);
|
ch->bufsize = sndbuf_getsize(ch->buffer);
|
||||||
|
|
||||||
/* host dma buffer pointers */
|
/* host dma buffer pointers */
|
||||||
bus_addr = vtophys(sndbuf_getbuf(ch->buffer));
|
bus_addr = sndbuf_getbufaddr(ch->buffer);
|
||||||
if (bus_addr & 3) {
|
if (bus_addr & 3) {
|
||||||
device_printf(sc->dev, "m3_pchan_init unaligned bus_addr\n");
|
device_printf(sc->dev, "m3_pchan_init unaligned bus_addr\n");
|
||||||
bus_addr = (bus_addr + 4) & ~3;
|
bus_addr = (bus_addr + 4) & ~3;
|
||||||
@ -600,7 +600,7 @@ m3_pchan_getptr(kobj_t kobj, void *chdata)
|
|||||||
struct sc_pchinfo *ch = chdata;
|
struct sc_pchinfo *ch = chdata;
|
||||||
struct sc_info *sc = ch->parent;
|
struct sc_info *sc = ch->parent;
|
||||||
u_int32_t hi, lo, bus_crnt;
|
u_int32_t hi, lo, bus_crnt;
|
||||||
u_int32_t bus_base = vtophys(sndbuf_getbuf(ch->buffer));
|
u_int32_t bus_base = sndbuf_getbufaddr(ch->buffer);
|
||||||
|
|
||||||
hi = m3_rd_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTH);
|
hi = m3_rd_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTH);
|
||||||
lo = m3_rd_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTL);
|
lo = m3_rd_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTL);
|
||||||
@ -670,7 +670,7 @@ m3_rchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel
|
|||||||
ch->bufsize = sndbuf_getsize(ch->buffer);
|
ch->bufsize = sndbuf_getsize(ch->buffer);
|
||||||
|
|
||||||
/* host dma buffer pointers */
|
/* host dma buffer pointers */
|
||||||
bus_addr = vtophys(sndbuf_getbuf(ch->buffer));
|
bus_addr = sndbuf_getbufaddr(ch->buffer);
|
||||||
if (bus_addr & 3) {
|
if (bus_addr & 3) {
|
||||||
device_printf(sc->dev, "m3_rchan_init unaligned bus_addr\n");
|
device_printf(sc->dev, "m3_rchan_init unaligned bus_addr\n");
|
||||||
bus_addr = (bus_addr + 4) & ~3;
|
bus_addr = (bus_addr + 4) & ~3;
|
||||||
@ -870,7 +870,7 @@ m3_rchan_getptr(kobj_t kobj, void *chdata)
|
|||||||
struct sc_rchinfo *ch = chdata;
|
struct sc_rchinfo *ch = chdata;
|
||||||
struct sc_info *sc = ch->parent;
|
struct sc_info *sc = ch->parent;
|
||||||
u_int32_t hi, lo, bus_crnt;
|
u_int32_t hi, lo, bus_crnt;
|
||||||
u_int32_t bus_base = vtophys(sndbuf_getbuf(ch->buffer));
|
u_int32_t bus_base = sndbuf_getbufaddr(ch->buffer);
|
||||||
|
|
||||||
hi = m3_rd_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTH);
|
hi = m3_rd_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTH);
|
||||||
lo = m3_rd_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTL);
|
lo = m3_rd_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTL);
|
||||||
|
@ -572,7 +572,7 @@ esschan_trigger(kobj_t obj, void *data, int go)
|
|||||||
|
|
||||||
switch (go) {
|
switch (go) {
|
||||||
case PCMTRIG_START:
|
case PCMTRIG_START:
|
||||||
ess_dmasetup(sc, ch->hwch, vtophys(sndbuf_getbuf(ch->buffer)), sndbuf_getsize(ch->buffer), ch->dir);
|
ess_dmasetup(sc, ch->hwch, sndbuf_getbufaddr(ch->buffer), sndbuf_getsize(ch->buffer), ch->dir);
|
||||||
ess_dmatrigger(sc, ch->hwch, 1);
|
ess_dmatrigger(sc, ch->hwch, 1);
|
||||||
ess_start(ch);
|
ess_start(ch);
|
||||||
break;
|
break;
|
||||||
|
@ -531,7 +531,7 @@ trpchan_trigger(kobj_t obj, void *data, int go)
|
|||||||
ch->fms = 0;
|
ch->fms = 0;
|
||||||
ch->ec = 0;
|
ch->ec = 0;
|
||||||
ch->alpha = 0;
|
ch->alpha = 0;
|
||||||
ch->lba = vtophys(sndbuf_getbuf(ch->buffer));
|
ch->lba = sndbuf_getbufaddr(ch->buffer);
|
||||||
ch->cso = 0;
|
ch->cso = 0;
|
||||||
ch->eso = (sndbuf_getsize(ch->buffer) / sndbuf_getbps(ch->buffer)) - 1;
|
ch->eso = (sndbuf_getsize(ch->buffer) / sndbuf_getbps(ch->buffer)) - 1;
|
||||||
ch->rvol = ch->cvol = 0x7f;
|
ch->rvol = ch->cvol = 0x7f;
|
||||||
@ -657,7 +657,7 @@ trrchan_trigger(kobj_t obj, void *data, int go)
|
|||||||
i = tr_rd(tr, TR_REG_DMAR11, 1) & 0x03;
|
i = tr_rd(tr, TR_REG_DMAR11, 1) & 0x03;
|
||||||
tr_wr(tr, TR_REG_DMAR11, i | 0x54, 1);
|
tr_wr(tr, TR_REG_DMAR11, i | 0x54, 1);
|
||||||
/* set up base address */
|
/* set up base address */
|
||||||
tr_wr(tr, TR_REG_DMAR0, vtophys(sndbuf_getbuf(ch->buffer)), 4);
|
tr_wr(tr, TR_REG_DMAR0, sndbuf_getbufaddr(ch->buffer), 4);
|
||||||
/* set up buffer size */
|
/* set up buffer size */
|
||||||
i = tr_rd(tr, TR_REG_DMAR4, 4) & ~0x00ffffff;
|
i = tr_rd(tr, TR_REG_DMAR4, 4) & ~0x00ffffff;
|
||||||
tr_wr(tr, TR_REG_DMAR4, i | (sndbuf_runsz(ch->buffer) - 1), 4);
|
tr_wr(tr, TR_REG_DMAR4, i | (sndbuf_runsz(ch->buffer) - 1), 4);
|
||||||
@ -680,7 +680,7 @@ trrchan_getptr(kobj_t obj, void *data)
|
|||||||
struct tr_info *tr = ch->parent;
|
struct tr_info *tr = ch->parent;
|
||||||
|
|
||||||
/* return current byte offset of channel */
|
/* return current byte offset of channel */
|
||||||
return tr_rd(tr, TR_REG_DMAR0, 4) - vtophys(sndbuf_getbuf(ch->buffer));
|
return tr_rd(tr, TR_REG_DMAR0, 4) - sndbuf_getbufaddr(ch->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pcmchan_caps *
|
static struct pcmchan_caps *
|
||||||
|
@ -73,6 +73,7 @@ struct via_chinfo {
|
|||||||
struct pcm_channel *channel;
|
struct pcm_channel *channel;
|
||||||
struct snd_dbuf *buffer;
|
struct snd_dbuf *buffer;
|
||||||
struct via_dma_op *sgd_table;
|
struct via_dma_op *sgd_table;
|
||||||
|
bus_addr_t sgd_addr;
|
||||||
int dir, blksz;
|
int dir, blksz;
|
||||||
int rbase; /* base register for channel */
|
int rbase; /* base register for channel */
|
||||||
};
|
};
|
||||||
@ -83,6 +84,7 @@ struct via_info {
|
|||||||
bus_dma_tag_t parent_dmat;
|
bus_dma_tag_t parent_dmat;
|
||||||
bus_dma_tag_t sgd_dmat;
|
bus_dma_tag_t sgd_dmat;
|
||||||
bus_dmamap_t sgd_dmamap;
|
bus_dmamap_t sgd_dmamap;
|
||||||
|
bus_addr_t sgd_addr;
|
||||||
|
|
||||||
struct resource *reg, *irq;
|
struct resource *reg, *irq;
|
||||||
int regid, irqid;
|
int regid, irqid;
|
||||||
@ -229,7 +231,7 @@ via_buildsgdt(struct via_chinfo *ch)
|
|||||||
*/
|
*/
|
||||||
seg_size = sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN;
|
seg_size = sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN;
|
||||||
|
|
||||||
phys_addr = vtophys(sndbuf_getbuf(ch->buffer));
|
phys_addr = sndbuf_getbufaddr(ch->buffer);
|
||||||
|
|
||||||
for (i = 0; i < SEGS_PER_CHAN; i++) {
|
for (i = 0; i < SEGS_PER_CHAN; i++) {
|
||||||
flag = (i == SEGS_PER_CHAN - 1) ? VIA_DMAOP_EOL : VIA_DMAOP_FLAG;
|
flag = (i == SEGS_PER_CHAN - 1) ? VIA_DMAOP_EOL : VIA_DMAOP_FLAG;
|
||||||
@ -360,6 +362,8 @@ via8233chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
|
|||||||
ch->buffer = b;
|
ch->buffer = b;
|
||||||
ch->dir = dir;
|
ch->dir = dir;
|
||||||
ch->sgd_table = &via->sgd_table[(dir == PCMDIR_PLAY)? 0 : SEGS_PER_CHAN];
|
ch->sgd_table = &via->sgd_table[(dir == PCMDIR_PLAY)? 0 : SEGS_PER_CHAN];
|
||||||
|
ch->sgd_addr = dir == PCMDIR_PLAY ? via->sgd_addr :
|
||||||
|
via->sgd_addr * SEGS_PER_CHAN;
|
||||||
|
|
||||||
if (ch->dir == PCMDIR_PLAY) {
|
if (ch->dir == PCMDIR_PLAY) {
|
||||||
ch->rbase = VIA_MC_SGD_STATUS;
|
ch->rbase = VIA_MC_SGD_STATUS;
|
||||||
@ -381,12 +385,11 @@ via8233chan_trigger(kobj_t obj, void* data, int go)
|
|||||||
{
|
{
|
||||||
struct via_chinfo *ch = data;
|
struct via_chinfo *ch = data;
|
||||||
struct via_info *via = ch->parent;
|
struct via_info *via = ch->parent;
|
||||||
struct via_dma_op *ado = ch->sgd_table;
|
|
||||||
|
|
||||||
switch(go) {
|
switch(go) {
|
||||||
case PCMTRIG_START:
|
case PCMTRIG_START:
|
||||||
via_buildsgdt(ch);
|
via_buildsgdt(ch);
|
||||||
via_wr(via, ch->rbase + VIA_RP_TABLE_PTR, vtophys(ado), 4);
|
via_wr(via, ch->rbase + VIA_RP_TABLE_PTR, ch->sgd_addr, 4);
|
||||||
via_wr(via, ch->rbase + VIA_RP_CONTROL,
|
via_wr(via, ch->rbase + VIA_RP_CONTROL,
|
||||||
SGD_CONTROL_START | SGD_CONTROL_AUTOSTART |
|
SGD_CONTROL_START | SGD_CONTROL_AUTOSTART |
|
||||||
SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1);
|
SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1);
|
||||||
@ -478,6 +481,8 @@ via_probe(device_t dev)
|
|||||||
static void
|
static void
|
||||||
dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
|
dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
|
||||||
{
|
{
|
||||||
|
struct via_info *via = (struct via_info *)p;
|
||||||
|
via->sgd_addr = bds->ds_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -580,7 +585,7 @@ via_attach(device_t dev)
|
|||||||
BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1)
|
BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1)
|
||||||
goto bad;
|
goto bad;
|
||||||
if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table,
|
if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table,
|
||||||
NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0))
|
NSEGS * sizeof(struct via_dma_op), dma_cb, via, 0))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if (via_chip_init(dev))
|
if (via_chip_init(dev))
|
||||||
|
@ -63,6 +63,7 @@ struct via_chinfo {
|
|||||||
struct pcm_channel *channel;
|
struct pcm_channel *channel;
|
||||||
struct snd_dbuf *buffer;
|
struct snd_dbuf *buffer;
|
||||||
struct via_dma_op *sgd_table;
|
struct via_dma_op *sgd_table;
|
||||||
|
bus_addr_t sgd_addr;
|
||||||
int dir, blksz;
|
int dir, blksz;
|
||||||
int base, count, mode, ctrl;
|
int base, count, mode, ctrl;
|
||||||
};
|
};
|
||||||
@ -73,6 +74,7 @@ struct via_info {
|
|||||||
bus_dma_tag_t parent_dmat;
|
bus_dma_tag_t parent_dmat;
|
||||||
bus_dma_tag_t sgd_dmat;
|
bus_dma_tag_t sgd_dmat;
|
||||||
bus_dmamap_t sgd_dmamap;
|
bus_dmamap_t sgd_dmamap;
|
||||||
|
bus_addr_t sgd_addr;
|
||||||
|
|
||||||
struct resource *reg, *irq;
|
struct resource *reg, *irq;
|
||||||
int regid, irqid;
|
int regid, irqid;
|
||||||
@ -224,7 +226,7 @@ via_buildsgdt(struct via_chinfo *ch)
|
|||||||
*/
|
*/
|
||||||
seg_size = ch->blksz;
|
seg_size = ch->blksz;
|
||||||
segs = sndbuf_getsize(ch->buffer) / seg_size;
|
segs = sndbuf_getsize(ch->buffer) / seg_size;
|
||||||
phys_addr = vtophys(sndbuf_getbuf(ch->buffer));
|
phys_addr = sndbuf_getbufaddr(ch->buffer);
|
||||||
|
|
||||||
for (i = 0; i < segs; i++) {
|
for (i = 0; i < segs; i++) {
|
||||||
flag = (i == segs - 1)? VIA_DMAOP_EOL : VIA_DMAOP_FLAG;
|
flag = (i == segs - 1)? VIA_DMAOP_EOL : VIA_DMAOP_FLAG;
|
||||||
@ -247,6 +249,8 @@ viachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *
|
|||||||
ch->buffer = b;
|
ch->buffer = b;
|
||||||
ch->dir = dir;
|
ch->dir = dir;
|
||||||
ch->sgd_table = &via->sgd_table[(dir == PCMDIR_PLAY)? 0 : SEGS_PER_CHAN];
|
ch->sgd_table = &via->sgd_table[(dir == PCMDIR_PLAY)? 0 : SEGS_PER_CHAN];
|
||||||
|
ch->sgd_addr = dir == PCMDIR_PLAY ? via->sgd_addr : via->sgd_addr +
|
||||||
|
sizeof(struct via_dma_op) * SEGS_PER_CHAN;
|
||||||
if (ch->dir == PCMDIR_PLAY) {
|
if (ch->dir == PCMDIR_PLAY) {
|
||||||
ch->base = VIA_PLAY_DMAOPS_BASE;
|
ch->base = VIA_PLAY_DMAOPS_BASE;
|
||||||
ch->count = VIA_PLAY_DMAOPS_COUNT;
|
ch->count = VIA_PLAY_DMAOPS_COUNT;
|
||||||
@ -326,16 +330,17 @@ viachan_trigger(kobj_t obj, void *data, int go)
|
|||||||
struct via_chinfo *ch = data;
|
struct via_chinfo *ch = data;
|
||||||
struct via_info *via = ch->parent;
|
struct via_info *via = ch->parent;
|
||||||
struct via_dma_op *ado;
|
struct via_dma_op *ado;
|
||||||
|
bus_addr_t sgd_addr = ch->sgd_addr;
|
||||||
|
|
||||||
if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
|
if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ado = ch->sgd_table;
|
ado = ch->sgd_table;
|
||||||
DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado)));
|
DEB(printf("ado located at va=%p pa=%x\n", ado, sgd_addr));
|
||||||
|
|
||||||
if (go == PCMTRIG_START) {
|
if (go == PCMTRIG_START) {
|
||||||
via_buildsgdt(ch);
|
via_buildsgdt(ch);
|
||||||
via_wr(via, ch->base, vtophys(ado), 4);
|
via_wr(via, ch->base, sgd_addr, 4);
|
||||||
via_wr(via, ch->ctrl, VIA_RPCTRL_START, 1);
|
via_wr(via, ch->ctrl, VIA_RPCTRL_START, 1);
|
||||||
} else
|
} else
|
||||||
via_wr(via, ch->ctrl, VIA_RPCTRL_TERMINATE, 1);
|
via_wr(via, ch->ctrl, VIA_RPCTRL_TERMINATE, 1);
|
||||||
@ -350,6 +355,7 @@ viachan_getptr(kobj_t obj, void *data)
|
|||||||
struct via_chinfo *ch = data;
|
struct via_chinfo *ch = data;
|
||||||
struct via_info *via = ch->parent;
|
struct via_info *via = ch->parent;
|
||||||
struct via_dma_op *ado;
|
struct via_dma_op *ado;
|
||||||
|
bus_addr_t sgd_addr = ch->sgd_addr;
|
||||||
int ptr, base, base1, len, seg;
|
int ptr, base, base1, len, seg;
|
||||||
|
|
||||||
ado = ch->sgd_table;
|
ado = ch->sgd_table;
|
||||||
@ -364,7 +370,7 @@ viachan_getptr(kobj_t obj, void *data)
|
|||||||
/* Base points to SGD segment to do, one past current */
|
/* Base points to SGD segment to do, one past current */
|
||||||
|
|
||||||
/* Determine how many segments have been done */
|
/* Determine how many segments have been done */
|
||||||
seg = (base - vtophys(ado)) / sizeof(struct via_dma_op);
|
seg = (base - sgd_addr) / sizeof(struct via_dma_op);
|
||||||
if (seg == 0)
|
if (seg == 0)
|
||||||
seg = SEGS_PER_CHAN;
|
seg = SEGS_PER_CHAN;
|
||||||
|
|
||||||
@ -442,6 +448,8 @@ via_probe(device_t dev)
|
|||||||
static void
|
static void
|
||||||
dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
|
dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
|
||||||
{
|
{
|
||||||
|
struct via_info *via = (struct via_info *)p;
|
||||||
|
via->sgd_addr = bds->ds_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -526,7 +534,7 @@ via_attach(device_t dev)
|
|||||||
|
|
||||||
if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1)
|
if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1)
|
||||||
goto bad;
|
goto bad;
|
||||||
if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0))
|
if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, NSEGS * sizeof(struct via_dma_op), dma_cb, via, 0))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", rman_get_start(via->reg), rman_get_start(via->irq));
|
snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", rman_get_start(via->reg), rman_get_start(via->irq));
|
||||||
|
@ -324,7 +324,7 @@ svrchan_trigger(kobj_t obj, void *data, int go)
|
|||||||
/* Program DMA */
|
/* Program DMA */
|
||||||
count = sndbuf_getsize(ch->buffer) / 2; /* DMAC uses words */
|
count = sndbuf_getsize(ch->buffer) / 2; /* DMAC uses words */
|
||||||
sv_dma_set_config(sc->dmac_st, sc->dmac_sh,
|
sv_dma_set_config(sc->dmac_st, sc->dmac_sh,
|
||||||
vtophys(sndbuf_getbuf(ch->buffer)),
|
sndbuf_getbufaddr(ch->buffer),
|
||||||
count - 1,
|
count - 1,
|
||||||
SV_DMA_MODE_AUTO | SV_DMA_MODE_RD);
|
SV_DMA_MODE_AUTO | SV_DMA_MODE_RD);
|
||||||
count = count / SV_INTR_PER_BUFFER - 1;
|
count = count / SV_INTR_PER_BUFFER - 1;
|
||||||
@ -399,7 +399,7 @@ svpchan_trigger(kobj_t obj, void *data, int go)
|
|||||||
/* Program DMA */
|
/* Program DMA */
|
||||||
count = sndbuf_getsize(ch->buffer);
|
count = sndbuf_getsize(ch->buffer);
|
||||||
sv_dma_set_config(sc->dmaa_st, sc->dmaa_sh,
|
sv_dma_set_config(sc->dmaa_st, sc->dmaa_sh,
|
||||||
vtophys(sndbuf_getbuf(ch->buffer)),
|
sndbuf_getbufaddr(ch->buffer),
|
||||||
count - 1,
|
count - 1,
|
||||||
SV_DMA_MODE_AUTO | SV_DMA_MODE_WR);
|
SV_DMA_MODE_AUTO | SV_DMA_MODE_WR);
|
||||||
count = count / SV_INTR_PER_BUFFER - 1;
|
count = count / SV_INTR_PER_BUFFER - 1;
|
||||||
|
@ -48,6 +48,12 @@ sndbuf_destroy(struct snd_dbuf *b)
|
|||||||
free(b, M_DEVBUF);
|
free(b, M_DEVBUF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bus_addr_t
|
||||||
|
sndbuf_getbufaddr(struct snd_dbuf *buf)
|
||||||
|
{
|
||||||
|
return (buf->buf_addr);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sndbuf_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
sndbuf_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||||
{
|
{
|
||||||
@ -58,12 +64,14 @@ sndbuf_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
|||||||
(unsigned long)segs->ds_len);
|
(unsigned long)segs->ds_len);
|
||||||
printf("%p -> %lx\n", b->buf, (unsigned long)vtophys(b->buf));
|
printf("%p -> %lx\n", b->buf, (unsigned long)vtophys(b->buf));
|
||||||
}
|
}
|
||||||
|
b->buf_addr = segs->ds_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate memory for DMA buffer. If the device does not use DMA transfers,
|
* Allocate memory for DMA buffer. If the device does not use DMA transfers,
|
||||||
* the driver can call malloc(9) and sndbuf_setup() itself.
|
* the driver can call malloc(9) and sndbuf_setup() itself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, unsigned int size)
|
sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, unsigned int size)
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,7 @@ struct snd_dbuf {
|
|||||||
u_int32_t flags;
|
u_int32_t flags;
|
||||||
bus_dmamap_t dmamap;
|
bus_dmamap_t dmamap;
|
||||||
bus_dma_tag_t dmatag;
|
bus_dma_tag_t dmatag;
|
||||||
|
u_int32_t buf_addr;
|
||||||
struct selinfo sel;
|
struct selinfo sel;
|
||||||
char name[SNDBUF_NAMELEN];
|
char name[SNDBUF_NAMELEN];
|
||||||
};
|
};
|
||||||
@ -75,6 +76,8 @@ unsigned int sndbuf_getspd(struct snd_dbuf *b);
|
|||||||
void sndbuf_setspd(struct snd_dbuf *b, unsigned int spd);
|
void sndbuf_setspd(struct snd_dbuf *b, unsigned int spd);
|
||||||
unsigned int sndbuf_getbps(struct snd_dbuf *b);
|
unsigned int sndbuf_getbps(struct snd_dbuf *b);
|
||||||
|
|
||||||
|
bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf);
|
||||||
|
|
||||||
void *sndbuf_getbuf(struct snd_dbuf *b);
|
void *sndbuf_getbuf(struct snd_dbuf *b);
|
||||||
void *sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs);
|
void *sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs);
|
||||||
unsigned int sndbuf_getsize(struct snd_dbuf *b);
|
unsigned int sndbuf_getsize(struct snd_dbuf *b);
|
||||||
|
Loading…
Reference in New Issue
Block a user