diff options
author | Peter Zubaj <pzubaj@marticonet.sk> | 2015-04-28 15:57:29 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-04-29 01:27:30 -0400 |
commit | 7241ea558c6715501e777396b5fc312c372e11d9 (patch) | |
tree | c42534e1c1f313b32c3f28a3bb324aa6be0a2be1 | |
parent | 1c94e65c668f44d2c69ae7e7fc268ab3268fba3e (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>
-rw-r--r-- | include/sound/emu10k1.h | 14 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_callback.c | 4 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 17 | ||||
-rw-r--r-- | sound/pci/emu10k1/emupcm.c | 2 | ||||
-rw-r--r-- | sound/pci/emu10k1/memory.c | 11 |
5 files changed, 30 insertions, 18 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 0de95ccb92cf..5bd134651f5e 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -41,7 +41,8 @@ | |||
41 | 41 | ||
42 | #define EMUPAGESIZE 4096 | 42 | #define EMUPAGESIZE 4096 |
43 | #define MAXREQVOICES 8 | 43 | #define MAXREQVOICES 8 |
44 | #define MAXPAGES 8192 | 44 | #define MAXPAGES0 4096 /* 32 bit mode */ |
45 | #define MAXPAGES1 8192 /* 31 bit mode */ | ||
45 | #define RESERVED 0 | 46 | #define RESERVED 0 |
46 | #define NUM_MIDI 16 | 47 | #define NUM_MIDI 16 |
47 | #define NUM_G 64 /* use all channels */ | 48 | #define NUM_G 64 /* use all channels */ |
@@ -50,8 +51,7 @@ | |||
50 | 51 | ||
51 | /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */ | 52 | /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */ |
52 | #define EMU10K1_DMA_MASK 0x7fffffffUL /* 31bit */ | 53 | #define EMU10K1_DMA_MASK 0x7fffffffUL /* 31bit */ |
53 | #define AUDIGY_DMA_MASK 0x7fffffffUL /* 31bit FIXME - 32 should work? */ | 54 | #define AUDIGY_DMA_MASK 0xffffffffUL /* 32bit mode */ |
54 | /* See ALSA bug #1276 - rlrevell */ | ||
55 | 55 | ||
56 | #define TMEMSIZE 256*1024 | 56 | #define TMEMSIZE 256*1024 |
57 | #define TMEMSIZEREG 4 | 57 | #define TMEMSIZEREG 4 |
@@ -466,8 +466,11 @@ | |||
466 | 466 | ||
467 | #define MAPB 0x0d /* Cache map B */ | 467 | #define MAPB 0x0d /* Cache map B */ |
468 | 468 | ||
469 | #define MAP_PTE_MASK 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */ | 469 | #define MAP_PTE_MASK0 0xfffff000 /* The 20 MSBs of the PTE indexed by the PTI */ |
470 | #define MAP_PTI_MASK 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */ | 470 | #define MAP_PTI_MASK0 0x00000fff /* The 12 bit index to one of the 4096 PTE dwords */ |
471 | |||
472 | #define MAP_PTE_MASK1 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */ | ||
473 | #define MAP_PTI_MASK1 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */ | ||
471 | 474 | ||
472 | /* 0x0e, 0x0f: Not used */ | 475 | /* 0x0e, 0x0f: Not used */ |
473 | 476 | ||
@@ -1704,6 +1707,7 @@ struct snd_emu10k1 { | |||
1704 | unsigned short model; /* subsystem id */ | 1707 | unsigned short model; /* subsystem id */ |
1705 | unsigned int card_type; /* EMU10K1_CARD_* */ | 1708 | unsigned int card_type; /* EMU10K1_CARD_* */ |
1706 | unsigned int ecard_ctrl; /* ecard control bits */ | 1709 | unsigned int ecard_ctrl; /* ecard control bits */ |
1710 | unsigned int address_mode; /* address mode */ | ||
1707 | unsigned long dma_mask; /* PCI DMA mask */ | 1711 | unsigned long dma_mask; /* PCI DMA mask */ |
1708 | unsigned int delay_pcm_irq; /* in samples */ | 1712 | unsigned int delay_pcm_irq; /* in samples */ |
1709 | int max_cache_pages; /* max memory size / PAGE_SIZE */ | 1713 | int max_cache_pages; /* max memory size / PAGE_SIZE */ |
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)) |