/*
 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
 *
 * Authors: 	Shlomi Gridish <gridish@freescale.com>
 * 		Li Yang <leoli@freescale.com>
 *
 * Description:
 * QE UCC Fast API Set - UCC Fast specific routines implementations.
 *
 * 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.
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/interrupt.h>

#include <asm/io.h>
#include <asm/immap_qe.h>
#include <asm/qe.h>

#include <asm/ucc.h>
#include <asm/ucc_fast.h>

void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
{
	printk(KERN_INFO "UCC%d Fast registers:", uccf->uf_info->ucc_num);
	printk(KERN_INFO "Base address: 0x%08x", (u32) uccf->uf_regs);

	printk(KERN_INFO "gumr  : addr - 0x%08x, val - 0x%08x",
		  (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
	printk(KERN_INFO "upsmr : addr - 0x%08x, val - 0x%08x",
		  (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
	printk(KERN_INFO "utodr : addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
	printk(KERN_INFO "udsr  : addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
	printk(KERN_INFO "ucce  : addr - 0x%08x, val - 0x%08x",
		  (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
	printk(KERN_INFO "uccm  : addr - 0x%08x, val - 0x%08x",
		  (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
	printk(KERN_INFO "uccs  : addr - 0x%08x, val - 0x%02x",
		  (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs);
	printk(KERN_INFO "urfb  : addr - 0x%08x, val - 0x%08x",
		  (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
	printk(KERN_INFO "urfs  : addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
	printk(KERN_INFO "urfet : addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
	printk(KERN_INFO "urfset: addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->urfset,
		  in_be16(&uccf->uf_regs->urfset));
	printk(KERN_INFO "utfb  : addr - 0x%08x, val - 0x%08x",
		  (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
	printk(KERN_INFO "utfs  : addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
	printk(KERN_INFO "utfet : addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
	printk(KERN_INFO "utftt : addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
	printk(KERN_INFO "utpt  : addr - 0x%08x, val - 0x%04x",
		  (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
	printk(KERN_INFO "urtry : addr - 0x%08x, val - 0x%08x",
		  (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
	printk(KERN_INFO "guemr : addr - 0x%08x, val - 0x%02x",
		  (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr);
}

u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
{
	switch (uccf_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;
	}
}

void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf)
{
	out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
}

void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
{
	struct ucc_fast *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(struct ucc_fast_private * uccf, enum comm_dir mode)
{
	struct ucc_fast *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(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret)
{
	struct ucc_fast_private *uccf;
	struct ucc_fast *uf_regs;
	u32 gumr;
	int ret;

	if (!uf_info)
		return -EINVAL;

	/* check if the UCC port number is in range. */
	if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
		printk(KERN_ERR "%s: illegal UCC number", __FUNCTION__);
		return -EINVAL;
	}

	/* Check that 'max_rx_buf_length' is properly aligned (4). */
	if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) {
		printk(KERN_ERR "%s: max_rx_buf_length not aligned", __FUNCTION__);
		return -EINVAL;
	}

	/* Validate Virtual Fifo register values */
	if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) {
		printk(KERN_ERR "%s: urfs is too small", __FUNCTION__);
		return -EINVAL;
	}

	if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
		printk(KERN_ERR "%s: urfs is not aligned", __FUNCTION__);
		return -EINVAL;
	}

	if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
		printk(KERN_ERR "%s: urfet is not aligned.", __FUNCTION__);
		return -EINVAL;
	}

	if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
		printk(KERN_ERR "%s: urfset is not aligned", __FUNCTION__);
		return -EINVAL;
	}

	if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
		printk(KERN_ERR "%s: utfs is not aligned", __FUNCTION__);
		return -EINVAL;
	}

	if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
		printk(KERN_ERR "%s: utfet is not aligned", __FUNCTION__);
		return -EINVAL;
	}

	if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
		printk(KERN_ERR "%s: utftt is not aligned", __FUNCTION__);
		return -EINVAL;
	}

	uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
	if (!uccf) {
		printk(KERN_ERR "%s: Cannot allocate private data", __FUNCTION__);
		return -ENOMEM;
	}

	/* Fill fast UCC structure */
	uccf->uf_info = uf_info;
	/* Set the PHY base address */
	uccf->uf_regs = ioremap(uf_info->regs, sizeof(struct ucc_fast));
	if (uccf->uf_regs == NULL) {
		printk(KERN_ERR "%s: Cannot map UCC registers", __FUNCTION__);
		return -ENOMEM;
	}

	uccf->enabled_tx = 0;
	uccf->enabled_rx = 0;
	uccf->stopped_tx = 0;
	uccf->stopped_rx = 0;
	uf_regs = uccf->uf_regs;
	uccf->p_ucce = (u32 *) & (uf_regs->ucce);
	uccf->p_uccm = (u32 *) & (uf_regs->uccm);
#ifdef CONFIG_UGETH_TX_ON_DEMAND
	uccf->p_utodr = (u16 *) & (uf_regs->utodr);
