/*
 * Driver for MPC52xx processor BestComm General Buffer Descriptor
 *
 * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
 * Copyright (C) 2006 AppSpec Computer Technologies Corp.
 *                    Jeff Gibbons <jeff.gibbons@appspec.com>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 */

#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
#include <asm/errno.h>
#include <asm/io.h>

#include <asm/mpc52xx.h>

#include "bestcomm.h"
#include "bestcomm_priv.h"
#include "gen_bd.h"


/* ======================================================================== */
/* Task image/var/inc                                                       */
/* ======================================================================== */

/* gen_bd tasks images */
extern u32 bcom_gen_bd_rx_task[];
extern u32 bcom_gen_bd_tx_task[];

/* rx task vars that need to be set before enabling the task */
struct bcom_gen_bd_rx_var {
	u32 enable;		/* (u16*) address of task's control register */
	u32 fifo;		/* (u32*) address of gen_bd's fifo */
	u32 bd_base;		/* (struct bcom_bd*) beginning of ring buffer */
	u32 bd_last;		/* (struct bcom_bd*) end of ring buffer */
	u32 bd_start;		/* (struct bcom_bd*) current bd */
	u32 buffer_size;	/* size of receive buffer */
};

/* rx task incs that need to be set before enabling the task */
struct bcom_gen_bd_rx_inc {
	u16 pad0;
	s16 incr_bytes;
	u16 pad1;
	s16 incr_dst;
};

/* tx task vars that need to be set before enabling the task */
struct bcom_gen_bd_tx_var {
	u32 fifo;		/* (u32*) address of gen_bd's fifo */
	u32 enable;		/* (u16*) address of task's control register */
	u32 bd_base;		/* (struct bcom_bd*) beginning of ring buffer */
	u32 bd_last;		/* (struct bcom_bd*) end of ring buffer */
	u32 bd_start;		/* (struct bcom_bd*) current bd */
	u32 buffer_size;	/* set by uCode for each packet */
};

/* tx task incs that need to be set before enabling the task */
struct bcom_gen_bd_tx_inc {
	u16 pad0;
	s16 incr_bytes;
	u16 pad1;
	s16 incr_src;
	u16 pad2;
	s16 incr_src_ma;
};

/* private structure */
struct bcom_gen_bd_priv {
	phys_addr_t	fifo;
	int		initiator;
	int		ipr;
	int		maxbufsize;
};


/* ======================================================================== */
/* Task support code                                                        */
/* ======================================================================== */

struct bcom_task *
bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo,
			int initiator, int ipr, int maxbufsize)
{
	struct bcom_task *tsk;
	struct bcom_gen_bd_priv *priv;

	tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_gen_bd),
			sizeof(struct bcom_gen_bd_priv));
	if (!tsk)
		return NULL;

	tsk->flags = BCOM_FLAGS_NONE;

	priv = tsk->priv;
	priv->fifo	= fifo;
	priv->initiator	= initiator;
	priv->ipr	= ipr;
	priv->maxbufsize = maxbufsize;

	if (bcom_gen_bd_rx_reset(tsk)) {
		bcom_task_free(tsk);
		return NULL;
	}

	return tsk;
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init);

int
bcom_gen_bd_rx_reset(struct bcom_task *tsk)
{
	struct bcom_gen_bd_priv *priv = tsk->priv;
	struct bcom_gen_bd_rx_var *var;
	struct bcom_gen_bd_rx_inc *inc;

	/* Shutdown the task */
	bcom_disable_task(tsk->tasknum);

	/* Reset the microcode */
	var = (struct bcom_gen_bd_rx_var *) bcom_task_var(tsk->tasknum);
	inc = (struct bcom_gen_bd_rx_inc *) bcom_task_inc(tsk->tasknum);

	if (bcom_load_image(tsk->tasknum, bcom_gen_bd_rx_task))
		return -1;

	var->enable	= bcom_eng->regs_base +
				offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
	var->fifo	= (u32) priv->fifo;
	var->bd_base	= tsk->bd_pa;
	var->bd_last	= tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
	var->bd_start	= tsk->bd_pa;
	var->buffer_size = priv->maxbufsize;

	inc->incr_bytes	= -(s16)sizeof(u32);
	inc->incr_dst	= sizeof(u32);

	/* Reset the BDs */
	tsk->index = 0;
	tsk->outdex = 0;

	memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);

	/* Configure some stuff */
	bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_RX_BD_PRAGMA);
	bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);

	out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
	bcom_set_initiator(tsk->tasknum, priv->initiator);

	out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum);	/* Clear ints */

	return 0;
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_reset);

void
bcom_gen_bd_rx_release(struct bcom_task *tsk)
{
	/* Nothing special for the GenBD tasks */
	bcom_task_free(tsk);
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release);


extern struct bcom_task *
bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo,
			int initiator, int ipr)
{
	struct bcom_task *tsk;
	struct bcom_gen_bd_priv *priv;

	tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_gen_bd),
			sizeof(struct bcom_gen_bd_priv));
	if (!tsk)
		return NULL;

	tsk->flags = BCOM_FLAGS_NONE;

	priv = tsk->priv;
	priv->fifo	= fifo;
	priv->initiator	= initiator;
	priv->ipr	= ipr;

	if (bcom_gen_bd_tx_reset(tsk)) {
		bcom_task_free(tsk);
		return NULL;
	}

	return tsk;
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init);

int
bcom_gen_bd_tx_reset(struct bcom_task *tsk)
{
	struct bcom_gen_bd_priv *priv = tsk->priv;
	struct bcom_gen_bd_tx_var *var;
	struct bcom_gen_bd_tx_inc *inc;

	/* Shutdown the task */
	bcom_disable_task(tsk->tasknum);

	/* Reset the microcode */
	var = (struct bcom_gen_bd_tx_var *) bcom_task_var(tsk->tasknum);
	inc = (struct bcom_gen_bd_tx_inc *) bcom_task_inc(tsk->tasknum);

	if (bcom_load_image(tsk->tasknum, bcom_gen_bd_tx_task))
		return -1;

	var->enable	= bcom_eng->regs_base +
				offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
	var->fifo	= (u32) priv->fifo;
	var->bd_base	= tsk->bd_pa;
	var->bd_last	= tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
	var->bd_start	= tsk->bd_pa;

	inc->incr_bytes	= -(s16)sizeof(u32);
	inc->incr_src	= sizeof(u32);
	inc->incr_src_ma = sizeof(u8);

	/* Reset the BDs */
	tsk->index = 0;
	tsk->outdex = 0;

	memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);

	/* Configure some stuff */
	bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_TX_BD_PRAGMA);
	bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);

	out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
	bcom_set_initiator(tsk->tasknum, priv->initiator);

	out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum);	/* Clear ints */

	return 0;
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_reset);

void
bcom_gen_bd_tx_release(struct bcom_task *tsk)
{
	/* Nothing special for the GenBD tasks */
	bcom_task_free(tsk);
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release);


MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");
MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");
MODULE_LICENSE("GPL v2");

