Skip to content

Commit a4f2fa5

Browse files
Joakim Zhangtiwai
authored andcommitted
ALSA: hda/core: add addr_offset field for bus address translation
Add bus addr_offset field for dma address translation, for some SoCs such as CIX SKY1 which is ARM64 Arch, HOST and HDAC has different memory view, so need to do dma address translation between HOST and HDAC. Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20251205154621.3019640-3-joakim.zhang@cixtech.com
1 parent 85a6544 commit a4f2fa5

4 files changed

Lines changed: 15 additions & 11 deletions

File tree

include/sound/hdaudio.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,9 @@ struct hdac_bus {
380380

381381
/* factor used to derive STRIPE control value */
382382
unsigned int sdo_limit;
383+
384+
/* address offset between host and hadc */
385+
dma_addr_t addr_offset;
383386
};
384387

385388
int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,

sound/hda/core/bus.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
4747
INIT_LIST_HEAD(&bus->hlink_list);
4848
init_waitqueue_head(&bus->rirb_wq);
4949
bus->irq = -1;
50+
bus->addr_offset = 0;
5051

5152
/*
5253
* Default value of '8' is as per the HD audio specification (Rev 1.0a).

sound/hda/core/controller.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
4848
/* CORB set up */
4949
bus->corb.addr = bus->rb.addr;
5050
bus->corb.buf = (__le32 *)bus->rb.area;
51-
snd_hdac_chip_writel(bus, CORBLBASE, (u32)bus->corb.addr);
52-
snd_hdac_chip_writel(bus, CORBUBASE, upper_32_bits(bus->corb.addr));
51+
snd_hdac_chip_writel(bus, CORBLBASE, (u32)(bus->corb.addr + bus->addr_offset));
52+
snd_hdac_chip_writel(bus, CORBUBASE, upper_32_bits(bus->corb.addr + bus->addr_offset));
5353

5454
/* set the corb size to 256 entries (ULI requires explicitly) */
5555
snd_hdac_chip_writeb(bus, CORBSIZE, 0x02);
@@ -70,8 +70,8 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
7070
bus->rirb.buf = (__le32 *)(bus->rb.area + 2048);
7171
bus->rirb.wp = bus->rirb.rp = 0;
7272
memset(bus->rirb.cmds, 0, sizeof(bus->rirb.cmds));
73-
snd_hdac_chip_writel(bus, RIRBLBASE, (u32)bus->rirb.addr);
74-
snd_hdac_chip_writel(bus, RIRBUBASE, upper_32_bits(bus->rirb.addr));
73+
snd_hdac_chip_writel(bus, RIRBLBASE, (u32)(bus->rirb.addr + bus->addr_offset));
74+
snd_hdac_chip_writel(bus, RIRBUBASE, upper_32_bits(bus->rirb.addr + bus->addr_offset));
7575

7676
/* set the rirb size to 256 entries (ULI requires explicitly) */
7777
snd_hdac_chip_writeb(bus, RIRBSIZE, 0x02);
@@ -625,8 +625,8 @@ bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
625625

626626
/* program the position buffer */
627627
if (bus->use_posbuf && bus->posbuf.addr) {
628-
snd_hdac_chip_writel(bus, DPLBASE, (u32)bus->posbuf.addr);
629-
snd_hdac_chip_writel(bus, DPUBASE, upper_32_bits(bus->posbuf.addr));
628+
snd_hdac_chip_writel(bus, DPLBASE, (u32)(bus->posbuf.addr + bus->addr_offset));
629+
snd_hdac_chip_writel(bus, DPUBASE, upper_32_bits(bus->posbuf.addr + bus->addr_offset));
630630
}
631631

632632
bus->chip_init = true;

sound/hda/core/stream.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,16 +288,16 @@ int snd_hdac_stream_setup(struct hdac_stream *azx_dev, bool code_loading)
288288

289289
/* program the BDL address */
290290
/* lower BDL address */
291-
snd_hdac_stream_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr);
291+
snd_hdac_stream_writel(azx_dev, SD_BDLPL, (u32)(azx_dev->bdl.addr + bus->addr_offset));
292292
/* upper BDL address */
293293
snd_hdac_stream_writel(azx_dev, SD_BDLPU,
294-
upper_32_bits(azx_dev->bdl.addr));
294+
upper_32_bits(azx_dev->bdl.addr + bus->addr_offset));
295295

296296
/* enable the position buffer */
297297
if (bus->use_posbuf && bus->posbuf.addr) {
298298
if (!(snd_hdac_chip_readl(bus, DPLBASE) & AZX_DPLBASE_ENABLE))
299299
snd_hdac_chip_writel(bus, DPLBASE,
300-
(u32)bus->posbuf.addr | AZX_DPLBASE_ENABLE);
300+
(u32)(bus->posbuf.addr + bus->addr_offset) | AZX_DPLBASE_ENABLE);
301301
}
302302

303303
/* set the interrupt enable bits in the descriptor control register */
@@ -464,8 +464,8 @@ static int setup_bdle(struct hdac_bus *bus,
464464

465465
addr = snd_sgbuf_get_addr(dmab, ofs);
466466
/* program the address field of the BDL entry */
467-
bdl[0] = cpu_to_le32((u32)addr);
468-
bdl[1] = cpu_to_le32(upper_32_bits(addr));
467+
bdl[0] = cpu_to_le32((u32)(addr + bus->addr_offset));
468+
bdl[1] = cpu_to_le32(upper_32_bits(addr + bus->addr_offset));
469469
/* program the size field of the BDL entry */
470470
chunk = snd_sgbuf_get_chunk_size(dmab, ofs, size);
471471
/* one BDLE cannot cross 4K boundary on CTHDA chips */

0 commit comments

Comments
 (0)