/*
 *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
 *  Copyright (c) by Takashi Iwai <tiwai@suse.de>
 *  Copyright (c) by Scott McNab <sdm@fractalgraphics.com.au>
 *
 *  Trident 4DWave-NX memory page allocation (TLB area)
 *  Trident chip can handle only 16MByte of the memory at the same time.
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <sound/driver.h>
#include <asm/io.h>
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/mutex.h>

#include <sound/core.h>
#include <sound/trident.h>

/* page arguments of these two macros are Trident page (4096 bytes), not like
 * aligned pages in others
 */
#define __set_tlb_bus(trident,page,ptr,addr) \
	do { (trident)->tlb.entries[page] = cpu_to_le32((addr) & ~(SNDRV_TRIDENT_PAGE_SIZE-1)); \
	     (trident)->tlb.shadow_entries[page] = (ptr); } while (0)
#define __tlb_to_ptr(trident,page) \
	(void*)((trident)->tlb.shadow_entries[page])
#define __tlb_to_addr(trident,page) \
	(dma_addr_t)le32_to_cpu((trident->tlb.entries[page]) & ~(SNDRV_TRIDENT_PAGE_SIZE - 1))

#if PAGE_SIZE == 4096
/* page size == SNDRV_TRIDENT_PAGE_SIZE */
#define ALIGN_PAGE_SIZE		PAGE_SIZE	/* minimum page size for allocation */
#define MAX_ALIGN_PAGES		SNDRV_TRIDENT_MAX_PAGES	/* maxmium aligned pages */
/* fill TLB entrie(s) corresponding to page with ptr */
#define set_tlb_bus(trident,page,ptr,addr) __set_tlb_bus(trident,page,ptr,addr)
/* fill TLB entrie(s) corresponding to page with silence pointer */
#define set_silent_tlb(trident,page)	__set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr)
/* get aligned page from offset address */
#define get_aligned_page(offset)	((offset) >> 12)
/* get offset address from aligned page */
#define aligned_page_offset(page)	((page) << 12)
/* get buffer address from aligned page */
#define page_to_ptr(trident,page)	__tlb_to_ptr(trident, page)
/* get PCI physical address from aligned page */
#define page_to_addr(trident,page)	__tlb_to_addr(trident, page)

#elif PAGE_SIZE == 8192
/* page size == SNDRV_TRIDENT_PAGE_SIZE x 2*/
#define ALIGN_PAGE_SIZE		PAGE_SIZE
#define MAX_ALIGN_PAGES		(SNDRV_TRIDENT_MAX_PAGES / 2)
#define get_aligned_page(offset)	((offset) >> 13)
#define aligned_page_offset(page)	((page) << 13)
#define page_to_ptr(trident,page)	__tlb_to_ptr(trident, (page) << 1)
#define page_to_addr(trident,page)	__tlb_to_addr(trident, (page) << 1)

