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" 21652f99eaSTobias Klauser #include "altera_msgdma.h" 2294fb0ef4SVince Bridgers 2394fb0ef4SVince Bridgers /* No initialization work to do for MSGDMA */ 2494fb0ef4SVince Bridgers int msgdma_initialize(struct altera_tse_private *priv) 2594fb0ef4SVince Bridgers { 2694fb0ef4SVince Bridgers return 0; 2794fb0ef4SVince Bridgers } 2894fb0ef4SVince Bridgers 2994fb0ef4SVince Bridgers void msgdma_uninitialize(struct altera_tse_private *priv) 3094fb0ef4SVince Bridgers { 3194fb0ef4SVince Bridgers } 3294fb0ef4SVince Bridgers 3337c0ffaaSVince Bridgers void msgdma_start_rxdma(struct altera_tse_private *priv) 3437c0ffaaSVince Bridgers { 3537c0ffaaSVince Bridgers } 3637c0ffaaSVince Bridgers 3794fb0ef4SVince Bridgers void msgdma_reset(struct altera_tse_private *priv) 3894fb0ef4SVince Bridgers { 3994fb0ef4SVince Bridgers int counter; 4094fb0ef4SVince Bridgers 4194fb0ef4SVince Bridgers /* Reset Rx mSGDMA */ 42*89830580SVince Bridgers csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, 43*89830580SVince Bridgers msgdma_csroffs(status)); 44*89830580SVince Bridgers csrwr32(MSGDMA_CSR_CTL_RESET, priv->rx_dma_csr, 45*89830580SVince Bridgers msgdma_csroffs(control)); 4694fb0ef4SVince Bridgers 4794fb0ef4SVince Bridgers counter = 0; 4894fb0ef4SVince Bridgers while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { 49*89830580SVince Bridgers if (tse_bit_is_clear(priv->rx_dma_csr, msgdma_csroffs(status), 5094fb0ef4SVince Bridgers MSGDMA_CSR_STAT_RESETTING)) 5194fb0ef4SVince Bridgers break; 5294fb0ef4SVince Bridgers udelay(1); 5394fb0ef4SVince Bridgers } 5494fb0ef4SVince Bridgers 5594fb0ef4SVince Bridgers if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) 5694fb0ef4SVince Bridgers netif_warn(priv, drv, priv->dev, 5794fb0ef4SVince Bridgers "TSE Rx mSGDMA resetting bit never cleared!\n"); 5894fb0ef4SVince Bridgers 5994fb0ef4SVince Bridgers /* clear all status bits */ 60*89830580SVince Bridgers csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, msgdma_csroffs(status)); 6194fb0ef4SVince Bridgers 6294fb0ef4SVince Bridgers /* Reset Tx mSGDMA */ 63*89830580SVince Bridgers csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, 64*89830580SVince Bridgers msgdma_csroffs(status)); 65*89830580SVince Bridgers 66*89830580SVince Bridgers csrwr32(MSGDMA_CSR_CTL_RESET, priv->tx_dma_csr, 67*89830580SVince Bridgers msgdma_csroffs(control)); 6894fb0ef4SVince Bridgers 6994fb0ef4SVince Bridgers counter = 0; 7094fb0ef4SVince Bridgers while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { 71*89830580SVince Bridgers if (tse_bit_is_clear(priv->tx_dma_csr, msgdma_csroffs(status), 7294fb0ef4SVince Bridgers MSGDMA_CSR_STAT_RESETTING)) 7394fb0ef4SVince Bridgers break; 7494fb0ef4SVince Bridgers udelay(1); 7594fb0ef4SVince Bridgers } 7694fb0ef4SVince Bridgers 7794fb0ef4SVince Bridgers if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) 7894fb0ef4SVince Bridgers netif_warn(priv, drv, priv->dev, 7994fb0ef4SVince Bridgers "TSE Tx mSGDMA resetting bit never cleared!\n"); 8094fb0ef4SVince Bridgers 8194fb0ef4SVince Bridgers /* clear all status bits */ 82*89830580SVince Bridgers csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, msgdma_csroffs(status)); 8394fb0ef4SVince Bridgers } 8494fb0ef4SVince Bridgers 8594fb0ef4SVince Bridgers void msgdma_disable_rxirq(struct altera_tse_private *priv) 8694fb0ef4SVince Bridgers { 87*89830580SVince Bridgers tse_clear_bit(priv->rx_dma_csr, msgdma_csroffs(control), 88*89830580SVince Bridgers MSGDMA_CSR_CTL_GLOBAL_INTR); 8994fb0ef4SVince Bridgers } 9094fb0ef4SVince Bridgers 9194fb0ef4SVince Bridgers void msgdma_enable_rxirq(struct altera_tse_private *priv) 9294fb0ef4SVince Bridgers { 93*89830580SVince Bridgers tse_set_bit(priv->rx_dma_csr, msgdma_csroffs(control), 94*89830580SVince Bridgers MSGDMA_CSR_CTL_GLOBAL_INTR); 9594fb0ef4SVince Bridgers } 9694fb0ef4SVince Bridgers 9794fb0ef4SVince Bridgers void msgdma_disable_txirq(struct altera_tse_private *priv) 9894fb0ef4SVince Bridgers { 99*89830580SVince Bridgers tse_clear_bit(priv->tx_dma_csr, msgdma_csroffs(control), 100*89830580SVince Bridgers MSGDMA_CSR_CTL_GLOBAL_INTR); 10194fb0ef4SVince Bridgers } 10294fb0ef4SVince Bridgers 10394fb0ef4SVince Bridgers void msgdma_enable_txirq(struct altera_tse_private *priv) 10494fb0ef4SVince Bridgers { 105*89830580SVince Bridgers tse_set_bit(priv->tx_dma_csr, msgdma_csroffs(control), 106*89830580SVince Bridgers MSGDMA_CSR_CTL_GLOBAL_INTR); 10794fb0ef4SVince Bridgers } 10894fb0ef4SVince Bridgers 10994fb0ef4SVince Bridgers void msgdma_clear_rxirq(struct altera_tse_private *priv) 11094fb0ef4SVince Bridgers { 111*89830580SVince Bridgers csrwr32(MSGDMA_CSR_STAT_IRQ, priv->rx_dma_csr, msgdma_csroffs(status)); 11294fb0ef4SVince Bridgers } 11394fb0ef4SVince Bridgers 11494fb0ef4SVince Bridgers void msgdma_clear_txirq(struct altera_tse_private *priv) 11594fb0ef4SVince Bridgers { 116*89830580SVince Bridgers csrwr32(MSGDMA_CSR_STAT_IRQ, priv->tx_dma_csr, msgdma_csroffs(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 { 122*89830580SVince Bridgers csrwr32(lower_32_bits(buffer->dma_addr), priv->tx_dma_desc, 123*89830580SVince Bridgers msgdma_descroffs(read_addr_lo)); 124*89830580SVince Bridgers csrwr32(upper_32_bits(buffer->dma_addr), priv->tx_dma_desc, 125*89830580SVince Bridgers msgdma_descroffs(read_addr_hi)); 126*89830580SVince Bridgers csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_lo)); 127*89830580SVince Bridgers csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_hi)); 128*89830580SVince Bridgers csrwr32(buffer->len, priv->tx_dma_desc, msgdma_descroffs(len)); 129*89830580SVince Bridgers csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(burst_seq_num)); 130*89830580SVince Bridgers csrwr32(MSGDMA_DESC_TX_STRIDE, priv->tx_dma_desc, 131*89830580SVince Bridgers msgdma_descroffs(stride)); 132*89830580SVince Bridgers csrwr32(MSGDMA_DESC_CTL_TX_SINGLE, priv->tx_dma_desc, 133*89830580SVince Bridgers msgdma_descroffs(control)); 13494fb0ef4SVince Bridgers return 0; 13594fb0ef4SVince Bridgers } 13694fb0ef4SVince Bridgers 13794fb0ef4SVince Bridgers u32 msgdma_tx_completions(struct altera_tse_private *priv) 13894fb0ef4SVince Bridgers { 13994fb0ef4SVince Bridgers u32 ready = 0; 14094fb0ef4SVince Bridgers u32 inuse; 14194fb0ef4SVince Bridgers u32 status; 14294fb0ef4SVince Bridgers 14394fb0ef4SVince Bridgers /* Get number of sent descriptors */ 144*89830580SVince Bridgers inuse = csrrd32(priv->tx_dma_csr, msgdma_csroffs(rw_fill_level)) 145*89830580SVince Bridgers & 0xffff; 14694fb0ef4SVince Bridgers 14794fb0ef4SVince Bridgers if (inuse) { /* Tx FIFO is not empty */ 14894fb0ef4SVince Bridgers ready = priv->tx_prod - priv->tx_cons - inuse - 1; 14994fb0ef4SVince Bridgers } else { 15094fb0ef4SVince Bridgers /* Check for buffered last packet */ 151*89830580SVince Bridgers status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status)); 15294fb0ef4SVince Bridgers if (status & MSGDMA_CSR_STAT_BUSY) 15394fb0ef4SVince Bridgers ready = priv->tx_prod - priv->tx_cons - 1; 15494fb0ef4SVince Bridgers else 15594fb0ef4SVince Bridgers ready = priv->tx_prod - priv->tx_cons; 15694fb0ef4SVince Bridgers } 15794fb0ef4SVince Bridgers return ready; 15894fb0ef4SVince Bridgers } 15994fb0ef4SVince Bridgers 16094fb0ef4SVince Bridgers /* Put buffer to the mSGDMA RX FIFO 16194fb0ef4SVince Bridgers */ 16237c0ffaaSVince Bridgers void msgdma_add_rx_desc(struct altera_tse_private *priv, 16394fb0ef4SVince Bridgers struct tse_buffer *rxbuffer) 16494fb0ef4SVince Bridgers { 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 174*89830580SVince Bridgers csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_lo)); 175*89830580SVince Bridgers csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_hi)); 176*89830580SVince Bridgers csrwr32(lower_32_bits(dma_addr), priv->rx_dma_desc, 177*89830580SVince Bridgers msgdma_descroffs(write_addr_lo)); 178*89830580SVince Bridgers csrwr32(upper_32_bits(dma_addr), priv->rx_dma_desc, 179*89830580SVince Bridgers msgdma_descroffs(write_addr_hi)); 180*89830580SVince Bridgers csrwr32(len, priv->rx_dma_desc, msgdma_descroffs(len)); 181*89830580SVince Bridgers csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(burst_seq_num)); 182*89830580SVince Bridgers csrwr32(0x00010001, priv->rx_dma_desc, msgdma_descroffs(stride)); 183*89830580SVince Bridgers csrwr32(control, priv->rx_dma_desc, msgdma_descroffs(control)); 18494fb0ef4SVince Bridgers } 18594fb0ef4SVince Bridgers 18694fb0ef4SVince Bridgers /* status is returned on upper 16 bits, 18794fb0ef4SVince Bridgers * length is returned in lower 16 bits 18894fb0ef4SVince Bridgers */ 18994fb0ef4SVince Bridgers u32 msgdma_rx_status(struct altera_tse_private *priv) 19094fb0ef4SVince Bridgers { 19194fb0ef4SVince Bridgers u32 rxstatus = 0; 19294fb0ef4SVince Bridgers u32 pktlength; 19394fb0ef4SVince Bridgers u32 pktstatus; 19494fb0ef4SVince Bridgers 195*89830580SVince Bridgers if (csrrd32(priv->rx_dma_csr, msgdma_csroffs(resp_fill_level)) 196*89830580SVince Bridgers & 0xffff) { 197*89830580SVince Bridgers pktlength = csrrd32(priv->rx_dma_resp, 198*89830580SVince Bridgers msgdma_respoffs(bytes_transferred)); 199*89830580SVince Bridgers pktstatus = csrrd32(priv->rx_dma_resp, 200*89830580SVince Bridgers msgdma_respoffs(status)); 20194fb0ef4SVince Bridgers rxstatus = pktstatus; 20294fb0ef4SVince Bridgers rxstatus = rxstatus << 16; 20394fb0ef4SVince Bridgers rxstatus |= (pktlength & 0xffff); 20494fb0ef4SVince Bridgers } 20594fb0ef4SVince Bridgers return rxstatus; 20694fb0ef4SVince Bridgers } 207