All of lore.kernel.org
 help / color / mirror / Atom feed
* Emu10k2 - support for 32 bit DMA mode
@ 2015-04-26 18:27 Peter Zubaj
  2015-04-27 12:34 ` Takashi Iwai
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Zubaj @ 2015-04-26 18:27 UTC (permalink / raw)
  To: alsa-devel

[-- Attachment #1: Type: text/plain, Size: 588 bytes --]

Hi,

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.

If someone wants to play with it, attached is patch to enable this mode
for audigy. It is tested only on audigy rx (8 GB ram, 64 bit os). 

Regards,
Peter

[-- Attachment #2: audigy_32_bit_am.patch --]
[-- Type: text/x-patch, Size: 7741 bytes --]

diff -ur linux-4.0_orig/include/sound/emu10k1.h linux-4.0/include/sound/emu10k1.h
--- linux-4.0_orig/include/sound/emu10k1.h	2015-04-13 00:12:50.000000000 +0200
+++ linux-4.0/include/sound/emu10k1.h	2015-04-25 22:57:39.984002932 +0200
@@ -41,7 +41,8 @@
 
 #define EMUPAGESIZE     4096
 #define MAXREQVOICES    8
-#define MAXPAGES        8192
+#define MAXPAGES0       4096	/* 32 bit mode */
+#define MAXPAGES1       8192	/* 31 bit mode */
 #define RESERVED        0
 #define NUM_MIDI        16
 #define NUM_G           64              /* use all channels */
@@ -50,8 +51,7 @@
 
 /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
 #define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
-#define AUDIGY_DMA_MASK		0x7fffffffUL	/* 31bit FIXME - 32 should work? */
-						/* See ALSA bug #1276 - rlrevell */
+#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit mode */
 
 #define TMEMSIZE        256*1024
 #define TMEMSIZEREG     4
@@ -466,8 +466,11 @@
 
 #define MAPB			0x0d		/* Cache map B						*/
 
-#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
-#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
+#define MAP_PTE_MASK0		0xfffff000	/* The 20 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK0		0x00000fff	/* The 12 bit index to one of the 4096 PTE dwords      	*/
+
+#define MAP_PTE_MASK1		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK1		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
 
 /* 0x0e, 0x0f: Not used */
 
@@ -1704,6 +1707,7 @@
 	unsigned short model;			/* subsystem id */
 	unsigned int card_type;			/* EMU10K1_CARD_* */
 	unsigned int ecard_ctrl;		/* ecard control bits */
+	unsigned int address_mode;		/* address mode */
 	unsigned long dma_mask;			/* PCI DMA mask */
 	unsigned int delay_pcm_irq;		/* in samples */
 	int max_cache_pages;			/* max memory size / PAGE_SIZE */
diff -ur linux-4.0_orig/sound/pci/emu10k1/emu10k1_callback.c linux-4.0/sound/pci/emu10k1/emu10k1_callback.c
--- linux-4.0_orig/sound/pci/emu10k1/emu10k1_callback.c	2015-04-13 00:12:50.000000000 +0200
+++ linux-4.0/sound/pci/emu10k1/emu10k1_callback.c	2015-04-25 22:12:20.301949674 +0200
@@ -415,7 +415,7 @@
 	snd_emu10k1_ptr_write(hw, Z2, ch, 0);
 
 	/* invalidate maps */
-	temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
+	temp = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 	snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
 	snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
 #if 0
@@ -436,7 +436,7 @@
 		snd_emu10k1_ptr_write(hw, CDF, ch, sample);
 
 		/* invalidate maps */
-		temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
+		temp = ((unsigned int)hw->silent_page.addr << hw_address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 		snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
 		snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
 		
diff -ur linux-4.0_orig/sound/pci/emu10k1/emu10k1_main.c linux-4.0/sound/pci/emu10k1/emu10k1_main.c
--- linux-4.0_orig/sound/pci/emu10k1/emu10k1_main.c	2015-04-13 00:12:50.000000000 +0200
+++ linux-4.0/sound/pci/emu10k1/emu10k1_main.c	2015-04-25 23:25:48.695837022 +0200
@@ -160,7 +160,7 @@
 	unsigned int silent_page;
 	int ch;
 	u32 tmp;
-
+	
 	/* disable audio and lock cache */
 	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
 		HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
@@ -282,7 +282,7 @@
 	snd_emu10k1_ptr_write(emu, TCB, 0, 0);	/* taken from original driver */
 	snd_emu10k1_ptr_write(emu, TCBS, 0, 4);	/* taken from original driver */
 
-	silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
+	silent_page = (emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 	for (ch = 0; ch < NUM_G; ch++) {
 		snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
 		snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
@@ -348,6 +348,11 @@
 		outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
 	}
 
+	if (emu->address_mode == 0) {
+		/* use 16M in 4G */
+		outl(inl(emu->port + HCFG) | HCFG_EXPANDED_MEM, emu->port + HCFG);
+	}
+
 	return 0;
 }
 
@@ -1877,8 +1882,10 @@
 
 	is_audigy = emu->audigy = c->emu10k2_chip;
 
+	/* set addressing mode */
+	emu->address_mode = is_audigy ? 0 : 1;
 	/* set the DMA transfer mask */
-	emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
+	emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK;
 	if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
 	    pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
 		dev_err(card->dev,
@@ -1903,7 +1910,7 @@
 
 	emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-				32 * 1024, &emu->ptb_pages) < 0) {
+				(emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) {
 		err = -ENOMEM;
 		goto error;
 	}
@@ -2002,8 +2009,8 @@
 
 	/* Clear silent pages and set up pointers */
 	memset(emu->silent_page.area, 0, PAGE_SIZE);
-	silent_page = emu->silent_page.addr << 1;
-	for (idx = 0; idx < MAXPAGES; idx++)
+	silent_page = emu->silent_page.addr << emu->address_mode;
+	for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++)
 		((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
 
 	/* set up voice indices */
diff -ur linux-4.0_orig/sound/pci/emu10k1/emupcm.c linux-4.0/sound/pci/emu10k1/emupcm.c
--- linux-4.0_orig/sound/pci/emu10k1/emupcm.c	2015-04-13 00:12:50.000000000 +0200
+++ linux-4.0/sound/pci/emu10k1/emupcm.c	2015-04-25 22:48:39.794353213 +0200
@@ -380,7 +380,7 @@
 	snd_emu10k1_ptr_write(emu, Z1, voice, 0);
 	snd_emu10k1_ptr_write(emu, Z2, voice, 0);
 	/* invalidate maps */
-	silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
+	silent_page = ((unsigned int)emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 	snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
 	snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
 	/* modulation envelope */
diff -ur linux-4.0_orig/sound/pci/emu10k1/memory.c linux-4.0/sound/pci/emu10k1/memory.c
--- linux-4.0_orig/sound/pci/emu10k1/memory.c	2015-04-13 00:12:50.000000000 +0200
+++ linux-4.0/sound/pci/emu10k1/memory.c	2015-04-25 22:55:56.865308462 +0200
@@ -34,10 +34,11 @@
  * aligned pages in others
  */
 #define __set_ptb_entry(emu,page,addr) \
-	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page)))
+	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page)))
 
 #define UNIT_PAGES		(PAGE_SIZE / EMUPAGESIZE)
-#define MAX_ALIGN_PAGES		(MAXPAGES / UNIT_PAGES)
+#define MAX_ALIGN_PAGES0		(MAXPAGES0 / UNIT_PAGES)
+#define MAX_ALIGN_PAGES1		(MAXPAGES1 / UNIT_PAGES)
 /* get aligned page from offset address */
 #define get_aligned_page(offset)	((offset) >> PAGE_SHIFT)
 /* get offset address from aligned page */
@@ -124,7 +125,7 @@
 		}
 		page = blk->mapped_page + blk->pages;
 	}
-	size = MAX_ALIGN_PAGES - page;
+	size = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0) - page;
 	if (size >= max_size) {
 		*nextp = pos;
 		return page;
@@ -181,7 +182,7 @@
 		q = get_emu10k1_memblk(p, mapped_link);
 		end_page = q->mapped_page;
 	} else
-		end_page = MAX_ALIGN_PAGES;
+		end_page = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0);
 
 	/* remove links */
 	list_del(&blk->mapped_link);
@@ -307,7 +308,7 @@
 	if (snd_BUG_ON(!emu))
 		return NULL;
 	if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
-		       runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE))
+		       runtime->dma_bytes >= (emu->address_mode ? MAXPAGES1 : MAXPAGES0) * EMUPAGESIZE))
 		return NULL;
 	hdr = emu->memhdr;
 	if (snd_BUG_ON(!hdr))

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Emu10k2 - support for 32 bit DMA mode
  2015-04-26 18:27 Emu10k2 - support for 32 bit DMA mode Peter Zubaj
@ 2015-04-27 12:34 ` Takashi Iwai
  2015-04-28 20:06   ` Peter Zubaj
  0 siblings, 1 reply; 4+ messages in thread
From: Takashi Iwai @ 2015-04-27 12:34 UTC (permalink / raw)
  To: Peter Zubaj; +Cc: alsa-devel

At Sun, 26 Apr 2015 20:27:50 +0200,
Peter Zubaj wrote:
> 
> Hi,
> 
> 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.
> 
> If someone wants to play with it, attached is patch to enable this mode
> for audigy. It is tested only on audigy rx (8 GB ram, 64 bit os). 

Great, thanks for spotting out this.
I quickly tested an old board and confirmed to work.

The patch looks mostly OK for merge.  Could you give your sign-off
tag?


thanks,

Takashi

> 
> Regards,
> Peter
> diff -ur linux-4.0_orig/include/sound/emu10k1.h linux-4.0/include/sound/emu10k1.h
> --- linux-4.0_orig/include/sound/emu10k1.h	2015-04-13 00:12:50.000000000 +0200
> +++ linux-4.0/include/sound/emu10k1.h	2015-04-25 22:57:39.984002932 +0200
> @@ -41,7 +41,8 @@
>  
>  #define EMUPAGESIZE     4096
>  #define MAXREQVOICES    8
> -#define MAXPAGES        8192
> +#define MAXPAGES0       4096	/* 32 bit mode */
> +#define MAXPAGES1       8192	/* 31 bit mode */
>  #define RESERVED        0
>  #define NUM_MIDI        16
>  #define NUM_G           64              /* use all channels */
> @@ -50,8 +51,7 @@
>  
>  /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
>  #define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
> -#define AUDIGY_DMA_MASK		0x7fffffffUL	/* 31bit FIXME - 32 should work? */
> -						/* See ALSA bug #1276 - rlrevell */
> +#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit mode */
>  
>  #define TMEMSIZE        256*1024
>  #define TMEMSIZEREG     4
> @@ -466,8 +466,11 @@
>  
>  #define MAPB			0x0d		/* Cache map B						*/
>  
> -#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
> -#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
> +#define MAP_PTE_MASK0		0xfffff000	/* The 20 MSBs of the PTE indexed by the PTI		*/
> +#define MAP_PTI_MASK0		0x00000fff	/* The 12 bit index to one of the 4096 PTE dwords      	*/
> +
> +#define MAP_PTE_MASK1		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
> +#define MAP_PTI_MASK1		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
>  
>  /* 0x0e, 0x0f: Not used */
>  
> @@ -1704,6 +1707,7 @@
>  	unsigned short model;			/* subsystem id */
>  	unsigned int card_type;			/* EMU10K1_CARD_* */
>  	unsigned int ecard_ctrl;		/* ecard control bits */
> +	unsigned int address_mode;		/* address mode */
>  	unsigned long dma_mask;			/* PCI DMA mask */
>  	unsigned int delay_pcm_irq;		/* in samples */
>  	int max_cache_pages;			/* max memory size / PAGE_SIZE */
> diff -ur linux-4.0_orig/sound/pci/emu10k1/emu10k1_callback.c linux-4.0/sound/pci/emu10k1/emu10k1_callback.c
> --- linux-4.0_orig/sound/pci/emu10k1/emu10k1_callback.c	2015-04-13 00:12:50.000000000 +0200
> +++ linux-4.0/sound/pci/emu10k1/emu10k1_callback.c	2015-04-25 22:12:20.301949674 +0200
> @@ -415,7 +415,7 @@
>  	snd_emu10k1_ptr_write(hw, Z2, ch, 0);
>  
>  	/* invalidate maps */
> -	temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
> +	temp = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
>  	snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
>  	snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
>  #if 0
> @@ -436,7 +436,7 @@
>  		snd_emu10k1_ptr_write(hw, CDF, ch, sample);
>  
>  		/* invalidate maps */
> -		temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
> +		temp = ((unsigned int)hw->silent_page.addr << hw_address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
>  		snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
>  		snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
>  		
> diff -ur linux-4.0_orig/sound/pci/emu10k1/emu10k1_main.c linux-4.0/sound/pci/emu10k1/emu10k1_main.c
> --- linux-4.0_orig/sound/pci/emu10k1/emu10k1_main.c	2015-04-13 00:12:50.000000000 +0200
> +++ linux-4.0/sound/pci/emu10k1/emu10k1_main.c	2015-04-25 23:25:48.695837022 +0200
> @@ -160,7 +160,7 @@
>  	unsigned int silent_page;
>  	int ch;
>  	u32 tmp;
> -
> +	
>  	/* disable audio and lock cache */
>  	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
>  		HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
> @@ -282,7 +282,7 @@
>  	snd_emu10k1_ptr_write(emu, TCB, 0, 0);	/* taken from original driver */
>  	snd_emu10k1_ptr_write(emu, TCBS, 0, 4);	/* taken from original driver */
>  
> -	silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
> +	silent_page = (emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
>  	for (ch = 0; ch < NUM_G; ch++) {
>  		snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
>  		snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
> @@ -348,6 +348,11 @@
>  		outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
>  	}
>  
> +	if (emu->address_mode == 0) {
> +		/* use 16M in 4G */
> +		outl(inl(emu->port + HCFG) | HCFG_EXPANDED_MEM, emu->port + HCFG);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -1877,8 +1882,10 @@
>  
>  	is_audigy = emu->audigy = c->emu10k2_chip;
>  
> +	/* set addressing mode */
> +	emu->address_mode = is_audigy ? 0 : 1;
>  	/* set the DMA transfer mask */
> -	emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
> +	emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK;
>  	if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
>  	    pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
>  		dev_err(card->dev,
> @@ -1903,7 +1910,7 @@
>  
>  	emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
>  	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
> -				32 * 1024, &emu->ptb_pages) < 0) {
> +				(emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) {
>  		err = -ENOMEM;
>  		goto error;
>  	}
> @@ -2002,8 +2009,8 @@
>  
>  	/* Clear silent pages and set up pointers */
>  	memset(emu->silent_page.area, 0, PAGE_SIZE);
> -	silent_page = emu->silent_page.addr << 1;
> -	for (idx = 0; idx < MAXPAGES; idx++)
> +	silent_page = emu->silent_page.addr << emu->address_mode;
> +	for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++)
>  		((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
>  
>  	/* set up voice indices */
> diff -ur linux-4.0_orig/sound/pci/emu10k1/emupcm.c linux-4.0/sound/pci/emu10k1/emupcm.c
> --- linux-4.0_orig/sound/pci/emu10k1/emupcm.c	2015-04-13 00:12:50.000000000 +0200
> +++ linux-4.0/sound/pci/emu10k1/emupcm.c	2015-04-25 22:48:39.794353213 +0200
> @@ -380,7 +380,7 @@
>  	snd_emu10k1_ptr_write(emu, Z1, voice, 0);
>  	snd_emu10k1_ptr_write(emu, Z2, voice, 0);
>  	/* invalidate maps */
> -	silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
> +	silent_page = ((unsigned int)emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
>  	snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
>  	snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
>  	/* modulation envelope */
> diff -ur linux-4.0_orig/sound/pci/emu10k1/memory.c linux-4.0/sound/pci/emu10k1/memory.c
> --- linux-4.0_orig/sound/pci/emu10k1/memory.c	2015-04-13 00:12:50.000000000 +0200
> +++ linux-4.0/sound/pci/emu10k1/memory.c	2015-04-25 22:55:56.865308462 +0200
> @@ -34,10 +34,11 @@
>   * aligned pages in others
>   */
>  #define __set_ptb_entry(emu,page,addr) \
> -	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page)))
> +	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page)))
>  
>  #define UNIT_PAGES		(PAGE_SIZE / EMUPAGESIZE)
> -#define MAX_ALIGN_PAGES		(MAXPAGES / UNIT_PAGES)
> +#define MAX_ALIGN_PAGES0		(MAXPAGES0 / UNIT_PAGES)
> +#define MAX_ALIGN_PAGES1		(MAXPAGES1 / UNIT_PAGES)
>  /* get aligned page from offset address */
>  #define get_aligned_page(offset)	((offset) >> PAGE_SHIFT)
>  /* get offset address from aligned page */
> @@ -124,7 +125,7 @@
>  		}
>  		page = blk->mapped_page + blk->pages;
>  	}
> -	size = MAX_ALIGN_PAGES - page;
> +	size = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0) - page;
>  	if (size >= max_size) {
>  		*nextp = pos;
>  		return page;
> @@ -181,7 +182,7 @@
>  		q = get_emu10k1_memblk(p, mapped_link);
>  		end_page = q->mapped_page;
>  	} else
> -		end_page = MAX_ALIGN_PAGES;
> +		end_page = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0);
>  
>  	/* remove links */
>  	list_del(&blk->mapped_link);
> @@ -307,7 +308,7 @@
>  	if (snd_BUG_ON(!emu))
>  		return NULL;
>  	if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
> -		       runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE))
> +		       runtime->dma_bytes >= (emu->address_mode ? MAXPAGES1 : MAXPAGES0) * EMUPAGESIZE))
>  		return NULL;
>  	hdr = emu->memhdr;
>  	if (snd_BUG_ON(!hdr))
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Emu10k2 - support for 32 bit DMA mode
  2015-04-27 12:34 ` Takashi Iwai
