/*
 * Copyright (C) 2006 Freescale Semiconductor, Inc.
 *
 * Dave Liu <daveliu@freescale.com>
 * based on source code of Shlomi Gridish
 *
 * 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 "common.h"
#include "malloc.h"
#include "asm/errno.h"
#include "asm/io.h"
#include "asm/immap_qe.h"
#include "qe.h"
#include "uccf.h"

#if defined(CONFIG_QE)
void ucc_fast_transmit_on_demand(ucc_fast_private_t *uccf)
{
	out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
}

u32 ucc_fast_get_qe_cr_subblock(int ucc_num)
{
	switch (ucc_num) {
		case 0:	return QE_CR_SUBBLOCK_UCCFAST1;
		case 1:	return QE_CR_SUBBLOCK_UCCFAST2;
		case 2:	return QE_CR_SUBBLOCK_UCCFAST3;
		case 3:	return QE_CR_SUBBLOCK_UCCFAST4;
		case 4:	return QE_CR_SUBBLOCK_UCCFAST5;
		case 5:	return QE_CR_SUBBLOCK_UCCFAST6;
		case 6:	return QE_CR_SUBBLOCK_UCCFAST7;
		case 7:	return QE_CR_SUBBLOCK_UCCFAST8;
		default:	return QE_CR_SUBBLOCK_INVALID;
	}
}

static void ucc_get_cmxucr_reg(int ucc_num, volatile u32 **p_cmxucr,
				 u8 *reg_num, u8 *shift)
{
	switch (ucc_num) {
		case 0:	/* UCC1 */
			*p_cmxucr  = &(qe_immr->qmx.cmxucr1);
			*reg_num = 1;
			*shift  = 16;
			break;
		case 2:	/* UCC3 */
			*p_cmxucr  = &(qe_immr->qmx.cmxucr1);
			*reg_num = 1;
			*shift  = 0;
			break;
		case 4:	/* UCC5 */
			*p_cmxucr  = &(qe_immr->qmx.cmxucr2);
			*reg_num = 2;
			*shift  = 16;
			break;
		case 6:	/* UCC7 */
			*p_cmxucr  = &(qe_immr->qmx.cmxucr2);
			*reg_num = 2;
			*shift  = 0;
			break;
		case 1:	/* UCC2 */
			*p_cmxucr  = &(qe_immr->qmx.cmxucr3);
			*reg_num = 3;
			*shift  = 16;
			break;
		case 3:	/* UCC4 */
			*p_cmxucr  = &(qe_immr->qmx.cmxucr3);
			*reg_num = 3;
			*shift  = 0;
			break;
		case 5:	/* UCC6 */
			*p_cmxucr  = &(qe_immr->qmx.cmxucr4);
			*reg_num = 4;
			*shift  = 16;
			break;
		case 7:	/* UCC8 */
			*p_cmxucr  = &(qe_immr->qmx.cmxucr4);
			*reg_num = 4;
			*shift  = 0;
			break;
		default:
			break;
	}
}

static int ucc_set_clk_src(int ucc_num, qe_clock_e clock, comm_dir_e mode)
{
	volatile u32	*p_cmxucr = NULL;
	u8		reg_num = 0;
	u8		shift = 0;
	u32		clockBits;
	u32		clockMask;
	int		source = -1;

	/* check if the UCC number is in range. */
	if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
		return -EINVAL;

	if (! ((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX))) {
		printf("%s: bad comm mode type passed\n", __FUNCTION__);
		return -EINVAL;
	}

	ucc_get_cmxucr_reg(ucc_num, &p_cmxucr, &reg_num, &shift);

	switch (reg_num) {
		case 1:
			switch (clock) {
				case QE_BRG1:	source = 1; break;
				case QE_BRG2:	source = 2; break;
				case QE_BRG7:	source = 3; break;
				case QE_BRG8:	source = 4; break;
				case QE_CLK9:	source = 5; break;
				case QE_CLK10:	source = 6; break;
				case QE_CLK11:	source = 7; break;
				case QE_CLK12:	source = 8; break;
				case QE_CLK15:	source = 9; break;
				case QE_CLK16:	source = 10; break;
				default:	source = -1; break;
			}
			break;
		case 2:
			switch (clock) {
				case QE_BRG5:	source = 1; break;
				case QE_BRG6:	source = 2; break;
				case QE_BRG7:	source = 3; break;
				case QE_BRG8:	source = 4; break;
				case QE_CLK13:	source = 5; break;
				case QE_CLK14:	source = 6; break;
				case QE_CLK19:	source = 7; break;
				case QE_CLK20:	source = 8; break;
				case QE_CLK15:	source = 9; break;
				case QE_CLK16:	source = 10; break;
				default:	source = -1; break;
			}
			break;
		case 3:
			switch (clock) {
				case QE_BRG9:	source = 1; break;
				case QE_BRG10:	source = 2; break;
				case QE_BRG15:	source = 3; break;
				case QE_BRG16:	source = 4; break;
				case QE_CLK3:	source = 5; break;
				case QE_CLK4:	source = 6; break;
				case QE_CLK17:	source = 7; break;
				case QE_CLK18:	source = 8; break;
				case QE_CLK7:	source = 9; break;
				case QE_CLK8:	source = 10; break;
				case QE_CLK16:	source = 11; break;
				default:	source = -1; break;
			}
			break;
		case 4:
			switch (clock) {
				case QE_BRG13:	source = 1; break;
				case QE_BRG14:	source = 2; break;
				case QE_BRG15:	source = 3; break;
				case QE_BRG16:	source = 4; break;
				case QE_CLK5:	source = 5; break;
				case QE_CLK6:	source = 6; break;
				case QE_CLK21:	source = 7; break;
				case QE_CLK22:	source = 8; break;
				case QE_CLK7:	source = 9; break;
				case QE_CLK8:	source = 10; break;
				case QE_CLK16:	source = 11; break;
				default:	source = -1; break;
			}
			break;
		default:
			source = -1;
			break;
	}

	if (source == -1) {
		printf("%s: Bad combination of clock and UCC\n", __FUNCTION__);
		return -ENOENT;
	}

	clockBits = (u32) source;
	clockMask = QE_CMXUCR_TX_CLK_SRC_MASK;
	if (mode == COMM_DIR_RX) {
		clockBits <<= 4; /* Rx field is 4 bits to left of Tx field */
		clockMask <<= 4; /* Rx field is 4 bits to left of Tx field */
	}
	clockBits <<= shift;
	clockMask <<= shift;

	out_be32(p_cmxucr, (in_be32(p_cmxucr) & ~clockMask) | clockBits);

	return 0;
}

