aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorPeter Zubaj <pzubaj@marticonet.sk>2015-04-28 15:57:29 -0400
committerTakashi Iwai <tiwai@suse.de>2015-04-29 01:27:30 -0400
commit7241ea558c6715501e777396b5fc312c372e11d9 (patch)
treec42534e1c1f313b32c3f28a3bb324aa6be0a2be1 /sound/pci
parent1c94e65c668f44d2c69ae7e7fc268ab3268fba3e (diff)
ALSA: emu10k1: Emu10k2 32 bit DMA mode
Looks like audigy emu10k2 (probably emu10k1 - sb live too) support two modes for DMA. Second mode is useful for 64 bit os with more then 2 GB of ram (fixes problems with big soundfont loading) 1) 32MB from 2 GB address space using 8192 pages (used now as default) 2) 16MB from 4 GB address space using 4096 pages Mode is set using HCFG_EXPANDED_MEM flag in HCFG register. Also format of emu10k2 page table is then different. Signed-off-by: Peter Zubaj <pzubaj@marticonet.sk> Tested-by: Takashi Iwai <tiwai@suse.de> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c4
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c17
-rw-r--r--sound/pci/emu10k1/emupcm.c2
-rw-r--r--sound/pci/emu10k1/memory.c11
4 files changed, 21 insertions, 13 deletions
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 874cd76c7b7f..d2c7ea3a7610 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -415,7 +415,7 @@ start_voice(struct snd_emux_voice *vp)
415 snd_emu10k1_ptr_write(hw, Z2, ch, 0); 415 snd_emu10k1_ptr_write(hw, Z2, ch, 0);
416 416
417 /* invalidate maps */ 417 /* invalidate maps */
418 temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK; 418 temp = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
419 snd_emu10k1_ptr_write(hw, MAPA, ch, temp); 419 snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
420 snd_emu10k1_ptr_write(hw, MAPB, ch, temp); 420 snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
421#if 0 421#if 0
@@ -436,7 +436,7 @@ start_voice(struct snd_emux_voice *vp)
436 snd_emu10k1_ptr_write(hw, CDF, ch, sample); 436 snd_emu10k1_ptr_write(hw, CDF, ch, sample);
437 437
438 /* invalidate maps */ 438 /* invalidate maps */
439 temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK; 439 temp = ((unsigned int)hw->silent_page.addr << hw_address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
440 snd_emu10k1_ptr_write(hw, MAPA, ch, temp); 440 snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
441 snd_emu10k1_ptr_write(hw, MAPB, ch, temp); 441 snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
442 442
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 4f8cf5e7e45f..a4548147c621 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -282,7 +282,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
282 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ 282 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
283 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */ 283 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
284 284
285 silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK; 285 silent_page = (emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
286 for (ch = 0; ch < NUM_G; ch++) { 286 for (ch = 0; ch < NUM_G; ch++) {
287 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page); 287 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
288 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page); 288 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
@@ -348,6 +348,11 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
348 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); 348 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
349 } 349 }
350 350
351 if (emu->address_mode == 0) {
352 /* use 16M in 4G */
353 outl(inl(emu->port + HCFG) | HCFG_EXPANDED_MEM, emu->port + HCFG);
354 }
355
351 return 0; 356 return 0;
352} 357}
353 358
@@ -1902,8 +1907,10 @@ int snd_emu10k1_create(struct snd_card *card,
1902 1907
1903 is_audigy = emu->audigy = c->emu10k2_chip; 1908 is_audigy = emu->audigy = c->emu10k2_chip;
1904 1909
1910 /* set addressing mode */
1911 emu->address_mode = is_audigy ? 0 : 1;
1905 /* set the DMA transfer mask */ 1912 /* set the DMA transfer mask */
1906 emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK; 1913 emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK;
1907 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 || 1914 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
1908 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) { 1915 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
1909 dev_err(card->dev, 1916 dev_err(card->dev,
@@ -1928,7 +1935,7 @@ int snd_emu10k1_create(struct snd_card *card,
1928 1935
1929 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; 1936 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
1930 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1937 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1931 32 * 1024, &emu->ptb_pages) < 0) { 1938 (emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) {
1932 err = -ENOMEM; 1939 err = -ENOMEM;
1933 goto error; 1940 goto error;
1934 } 1941 }
@@ -2027,8 +2034,8 @@ int snd_emu10k1_create(struct snd_card *card,
2027 2034
2028 /* Clear silent pages and set up pointers */ 2035 /* Clear silent pages and set up pointers */
2029 memset(emu->silent_page.area, 0, PAGE_SIZE); 2036 memset(emu->silent_page.area, 0, PAGE_SIZE);
2030 silent_page = emu->silent_page.addr << 1; 2037 silent_page = emu->silent_page.addr << emu->address_mode;
2031 for (idx = 0; idx < MAXPAGES; idx++) 2038 for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++)
2032 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx); 2039 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
2033 2040
2034 /* set up voice indices */ 2041 /* set up voice indices */
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 0dc07385af0e..14a305bd8a98 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -380,7 +380,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
380 snd_emu10k1_ptr_write(emu, Z1, voice, 0); 380 snd_emu10k1_ptr_write(emu, Z1, voice, 0);
381 snd_emu10k1_ptr_write(emu, Z2, voice, 0); 381 snd_emu10k1_ptr_write(emu, Z2, voice, 0);
382 /* invalidate maps */ 382 /* invalidate maps */
383 silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK; 383 silent_page = ((unsigned int)emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
384 snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page); 384 snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
385 snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page); 385 snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
386 /* modulation envelope */ 386 /* modulation envelope */
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index c68e6dd2fa67..4f1f69be1865 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -34,10 +34,11 @@
34 * aligned pages in others 34 * aligned pages in others
35 */ 35 */
36#define __set_ptb_entry(emu,page,addr) \ 36#define __set_ptb_entry(emu,page,addr) \
37 (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page))) 37 (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page)))
38 38
39#define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE) 39#define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE)
40#define MAX_ALIGN_PAGES (MAXPAGES / UNIT_PAGES) 40#define MAX_ALIGN_PAGES0 (MAXPAGES0 / UNIT_PAGES)
41#define MAX_ALIGN_PAGES1 (MAXPAGES1 / UNIT_PAGES)
41/* get aligned page from offset address */ 42/* get aligned page from offset address */
42#define get_aligned_page(offset) ((offset) >> PAGE_SHIFT) 43#define get_aligned_page(offset) ((offset) >> PAGE_SHIFT)
43/* get offset address from aligned page */ 44/* get offset address from aligned page */
@@ -124,7 +125,7 @@ static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct lis
124 } 125 }
125 page = blk->mapped_page + blk->pages; 126 page = blk->mapped_page + blk->pages;
126 } 127 }
127 size = MAX_ALIGN_PAGES - page; 128 size = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0) - page;
128 if (size >= max_size) { 129 if (size >= max_size) {
129 *nextp = pos; 130 *nextp = pos;
130 return page; 131 return page;
@@ -181,7 +182,7 @@ static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
181 q = get_emu10k1_memblk(p, mapped_link); 182 q = get_emu10k1_memblk(p, mapped_link);
182 end_page = q->mapped_page; 183 end_page = q->mapped_page;
183 } else 184 } else
184 end_page = MAX_ALIGN_PAGES; 185 end_page = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0);
185 186
186 /* remove links */ 187 /* remove links */
187 list_del(&blk->mapped_link); 188 list_del(&blk->mapped_link);
@@ -307,7 +308,7 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
307 if (snd_BUG_ON(!emu)) 308 if (snd_BUG_ON(!emu))
308 return NULL; 309 return NULL;
309 if (snd_BUG_ON(runtime->dma_bytes <= 0 || 310 if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
310 runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE)) 311 runtime->dma_bytes >= (emu->address_mode ? MAXPAGES1 : MAXPAGES0) * EMUPAGESIZE))
311 return NULL; 312 return NULL;
312 hdr = emu->memhdr; 313 hdr = emu->memhdr;
313 if (snd_BUG_ON(!hdr)) 314 if (snd_BUG_ON(!hdr))