@ 2015-04-28 20:06   ` Peter Zubaj
  2015-04-29  5:50     ` Takashi Iwai
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Zubaj @ 2015-04-28 20:06 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

[-- Attachment #1: Type: text/plain, Size: 9712 bytes --]

Hi,

I am not sure, if this is what you want.

Regards,
Peter

On Mon, 2015-04-27 at 14:34 +0200, Takashi Iwai wrote:
> At Sun, 26 Apr 2015 20:27:50 +0200,
> Peter Zubaj wrote:
> > 
> > Hi,
> > 
> > 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.
> > 
> > If someone wants to play with it, attached is patch to enable this mode
> > for audigy. It is tested only on audigy rx (8 GB ram, 64 bit os). 
> 
> Great, thanks for spotting out this.
> I quickly tested an old board and confirmed to work.
> 
> The patch looks mostly OK for merge.  Could you give your sign-off
> tag?
> 
> 
> thanks,
> 
> Takashi
> 
> > 
> > Regards,
> > Peter
> > diff -ur linux-4.0_orig/include/sound/emu10k1.h linux-4.0/include/sound/emu10k1.h
> > --- linux-4.0_orig/include/sound/emu10k1.h	2015-04-13 00:12:50.000000000 +0200
> > +++ linux-4.0/include/sound/emu10k1.h	2015-04-25 22:57:39.984002932 +0200
> > @@ -41,7 +41,8 @@
> >  
> >  #define EMUPAGESIZE     4096
> >  #define MAXREQVOICES    8
> > -#define MAXPAGES        8192
> > +#define MAXPAGES0       4096	/* 32 bit mode */
> > +#define MAXPAGES1       8192	/* 31 bit mode */
> >  #define RESERVED        0
> >  #define NUM_MIDI        16
> >  #define NUM_G           64              /* use all channels */
> > @@ -50,8 +51,7 @@
> >  
> >  /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
> >  #define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
> > -#define AUDIGY_DMA_MASK		0x7fffffffUL	/* 31bit FIXME - 32 should work? */
> > -						/* See ALSA bug #1276 - rlrevell */
> > +#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit mode */
> >  
> >  #define TMEMSIZE        256*1024
> >  #define TMEMSIZEREG     4
> > @@ -466,8 +466,11 @@
> >  
> >  #define MAPB			0x0d		/* Cache map B						*/
> >  
> > -#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
> > -#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
> > +#define MAP_PTE_MASK0		0xfffff000	/* The 20 MSBs of the PTE indexed by the PTI		*/
> > +#define MAP_PTI_MASK0		0x00000fff	/* The 12 bit index to one of the 4096 PTE dwords      	*/
> > +
> > +#define MAP_PTE_MASK1		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
> > +#define MAP_PTI_MASK1		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
> >  
> >  /* 0x0e, 0x0f: Not used */
> >  
> > @@ -1704,6 +1707,7 @@
> >  	unsigned short model;			/* subsystem id */
> >  	unsigned int card_type;			/* EMU10K1_CARD_* */
> >  	unsigned int ecard_ctrl;		/* ecard control bits */
> > +	unsigned int address_mode;		/* address mode */
> >  	unsigned long dma_mask;			/* PCI DMA mask */
> >  	unsigned int delay_pcm_irq;		/* in samples */
> >  	int max_cache_pages;			/* max memory size / PAGE_SIZE */
> > diff -ur linux-4.0_orig/sound/pci/emu10k1/emu10k1_callback.c linux-4.0/sound/pci/emu10k1/emu10k1_callback.c
> > --- linux-4.0_orig/sound/pci/emu10k1/emu10k1_callback.c	2015-04-13 00:12:50.000000000 +0200
> > +++ linux-4.0/sound/pci/emu10k1/emu10k1_callback.c	2015-04-25 22:12:20.301949674 +0200
> > @@ -415,7 +415,7 @@
> >  	snd_emu10k1_ptr_write(hw, Z2, ch, 0);
> >  
> >  	/* invalidate maps */
> > -	temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
> > +	temp = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
> >  	snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
> >  	snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
> >  #if 0
> > @@ -436,7 +436,7 @@
> >  		snd_emu10k1_ptr_write(hw, CDF, ch, sample);
> >  
> >  		/* invalidate maps */
> > -		temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
> > +		temp = ((unsigned int)hw->silent_page.addr << hw_address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
> >  		snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
> >  		snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
> >  		
> > diff -ur linux-4.0_orig/sound/pci/emu10k1/emu10k1_main.c linux-4.0/sound/pci/emu10k1/emu10k1_main.c
> > --- linux-4.0_orig/sound/pci/emu10k1/emu10k1_main.c	2015-04-13 00:12:50.000000000 +0200
> > +++ linux-4.0/sound/pci/emu10k1/emu10k1_main.c	2015-04-25 23:25:48.695837022 +0200
> > @@ -160,7 +160,7 @@
> >  	unsigned int silent_page;
> >  	int ch;
> >  	u32 tmp;
> > -
> > +	
> >  	/* disable audio and lock cache */
> >  	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
> >  		HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
> > @@ -282,7 +282,7 @@
> >  	snd_emu10k1_ptr_write(emu, TCB, 0, 0);	/* taken from original driver */
> >  	snd_emu10k1_ptr_write(emu, TCBS, 0, 4);	/* taken from original driver */
> >  
> > -	silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
> > +	silent_page = (emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
> >  	for (ch = 0; ch < NUM_G; ch++) {
> >  		snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
> >  		snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
> > @@ -348,6 +348,11 @@
> >  		outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
> >  	}
> >  
> > +	if (emu->address_mode == 0) {
> > +		/* use 16M in 4G */
> > +		outl(inl(emu->port + HCFG) | HCFG_EXPANDED_MEM, emu->port + HCFG);
> > +	}
> > +
> >  	return 0;
> >  }
> >  
> > @@ -1877,8 +1882,10 @@
> >  
> >  	is_audigy = emu->audigy = c->emu10k2_chip;
> >  
> > +	/* set addressing mode */
> > +	emu->address_mode = is_audigy ? 0 : 1;
> >  	/* set the DMA transfer mask */
> > -	emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
> > +	emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK;
> >  	if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
> >  	    pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
> >  		dev_err(card->dev,
> > @@ -1903,7 +1910,7 @@
> >  
> >  	emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
> >  	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
> > -				32 * 1024, &emu->ptb_pages) < 0) {
> > +				(emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) {
> >  		err = -ENOMEM;
> >  		goto error;
> >  	}
> > @@ -2002,8 +2009,8 @@
> >  
> >  	/* Clear silent pages and set up pointers */
> >  	memset(emu->silent_page.area, 0, PAGE_SIZE);
> > -	silent_page = emu->silent_page.addr << 1;
> > -	for (idx = 0; idx < MAXPAGES; idx++)
> > +	silent_page = emu->silent_page.addr << emu->address_mode;
> > +	for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++)
> >  		((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
> >  
> >  	/* set up voice indices */
> > diff -ur linux-4.0_orig/sound/pci/emu10k1/emupcm.c linux-4.0/sound/pci/emu10k1/emupcm.c
> > --- linux-4.0_orig/sound/pci/emu10k1/emupcm.c	2015-04-13 00:12:50.000000000 +0200
> > +++ linux-4.0/sound/pci/emu10k1/emupcm.c	2015-04-25 22:48:39.794353213 +0200
> > @@ -380,7 +380,7 @@
> >  	snd_emu10k1_ptr_write(emu, Z1, voice, 0);
> >  	snd_emu10k1_ptr_write(emu, Z2, voice, 0);
> >  	/* invalidate maps */
> > -	silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
> > +	silent_page = ((unsigned int)emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
> >  	snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
> >  	snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
> >  	/* modulation envelope */
> > diff -ur linux-4.0_orig/sound/pci/emu10k1/memory.c linux-4.0/sound/pci/emu10k1/memory.c
> > --- linux-4.0_orig/sound/pci/emu10k1/memory.c	2015-04-13 00:12:50.000000000 +0200
> > +++ linux-4.0/sound/pci/emu10k1/memory.c	2015-04-25 22:55:56.865308462 +0200
> > @@ -34,10 +34,11 @@
> >   * aligned pages in others
> >   */
> >  #define __set_ptb_entry(emu,page,addr) \
> > -	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page)))
> > +	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page)))
> >  
> >  #define UNIT_PAGES		(PAGE_SIZE / EMUPAGESIZE)
> > -#define MAX_ALIGN_PAGES		(MAXPAGES / UNIT_PAGES)
> > +#define MAX_ALIGN_PAGES0		(MAXPAGES0 / UNIT_PAGES)
> > +#define MAX_ALIGN_PAGES1		(MAXPAGES1 / UNIT_PAGES)
> >  /* get aligned page from offset address */
> >  #define get_aligned_page(offset)	((offset) >> PAGE_SHIFT)
> >  /* get offset address from aligned page */
> > @@ -124,7 +125,7 @@
> >  		}
> >  		page = blk->mapped_page + blk->pages;
> >  	}
> > -	size = MAX_ALIGN_PAGES - page;
> > +	size = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0) - page;
> >  	if (size >= max_size) {
> >  		*nextp = pos;
> >  		return page;
> > @@ -181,7 +182,7 @@
> >  		q = get_emu10k1_memblk(p, mapped_link);
> >  		end_page = q->mapped_page;
> >  	} else
> > -		end_page = MAX_ALIGN_PAGES;
> > +		end_page = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0);
> >  
> >  	/* remove links */
> >  	list_del(&blk->mapped_link);
> > @@ -307,7 +308,7 @@
> >  	if (snd_BUG_ON(!emu))
> >  		return NULL;
> >  	if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
> > -		       runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE))
> > +		       runtime->dma_bytes >= (emu->address_mode ? MAXPAGES1 : MAXPAGES0) * EMUPAGESIZE))
> >  		return NULL;
> >  	hdr = emu->memhdr;
> >  	if (snd_BUG_ON(!hdr))
> > _______________________________________________
> > Alsa-devel mailing list
> > Alsa-devel@alsa-project.org
> > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel


