/* * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * Copyright (C) 2009~1012 Reddy * Copyright (C) 2013 Lei Chuanhua * Copyright (C) 2016 Intel Corporation. */ #ifndef LANTIQ_DMA0_H #define LANTIQ_DMA0_H /*! * \defgroup LTQ_DMA_CORE UEIP Project - Central DMA core driver * \brief UEIP Project - Central DMA core Module, supports LTQ CPE * \ platforms(Danube/ASE/ARx/VRx/GRX). */ /*! * \defgroup LTQ_DMA_DRV_API External APIs * \ingroup LTQ_DMA_CORE * \brief External APIs definitions for other modules. */ /*! * \defgroup LTQ_DMA_DRV_STRUCTURE Driver Structures * \ingroup LTQ_DMA_CORE * \brief Definitions/Structures of LTQ dma core module. */ /*! * \file lantiq_dma.h * \ingroup LTQ_DMA_CORE * \brief Header file for LTQ Central DMA core driver */ #define MAX_DMA_DEVICE_NUM 7 #define MAX_DMA_CHANNEL_NUM 16 #define DMA_DEV_NAME_LEN 8 /* * Config the Num of descriptors from Kernel configurations * or else if will take default number of descriptors per channel */ #define MAX_DMA_DESC_NUM 256 /*! * \addtogroup LTQ_DMA_DRV_STRUCTURE */ /*@{*/ /*! * \enum dma_psuedeo_interrupts_t * \brief DMA pseudo interrupts. * These interrupts are generated by dma core driver to sync with client * drivers to handle the data between the clinet and core driver. */ typedef enum { RCV_INT = 1, /*!< Receive psuedo interrupt */ TX_BUF_FULL_INT = 2, /*!< Tx channel descriptors full interrupt */ TRANSMIT_CPT_INT = 4, /*!< Tx channel descriptors available interrupt */ } dma_psuedeo_interrupts_t; /*! * \enum ifx_dma_channel_onoff_t * \brief dma channel is on/ off. */ typedef enum { IFX_DMA_CH_OFF = 0, /*!< DMA channel is OFF */ IFX_DMA_CH_ON = 1, /*!< DMA channel is ON */ } ifx_dma_channel_onoff_t; /*! * \enum ifx_dma_class_t * \brief dma channel class value. */ typedef enum { IFX_DMA_CLASS_0 = 0, IFX_DMA_CLASS_1, IFX_DMA_CLASS_2, IFX_DMA_CLASS_3, IFX_DMA_CLASS_4, IFX_DMA_CLASS_5, IFX_DMA_CLASS_6, IFX_DMA_CLASS_7, } ifx_dma_class_t; /*! * \enum ifx_dma_endian_t * \brief DMA endiannes type. */ typedef enum { IFX_DMA_ENDIAN_TYPE0 = 0, /*!< No byte Swapping */ IFX_DMA_ENDIAN_TYPE1, /*!< Byte Swap(B0B1B2B3 => B1B0B3B2) */ IFX_DMA_ENDIAN_TYPE2, /*!< Word Swap (B0B1B2B3 => B2B3B0B1) */ IFX_DMA_ENDIAN_TYPE3, /*!< DWord Swap (B0B1B2B3 => B3B2B1B0) */ } ifx_dma_endian_t; enum { /** 2 DWORDS */ IFX_DMA_BURSTL_2 = 1, /** 4 DWORDS */ IFX_DMA_BURSTL_4 = 2, /** 8 DWORDS */ IFX_DMA_BURSTL_8 = 3, }; /*! * \enum ifx_dma_burst_len_t * \brief DMA Burst length. */ typedef enum { DMA_BURSTL_2DW = 2, /*!< 2 DWORD DMA burst length */ DMA_BURSTL_4DW = 4, /*!< 4 DWORD DMA burst length */ DMA_BURSTL_8DW = 8, /*!< 8 DWORD DMA burst length (not supported by all peripherals) */ } ifx_dma_burst_len_t; /*! * \typedef _dma_arbitration_info * \brief Parameter Structure to used to configure DMA arbitration * based on packet or burst also Descriptor read back enabled/disabled * (Supported only VR9) * Used by reference dma_device_info */ typedef struct dma_arbitration_info { __u32 packet_arbitration; /*!< enabled/disabled packet arbitration */ __u32 multiple_burst_arbitration; /*!< Enabled/Disabled Multi burst */ /*!< * Counter of the Multi burst arbitration(Num of bursts that served * before the arbitration of another peri port) */ unsigned int multiple_burst_counter; __u32 desc_read_back; /*!< enabled/disabled Descriptor read back */ } _dma_arbitration_info; /*! * \typedef _dma_channel_info * \brief The parameter structure is used to configure the DMA channel info * when the peripheral driver need to register with DMA core device driver. */ typedef struct dma_channel_info { int rel_chan_no; /*!< Relative channel number */ int dir; /*!< Direction of channel */ int irq; /*!< DMA channel IRQ number */ unsigned int desc_base; /*!< Channel descriptor base address */ unsigned int desc_phys; int desc_len; /*!< Num of descriptors per channel */ int curr_desc; /*!< Current Descriptor number */ int prev_desc; /*!< Previous Descriptor number */ int byte_offset; /*!< Byte offset */ int desc_handle; /*!< Descriptor handled flag ( to handle Rx Descriptor by client driver) */ int weight; /*!< WFQ present weight value for DMA channel */ int default_weight; /*!< WFQ default weight value to handle in driver for DMA channel */ int tx_channel_weight; /*!< Config the Tx DMA channel weight value */ ifx_dma_class_t class_value; /*!< Config the DMA class value */ int packet_size; /*!< Size of the packet length */ int channel_packet_drop_enable; /*!< Config channel based packet drop */ /*!< Channel based packet drop counter */ int channel_packet_drop_counter; int peri_to_peri; /*!< Config Peripheral to Peripheral */ int global_buffer_len; /*!< Config global buffer length, valid only when enabled peri_to_peri) */ int loopback_enable; /*!< Config Loop back between the DMA channels */ int loopback_channel_number; /*!< Config the loopback Channel number */ int req_irq_to_free; /*!< Release the DMA channel IRQ requested */ int dur; /*!< Flag for Descriptor underrun interrupt */ spinlock_t irq_lock; /*!< spin lock */ ifx_dma_channel_onoff_t control; /*!< Channel on/off flag */ void *opt[MAX_DMA_DESC_NUM]; /*!< Optional info */ void *dma_dev; /*!< Pointing to the devices */ void (*open)(struct dma_channel_info *pCh); /*!< DMA channel ON */ void (*close)(struct dma_channel_info *pCh); /*!< DMA channel OFF */ void (*reset)(struct dma_channel_info *pCh); /*!< Reset DMA channel */ /*!< Enable channel interrupt */ void (*enable_irq)(struct dma_channel_info *pCh); /*!< Disable channel interrupt */ void (*disable_irq)(struct dma_channel_info *pCh); void *pdev; } _dma_channel_info; /*! * \typedef _dma_device_info * \brief The parameter structure is used to configure the DMA Peripheral ports * info when the peripheral driver need to register with DMA core device driver. */ typedef struct dma_device_info { char device_name[DMA_DEV_NAME_LEN]; /*!< Peripheral Device name */ int port_reserved; /*!< Reserve the device by client driver */ int port_num; /*!< Port number */ ifx_dma_burst_len_t tx_burst_len; /*!< Configure the Tx burst length */ ifx_dma_burst_len_t rx_burst_len; /*!< Conigure the Rx burst length */ int port_tx_weight; /*!< Configure the Port based weight value */ int port_packet_drop_enable; /*!< Packet drop Enabled/Disabled */ int port_packet_drop_counter; /*!< Packet drop counter */ int mem_port_control; /*!< Configure the mem port control */ ifx_dma_endian_t tx_endianness_mode; /*!< Configure TX Endiannes */ ifx_dma_endian_t rx_endianness_mode; /*!< Configure RX Endiannes */ int current_tx_chan; /*!< Current Tx channel of the device */ int current_rx_chan; /*!< Current Rx channel of the device */ int num_tx_chan; /*!< Config the num of Tx channels for device */ int num_rx_chan; /*!< Config the num of Rx channels for device */ int max_rx_chan_num; /*!< Max number of Rx channels supported */ int max_tx_chan_num; /*!< Max number of Tx channels supported */ spinlock_t irq_lock; /*!< spin lock */ _dma_arbitration_info arbitration_info; /*!< arbitration config */ _dma_channel_info *tx_chan[MAX_DMA_CHANNEL_NUM]; /*!< Max TX channel */ _dma_channel_info *rx_chan[MAX_DMA_CHANNEL_NUM]; /*!< Max RX channel */ u8 *(*buffer_alloc)(int len, int *offset, void **opt); int (*buffer_free)(u8 *dataptr, void *opt); /*!< Buffer free */ /*!< DMA pseudo interrupt handler */ int (*intr_handler)(struct dma_device_info *info, int status); /*!< activate the polling (Used when NAPI enables) */ void (*activate_poll)(struct dma_device_info *dma_dev); /*!< Deactivate the polling (used when NAPI enabled) */ void (*inactivate_poll)(struct dma_device_info *dma_dev); void *priv; /*!< Pointer to the device private structure */ } _dma_device_info; /* @} */ /* Reserve the dma device port * This function should call before the dma_device_register */ extern _dma_device_info *dma_device_reserve(char *dev_name); /* * Unreseve the dma device port * This function will called after the dma_device_unregister */ extern int dma_device_release(_dma_device_info *dev); /* * Register with DMA device driver. * This function should call after dma_device_reserve function. * This function register with dma device driver to handle dma functionality. * Should provide the required configuration info during the register with * dma device. * if not provide config info, then take default values. */ extern int dma_device_register(_dma_device_info *info); /* * Unregister with DMA core driver * This function unregister with dma core driver. Once it unregister there is * no DMA handling with client driver. */ extern int dma_device_unregister(_dma_device_info *info); /* * Read data packet from DMA Rx channel. * This function gets the data from the current rx descriptor of the DMA * channel and send to the client driver. * This functions is called when the client driver gets a pseudo DMA interrupt * (RCV_INT). Handle with care when call this function as well as * dma_device_desc_setup function. */ extern int dma_device_read(struct dma_device_info *info, u8 **dataptr, void **opt); /* * Write data Packet to DMA Tx channel. * This function gets the data packet from the client driver and send over on * DMA channel.*/ extern int dma_device_write(struct dma_device_info *info, u8 *dataptr, int len, void *opt); /* * Setup the DMA channel descriptor. * This function setup the descriptor of the DMA channel used by client driver. * The client driver will take care the buffer allocation and do proper * checking of buffer for DMA burst alignment.Handle with care when call this * function as well as dma_device_read function */ extern int dma_device_desc_setup(_dma_device_info *dma_dev, char *buf, size_t len); /* * Clear the interrupt status flag * This function used to exit from DMA tasklet(tasklet don't need to run again * and again ) This is also used to avoid multiple psuedo interrupt (RCV_INT) * per packet. */ extern int dma_device_clear_int(_dma_device_info *dma_dev, int dir); /* *Clear the descriptor status word from the client driver once receive * a pseudo interrupt(RCV_INT) from the DMA module to avoid duplicate * interrupts from tasklet. */ extern int dma_device_clear_desc_status_word(_dma_device_info *dma_dev, int dir); /* * setup the dma channel class value * This function setup the class of service value for DMA channel. */ extern void dma_device_setup_class_val(_dma_channel_info *pCh, int cls); /* * poll DMA ownership bit to ensure that rx transactions are complete * to prevent descriptor errors */ extern void poll_dma_ownership_bit(_dma_device_info *dma_dev); #endif /* LANTIQ_DMA0_H */