/* fill TLB entries -- we need to fill two entries */
static inline void set_tlb_bus(struct snd_trident *trident, int page,
			       unsigned long ptr, dma_addr_t addr)
{
	page <<= 1;
	__set_tlb_bus(trident, page, ptr, addr);
	__set_tlb_bus(trident, page+1, ptr + SNDRV_TRIDENT_PAGE_SIZE, addr + SNDRV_TRIDENT_PAGE_SIZE);
}
static inline void set_silent_tlb(struct snd_trident *trident, int page)
{
	page <<= 1;
	__set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
	__set_tlb_bus(trident, page+1, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
}

#else
/* arbitrary size */
#define UNIT_PAGES		(PAGE_SIZE / SNDRV_TRIDENT_PAGE_SIZE)
#define ALIGN_PAGE_SIZE		(SNDRV_TRIDENT_PAGE_SIZE * UNIT_PAGES)
#define MAX_ALIGN_PAGES		(SNDRV_TRIDENT_MAX_PAGES / UNIT_PAGES)
/* Note: if alignment doesn't match to the maximum size, the last few blocks
 * become unusable.  To use such blocks, you'll need to check the validity
 * of accessing page in set_tlb_bus and set_silent_tlb.  search_empty()
 * should also check it, too.
 */
#define get_aligned_page(offset)	((offset) / ALIGN_PAGE_SIZE)
#define aligned_page_offset(page)	((page) * ALIGN_PAGE_SIZE)
#define page_to_ptr(trident,page)	__tlb_to_ptr(trident, (page) * UNIT_PAGES)
#define page_to_addr(trident,page)	__tlb_to_addr(trident, (page) * UNIT_PAGES)

/* fill TLB entries -- UNIT_PAGES entries must be filled */
static inline void set_tlb_bus(struct snd_trident *trident, int page,
			       unsigned long ptr, dma_addr_t addr)
{
	int i;
	page *= UNIT_PAGES;
	for (i = 0; i < UNIT_PAGES; i++, page++) {
		__set_tlb_bus(trident, page, ptr, addr);
		ptr += SNDRV_TRIDENT_PAGE_SIZE;
		addr += SNDRV_TRIDENT_PAGE_SIZE;
	}
}
static inline void set_silent_tlb(struct snd_trident *trident, int page)
{
	int i;
	page *= UNIT_PAGES;
	for (i = 0; i < UNIT_PAGES; i++, page++)
		__set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
}

#endif /* PAGE_SIZE */

/* calculate buffer pointer from offset address */
static inline void *offset_ptr(struct snd_trident *trident, int offset)
{
	char *ptr;
	ptr = page_to_ptr(trident, get_aligned_page(offset));
	ptr += offset % ALIGN_PAGE_SIZE;
	return (void*)ptr;
}

/* first and last (aligned) pages of memory block */
#define firstpg(blk)	(((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->first_page)
#define lastpg(blk)	(((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->last_page)

/*
 * search empty pages which may contain given size
 */
static struct snd_util_memblk *
search_empty(struct snd_util_memhdr *hdr, int size)
{
	struct snd_util_memblk *blk, *prev;
	int page, psize;
	struct list_head *p;

	psize = get_aligned_page(size + ALIGN_PAGE_SIZE -1);
	prev = NULL;
	page = 0;
	list_for_each(p, &hdr->block) {
		blk = list_entry(p, struct snd_util_memblk, list);
		if (page + psize <= firstpg(blk))
			goto __found_pages;
		page = lastpg(blk) + 1;
	}
	if (page + psize > MAX_ALIGN_PAGES)
		return NULL;

__found_pages:
	/* create a new memory block */
	blk = __snd_util_memblk_new(hdr, psize * ALIGN_PAGE_SIZE, p->prev);
	if (blk == NULL)
		return NULL;
	blk->offset = aligned_page_offset(page); /* set aligned offset */
	firstpg(blk) = page;
	lastpg(blk) = page + psize - 1;
	return blk;
}


/*
 * check if the given pointer is valid for pages
 */
static int is_valid_page(unsigned long ptr)
{
	if (ptr & ~0x3fffffffUL) {
		snd_printk(KERN_ERR "max memory size is 1GB!!\n");
		return 0;
	}
	if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
		snd_printk(KERN_ERR "page is not aligned\n");
		return 0;
	}
	return 1;
}

/*
 * page allocation for DMA (Scatter-Gather version)
 */
static struct snd_util_memblk *
snd_trident_alloc_sg_pages(struct snd_trident *trident,
			   struct snd_pcm_substream *substream)
{
	struct snd_util_memhdr *hdr;
	struct snd_util_memblk *blk;
	struct snd_pcm_runtime *runtime = substream->runtime;
	int idx, page;
	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);

	snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
	hdr = trident->tlb.memhdr;
	snd_assert(hdr != NULL, return NULL);

	

	mutex_lock(&hdr->block_mutex);
	blk = search_empty(hdr, runtime->dma_bytes);
	if (blk == NULL) {
		mutex_unlock(&hdr->block_mutex);
		return NULL;
	}
	if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) {
		snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk));
		__snd_util_mem_free(hdr, blk);
		mutex_unlock(&hdr->block_mutex);
		return NULL;
	}
			   
	/* set TLB entries */
	idx = 0;
	for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) {
		dma_addr_t addr = sgbuf->table[idx].addr;
		unsigned long ptr = (unsigned long)sgbuf->table[idx].buf;
		if (! is_valid_page(addr)) {
			__snd_util_mem_free(hdr, blk);
			mutex_unlock(&hdr->block_mutex);
			return NULL;
		}
		set_tlb_bus(trident, page, ptr, addr);
	}
	mutex_unlock(&hdr->block_mutex);
	return blk;
}