[-- Attachment #2: 0001-ALSA-Emu10k2-32-bit-DMA-mode.patch --]
[-- Type: text/x-patch, Size: 9129 bytes --]

From 74c6711fb90f235a5578d5d3342f14eeac8367a9 Mon Sep 17 00:00:00 2001
From: Peter Zubaj <pzubaj@marticonet.sk>
Date: Tue, 28 Apr 2015 21:57:29 +0200
Subject: [PATCH] ALSA: 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>
---
 include/sound/emu10k1.h              | 14 +++++++++-----
 sound/pci/emu10k1/emu10k1_callback.c |  4 ++--
 sound/pci/emu10k1/emu10k1_main.c     | 19 +++++++++++++------
 sound/pci/emu10k1/emupcm.c           |  2 +-
 sound/pci/emu10k1/memory.c           | 11 ++++++-----
 5 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 0de95cc..5bd1346 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -41,7 +41,8 @@
 
 #define EMUPAGESIZE     4096
 #define MAXREQVOICES    8
-#define MAXPAGES        8192
+#define MAXPAGES0       4096	/* 32 bit mode */
+#define MAXPAGES1       8192	/* 31 bit mode */
 #define RESERVED        0
 #define NUM_MIDI        16
 #define NUM_G           64              /* use all channels */
@@ -50,8 +51,7 @@
 
 /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
 #define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
-#define AUDIGY_DMA_MASK		0x7fffffffUL	/* 31bit FIXME - 32 should work? */
-						/* See ALSA bug #1276 - rlrevell */
+#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit mode */
 
 #define TMEMSIZE        256*1024
 #define TMEMSIZEREG     4
@@ -466,8 +466,11 @@
 
 #define MAPB			0x0d		/* Cache map B						*/
 
-#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
-#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
+#define MAP_PTE_MASK0		0xfffff000	/* The 20 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK0		0x00000fff	/* The 12 bit index to one of the 4096 PTE dwords      	*/
+
+#define MAP_PTE_MASK1		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK1		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
 
 /* 0x0e, 0x0f: Not used */
 
@@ -1704,6 +1707,7 @@ struct snd_emu10k1 {
 	unsigned short model;			/* subsystem id */
 	unsigned int card_type;			/* EMU10K1_CARD_* */
 	unsigned int ecard_ctrl;		/* ecard control bits */
+	unsigned int address_mode;		/* address mode */
 	unsigned long dma_mask;			/* PCI DMA mask */
 	unsigned int delay_pcm_irq;		/* in samples */
 	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 874cd76..d2c7ea3 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)
 	snd_emu10k1_ptr_write(hw, Z2, ch, 0);
 
 	/* invalidate maps */
-	temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
+	temp = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 	snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
 	snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
 #if 0
@@ -436,7 +436,7 @@ start_voice(struct snd_emux_voice *vp)
 		snd_emu10k1_ptr_write(hw, CDF, ch, sample);
 
 		/* invalidate maps */
-		temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
+		temp = ((unsigned int)hw->silent_page.addr << hw_address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 		snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
 		snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
 		
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 54079f5..b4f7f3e 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -160,7 +160,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
 	unsigned int silent_page;
 	int ch;
 	u32 tmp;
-
+	
 	/* disable audio and lock cache */
 	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
 		HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
@@ -282,7 +282,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
 	snd_emu10k1_ptr_write(emu, TCB, 0, 0);	/* taken from original driver */
 	snd_emu10k1_ptr_write(emu, TCBS, 0, 4);	/* taken from original driver */
 
-	silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
+	silent_page = (emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 	for (ch = 0; ch < NUM_G; ch++) {
 		snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
 		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)
 		outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
 	}
 
+	if (emu->address_mode == 0) {
+		/* use 16M in 4G */
+		outl(inl(emu->port + HCFG) | HCFG_EXPANDED_MEM, emu->port + HCFG);
+	}
+
 	return 0;
 }
 
@@ -1902,8 +1907,10 @@ int snd_emu10k1_create(struct snd_card *card,
 
 	is_audigy = emu->audigy = c->emu10k2_chip;
 
+	/* set addressing mode */
+	emu->address_mode = is_audigy ? 0 : 1;
 	/* set the DMA transfer mask */
-	emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
+	emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK;
 	if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
 	    pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
 		dev_err(card->dev,
@@ -1928,7 +1935,7 @@ int snd_emu10k1_create(struct snd_card *card,
 
 	emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-				32 * 1024, &emu->ptb_pages) < 0) {
+				(emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) {
 		err = -ENOMEM;
 		goto error;
 	}
@@ -2027,8 +2034,8 @@ int snd_emu10k1_create(struct snd_card *card,
 
 	/* Clear silent pages and set up pointers */
 	memset(emu->silent_page.area, 0, PAGE_SIZE);
-	silent_page = emu->silent_page.addr << 1;
-	for (idx = 0; idx < MAXPAGES; idx++)
+	silent_page = emu->silent_page.addr << emu->address_mode;
+	for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++)
 		((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
 
 	/* set up voice indices */
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 0dc0738..14a305b 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,
 	snd_emu10k1_ptr_write(emu, Z1, voice, 0);
 	snd_emu10k1_ptr_write(emu, Z2, voice, 0);
 	/* invalidate maps */
-	silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
+	silent_page = ((unsigned int)emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
 	snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
 	snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
 	/* modulation envelope */
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index c68e6dd..4f1f69b 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -34,10 +34,11 @@
  * aligned pages in others
  */
 #define __set_ptb_entry(emu,page,addr) \
-	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page)))
+	(((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page)))
 
 #define UNIT_PAGES		(PAGE_SIZE / EMUPAGESIZE)
-#define MAX_ALIGN_PAGES		(MAXPAGES / UNIT_PAGES)
+#define MAX_ALIGN_PAGES0		(MAXPAGES0 / UNIT_PAGES)
+#define MAX_ALIGN_PAGES1		(MAXPAGES1 / UNIT_PAGES)
 /* get aligned page from offset address */
 #define get_aligned_page(offset)	((offset) >> PAGE_SHIFT)
 /* get offset address from aligned page */
@@ -124,7 +125,7 @@ static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct lis
 		}
 		page = blk->mapped_page + blk->pages;
 	}
-	size = MAX_ALIGN_PAGES - page;
+	size = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0) - page;
 	if (size >= max_size) {
 		*nextp = pos;
 		return page;
@@ -181,7 +182,7 @@ static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 		q = get_emu10k1_memblk(p, mapped_link);
 		end_page = q->mapped_page;
 	} else
