aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-02-06 08:50:19 -0500
committerTakashi Iwai <tiwai@suse.de>2008-04-24 06:00:08 -0400
commit4ce107b990d994a0fccea9b1e885b08a0daea495 (patch)
treeee2ddb3f4a659c8ec8b004424c3b75ac7e3fc5d0 /sound
parentb76c850fbc280d6c0ff786653915f3a9700b5912 (diff)
[ALSA] hda-intel - Use SG buffer
Use SG buffers for the HD-audio instead of linear buffers. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_intel.c114
1 files changed, 71 insertions, 43 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 18475de074b2..b38a5a70ff08 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -206,8 +206,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
206#define MAX_AZX_DEV 16 206#define MAX_AZX_DEV 16
207 207
208/* max number of fragments - we may use more if allocating more pages for BDL */ 208/* max number of fragments - we may use more if allocating more pages for BDL */
209#define BDL_SIZE PAGE_ALIGN(8192) 209#define BDL_SIZE 4096
210#define AZX_MAX_FRAG (BDL_SIZE / (MAX_AZX_DEV * 16)) 210#define AZX_MAX_BDL_ENTRIES (BDL_SIZE / 16)
211#define AZX_MAX_FRAG 32
211/* max buffer size - no h/w limit, you can increase as you like */ 212/* max buffer size - no h/w limit, you can increase as you like */
212#define AZX_MAX_BUF_SIZE (1024*1024*1024) 213#define AZX_MAX_BUF_SIZE (1024*1024*1024)
213/* max number of PCM devics per card */ 214/* max number of PCM devics per card */
@@ -282,12 +283,10 @@ enum {
282 */ 283 */
283 284
284struct azx_dev { 285struct azx_dev {
285 u32 *bdl; /* virtual address of the BDL */ 286 struct snd_dma_buffer bdl; /* BDL buffer */
286 dma_addr_t bdl_addr; /* physical address of the BDL */
287 u32 *posbuf; /* position buffer pointer */ 287 u32 *posbuf; /* position buffer pointer */
288 288
289 unsigned int bufsize; /* size of the play buffer in bytes */ 289 unsigned int bufsize; /* size of the play buffer in bytes */
290 unsigned int fragsize; /* size of each period in bytes */
291 unsigned int frags; /* number for period in the play buffer */ 290 unsigned int frags; /* number for period in the play buffer */
292 unsigned int fifo_size; /* FIFO size */ 291 unsigned int fifo_size; /* FIFO size */
293 292
@@ -358,8 +357,7 @@ struct azx {
358 struct azx_rb corb; 357 struct azx_rb corb;
359 struct azx_rb rirb; 358 struct azx_rb rirb;
360 359
361 /* BDL, CORB/RIRB and position buffers */ 360 /* CORB/RIRB and position buffers */
362 struct snd_dma_buffer bdl;
363 struct snd_dma_buffer rb; 361 struct snd_dma_buffer rb;
364 struct snd_dma_buffer posbuf; 362 struct snd_dma_buffer posbuf;
365 363
@@ -962,30 +960,57 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
962/* 960/*
963 * set up BDL entries 961 * set up BDL entries
964 */ 962 */
965static void azx_setup_periods(struct azx_dev *azx_dev) 963static int azx_setup_periods(struct snd_pcm_substream *substream,
964 struct azx_dev *azx_dev)
966{ 965{
967 u32 *bdl = azx_dev->bdl; 966 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
968 dma_addr_t dma_addr = azx_dev->substream->runtime->dma_addr; 967 u32 *bdl;
969 int idx; 968 int i, ofs, periods, period_bytes;
970 969
971 /* reset BDL address */ 970 /* reset BDL address */
972 azx_sd_writel(azx_dev, SD_BDLPL, 0); 971 azx_sd_writel(azx_dev, SD_BDLPL, 0);
973 azx_sd_writel(azx_dev, SD_BDLPU, 0); 972 azx_sd_writel(azx_dev, SD_BDLPU, 0);
974 973
974 period_bytes = snd_pcm_lib_period_bytes(substream);
975 periods = azx_dev->bufsize / period_bytes;
976
975 /* program the initial BDL entries */ 977 /* program the initial BDL entries */
976 for (idx = 0; idx < azx_dev->frags; idx++) { 978 bdl = (u32 *)azx_dev->bdl.area;
977 unsigned int off = idx << 2; /* 4 dword step */ 979 ofs = 0;
978 dma_addr_t addr = dma_addr + idx * azx_dev->fragsize; 980 azx_dev->frags = 0;
979 /* program the address field of the BDL entry */ 981 for (i = 0; i < periods; i++) {
980 bdl[off] = cpu_to_le32((u32)addr); 982 int size, rest;
981 bdl[off+1] = cpu_to_le32(upper_32bit(addr)); 983 if (i >= AZX_MAX_BDL_ENTRIES) {
982 984 snd_printk(KERN_ERR "Too many BDL entries: "
983 /* program the size field of the BDL entry */ 985 "buffer=%d, period=%d\n",
984 bdl[off+2] = cpu_to_le32(azx_dev->fragsize); 986 azx_dev->bufsize, period_bytes);
985 987 /* reset */
986 /* program the IOC to enable interrupt when buffer completes */ 988 azx_sd_writel(azx_dev, SD_BDLPL, 0);
987 bdl[off+3] = cpu_to_le32(0x01); 989 azx_sd_writel(azx_dev, SD_BDLPU, 0);
990 return -EINVAL;
991 }
992 rest = period_bytes;
993 do {
994 dma_addr_t addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs);
995 /* program the address field of the BDL entry */
996 bdl[0] = cpu_to_le32((u32)addr);
997 bdl[1] = cpu_to_le32(upper_32bit(addr));
998 /* program the size field of the BDL entry */
999 size = PAGE_SIZE - (ofs % PAGE_SIZE);
1000 if (rest < size)
1001 size = rest;
1002 bdl[2] = cpu_to_le32(size);
1003 /* program the IOC to enable interrupt
1004 * only when the whole fragment is processed
1005 */
1006 rest -= size;
1007 bdl[3] = rest ? 0 : cpu_to_le32(0x01);
1008 bdl += 4;
1009 azx_dev->frags++;
1010 ofs += size;
1011 } while (rest > 0);
988 } 1012 }
1013 return 0;
989} 1014}
990 1015
991/* 1016/*
@@ -1034,9 +1059,9 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1034 1059
1035 /* program the BDL address */ 1060 /* program the BDL address */
1036 /* lower BDL address */ 1061 /* lower BDL address */
1037 azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl_addr); 1062 azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr);
1038 /* upper BDL address */ 1063 /* upper BDL address */
1039 azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr)); 1064 azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl.addr));
1040 1065
1041 /* enable the position buffer */ 1066 /* enable the position buffer */
1042 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) 1067 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
@@ -1272,8 +1297,6 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1272 struct snd_pcm_runtime *runtime = substream->runtime; 1297 struct snd_pcm_runtime *runtime = substream->runtime;
1273 1298
1274 azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream); 1299 azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream);
1275 azx_dev->fragsize = snd_pcm_lib_period_bytes(substream);
1276 azx_dev->frags = azx_dev->bufsize / azx_dev->fragsize;
1277 azx_dev->format_val = snd_hda_calc_stream_format(runtime->rate, 1300 azx_dev->format_val = snd_hda_calc_stream_format(runtime->rate,
1278 runtime->channels, 1301 runtime->channels,
1279 runtime->format, 1302 runtime->format,
@@ -1288,7 +1311,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1288 snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, " 1311 snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, "
1289 "format=0x%x\n", 1312 "format=0x%x\n",
1290 azx_dev->bufsize, azx_dev->fragsize, azx_dev->format_val); 1313 azx_dev->bufsize, azx_dev->fragsize, azx_dev->format_val);
1291 azx_setup_periods(azx_dev); 1314 if (azx_setup_periods(substream, azx_dev) < 0)
1315 return -EINVAL;
1292 azx_setup_controller(chip, azx_dev); 1316 azx_setup_controller(chip, azx_dev);
1293 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1317 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1294 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; 1318 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
@@ -1375,6 +1399,7 @@ static struct snd_pcm_ops azx_pcm_ops = {
1375 .prepare = azx_pcm_prepare, 1399 .prepare = azx_pcm_prepare,
1376 .trigger = azx_pcm_trigger, 1400 .trigger = azx_pcm_trigger,
1377 .pointer = azx_pcm_pointer, 1401 .pointer = azx_pcm_pointer,
1402 .page = snd_pcm_sgbuf_ops_page,
1378}; 1403};
1379 1404
1380static void azx_pcm_free(struct snd_pcm *pcm) 1405static void azx_pcm_free(struct snd_pcm *pcm)
@@ -1417,7 +1442,7 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
1417 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &azx_pcm_ops); 1442 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &azx_pcm_ops);
1418 if (cpcm->stream[1].substreams) 1443 if (cpcm->stream[1].substreams)
1419 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops); 1444 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops);
1420 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1445 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1421 snd_dma_pci_data(chip->pci), 1446 snd_dma_pci_data(chip->pci),
1422 1024 * 64, 1024 * 1024); 1447 1024 * 64, 1024 * 1024);
1423 chip->pcm[cpcm->device] = pcm; 1448 chip->pcm[cpcm->device] = pcm;
@@ -1507,10 +1532,7 @@ static int __devinit azx_init_stream(struct azx *chip)
1507 * and initialize 1532 * and initialize
1508 */ 1533 */
1509 for (i = 0; i < chip->num_streams; i++) { 1534 for (i = 0; i < chip->num_streams; i++) {
1510 unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4);
1511 struct azx_dev *azx_dev = &chip->azx_dev[i]; 1535 struct azx_dev *azx_dev = &chip->azx_dev[i];
1512 azx_dev->bdl = (u32 *)(chip->bdl.area + off);
1513 azx_dev->bdl_addr = chip->bdl.addr + off;
1514 azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8); 1536 azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8);
1515 /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */ 1537 /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
1516 azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); 1538 azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
@@ -1646,8 +1668,9 @@ static int azx_resume(struct pci_dev *pci)
1646 */ 1668 */
1647static int azx_free(struct azx *chip) 1669static int azx_free(struct azx *chip)
1648{ 1670{
1671 int i;
1672
1649 if (chip->initialized) { 1673 if (chip->initialized) {
1650 int i;
1651 for (i = 0; i < chip->num_streams; i++) 1674 for (i = 0; i < chip->num_streams; i++)
1652 azx_stream_stop(chip, &chip->azx_dev[i]); 1675 azx_stream_stop(chip, &chip->azx_dev[i]);
1653 azx_stop_chip(chip); 1676 azx_stop_chip(chip);
@@ -1662,8 +1685,11 @@ static int azx_free(struct azx *chip)
1662 if (chip->remap_addr) 1685 if (chip->remap_addr)
1663 iounmap(chip->remap_addr); 1686 iounmap(chip->remap_addr);
1664 1687
1665 if (chip->bdl.area) 1688 if (chip->azx_dev) {
1666 snd_dma_free_pages(&chip->bdl); 1689 for (i = 0; i < chip->num_streams; i++)
1690 if (chip->azx_dev[i].bdl.area)
1691 snd_dma_free_pages(&chip->azx_dev[i].bdl);
1692 }
1667 if (chip->rb.area) 1693 if (chip->rb.area)
1668 snd_dma_free_pages(&chip->rb); 1694 snd_dma_free_pages(&chip->rb);
1669 if (chip->posbuf.area) 1695 if (chip->posbuf.area)
@@ -1745,7 +1771,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
1745 struct azx **rchip) 1771 struct azx **rchip)
1746{ 1772{
1747 struct azx *chip; 1773 struct azx *chip;
1748 int err; 1774 int i, err;
1749 unsigned short gcap; 1775 unsigned short gcap;
1750 static struct snd_device_ops ops = { 1776 static struct snd_device_ops ops = {
1751 .dev_free = azx_dev_free, 1777 .dev_free = azx_dev_free,
@@ -1857,13 +1883,15 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
1857 goto errout; 1883 goto errout;
1858 } 1884 }
1859 1885
1860 /* allocate memory for the BDL for each stream */ 1886 for (i = 0; i < chip->num_streams; i++) {
1861 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 1887 /* allocate memory for the BDL for each stream */
1862 snd_dma_pci_data(chip->pci), 1888 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
1863 BDL_SIZE, &chip->bdl); 1889 snd_dma_pci_data(chip->pci),
1864 if (err < 0) { 1890 BDL_SIZE, &chip->azx_dev[i].bdl);
1865 snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); 1891 if (err < 0) {
1866 goto errout; 1892 snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
1893 goto errout;
1894 }
1867 } 1895 }
1868 /* allocate memory for the position buffer */ 1896 /* allocate memory for the position buffer */
1869 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 1897 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,