/*
 * page allocation for DMA (contiguous version)
 */
static struct snd_util_memblk *
snd_trident_alloc_cont_pages(struct snd_trident *trident,
			     struct snd_pcm_substream *substream)
{
	struct snd_util_memhdr *hdr;
	struct snd_util_memblk *blk;
	int page;
	struct snd_pcm_runtime *runtime = substream->runtime;
	dma_addr_t addr;
	unsigned long ptr;

	snd_assert(runtime->dma_bytes> 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
	hdr = trident->tlb.memhdr;
	snd_assert(hdr != NULL, return NULL);

	mutex_lock(&hdr->block_mutex);
	blk = search_empty(hdr, runtime->dma_bytes);
	if (blk == NULL) {
		mutex_unlock(&hdr->block_mutex);
		return NULL;
	}
			   
	/* set TLB entries */
	addr = runtime->dma_addr;
	ptr = (unsigned long)runtime->dma_area;
	for (page = firstpg(blk); page <= lastpg(blk); page++,
	     ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) {
		if (! is_valid_page(addr)) {
			__snd_util_mem_free(hdr, blk);
			mutex_unlock(&hdr->block_mutex);
			return NULL;
		}
		set_tlb_bus(trident, page, ptr, addr);
	}
	mutex_unlock(&hdr->block_mutex);
	return blk;
}

/*
 * page allocation for DMA
 */
struct snd_util_memblk *
snd_trident_alloc_pages(struct snd_trident *trident,
			struct snd_pcm_substream *substream)
{
	snd_assert(trident != NULL, return NULL);
	snd_assert(substream != NULL, return NULL);
	if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_SG)
		return snd_trident_alloc_sg_pages(trident, substream);
	else
		return snd_trident_alloc_cont_pages(trident, substream);
}


/*
 * release DMA buffer from page table
 */
int snd_trident_free_pages(struct snd_trident *trident,
			   struct snd_util_memblk *blk)
{
	struct snd_util_memhdr *hdr;
	int page;

	snd_assert(trident != NULL, return -EINVAL);
	snd_assert(blk != NULL, return -EINVAL);

	hdr = trident->tlb.memhdr;
	mutex_lock(&hdr->block_mutex);
	/* reset TLB entries */
	for (page = firstpg(blk); page <= lastpg(blk); page++)
		set_silent_tlb(trident, page);
	/* free memory block */
	__snd_util_mem_free(hdr, blk);
	mutex_unlock(&hdr->block_mutex);
	return 0;
}


/*----------------------------------------------------------------
 * memory allocation using multiple pages (for synth)
 *----------------------------------------------------------------
 * Unlike the DMA allocation above, non-contiguous pages are
 * assigned to TLB.
 *----------------------------------------------------------------*/

/*
 */
static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk);
static int synth_free_pages(struct snd_trident *hw, struct snd_util_memblk *blk);

/*
 * allocate a synth sample area
 */
struct snd_util_memblk *
snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size)
{
	struct snd_util_memblk *blk;
	struct snd_util_memhdr *hdr = hw->tlb.memhdr; 

	mutex_lock(&hdr->block_mutex);
	blk = __snd_util_mem_alloc(hdr, size);
	if (blk == NULL) {
		mutex_unlock(&hdr->block_mutex);
		return NULL;
	}
	if (synth_alloc_pages(hw, blk)) {
		__snd_util_mem_free(hdr, blk);
		mutex_unlock(&hdr->block_mutex);
		return NULL;
	}
	mutex_unlock(&hdr->block_mutex);
	return blk;
}

EXPORT_SYMBOL(snd_trident_synth_alloc);

/*
 * free a synth sample area
 */
