/*
 * DMA helper routines for Freescale STMP37XX/STMP378X
 *
 * Author: dmitry pervushin <dpervushin@embeddedalley.com>
 *
 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/dmapool.h>
#include <linux/sysdev.h>
#include <linux/cpufreq.h>

#include <asm/page.h>

#include <mach/platform.h>
#include <mach/dma.h>
#include <mach/regs-apbx.h>
#include <mach/regs-apbh.h>

static const size_t pool_item_size = sizeof(struct stmp3xxx_dma_command);
static const size_t pool_alignment = 8;
static struct stmp3xxx_dma_user {
	void *pool;
	int inuse;
	const char *name;
} channels[MAX_DMA_CHANNELS];

#define IS_VALID_CHANNEL(ch) ((ch) >= 0 && (ch) < MAX_DMA_CHANNELS)
#define IS_USED(ch) (channels[ch].inuse)

int stmp3xxx_dma_request(int ch, struct device *dev, const char *name)
{
	struct stmp3xxx_dma_user *user;
	int err = 0;

	user = channels + ch;
	if (!IS_VALID_CHANNEL(ch)) {
		err = -ENODEV;
		goto out;
	}
	if (IS_USED(ch)) {
		err = -EBUSY;
		goto out;
	}
	/* Create a pool to allocate dma commands from */
	user->pool = dma_pool_create(name, dev, pool_item_size,
				     pool_alignment, PAGE_SIZE);
	if (user->pool == NULL) {
		err = -ENOMEM;
		goto out;
	}
	user->name = name;
	user->inuse++;
out:
	return err;
}
EXPORT_SYMBOL(stmp3xxx_dma_request);

int stmp3xxx_dma_release(int ch)
{
	struct stmp3xxx_dma_user *user = channels + ch;
	int err = 0;

	if (!IS_VALID_CHANNEL(ch)) {
		err = -ENODEV;
		goto out;
	}
	if (!IS_USED(ch)) {
		err = -EBUSY;
		goto out;
	}
	BUG_ON(user->pool == NULL);
	dma_pool_destroy(user->pool);
	user->inuse--;
out:
	return err;
}
EXPORT_SYMBOL(stmp3xxx_dma_release);

int stmp3xxx_dma_read_semaphore(int channel)
{
	int sem = -1;

	switch (STMP3XXX_DMA_BUS(channel)) {
	case STMP3XXX_BUS_APBH:
		sem = __raw_readl(REGS_APBH_BASE + HW_APBH_CHn_SEMA +
				STMP3XXX_DMA_CHANNEL(channel) * 0x70);
		sem &= BM_APBH_CHn_SEMA_PHORE;
		sem >>= BP_APBH_CHn_SEMA_PHORE;
		break;

	case STMP3XXX_BUS_APBX:
		sem = __raw_readl(REGS_APBX_BASE + HW_APBX_CHn_SEMA +
				STMP3XXX_DMA_CHANNEL(channel) * 0x70);
		sem &= BM_APBX_CHn_SEMA_PHORE;
		sem >>= BP_APBX_CHn_SEMA_PHORE;
		break;
	default:
		BUG();
	}
	return sem;
}
EXPORT_SYMBOL(stmp3xxx_dma_read_semaphore);

int stmp3xxx_dma_allocate_command(int channel,
				  struct stmp3xxx_dma_descriptor *descriptor)
{
	struct stmp3xxx_dma_user *user = channels + channel;
	int err = 0;

	if (!IS_VALID_CHANNEL(channel)) {
		err = -ENODEV;
		goto out;
	}
	if (!IS_USED(channel)) {
		err = -EBUSY;
		goto out;
	}
	if (descriptor == NULL) {
		err = -EINVAL;
		goto out;
	}

	/* Allocate memory for a command from the buffer */
	descriptor->command =
	    dma_pool_alloc(user->pool, GFP_KERNEL, &descriptor->handle);

	/* Check it worked */
	if (!descriptor->command) {
		err = -ENOMEM;
		goto out;
	}

	memset(descriptor->command, 0, pool_item_size);
out:
	WARN_ON(err);
	return err;
}
EXPORT_SYMBOL(stmp3xxx_dma_allocate_command);

int stmp3xxx_dma_free_command(int channel,
			      struct stmp3xxx_dma_descriptor *descriptor)
{
	int err = 0;

	if (!IS_VALID_CHANNEL(channel)) {
		err = -ENODEV;
		goto out;
	}
	if (!IS_USED(channel)) {
		err = -EBUSY;
		goto out;
	}

	/* Return the command memory to the pool */
	dma_pool_free(channels[channel].pool, descriptor->command,
		      descriptor->handle);

	/* Initialise descriptor so we're not tempted to use it */
	descriptor->command = NULL;
	descriptor->handle = 0;
	descriptor->virtual_buf_ptr = NULL;
	descriptor->next_descr = NULL;