static uint ucc_get_reg_baseaddr(int ucc_num)
{
	uint base = 0;

	/* check if the UCC number is in range */
	if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) {
		printf("%s: the UCC num not in ranges\n", __FUNCTION__);
		return 0;
	}

	switch (ucc_num) {
		case 0:	base = 0x00002000; break;
		case 1:	base = 0x00003000; break;
		case 2:	base = 0x00002200; break;
		case 3:	base = 0x00003200; break;
		case 4:	base = 0x00002400; break;
		case 5:	base = 0x00003400; break;
		case 6:	base = 0x00002600; break;
		case 7:	base = 0x00003600; break;
		default: break;
	}

	base = (uint)qe_immr + base;
	return base;
}

void ucc_fast_enable(ucc_fast_private_t *uccf, comm_dir_e mode)
{
	ucc_fast_t	*uf_regs;
	u32		gumr;

	uf_regs = uccf->uf_regs;

	/* Enable reception and/or transmission on this UCC. */
	gumr = in_be32(&uf_regs->gumr);
	if (mode & COMM_DIR_TX) {
		gumr |= UCC_FAST_GUMR_ENT;
		uccf->enabled_tx = 1;
	}
	if (mode & COMM_DIR_RX) {
		gumr |= UCC_FAST_GUMR_ENR;
		uccf->enabled_rx = 1;
	}
	out_be32(&uf_regs->gumr, gumr);
}

void ucc_fast_disable(ucc_fast_private_t *uccf, comm_dir_e mode)
{
	ucc_fast_t	*uf_regs;
	u32		gumr;

	uf_regs = uccf->uf_regs;

	/* Disable reception and/or transmission on this UCC. */
	gumr = in_be32(&uf_regs->gumr);
	if (mode & COMM_DIR_TX) {
		gumr &= ~UCC_FAST_GUMR_ENT;
		uccf->enabled_tx = 0;
	}
	if (mode & COMM_DIR_RX) {
		gumr &= ~UCC_FAST_GUMR_ENR;
		uccf->enabled_rx = 0;
	}
	out_be32(&uf_regs->gumr, gumr);
}

