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;
|
||||
u_int32_t buf, bufsz, count, dma_prog;
|
||||
|
||||
buf = vtophys(sndbuf_getbuf(ch->buffer));
|
||||
buf = sndbuf_getbufaddr(ch->buffer);
|
||||
bufsz = sndbuf_getsize(ch->buffer);
|
||||
count = bufsz / 2;
|
||||
if (ch->format & AFMT_16BIT)
|
||||
@ -428,7 +428,7 @@ als_capture_start(struct sc_chinfo *ch)
|
||||
struct sc_info *sc = ch->parent;
|
||||
u_int32_t buf, bufsz, count, dma_prog;
|
||||
|
||||
buf = vtophys(sndbuf_getbuf(ch->buffer));
|
||||
buf = sndbuf_getbufaddr(ch->buffer);
|
||||
bufsz = sndbuf_getsize(ch->buffer);
|
||||
count = bufsz / 2;
|
||||
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;
|
||||
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, 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;
|
||||
|
||||
ch->phys_buf = vtophys(sndbuf_getbuf(ch->buffer));
|
||||
ch->phys_buf = sndbuf_getbufaddr(ch->buffer);
|
||||
|
||||
cmi_wr(sc, base, ch->phys_buf, 4);
|
||||
sz = (u_int32_t)sndbuf_getsize(ch->buffer);
|
||||
|
@ -487,7 +487,7 @@ adcdac_prog(struct sc_chinfo *ch)
|
||||
if (!ch->dma_setup) {
|
||||
go = adcdac_go(ch, 0);
|
||||
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),
|
||||
sndbuf_getsize(ch->buffer) / ch->bps - 1);
|
||||
ch->dma_setup = 1;
|
||||
|
@ -463,7 +463,7 @@ csa_setupchan(struct csa_chinfo *ch)
|
||||
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
/* direction */
|
||||
csa_writemem(resp, BA1_PBA, vtophys(sndbuf_getbuf(ch->buffer)));
|
||||
csa_writemem(resp, BA1_PBA, sndbuf_getbufaddr(ch->buffer));
|
||||
|
||||
/* format */
|
||||
csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f;
|
||||
@ -492,7 +492,7 @@ csa_setupchan(struct csa_chinfo *ch)
|
||||
csa_setplaysamplerate(resp, ch->spd);
|
||||
} else if (ch->dir == PCMDIR_REC) {
|
||||
/* direction */
|
||||
csa_writemem(resp, BA1_CBA, vtophys(sndbuf_getbuf(ch->buffer)));
|
||||
csa_writemem(resp, BA1_CBA, sndbuf_getbufaddr(ch->buffer));
|
||||
|
||||
/* format */
|
||||
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;
|
||||
|
||||
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)
|
||||
ptr >>= 1;
|
||||
} 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)
|
||||
ptr >>= 1;
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ ds_allocpslot(struct sc_info *sc)
|
||||
}
|
||||
|
||||
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 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 |= (stereo && (ch == 2 || ch == 4))? 0x00000001 : 0;
|
||||
pb->LoopDefault = 0;
|
||||
pb->PgBase = base? vtophys(base) : 0;
|
||||
pb->PgBase = base? base : 0;
|
||||
pb->PgLoop = 0;
|
||||
pb->PgLoopEnd = len >> ss;
|
||||
pb->PgLoopFrac = 0;
|
||||
@ -430,18 +430,18 @@ static void
|
||||
ds_setuppch(struct sc_pchinfo *ch)
|
||||
{
|
||||
int stereo, b16, c, sz;
|
||||
void *buf;
|
||||
bus_addr_t addr;
|
||||
|
||||
stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
|
||||
b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
|
||||
c = stereo? 1 : 0;
|
||||
buf = sndbuf_getbuf(ch->buffer);
|
||||
addr = sndbuf_getbufaddr(ch->buffer);
|
||||
sz = sndbuf_getsize(ch->buffer);
|
||||
|
||||
ds_initpbank(ch->lslot, c, stereo, b16, ch->spd, buf, sz);
|
||||
ds_initpbank(ch->lslot + 1, c, stereo, b16, ch->spd, buf, sz);
|
||||
ds_initpbank(ch->rslot, 2, stereo, b16, ch->spd, buf, sz);
|
||||
ds_initpbank(ch->rslot + 1, 2, 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, addr, sz);
|
||||
ds_initpbank(ch->rslot, 2, stereo, b16, ch->spd, addr, sz);
|
||||
ds_initpbank(ch->rslot + 1, 2, stereo, b16, ch->spd, addr, sz);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -450,16 +450,16 @@ ds_setuprch(struct sc_rchinfo *ch)
|
||||
struct sc_info *sc = ch->parent;
|
||||
int stereo, b16, i, sz, pri;
|
||||
u_int32_t x, y;
|
||||
void *buf;
|
||||
bus_addr_t addr;
|
||||
|
||||
stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
|
||||
b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
|
||||
buf = sndbuf_getbuf(ch->buffer);
|
||||
addr = sndbuf_getbufaddr(ch->buffer);
|
||||
sz = sndbuf_getsize(ch->buffer);
|
||||
pri = (ch->num == DS1_RECPRIMARY)? 1 : 0;
|
||||
|
||||
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].PgStart = 0;
|
||||
ch->slot[i].NumOfLoops = 0;
|
||||
|
@ -45,6 +45,7 @@ SND_DECLARE_FILE("$FreeBSD$");
|
||||
struct emu_memblk {
|
||||
SLIST_ENTRY(emu_memblk) link;
|
||||
void *buf;
|
||||
bus_addr_t buf_addr;
|
||||
u_int32_t pte_start, pte_size;
|
||||
};
|
||||
|
||||
@ -52,6 +53,8 @@ struct emu_mem {
|
||||
u_int8_t bmap[MAXPAGES / 8];
|
||||
u_int32_t *ptb_pages;
|
||||
void *silent_page;
|
||||
bus_addr_t silent_page_addr;
|
||||
bus_addr_t ptb_pages_addr;
|
||||
SLIST_HEAD(, emu_memblk) blocks;
|
||||
};
|
||||
|
||||
@ -116,8 +119,8 @@ struct sc_info {
|
||||
/* stuff */
|
||||
static int emu_init(struct sc_info *);
|
||||
static void emu_intr(void *);
|
||||
static void *emu_malloc(struct sc_info *sc, u_int32_t sz);
|
||||
static void *emu_memalloc(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, bus_addr_t *addr);
|
||||
static int emu_memfree(struct sc_info *sc, void *buf);
|
||||
static int emu_memstart(struct sc_info *sc, void *buf);
|
||||
#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)
|
||||
{
|
||||
void *buf;
|
||||
bus_addr_t tmp_addr;
|
||||
|
||||
buf = emu_memalloc(sc, sz);
|
||||
buf = emu_memalloc(sc, sz, &tmp_addr);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
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->ismaster = 1;
|
||||
m->vol = 0xff;
|
||||
m->buf = vtophys(buf);
|
||||
m->buf = tmp_addr;
|
||||
m->slave = s;
|
||||
if (s != NULL) {
|
||||
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, 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, MAPB, silent_page);
|
||||
|
||||
@ -799,7 +803,7 @@ emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel
|
||||
return NULL;
|
||||
else {
|
||||
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 */
|
||||
snd_mtxunlock(sc->lock);
|
||||
return ch;
|
||||
@ -1030,15 +1034,16 @@ emu_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
*addr = 0;
|
||||
if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map))
|
||||
return NULL;
|
||||
if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, &phys, 0)
|
||||
|| !phys)
|
||||
if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, addr, 0)
|
||||
|| !addr)
|
||||
return NULL;
|
||||
return buf;
|
||||
}
|
||||
@ -1050,7 +1055,7 @@ emu_free(struct sc_info *sc, void *buf)
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
if (blk == NULL)
|
||||
return NULL;
|
||||
buf = emu_malloc(sc, sz);
|
||||
buf = emu_malloc(sc, sz, &blk->buf_addr);
|
||||
*addr = blk->buf_addr;
|
||||
if (buf == NULL) {
|
||||
free(blk, M_DEVBUF);
|
||||
return NULL;
|
||||
@ -1088,7 +1094,7 @@ emu_memalloc(struct sc_info *sc, u_int32_t sz)
|
||||
ofs = 0;
|
||||
for (idx = start; idx < start + blksz; idx++) {
|
||||
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); */
|
||||
mem->ptb_pages[idx] = (tmp << 1) | idx;
|
||||
ofs += EMUPAGESIZE;
|
||||
@ -1113,7 +1119,7 @@ emu_memfree(struct sc_info *sc, void *buf)
|
||||
return EINVAL;
|
||||
SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
|
||||
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++) {
|
||||
mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
|
||||
mem->ptb_pages[idx] = tmp | idx;
|
||||
@ -1326,22 +1332,22 @@ emu_init(struct sc_info *sc)
|
||||
emu_initefx(sc);
|
||||
|
||||
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)
|
||||
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) {
|
||||
emu_free(sc, sc->mem.ptb_pages);
|
||||
return -1;
|
||||
}
|
||||
/* Clear page with silence & setup all pointers to this page */
|
||||
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++)
|
||||
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, TCBS, 0); /* taken from original driver */
|
||||
|
||||
|
@ -283,11 +283,11 @@ eschan_setdir(kobj_t obj, void *data, int dir)
|
||||
|
||||
if (dir == PCMDIR_PLAY) {
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
ch->dir = dir;
|
||||
|
@ -436,7 +436,7 @@ fm801ch_trigger(kobj_t obj, void *data, int go)
|
||||
{
|
||||
struct fm801_chinfo *ch = data;
|
||||
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;
|
||||
|
||||
DPRINT("fm801ch_trigger go %d , ", go);
|
||||
|
@ -65,6 +65,7 @@ struct sc_chinfo {
|
||||
struct sc_info *parent;
|
||||
|
||||
struct ich_desc *dtbl;
|
||||
bus_addr_t desc_addr;
|
||||
};
|
||||
|
||||
/* device private data */
|
||||
@ -86,6 +87,7 @@ struct sc_info {
|
||||
struct sc_chinfo ch[3];
|
||||
int ac97rate;
|
||||
struct ich_desc *dtbl;
|
||||
bus_addr_t desc_addr;
|
||||
struct intr_config_hook intrhook;
|
||||
int use_intrhook;
|
||||
};
|
||||
@ -188,7 +190,7 @@ ich_filldtbl(struct sc_chinfo *ch)
|
||||
u_int32_t base;
|
||||
int i;
|
||||
|
||||
base = vtophys(sndbuf_getbuf(ch->buffer));
|
||||
base = sndbuf_getbufaddr(ch->buffer);
|
||||
ch->blkcnt = sndbuf_getsize(ch->buffer) / ch->blksz;
|
||||
if (ch->blkcnt != 2 && ch->blkcnt != 4 && ch->blkcnt != 8 && ch->blkcnt != 16 && ch->blkcnt != 32) {
|
||||
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->run = 0;
|
||||
ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH);
|
||||
ch->desc_addr = sc->desc_addr + (ch->num * ICH_DTBL_LENGTH);
|
||||
ch->blkcnt = 2;
|
||||
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))
|
||||
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;
|
||||
}
|
||||
@ -335,7 +338,7 @@ ichchan_trigger(kobj_t obj, void *data, int go)
|
||||
switch (go) {
|
||||
case PCMTRIG_START:
|
||||
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);
|
||||
break;
|
||||
|
||||
@ -499,7 +502,7 @@ void ich_calibrate(void *arg)
|
||||
/* prepare */
|
||||
ociv = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1);
|
||||
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 */
|
||||
microtime(&t1);
|
||||
@ -553,6 +556,8 @@ void ich_calibrate(void *arg)
|
||||
static void
|
||||
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;
|
||||
}
|
||||
|
||||
@ -584,7 +589,7 @@ ich_init(struct sc_info *sc)
|
||||
return ENOSPC;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
/* host dma buffer pointers */
|
||||
bus_addr = vtophys(sndbuf_getbuf(ch->buffer));
|
||||
bus_addr = sndbuf_getbufaddr(ch->buffer);
|
||||
if (bus_addr & 3) {
|
||||
device_printf(sc->dev, "m3_pchan_init unaligned bus_addr\n");
|
||||
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_info *sc = ch->parent;
|
||||
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);
|
||||
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);
|
||||
|
||||
/* host dma buffer pointers */
|
||||
bus_addr = vtophys(sndbuf_getbuf(ch->buffer));
|
||||
bus_addr = sndbuf_getbufaddr(ch->buffer);
|
||||
if (bus_addr & 3) {
|
||||
device_printf(sc->dev, "m3_rchan_init unaligned bus_addr\n");
|
||||
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_info *sc = ch->parent;
|
||||
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);
|
||||
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) {
|
||||
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_start(ch);
|
||||
break;
|
||||
|
@ -531,7 +531,7 @@ trpchan_trigger(kobj_t obj, void *data, int go)
|
||||
ch->fms = 0;
|
||||
ch->ec = 0;
|
||||
ch->alpha = 0;
|
||||
ch->lba = vtophys(sndbuf_getbuf(ch->buffer));
|
||||
ch->lba = sndbuf_getbufaddr(ch->buffer);
|
||||
ch->cso = 0;
|
||||
ch->eso = (sndbuf_getsize(ch->buffer) / sndbuf_getbps(ch->buffer)) - 1;
|
||||
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;
|
||||
tr_wr(tr, TR_REG_DMAR11, i | 0x54, 1);
|
||||
/* 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 */
|
||||
i = tr_rd(tr, TR_REG_DMAR4, 4) & ~0x00ffffff;
|
||||
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;
|
||||
|
||||
/* 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 *
|
||||
|
@ -73,6 +73,7 @@ struct via_chinfo {
|
||||
struct pcm_channel *channel;
|
||||
struct snd_dbuf *buffer;
|
||||
struct via_dma_op *sgd_table;
|
||||
bus_addr_t sgd_addr;
|
||||
int dir, blksz;
|
||||
int rbase; /* base register for channel */
|
||||
};
|
||||
@ -83,6 +84,7 @@ struct via_info {
|
||||
bus_dma_tag_t parent_dmat;
|
||||
bus_dma_tag_t sgd_dmat;
|
||||
bus_dmamap_t sgd_dmamap;
|
||||
bus_addr_t sgd_addr;
|
||||
|
||||
struct resource *reg, *irq;
|
||||
int regid, irqid;
|
||||
@ -229,7 +231,7 @@ via_buildsgdt(struct via_chinfo *ch)
|
||||
*/
|
||||
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++) {
|
||||
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->dir = dir;
|
||||
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) {
|
||||
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_info *via = ch->parent;
|
||||
struct via_dma_op *ado = ch->sgd_table;
|
||||
|
||||
switch(go) {
|
||||
case PCMTRIG_START:
|
||||
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,
|
||||
SGD_CONTROL_START | SGD_CONTROL_AUTOSTART |
|
||||
SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1);
|
||||
@ -478,6 +481,8 @@ via_probe(device_t dev)
|
||||
static void
|
||||
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
|
||||
@ -580,7 +585,7 @@ via_attach(device_t dev)
|
||||
BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1)
|
||||
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))
|
||||
NSEGS * sizeof(struct via_dma_op), dma_cb, via, 0))
|
||||
goto bad;
|
||||
|
||||
if (via_chip_init(dev))
|
||||
|
@ -63,6 +63,7 @@ struct via_chinfo {
|
||||
struct pcm_channel *channel;
|
||||
struct snd_dbuf *buffer;
|
||||
struct via_dma_op *sgd_table;
|
||||
bus_addr_t sgd_addr;
|
||||
int dir, blksz;
|
||||
int base, count, mode, ctrl;
|
||||
};
|
||||
@ -73,6 +74,7 @@ struct via_info {
|
||||
bus_dma_tag_t parent_dmat;
|
||||
bus_dma_tag_t sgd_dmat;
|
||||
bus_dmamap_t sgd_dmamap;
|
||||
bus_addr_t sgd_addr;
|
||||
|
||||
struct resource *reg, *irq;
|
||||
int regid, irqid;
|
||||
@ -224,7 +226,7 @@ via_buildsgdt(struct via_chinfo *ch)
|
||||
*/
|
||||
seg_size = ch->blksz;
|
||||
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++) {
|
||||
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->dir = dir;
|
||||
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) {
|
||||
ch->base = VIA_PLAY_DMAOPS_BASE;
|
||||
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_info *via = ch->parent;
|
||||
struct via_dma_op *ado;
|
||||
bus_addr_t sgd_addr = ch->sgd_addr;
|
||||
|
||||
if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
|
||||
return 0;
|
||||
|
||||
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) {
|
||||
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);
|
||||
} else
|
||||
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_info *via = ch->parent;
|
||||
struct via_dma_op *ado;
|
||||
bus_addr_t sgd_addr = ch->sgd_addr;
|
||||
int ptr, base, base1, len, seg;
|
||||
|
||||
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 */
|
||||
|
||||
/* 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)
|
||||
seg = SEGS_PER_CHAN;
|
||||
|
||||
@ -442,6 +448,8 @@ via_probe(device_t dev)
|
||||
static void
|
||||
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)
|
||||
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;
|
||||
|
||||
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 */
|
||||
count = sndbuf_getsize(ch->buffer) / 2; /* DMAC uses words */
|
||||
sv_dma_set_config(sc->dmac_st, sc->dmac_sh,
|
||||
vtophys(sndbuf_getbuf(ch->buffer)),
|
||||
sndbuf_getbufaddr(ch->buffer),
|
||||
count - 1,
|
||||
SV_DMA_MODE_AUTO | SV_DMA_MODE_RD);
|
||||
count = count / SV_INTR_PER_BUFFER - 1;
|
||||
@ -399,7 +399,7 @@ svpchan_trigger(kobj_t obj, void *data, int go)
|
||||
/* Program DMA */
|
||||
count = sndbuf_getsize(ch->buffer);
|
||||
sv_dma_set_config(sc->dmaa_st, sc->dmaa_sh,
|
||||
vtophys(sndbuf_getbuf(ch->buffer)),
|
||||
sndbuf_getbufaddr(ch->buffer),
|
||||
count - 1,
|
||||
SV_DMA_MODE_AUTO | SV_DMA_MODE_WR);
|
||||
count = count / SV_INTR_PER_BUFFER - 1;
|
||||
|
@ -48,6 +48,12 @@ sndbuf_destroy(struct snd_dbuf *b)
|
||||
free(b, M_DEVBUF);
|
||||
}
|
||||
|
||||
bus_addr_t
|
||||
sndbuf_getbufaddr(struct snd_dbuf *buf)
|
||||
{
|
||||
return (buf->buf_addr);
|
||||
}
|
||||
|
||||
static void
|
||||
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);
|
||||
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,
|
||||
* the driver can call malloc(9) and sndbuf_setup() itself.
|
||||
*/
|
||||
|
||||
int
|
||||
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;
|
||||
bus_dmamap_t dmamap;
|
||||
bus_dma_tag_t dmatag;
|
||||
u_int32_t buf_addr;
|
||||
struct selinfo sel;
|
||||
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);
|
||||
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_getbufofs(struct snd_dbuf *b, unsigned int ofs);
|
||||
unsigned int sndbuf_getsize(struct snd_dbuf *b);
|
||||
|
Loading…
Reference in New Issue
Block a user