/* Altera TSE SGDMA and MSGDMA Linux driver
 * Copyright (C) 2014 Altera Corporation. All rights reserved
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
 */

#include <linux/netdevice.h>
#include "altera_utils.h"
#include "altera_tse.h"
#include "altera_msgdmahw.h"

/* No initialization work to do for MSGDMA */
int msgdma_initialize(struct altera_tse_private *priv)
{
	return 0;
}

void msgdma_uninitialize(struct altera_tse_private *priv)
{
}

void msgdma_reset(struct altera_tse_private *priv)
{
	int counter;
	struct msgdma_csr *txcsr =
		(struct msgdma_csr *)priv->tx_dma_csr;
	struct msgdma_csr *rxcsr =
		(struct msgdma_csr *)priv->rx_dma_csr;

	/* Reset Rx mSGDMA */
	iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);
	iowrite32(MSGDMA_CSR_CTL_RESET, &rxcsr->control);

	counter = 0;
	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
		if (tse_bit_is_clear(&rxcsr->status,
				     MSGDMA_CSR_STAT_RESETTING))
			break;
		udelay(1);
	}

	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
		netif_warn(priv, drv, priv->dev,
			   "TSE Rx mSGDMA resetting bit never cleared!\n");

	/* clear all status bits */
	iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);

	/* Reset Tx mSGDMA */
	iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status);
	iowrite32(MSGDMA_CSR_CTL_RESET, &txcsr->control);

	counter = 0;
	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
		if (tse_bit_is_clear(&txcsr->status,
				     MSGDMA_CSR_STAT_RESETTING))
			break;
		udelay(1);
	}

	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
		netif_warn(priv, drv, priv->dev,
			   "TSE Tx mSGDMA resetting bit never cleared!\n");

	/* clear all status bits */
	iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status);
}

void msgdma_disable_rxirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->rx_dma_csr;
	tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
}

void msgdma_enable_rxirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->rx_dma_csr;
	tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
}

void msgdma_disable_txirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->tx_dma_csr;
	tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
}

void msgdma_enable_txirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->tx_dma_csr;
	tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
}

void msgdma_clear_rxirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->rx_dma_csr;
	iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status);
}

void msgdma_clear_txirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->tx_dma_csr;
	iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status);
}

/* return 0 to indicate transmit is pending */
int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
{
	struct msgdma_extended_desc *desc = priv->tx_dma_desc;

	iowrite32(lower_32_bits(buffer->dma_addr), &desc->read_addr_lo);
	iowrite32(upper_32_bits(buffer->dma_addr), &desc->read_addr_hi);
	iowrite32(0, &desc->write_addr_lo);
	iowrite32(0, &desc->write_addr_hi);
	iowrite32(buffer->len, &desc->len);
	iowrite32(0, &desc->burst_seq_num);
	iowrite32(MSGDMA_DESC_TX_STRIDE, &desc->stride);
	iowrite32(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control);
	return 0;
}

u32 msgdma_tx_completions(struct altera_tse_private *priv)
{
	u32 ready = 0;
	u32 inuse;
	u32 status;
	struct msgdma_csr *txcsr =
		(struct msgdma_csr *)priv->tx_dma_csr;

	/* Get number of sent descriptors */
	inuse = ioread32(&txcsr->rw_fill_level) & 0xffff;

	if (inuse) { /* Tx FIFO is not empty */
		ready = priv->tx_prod - priv->tx_cons - inuse - 1;
	} else {
		/* Check for buffered last packet */
		status = ioread32(&txcsr->status);
		if (status & MSGDMA_CSR_STAT_BUSY)
			ready = priv->tx_prod - priv->tx_cons - 1;
		else
			ready = priv->tx_prod - priv->tx_cons;
	}
	return ready;
}

/* Put buffer to the mSGDMA RX FIFO
 */
int msgdma_add_rx_desc(struct altera_tse_private *priv,
			struct tse_buffer *rxbuffer)
{
	struct msgdma_extended_desc *desc = priv->rx_dma_desc;
	u32 len = priv->rx_dma_buf_sz;
	dma_addr_t dma_addr = rxbuffer->dma_addr;
	u32 control = (MSGDMA_DESC_CTL_END_ON_EOP
			| MSGDMA_DESC_CTL_END_ON_LEN
			| MSGDMA_DESC_CTL_TR_COMP_IRQ
			| MSGDMA_DESC_CTL_EARLY_IRQ
			| MSGDMA_DESC_CTL_TR_ERR_IRQ
			| MSGDMA_DESC_CTL_GO);

	iowrite32(0, &desc->read_addr_lo);
	iowrite32(0, &desc->read_addr_hi);
	iowrite32(lower_32_bits(dma_addr), &desc->write_addr_lo);
	iowrite32(upper_32_bits(dma_addr), &desc->write_addr_hi);
	iowrite32(len, &desc->len);
	iowrite32(0, &desc->burst_seq_num);
	iowrite32(0x00010001, &desc->stride);
	iowrite32(control, &desc->control);
	return 1;
}

/* status is returned on upper 16 bits,
 * length is returned in lower 16 bits
 */
u32 msgdma_rx_status(struct altera_tse_private *priv)
{
	u32 rxstatus = 0;
	u32 pktlength;
	u32 pktstatus;
	struct msgdma_csr *rxcsr =
		(struct msgdma_csr *)priv->rx_dma_csr;
	struct msgdma_response *rxresp =
		(struct msgdma_response *)priv->rx_dma_resp;

	if (ioread32(&rxcsr->resp_fill_level) & 0xffff) {
		pktlength = ioread32(&rxresp->bytes_transferred);
		pktstatus = ioread32(&rxresp->status);
		rxstatus = pktstatus;
		rxstatus = rxstatus << 16;
		rxstatus |= (pktlength & 0xffff);
	}
	return rxstatus;
}