int
snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk)
{
	struct snd_util_memhdr *hdr = hw->tlb.memhdr; 

	mutex_lock(&hdr->block_mutex);
	synth_free_pages(hw, blk);
	 __snd_util_mem_free(hdr, blk);
	mutex_unlock(&hdr->block_mutex);
	return 0;
}

EXPORT_SYMBOL(snd_trident_synth_free);

/*
 * reset TLB entry and free kernel page
 */
static void clear_tlb(struct snd_trident *trident, int page)
{
	void *ptr = page_to_ptr(trident, page);
	dma_addr_t addr = page_to_addr(trident, page);
	set_silent_tlb(trident, page);
	if (ptr) {
		struct snd_dma_buffer dmab;
		dmab.dev.type = SNDRV_DMA_TYPE_DEV;
		dmab.dev.dev = snd_dma_pci_data(trident->pci);
		dmab.area = ptr;
		dmab.addr = addr;
		dmab.bytes = ALIGN_PAGE_SIZE;
		snd_dma_free_pages(&dmab);
	}
}

/* check new allocation range */
static void get_single_page_range(struct snd_util_memhdr *hdr,
				  struct snd_util_memblk *blk,
				  int *first_page_ret, int *last_page_ret)
{
	struct list_head *p;
	struct snd_util_memblk *q;
	int first_page, last_page;
	first_page = firstpg(blk);
	if ((p = blk->list.prev) != &hdr->block) {
		q = list_entry(p, struct snd_util_memblk, list);
		if (lastpg(q) == first_page)
			first_page++;  /* first page was already allocated */
	}
	last_page = lastpg(blk);
	if ((p = blk->list.next) != &hdr->block) {
		q = list_entry(p, struct snd_util_memblk, list);
		if (firstpg(q) == last_page)
			last_page--; /* last page was already allocated */
	}
	*first_page_ret = first_page;
	*last_page_ret = last_page;
}

/*
 * allocate kernel pages and assign them to TLB
 */
static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk)
{
	int page, first_page, last_page;
	struct snd_dma_buffer dmab;

	firstpg(blk) = get_aligned_page(blk->offset);
	lastpg(blk) = get_aligned_page(blk->offset + blk->size - 1);
	get_single_page_range(hw->tlb.memhdr, blk, &first_page, &last_page);

	/* allocate a kernel page for each Trident page -
	 * fortunately Trident page size and kernel PAGE_SIZE is identical!
	 */
	for (page = first_page; page <= last_page; page++) {
		if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(hw->pci),
					ALIGN_PAGE_SIZE, &dmab) < 0)
			goto __fail;
		if (! is_valid_page(dmab.addr)) {
			snd_dma_free_pages(&dmab);
			goto __fail;
		}
		set_tlb_bus(hw, page, (unsigned long)dmab.area, dmab.addr);
	}
	return 0;

__fail:
	/* release allocated pages */
	last_page = page - 1;
	for (page = first_page; page <= last_page; page++)
		clear_tlb(hw, page);

	return -ENOMEM;
}

/*
 * free pages
 */
static int synth_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk)
{
	int page, first_page, last_page;

	get_single_page_range(trident->tlb.memhdr, blk, &first_page, &last_page);
	for (page = first_page; page <= last_page; page++)
		clear_tlb(trident, page);

	return 0;
}

/*
 * copy_from_user(blk + offset, data, size)
 */
int snd_trident_synth_copy_from_user(struct snd_trident *trident,
				     struct snd_util_memblk *blk,
				     int offset, const char __user *data, int size)
{
	int page, nextofs, end_offset, temp, temp1;

	offset += blk->offset;
	end_offset = offset + size;
	page = get_aligned_page(offset) + 1;
	do {
		nextofs = aligned_page_offset(page);
		temp = nextofs - offset;
		temp1 = end_offset - offset;
		if (temp1 < temp)
			temp = temp1;
		if (copy_from_user(offset_ptr(trident, offset), data, temp))
			return -EFAULT;
		offset = nextofs;
		data += temp;
		page++;
	} while (offset < end_offset);
	return 0;
}

EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
