xref: /openbmc/linux/drivers/net/ethernet/altera/altera_msgdma.c (revision 37c0ffaad21401eacc6618a121cc2c501131026f)
194fb0ef4SVince Bridgers /* Altera TSE SGDMA and MSGDMA Linux driver
294fb0ef4SVince Bridgers  * Copyright (C) 2014 Altera Corporation. All rights reserved
394fb0ef4SVince Bridgers  *
494fb0ef4SVince Bridgers  * This program is free software; you can redistribute it and/or modify it
594fb0ef4SVince Bridgers  * under the terms and conditions of the GNU General Public License,
694fb0ef4SVince Bridgers  * version 2, as published by the Free Software Foundation.
794fb0ef4SVince Bridgers  *
894fb0ef4SVince Bridgers  * This program is distributed in the hope it will be useful, but WITHOUT
994fb0ef4SVince Bridgers  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1094fb0ef4SVince Bridgers  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1194fb0ef4SVince Bridgers  * more details.
1294fb0ef4SVince Bridgers  *
1394fb0ef4SVince Bridgers  * You should have received a copy of the GNU General Public License along with
1494fb0ef4SVince Bridgers  * this program.  If not, see <http://www.gnu.org/licenses/>.
1594fb0ef4SVince Bridgers  */
1694fb0ef4SVince Bridgers 
1794fb0ef4SVince Bridgers #include <linux/netdevice.h>
1894fb0ef4SVince Bridgers #include "altera_utils.h"
1994fb0ef4SVince Bridgers #include "altera_tse.h"
2094fb0ef4SVince Bridgers #include "altera_msgdmahw.h"
2194fb0ef4SVince Bridgers 
2294fb0ef4SVince Bridgers /* No initialization work to do for MSGDMA */
2394fb0ef4SVince Bridgers int msgdma_initialize(struct altera_tse_private *priv)
2494fb0ef4SVince Bridgers {
2594fb0ef4SVince Bridgers 	return 0;
2694fb0ef4SVince Bridgers }
2794fb0ef4SVince Bridgers 
2894fb0ef4SVince Bridgers void msgdma_uninitialize(struct altera_tse_private *priv)
2994fb0ef4SVince Bridgers {
3094fb0ef4SVince Bridgers }
3194fb0ef4SVince Bridgers 
32*37c0ffaaSVince Bridgers void msgdma_start_rxdma(struct altera_tse_private *priv)
33*37c0ffaaSVince Bridgers {
34*37c0ffaaSVince Bridgers }
35*37c0ffaaSVince Bridgers 
3694fb0ef4SVince Bridgers void msgdma_reset(struct altera_tse_private *priv)
3794fb0ef4SVince Bridgers {
3894fb0ef4SVince Bridgers 	int counter;
3994fb0ef4SVince Bridgers 	struct msgdma_csr *txcsr =
4094fb0ef4SVince Bridgers 		(struct msgdma_csr *)priv->tx_dma_csr;
4194fb0ef4SVince Bridgers 	struct msgdma_csr *rxcsr =
4294fb0ef4SVince Bridgers 		(struct msgdma_csr *)priv->rx_dma_csr;
4394fb0ef4SVince Bridgers 
4494fb0ef4SVince Bridgers 	/* Reset Rx mSGDMA */
4594fb0ef4SVince Bridgers 	iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);
4694fb0ef4SVince Bridgers 	iowrite32(MSGDMA_CSR_CTL_RESET, &rxcsr->control);
4794fb0ef4SVince Bridgers 
4894fb0ef4SVince Bridgers 	counter = 0;
4994fb0ef4SVince Bridgers 	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
5094fb0ef4SVince Bridgers 		if (tse_bit_is_clear(&rxcsr->status,
5194fb0ef4SVince Bridgers 				     MSGDMA_CSR_STAT_RESETTING))
5294fb0ef4SVince Bridgers 			break;
5394fb0ef4SVince Bridgers 		udelay(1);
5494fb0ef4SVince Bridgers 	}
5594fb0ef4SVince Bridgers 
5694fb0ef4SVince Bridgers 	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
5794fb0ef4SVince Bridgers 		netif_warn(priv, drv, priv->dev,
5894fb0ef4SVince Bridgers 			   "TSE Rx mSGDMA resetting bit never cleared!\n");
5994fb0ef4SVince Bridgers 
6094fb0ef4SVince Bridgers 	/* clear all status bits */
6194fb0ef4SVince Bridgers 	iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);
6294fb0ef4SVince Bridgers 
6394fb0ef4SVince Bridgers 	/* Reset Tx mSGDMA */
6494fb0ef4SVince Bridgers 	iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status);
6594fb0ef4SVince Bridgers 	iowrite32(MSGDMA_CSR_CTL_RESET, &txcsr->control);
6694fb0ef4SVince Bridgers 
6794fb0ef4SVince Bridgers 	counter = 0;
6894fb0ef4SVince Bridgers 	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
6994fb0ef4SVince Bridgers 		if (tse_bit_is_clear(&txcsr->status,
7094fb0ef4SVince Bridgers 				     MSGDMA_CSR_STAT_RESETTING))
7194fb0ef4SVince Bridgers 			break;
7294fb0ef4SVince Bridgers 		udelay(1);
7394fb0ef4SVince Bridgers 	}
7494fb0ef4SVince Bridgers 
7594fb0ef4SVince Bridgers 	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
7694fb0ef4SVince Bridgers 		netif_warn(priv, drv, priv->dev,
7794fb0ef4SVince Bridgers 			   "TSE Tx mSGDMA resetting bit never cleared!\n");
7894fb0ef4SVince Bridgers 
7994fb0ef4SVince Bridgers 	/* clear all status bits */
8094fb0ef4SVince Bridgers 	iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status);
8194fb0ef4SVince Bridgers }
8294fb0ef4SVince Bridgers 
8394fb0ef4SVince Bridgers void msgdma_disable_rxirq(struct altera_tse_private *priv)
8494fb0ef4SVince Bridgers {
8594fb0ef4SVince Bridgers 	struct msgdma_csr *csr = priv->rx_dma_csr;
8694fb0ef4SVince Bridgers 	tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
8794fb0ef4SVince Bridgers }
8894fb0ef4SVince Bridgers 
8994fb0ef4SVince Bridgers void msgdma_enable_rxirq(struct altera_tse_private *priv)
9094fb0ef4SVince Bridgers {
9194fb0ef4SVince Bridgers 	struct msgdma_csr *csr = priv->rx_dma_csr;
9294fb0ef4SVince Bridgers 	tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
9394fb0ef4SVince Bridgers }
9494fb0ef4SVince Bridgers 
9594fb0ef4SVince Bridgers void msgdma_disable_txirq(struct altera_tse_private *priv)
9694fb0ef4SVince Bridgers {
9794fb0ef4SVince Bridgers 	struct msgdma_csr *csr = priv->tx_dma_csr;
9894fb0ef4SVince Bridgers 	tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
9994fb0ef4SVince Bridgers }
10094fb0ef4SVince Bridgers 
10194fb0ef4SVince Bridgers void msgdma_enable_txirq(struct altera_tse_private *priv)
10294fb0ef4SVince Bridgers {
10394fb0ef4SVince Bridgers 	struct msgdma_csr *csr = priv->tx_dma_csr;
10494fb0ef4SVince Bridgers 	tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
10594fb0ef4SVince Bridgers }
10694fb0ef4SVince Bridgers 
10794fb0ef4SVince Bridgers void msgdma_clear_rxirq(struct altera_tse_private *priv)
10894fb0ef4SVince Bridgers {
10994fb0ef4SVince Bridgers 	struct msgdma_csr *csr = priv->rx_dma_csr;
11094fb0ef4SVince Bridgers 	iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status);
11194fb0ef4SVince Bridgers }
11294fb0ef4SVince Bridgers 
11394fb0ef4SVince Bridgers void msgdma_clear_txirq(struct altera_tse_private *priv)
11494fb0ef4SVince Bridgers {
11594fb0ef4SVince Bridgers 	struct msgdma_csr *csr = priv->tx_dma_csr;
11694fb0ef4SVince Bridgers 	iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status);
11794fb0ef4SVince Bridgers }
11894fb0ef4SVince Bridgers 
11994fb0ef4SVince Bridgers /* return 0 to indicate transmit is pending */
12094fb0ef4SVince Bridgers int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
12194fb0ef4SVince Bridgers {
12294fb0ef4SVince Bridgers 	struct msgdma_extended_desc *desc = priv->tx_dma_desc;
12394fb0ef4SVince Bridgers 
12494fb0ef4SVince Bridgers 	iowrite32(lower_32_bits(buffer->dma_addr), &desc->read_addr_lo);
12594fb0ef4SVince Bridgers 	iowrite32(upper_32_bits(buffer->dma_addr), &desc->read_addr_hi);
12694fb0ef4SVince Bridgers 	iowrite32(0, &desc->write_addr_lo);
12794fb0ef4SVince Bridgers 	iowrite32(0, &desc->write_addr_hi);
12894fb0ef4SVince Bridgers 	iowrite32(buffer->len, &desc->len);
12994fb0ef4SVince Bridgers 	iowrite32(0, &desc->burst_seq_num);
13094fb0ef4SVince Bridgers 	iowrite32(MSGDMA_DESC_TX_STRIDE, &desc->stride);
13194fb0ef4SVince Bridgers 	iowrite32(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control);
13294fb0ef4SVince Bridgers 	return 0;
13394fb0ef4SVince Bridgers }
13494fb0ef4SVince Bridgers 
13594fb0ef4SVince Bridgers u32 msgdma_tx_completions(struct altera_tse_private *priv)
13694fb0ef4SVince Bridgers {
13794fb0ef4SVince Bridgers 	u32 ready = 0;
13894fb0ef4SVince Bridgers 	u32 inuse;
13994fb0ef4SVince Bridgers 	u32 status;
14094fb0ef4SVince Bridgers 	struct msgdma_csr *txcsr =
14194fb0ef4SVince Bridgers 		(struct msgdma_csr *)priv->tx_dma_csr;
14294fb0ef4SVince Bridgers 
14394fb0ef4SVince Bridgers 	/* Get number of sent descriptors */
14494fb0ef4SVince Bridgers 	inuse = ioread32(&txcsr->rw_fill_level) & 0xffff;
14594fb0ef4SVince Bridgers 
14694fb0ef4SVince Bridgers 	if (inuse) { /* Tx FIFO is not empty */
14794fb0ef4SVince Bridgers 		ready = priv->tx_prod - priv->tx_cons - inuse - 1;
14894fb0ef4SVince Bridgers 	} else {
14994fb0ef4SVince Bridgers 		/* Check for buffered last packet */
15094fb0ef4SVince Bridgers 		status = ioread32(&txcsr->status);
15194fb0ef4SVince Bridgers 		if (status & MSGDMA_CSR_STAT_BUSY)
15294fb0ef4SVince Bridgers 			ready = priv->tx_prod - priv->tx_cons - 1;
15394fb0ef4SVince Bridgers 		else
15494fb0ef4SVince Bridgers 			ready = priv->tx_prod - priv->tx_cons;
15594fb0ef4SVince Bridgers 	}
15694fb0ef4SVince Bridgers 	return ready;
15794fb0ef4SVince Bridgers }
15894fb0ef4SVince Bridgers 
15994fb0ef4SVince Bridgers /* Put buffer to the mSGDMA RX FIFO
16094fb0ef4SVince Bridgers  */
161*37c0ffaaSVince Bridgers void msgdma_add_rx_desc(struct altera_tse_private *priv,
16294fb0ef4SVince Bridgers 			struct tse_buffer *rxbuffer)
16394fb0ef4SVince Bridgers {
16494fb0ef4SVince Bridgers 	struct msgdma_extended_desc *desc = priv->rx_dma_desc;
16594fb0ef4SVince Bridgers 	u32 len = priv->rx_dma_buf_sz;
16694fb0ef4SVince Bridgers 	dma_addr_t dma_addr = rxbuffer->dma_addr;
16794fb0ef4SVince Bridgers 	u32 control = (MSGDMA_DESC_CTL_END_ON_EOP
16894fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_END_ON_LEN
16994fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_TR_COMP_IRQ
17094fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_EARLY_IRQ
17194fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_TR_ERR_IRQ
17294fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_GO);
17394fb0ef4SVince Bridgers 
17494fb0ef4SVince Bridgers 	iowrite32(0, &desc->read_addr_lo);
17594fb0ef4SVince Bridgers 	iowrite32(0, &desc->read_addr_hi);
17694fb0ef4SVince Bridgers 	iowrite32(lower_32_bits(dma_addr), &desc->write_addr_lo);
17794fb0ef4SVince Bridgers 	iowrite32(upper_32_bits(dma_addr), &desc->write_addr_hi);
17894fb0ef4SVince Bridgers 	iowrite32(len, &desc->len);
17994fb0ef4SVince Bridgers 	iowrite32(0, &desc->burst_seq_num);
18094fb0ef4SVince Bridgers 	iowrite32(0x00010001, &desc->stride);
18194fb0ef4SVince Bridgers 	iowrite32(control, &desc->control);
18294fb0ef4SVince Bridgers }
18394fb0ef4SVince Bridgers 
18494fb0ef4SVince Bridgers /* status is returned on upper 16 bits,
18594fb0ef4SVince Bridgers  * length is returned in lower 16 bits
18694fb0ef4SVince Bridgers  */
18794fb0ef4SVince Bridgers u32 msgdma_rx_status(struct altera_tse_private *priv)
18894fb0ef4SVince Bridgers {
18994fb0ef4SVince Bridgers 	u32 rxstatus = 0;
19094fb0ef4SVince Bridgers 	u32 pktlength;
19194fb0ef4SVince Bridgers 	u32 pktstatus;
19294fb0ef4SVince Bridgers 	struct msgdma_csr *rxcsr =
19394fb0ef4SVince Bridgers 		(struct msgdma_csr *)priv->rx_dma_csr;
19494fb0ef4SVince Bridgers 	struct msgdma_response *rxresp =
19594fb0ef4SVince Bridgers 		(struct msgdma_response *)priv->rx_dma_resp;
19694fb0ef4SVince Bridgers 
19794fb0ef4SVince Bridgers 	if (ioread32(&rxcsr->resp_fill_level) & 0xffff) {
19894fb0ef4SVince Bridgers 		pktlength = ioread32(&rxresp->bytes_transferred);
19994fb0ef4SVince Bridgers 		pktstatus = ioread32(&rxresp->status);
20094fb0ef4SVince Bridgers 		rxstatus = pktstatus;
20194fb0ef4SVince Bridgers 		rxstatus = rxstatus << 16;
20294fb0ef4SVince Bridgers 		rxstatus |= (pktlength & 0xffff);
20394fb0ef4SVince Bridgers 	}
20494fb0ef4SVince Bridgers 	return rxstatus;
20594fb0ef4SVince Bridgers }
206