int ucc_fast_init(ucc_fast_info_t *uf_info, ucc_fast_private_t  **uccf_ret)
{
	ucc_fast_private_t	*uccf;
	ucc_fast_t		*uf_regs;

	if (!uf_info)
		return -EINVAL;

	if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
		printf("%s: Illagal UCC number!\n", __FUNCTION__);
		return -EINVAL;
	}

	uccf = (ucc_fast_private_t *)malloc(sizeof(ucc_fast_private_t));
	if (!uccf) {
		printf("%s: No memory for UCC fast data structure!\n",
			 __FUNCTION__);
		return -ENOMEM;
	}
	memset(uccf, 0, sizeof(ucc_fast_private_t));

	/* Save fast UCC structure */
	uccf->uf_info	= uf_info;
	uccf->uf_regs	= (ucc_fast_t *)ucc_get_reg_baseaddr(uf_info->ucc_num);

	if (uccf->uf_regs == NULL) {
		printf("%s: No memory map for UCC fast controller!\n",
			 __FUNCTION__);
		return -ENOMEM;
	}

	uccf->enabled_tx	= 0;
	uccf->enabled_rx	= 0;

	uf_regs			= uccf->uf_regs;
	uccf->p_ucce		= (u32 *) &(uf_regs->ucce);
	uccf->p_uccm		= (u32 *) &(uf_regs->uccm);

	/* Init GUEMR register, UCC both Rx and Tx is Fast protocol */
	out_8(&uf_regs->guemr, UCC_GUEMR_SET_RESERVED3 | UCC_GUEMR_MODE_FAST_RX
				 | UCC_GUEMR_MODE_FAST_TX);

	/* Set GUMR, disable UCC both Rx and Tx, Ethernet protocol */
	out_be32(&uf_regs->gumr, UCC_FAST_GUMR_ETH);

	/* Set the Giga ethernet VFIFO stuff */
	if (uf_info->eth_type == GIGA_ETH) {
		/* Allocate memory for Tx Virtual Fifo */
		uccf->ucc_fast_tx_virtual_fifo_base_offset =
		qe_muram_alloc(UCC_GETH_UTFS_GIGA_INIT,
				 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);

		/* Allocate memory for Rx Virtual Fifo */
		uccf->ucc_fast_rx_virtual_fifo_base_offset =
		qe_muram_alloc(UCC_GETH_URFS_GIGA_INIT +
				 UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD,
				UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);

		/* utfb, urfb are offsets from MURAM base */
		out_be32(&uf_regs->utfb,
			 uccf->ucc_fast_tx_virtual_fifo_base_offset);
		out_be32(&uf_regs->urfb,
			 uccf->ucc_fast_rx_virtual_fifo_base_offset);

		/* Set Virtual Fifo registers */
		out_be16(&uf_regs->urfs, UCC_GETH_URFS_GIGA_INIT);
		out_be16(&uf_regs->urfet, UCC_GETH_URFET_GIGA_INIT);
		out_be16(&uf_regs->urfset, UCC_GETH_URFSET_GIGA_INIT);
		out_be16(&uf_regs->utfs, UCC_GETH_UTFS_GIGA_INIT);
		out_be16(&uf_regs->utfet, UCC_GETH_UTFET_GIGA_INIT);
		out_be16(&uf_regs->utftt, UCC_GETH_UTFTT_GIGA_INIT);
	}

	/* Set the Fast ethernet VFIFO stuff */
	if (uf_info->eth_type == FAST_ETH) {
		/* Allocate memory for Tx Virtual Fifo */
		uccf->ucc_fast_tx_virtual_fifo_base_offset =
		qe_muram_alloc(UCC_GETH_UTFS_INIT,
				 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);

		/* Allocate memory for Rx Virtual Fifo */
		uccf->ucc_fast_rx_virtual_fifo_base_offset =
		qe_muram_alloc(UCC_GETH_URFS_INIT +
				 UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD,
				UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);

		/* utfb, urfb are offsets from MURAM base */
		out_be32(&uf_regs->utfb,
			 uccf->ucc_fast_tx_virtual_fifo_base_offset);
		out_be32(&uf_regs->urfb,
			 uccf->ucc_fast_rx_virtual_fifo_base_offset);

		/* Set Virtual Fifo registers */
		out_be16(&uf_regs->urfs, UCC_GETH_URFS_INIT);
		out_be16(&uf_regs->urfet, UCC_GETH_URFET_INIT);
		out_be16(&uf_regs->urfset, UCC_GETH_URFSET_INIT);
		out_be16(&uf_regs->utfs, UCC_GETH_UTFS_INIT);
		out_be16(&uf_regs->utfet, UCC_GETH_UTFET_INIT);
 		out_be16(&uf_regs->utftt, UCC_GETH_UTFTT_INIT);
	}

	/* Rx clock routing */
	if (uf_info->rx_clock != QE_CLK_NONE) {
		if (ucc_set_clk_src(uf_info->ucc_num,
			 uf_info->rx_clock, COMM_DIR_RX)) {
			printf("%s: Illegal value for parameter 'RxClock'.\n",
				 __FUNCTION__);
			return -EINVAL;
		}
	}

	/* Tx clock routing */
	if (uf_info->tx_clock != QE_CLK_NONE) {
		if (ucc_set_clk_src(uf_info->ucc_num,
			 uf_info->tx_clock, COMM_DIR_TX)) {
			printf("%s: Illegal value for parameter 'TxClock'.\n",
				 __FUNCTION__);
			return -EINVAL;
		}
	}

	/* Clear interrupt mask register to disable all of interrupts */
	out_be32(&uf_regs->uccm, 0x0);

	/* Writing '1' to clear all of envents */
	out_be32(&uf_regs->ucce, 0xffffffff);

	*uccf_ret = uccf;
	return 0;
}
#endif /* CONFIG_QE */
