Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Joakim Zhang and committed by
Takashi Iwai
a4f2fa51 85a65447

+15 -11
+3
include/sound/hdaudio.h
··· 380 380 381 381 /* factor used to derive STRIPE control value */ 382 382 unsigned int sdo_limit; 383 + 384 + /* address offset between host and hadc */ 385 + dma_addr_t addr_offset; 383 386 }; 384 387 385 388 int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
+1
sound/hda/core/bus.c
··· 47 47 INIT_LIST_HEAD(&bus->hlink_list); 48 48 init_waitqueue_head(&bus->rirb_wq); 49 49 bus->irq = -1; 50 + bus->addr_offset = 0; 50 51 51 52 /* 52 53 * Default value of '8' is as per the HD audio specification (Rev 1.0a).
+6 -6
sound/hda/core/controller.c
··· 48 48 /* CORB set up */ 49 49 bus->corb.addr = bus->rb.addr; 50 50 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)); 53 53 54 54 /* set the corb size to 256 entries (ULI requires explicitly) */ 55 55 snd_hdac_chip_writeb(bus, CORBSIZE, 0x02); ··· 70 70 bus->rirb.buf = (__le32 *)(bus->rb.area + 2048); 71 71 bus->rirb.wp = bus->rirb.rp = 0; 72 72 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)); 75 75 76 76 /* set the rirb size to 256 entries (ULI requires explicitly) */ 77 77 snd_hdac_chip_writeb(bus, RIRBSIZE, 0x02); ··· 625 625 626 626 /* program the position buffer */ 627 627 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)); 630 630 } 631 631 632 632 bus->chip_init = true;
+5 -5
sound/hda/core/stream.c
··· 288 288 289 289 /* program the BDL address */ 290 290 /* 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)); 292 292 /* upper BDL address */ 293 293 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)); 295 295 296 296 /* enable the position buffer */ 297 297 if (bus->use_posbuf && bus->posbuf.addr) { 298 298 if (!(snd_hdac_chip_readl(bus, DPLBASE) & AZX_DPLBASE_ENABLE)) 299 299 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); 301 301 } 302 302 303 303 /* set the interrupt enable bits in the descriptor control register */ ··· 464 464 465 465 addr = snd_sgbuf_get_addr(dmab, ofs); 466 466 /* 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)); 469 469 /* program the size field of the BDL entry */ 470 470 chunk = snd_sgbuf_get_chunk_size(dmab, ofs, size); 471 471 /* one BDLE cannot cross 4K boundary on CTHDA chips */