	WARN_ON(err);
out:
	return err;
}
EXPORT_SYMBOL(stmp3xxx_dma_free_command);

void stmp3xxx_dma_go(int channel,
		     struct stmp3xxx_dma_descriptor *head, u32 semaphore)
{
	int ch = STMP3XXX_DMA_CHANNEL(channel);
	void __iomem *c, *s;

	switch (STMP3XXX_DMA_BUS(channel)) {
	case STMP3XXX_BUS_APBH:
		c = REGS_APBH_BASE + HW_APBH_CHn_NXTCMDAR + 0x70 * ch;
		s = REGS_APBH_BASE + HW_APBH_CHn_SEMA + 0x70 * ch;
		break;

	case STMP3XXX_BUS_APBX:
		c = REGS_APBX_BASE + HW_APBX_CHn_NXTCMDAR + 0x70 * ch;
		s = REGS_APBX_BASE + HW_APBX_CHn_SEMA + 0x70 * ch;
		break;

	default:
		return;
	}

	/* Set next command */
	__raw_writel(head->handle, c);
	/* Set counting semaphore (kicks off transfer). Assumes
	   peripheral has been set up correctly */
	__raw_writel(semaphore, s);
}
EXPORT_SYMBOL(stmp3xxx_dma_go);

int stmp3xxx_dma_running(int channel)
{
	switch (STMP3XXX_DMA_BUS(channel)) {
	case STMP3XXX_BUS_APBH:
		return (__raw_readl(REGS_APBH_BASE + HW_APBH_CHn_SEMA +
			0x70 * STMP3XXX_DMA_CHANNEL(channel))) &
			    BM_APBH_CHn_SEMA_PHORE;

	case STMP3XXX_BUS_APBX:
		return (__raw_readl(REGS_APBX_BASE + HW_APBX_CHn_SEMA +
			0x70 * STMP3XXX_DMA_CHANNEL(channel))) &
			    BM_APBX_CHn_SEMA_PHORE;
	default:
		BUG();
		return 0;
	}
}
EXPORT_SYMBOL(stmp3xxx_dma_running);

/*
 * Circular dma chain management
 */
void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain)
{
	int i;

	for (i = 0; i < chain->total_count; i++)
		stmp3xxx_dma_free_command(
			STMP3XXX_DMA(chain->channel, chain->bus),
			&chain->chain[i]);
}
EXPORT_SYMBOL(stmp3xxx_dma_free_chain);

int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain,
			    struct stmp3xxx_dma_descriptor descriptors[],
			    unsigned items)
{
	int i;
	int err = 0;

	if (items == 0)
		return err;

	for (i = 0; i < items; i++) {
		err = stmp3xxx_dma_allocate_command(ch, &descriptors[i]);
		if (err) {
			WARN_ON(err);
			/*
			 * Couldn't allocate the whole chain.
			 * deallocate what has been allocated
			 */
			if (i) {
				do {
					stmp3xxx_dma_free_command(ch,
								  &descriptors
								  [i]);
				} while (i-- >= 0);
			}
			return err;
		}

		/* link them! */
		if (i > 0) {
			descriptors[i - 1].next_descr = &descriptors[i];
			descriptors[i - 1].command->next =
						descriptors[i].handle;
		}
	}

	/* make list circular */
	descriptors[items - 1].next_descr = &descriptors[0];
	descriptors[items - 1].command->next = descriptors[0].handle;

	chain->total_count = items;
	chain->chain = descriptors;
	chain->free_index = 0;
	chain->active_index = 0;
	chain->cooked_index = 0;
	chain->free_count = items;
	chain->active_count = 0;
	chain->cooked_count = 0;
	chain->bus = STMP3XXX_DMA_BUS(ch);
	chain->channel = STMP3XXX_DMA_CHANNEL(ch);
	return err;
}
EXPORT_SYMBOL(stmp3xxx_dma_make_chain);

void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain)
{
	BUG_ON(stmp3xxx_dma_running(STMP3XXX_DMA(chain->channel, chain->bus)));
	chain->free_index = 0;
	chain->active_index = 0;
	chain->cooked_index = 0;
	chain->free_count = chain->total_count;
	chain->active_count = 0;
	chain->cooked_count = 0;
}
EXPORT_SYMBOL(stmp37xx_circ_clear_chain);

void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain,
		unsigned count)
{
	BUG_ON(chain->cooked_count < count);

	chain->cooked_count -= count;
	chain->cooked_index += count;
	chain->cooked_index %= chain->total_count;
	chain->free_count += count;
}
EXPORT_SYMBOL(stmp37xx_circ_advance_free);