#endif
#ifdef STATISTICS
	uccf->tx_frames = 0;
	uccf->rx_frames = 0;
	uccf->rx_discarded = 0;
#endif				/* STATISTICS */

	/* Init Guemr register */
	if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) {
		printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__);
		ucc_fast_free(uccf);
		return ret;
	}

	/* Set UCC to fast type */
	if ((ret = ucc_set_type(uf_info->ucc_num,
				(struct ucc_common *) (uf_regs),
				UCC_SPEED_TYPE_FAST))) {
		printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__);
		ucc_fast_free(uccf);
		return ret;
	}

	uccf->mrblr = uf_info->max_rx_buf_length;

	/* Set GUMR */
	/* For more details see the hardware spec. */
	gumr = uf_info->ttx_trx;
	if (uf_info->tci)
		gumr |= UCC_FAST_GUMR_TCI;
	if (uf_info->cdp)
		gumr |= UCC_FAST_GUMR_CDP;
	if (uf_info->ctsp)
		gumr |= UCC_FAST_GUMR_CTSP;
	if (uf_info->cds)
		gumr |= UCC_FAST_GUMR_CDS;
	if (uf_info->ctss)
		gumr |= UCC_FAST_GUMR_CTSS;
	if (uf_info->txsy)
		gumr |= UCC_FAST_GUMR_TXSY;
	if (uf_info->rsyn)
		gumr |= UCC_FAST_GUMR_RSYN;
	gumr |= uf_info->synl;
	if (uf_info->rtsm)
		gumr |= UCC_FAST_GUMR_RTSM;
	gumr |= uf_info->renc;
	if (uf_info->revd)
		gumr |= UCC_FAST_GUMR_REVD;
	gumr |= uf_info->tenc;
	gumr |= uf_info->tcrc;
	gumr |= uf_info->mode;
	out_be32(&uf_regs->gumr, gumr);

	/* Allocate memory for Tx Virtual Fifo */
	uccf->ucc_fast_tx_virtual_fifo_base_offset =
	    qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
	if (IS_MURAM_ERR(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
		printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO", __FUNCTION__);
		uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
		ucc_fast_free(uccf);
		return -ENOMEM;
	}

	/* Allocate memory for Rx Virtual Fifo */
	uccf->ucc_fast_rx_virtual_fifo_base_offset =
		qe_muram_alloc(uf_info->urfs +
			   UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
			   UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
	if (IS_MURAM_ERR(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
		printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO", __FUNCTION__);
		uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
		ucc_fast_free(uccf);
		return -ENOMEM;
	}

	/* Set Virtual Fifo registers */
	out_be16(&uf_regs->urfs, uf_info->urfs);
	out_be16(&uf_regs->urfet, uf_info->urfet);
	out_be16(&uf_regs->urfset, uf_info->urfset);
	out_be16(&uf_regs->utfs, uf_info->utfs);
	out_be16(&uf_regs->utfet, uf_info->utfet);
	out_be16(&uf_regs->utftt, uf_info->utftt);
	/* 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);

	/* Mux clocking */
	/* Grant Support */
	ucc_set_qe_mux_grant(uf_info->ucc_num, uf_info->grant_support);
	/* Breakpoint Support */
	ucc_set_qe_mux_bkpt(uf_info->ucc_num, uf_info->brkpt_support);
	/* Set Tsa or NMSI mode. */
	ucc_set_qe_mux_tsa(uf_info->ucc_num, uf_info->tsa);
	/* If NMSI (not Tsa), set Tx and Rx clock. */
	if (!uf_info->tsa) {
		/* Rx clock routing */
		if ((uf_info->rx_clock != QE_CLK_NONE) &&
		    ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->rx_clock,
					COMM_DIR_RX)) {
			printk(KERN_ERR "%s: illegal value for RX clock",
			       __FUNCTION__);
			ucc_fast_free(uccf);
			return -EINVAL;
		}
		/* Tx clock routing */
		if ((uf_info->tx_clock != QE_CLK_NONE) &&
		    ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->tx_clock,
					COMM_DIR_TX)) {
			printk(KERN_ERR "%s: illegal value for TX clock",
			       __FUNCTION__);
			ucc_fast_free(uccf);
			return -EINVAL;
		}
	}

	/* Set interrupt mask register at UCC level. */
	out_be32(&uf_regs->uccm, uf_info->uccm_mask);

	/* First, clear anything pending at UCC level,
	 * otherwise, old garbage may come through
	 * as soon as the dam is opened. */

	/* Writing '1' clears */
	out_be32(&uf_regs->ucce, 0xffffffff);

	*uccf_ret = uccf;
	return 0;
}

void ucc_fast_free(struct ucc_fast_private * uccf)
{
	if (!uccf)
		return;

	if (uccf->ucc_fast_tx_virtual_fifo_base_offset)
		qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset);

	if (uccf->ucc_fast_rx_virtual_fifo_base_offset)
		qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);

	kfree(uccf);
}