-		end_page = MAX_ALIGN_PAGES;
+		end_page = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0);
 
 	/* remove links */
 	list_del(&blk->mapped_link);
@@ -307,7 +308,7 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
 	if (snd_BUG_ON(!emu))
 		return NULL;
 	if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
-		       runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE))
+		       runtime->dma_bytes >= (emu->address_mode ? MAXPAGES1 : MAXPAGES0) * EMUPAGESIZE))
 		return NULL;
 	hdr = emu->memhdr;
 	if (snd_BUG_ON(!hdr))
-- 
2.1.0


[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: Emu10k2 - support for 32 bit DMA mode
  2015-04-28 20:06   ` Peter Zubaj
@ 2015-04-29  5:50     ` Takashi Iwai
  0 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2015-04-29  5:50 UTC (permalink / raw)
  To: Peter Zubaj; +Cc: alsa-devel

At Tue, 28 Apr 2015 22:06:08 +0200,
Peter Zubaj wrote:
> 
> Hi,
> 
> I am not sure, if this is what you want.

That's fine.  Now I merged with Cc to stable.

Thanks!


Takashi

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-04-29  5:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-26 18:27 Emu10k2 - support for 32 bit DMA mode Peter Zubaj
2015-04-27 12:34 ` Takashi Iwai
2015-04-28 20:06   ` Peter Zubaj
2015-04-29  5:50     ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.