/*
 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
 * Copyright (C) 2009 Wind River Systems Inc
 *  Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
 *
 * Based on DMA code from MIPS.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/types.h>
#include <linux/mm.h>
#include <linux/export.h>
#include <linux/string.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/cache.h>
#include <asm/cacheflush.h>

static inline void __dma_sync_for_device(void *vaddr, size_t size,
			      enum dma_data_direction direction)
{
	switch (direction) {
	case DMA_FROM_DEVICE:
		invalidate_dcache_range((unsigned long)vaddr,
			(unsigned long)(vaddr + size));
		break;
	case DMA_TO_DEVICE:
		/*
		 * We just need to flush the caches here , but Nios2 flush
		 * instruction will do both writeback and invalidate.
		 */
	case DMA_BIDIRECTIONAL: /* flush and invalidate */
		flush_dcache_range((unsigned long)vaddr,
			(unsigned long)(vaddr + size));
		break;
	default:
		BUG();
	}
}

static inline void __dma_sync_for_cpu(void *vaddr, size_t size,
			      enum dma_data_direction direction)
{
	switch (direction) {
	case DMA_BIDIRECTIONAL:
	case DMA_FROM_DEVICE:
		invalidate_dcache_range((unsigned long)vaddr,
			(unsigned long)(vaddr + size));
		break;
	case DMA_TO_DEVICE:
		break;
	default:
		BUG();
	}
}

static void *nios2_dma_alloc(struct device *dev, size_t size,
		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
	void *ret;

	/* optimized page clearing */
	gfp |= __GFP_ZERO;

	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
		gfp |= GFP_DMA;

	ret = (void *) __get_free_pages(gfp, get_order(size));
	if (ret != NULL) {
		*dma_handle = virt_to_phys(ret);
		flush_dcache_range((unsigned long) ret,
			(unsigned long) ret + size);
		ret = UNCAC_ADDR(ret);
	}

	return ret;
}

static void nios2_dma_free(struct device *dev, size_t size, void *vaddr,
		dma_addr_t dma_handle, unsigned long attrs)
{
	unsigned long addr = (unsigned long) CAC_ADDR((unsigned long) vaddr);

	free_pages(addr, get_order(size));
}

static int nios2_dma_map_sg(struct device *dev, struct scatterlist *sg,
		int nents, enum dma_data_direction direction,
		unsigned long attrs)
{
	int i;

	for_each_sg(sg, sg, nents, i) {
		void *addr = sg_virt(sg);

		if (!addr)
			continue;

		sg->dma_address = sg_phys(sg);

		if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
			continue;

		__dma_sync_for_device(addr, sg->length, direction);
	}

	return nents;
}

static dma_addr_t nios2_dma_map_page(struct device *dev, struct page *page,
			unsigned long offset, size_t size,
			enum dma_data_direction direction,
			unsigned long attrs)
{
	void *addr = page_address(page) + offset;

	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
		__dma_sync_for_device(addr, size, direction);

	return page_to_phys(page) + offset;
}

static void nios2_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
		size_t size, enum dma_data_direction direction,
		unsigned long attrs)
{
	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
		__dma_sync_for_cpu(phys_to_virt(dma_address), size, direction);
}

static void nios2_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
		int nhwentries, enum dma_data_direction direction,
		unsigned long attrs)
{
	void *addr;
	int i;

	if (direction == DMA_TO_DEVICE)
		return;

	if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
		return;

	for_each_sg(sg, sg, nhwentries, i) {
		addr = sg_virt(sg);
		if (addr)
			__dma_sync_for_cpu(addr, sg->length, direction);
	}
}

static void nios2_dma_sync_single_for_cpu(struct device *dev,
		dma_addr_t dma_handle, size_t size,
		enum dma_data_direction direction)
{
	__dma_sync_for_cpu(phys_to_virt(dma_handle), size, direction);
}

static void nios2_dma_sync_single_for_device(struct device *dev,
		dma_addr_t dma_handle, size_t size,
		enum dma_data_direction direction)
{
	__dma_sync_for_device(phys_to_virt(dma_handle), size, direction);
}

static void nios2_dma_sync_sg_for_cpu(struct device *dev,
		struct scatterlist *sg, int nelems,
		enum dma_data_direction direction)
{
	int i;

	/* Make sure that gcc doesn't leave the empty loop body.  */
	for_each_sg(sg, sg, nelems, i)
		__dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
}

static void nios2_dma_sync_sg_for_device(struct device *dev,
		struct scatterlist *sg, int nelems,
		enum dma_data_direction direction)
{
	int i;

	/* Make sure that gcc doesn't leave the empty loop body.  */
	for_each_sg(sg, sg, nelems, i)
		__dma_sync_for_device(sg_virt(sg), sg->length, direction);

}

const struct dma_map_ops nios2_dma_ops = {
	.alloc			= nios2_dma_alloc,
	.free			= nios2_dma_free,
	.map_page		= nios2_dma_map_page,
	.unmap_page		= nios2_dma_unmap_page,
	.map_sg			= nios2_dma_map_sg,
	.unmap_sg		= nios2_dma_unmap_sg,
	.sync_single_for_device	= nios2_dma_sync_single_for_device,
	.sync_single_for_cpu	= nios2_dma_sync_single_for_cpu,
	.sync_sg_for_cpu	= nios2_dma_sync_sg_for_cpu,
	.sync_sg_for_device	= nios2_dma_sync_sg_for_device,
};
EXPORT_SYMBOL(nios2_dma_ops);