void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain,
		unsigned count)
{
	void __iomem *c;
	u32 mask_clr, mask;
	BUG_ON(chain->free_count < count);

	chain->free_count -= count;
	chain->free_index += count;
	chain->free_index %= chain->total_count;
	chain->active_count += count;

	switch (chain->bus) {
	case STMP3XXX_BUS_APBH:
		c = REGS_APBH_BASE + HW_APBH_CHn_SEMA + 0x70 * chain->channel;
		mask_clr = BM_APBH_CHn_SEMA_INCREMENT_SEMA;
		mask = BF(count, APBH_CHn_SEMA_INCREMENT_SEMA);
		break;
	case STMP3XXX_BUS_APBX:
		c = REGS_APBX_BASE + HW_APBX_CHn_SEMA + 0x70 * chain->channel;
		mask_clr = BM_APBX_CHn_SEMA_INCREMENT_SEMA;
		mask = BF(count, APBX_CHn_SEMA_INCREMENT_SEMA);
		break;
	default:
		BUG();
		return;
	}

	/* Set counting semaphore (kicks off transfer). Assumes
	   peripheral has been set up correctly */
	stmp3xxx_clearl(mask_clr, c);
	stmp3xxx_setl(mask, c);
}
EXPORT_SYMBOL(stmp37xx_circ_advance_active);

unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain)
{
	unsigned cooked;

	cooked = chain->active_count -
	  stmp3xxx_dma_read_semaphore(STMP3XXX_DMA(chain->channel, chain->bus));

	chain->active_count -= cooked;
	chain->active_index += cooked;
	chain->active_index %= chain->total_count;

	chain->cooked_count += cooked;

	return cooked;
}
EXPORT_SYMBOL(stmp37xx_circ_advance_cooked);

void stmp3xxx_dma_set_alt_target(int channel, int function)
{
#if defined(CONFIG_ARCH_STMP37XX)
	unsigned bits = 4;
#elif defined(CONFIG_ARCH_STMP378X)
	unsigned bits = 2;
#else
#error wrong arch
#endif
	int shift = STMP3XXX_DMA_CHANNEL(channel) * bits;
	unsigned mask = (1<<bits) - 1;
	void __iomem *c;

	BUG_ON(function < 0 || function >= (1<<bits));
	pr_debug("%s: channel = %d, using mask %x, "
		 "shift = %d\n", __func__, channel, mask, shift);

	switch (STMP3XXX_DMA_BUS(channel)) {
	case STMP3XXX_BUS_APBH:
		c = REGS_APBH_BASE + HW_APBH_DEVSEL;
		break;
	case STMP3XXX_BUS_APBX:
		c = REGS_APBX_BASE + HW_APBX_DEVSEL;
		break;
	default:
		BUG();
	}
	stmp3xxx_clearl(mask << shift, c);
	stmp3xxx_setl(mask << shift, c);
}
EXPORT_SYMBOL(stmp3xxx_dma_set_alt_target);

void stmp3xxx_dma_suspend(void)
{
	stmp3xxx_setl(BM_APBH_CTRL0_CLKGATE, REGS_APBH_BASE + HW_APBH_CTRL0);
	stmp3xxx_setl(BM_APBX_CTRL0_CLKGATE, REGS_APBX_BASE + HW_APBX_CTRL0);
}

void stmp3xxx_dma_resume(void)
{
	stmp3xxx_clearl(BM_APBH_CTRL0_CLKGATE | BM_APBH_CTRL0_SFTRST,
			REGS_APBH_BASE + HW_APBH_CTRL0);
	stmp3xxx_clearl(BM_APBX_CTRL0_CLKGATE | BM_APBX_CTRL0_SFTRST,
			REGS_APBX_BASE + HW_APBX_CTRL0);
}

#ifdef CONFIG_CPU_FREQ

struct dma_notifier_block {
	struct notifier_block nb;
	void *data;
};

static int dma_cpufreq_notifier(struct notifier_block *self,
				unsigned long phase, void *p)
{
	switch (phase) {
	case CPUFREQ_POSTCHANGE:
		stmp3xxx_dma_resume();
		break;

	case CPUFREQ_PRECHANGE:
		stmp3xxx_dma_suspend();
		break;

	default:
		break;
	}

	return NOTIFY_DONE;
}

static struct dma_notifier_block dma_cpufreq_nb = {
	.nb = {
		.notifier_call = dma_cpufreq_notifier,
	},
};
#endif /* CONFIG_CPU_FREQ */

void __init stmp3xxx_dma_init(void)
{
	stmp3xxx_clearl(BM_APBH_CTRL0_CLKGATE | BM_APBH_CTRL0_SFTRST,
			REGS_APBH_BASE + HW_APBH_CTRL0);
	stmp3xxx_clearl(BM_APBX_CTRL0_CLKGATE | BM_APBX_CTRL0_SFTRST,
			REGS_APBX_BASE + HW_APBX_CTRL0);
#ifdef CONFIG_CPU_FREQ
	cpufreq_register_notifier(&dma_cpufreq_nb.nb,
				CPUFREQ_TRANSITION_NOTIFIER);
#endif /* CONFIG_CPU_FREQ */
}
