Commit 576e3c39 authored by Ramesh Babu K V's avatar Ramesh Babu K V Committed by Dan Williams

intel_mid_dma: Add sg list support to DMA driver

For a very high speed DMA various periphral devices need
scatter-gather list support. The DMA hardware support link list items.
This list can be circular also (adding new flag DMA_PREP_CIRCULAR_LIST)
Right now this flag is in driver header and should be moved to
dmaengine header file eventually
Signed-off-by: default avatarRamesh Babu K V <ramesh.b.k.v@intel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 03b96dca
This diff is collapsed.
...@@ -29,11 +29,12 @@ ...@@ -29,11 +29,12 @@
#include <linux/dmapool.h> #include <linux/dmapool.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#define INTEL_MID_DMA_DRIVER_VERSION "1.0.6" #define INTEL_MID_DMA_DRIVER_VERSION "1.1.0"
#define REG_BIT0 0x00000001 #define REG_BIT0 0x00000001
#define REG_BIT8 0x00000100 #define REG_BIT8 0x00000100
#define INT_MASK_WE 0x8
#define CLEAR_DONE 0xFFFFEFFF
#define UNMASK_INTR_REG(chan_num) \ #define UNMASK_INTR_REG(chan_num) \
((REG_BIT0 << chan_num) | (REG_BIT8 << chan_num)) ((REG_BIT0 << chan_num) | (REG_BIT8 << chan_num))
#define MASK_INTR_REG(chan_num) (REG_BIT8 << chan_num) #define MASK_INTR_REG(chan_num) (REG_BIT8 << chan_num)
...@@ -41,6 +42,9 @@ ...@@ -41,6 +42,9 @@
#define ENABLE_CHANNEL(chan_num) \ #define ENABLE_CHANNEL(chan_num) \
((REG_BIT0 << chan_num) | (REG_BIT8 << chan_num)) ((REG_BIT0 << chan_num) | (REG_BIT8 << chan_num))
#define DISABLE_CHANNEL(chan_num) \
(REG_BIT8 << chan_num)
#define DESCS_PER_CHANNEL 16 #define DESCS_PER_CHANNEL 16
/*DMA Registers*/ /*DMA Registers*/
/*registers associated with channel programming*/ /*registers associated with channel programming*/
...@@ -50,6 +54,7 @@ ...@@ -50,6 +54,7 @@
/*CH X REG = (DMA_CH_SIZE)*CH_NO + REG*/ /*CH X REG = (DMA_CH_SIZE)*CH_NO + REG*/
#define SAR 0x00 /* Source Address Register*/ #define SAR 0x00 /* Source Address Register*/
#define DAR 0x08 /* Destination Address Register*/ #define DAR 0x08 /* Destination Address Register*/
#define LLP 0x10 /* Linked List Pointer Register*/
#define CTL_LOW 0x18 /* Control Register*/ #define CTL_LOW 0x18 /* Control Register*/
#define CTL_HIGH 0x1C /* Control Register*/ #define CTL_HIGH 0x1C /* Control Register*/
#define CFG_LOW 0x40 /* Configuration Register Low*/ #define CFG_LOW 0x40 /* Configuration Register Low*/
...@@ -112,8 +117,8 @@ union intel_mid_dma_ctl_lo { ...@@ -112,8 +117,8 @@ union intel_mid_dma_ctl_lo {
union intel_mid_dma_ctl_hi { union intel_mid_dma_ctl_hi {
struct { struct {
u32 block_ts:12; /*block transfer size*/ u32 block_ts:12; /*block transfer size*/
/*configured by DMAC*/ u32 done:1; /*Done - updated by DMAC*/
u32 reser:20; u32 reser:19; /*configured by DMAC*/
} ctlx; } ctlx;
u32 ctl_hi; u32 ctl_hi;
...@@ -169,6 +174,8 @@ union intel_mid_dma_cfg_hi { ...@@ -169,6 +174,8 @@ union intel_mid_dma_cfg_hi {
* @dma: dma device struture pointer * @dma: dma device struture pointer
* @busy: bool representing if ch is busy (active txn) or not * @busy: bool representing if ch is busy (active txn) or not
* @in_use: bool representing if ch is in use or not * @in_use: bool representing if ch is in use or not
* @raw_tfr: raw trf interrupt recieved
* @raw_block: raw block interrupt recieved
*/ */
struct intel_mid_dma_chan { struct intel_mid_dma_chan {
struct dma_chan chan; struct dma_chan chan;
...@@ -185,6 +192,8 @@ struct intel_mid_dma_chan { ...@@ -185,6 +192,8 @@ struct intel_mid_dma_chan {
struct middma_device *dma; struct middma_device *dma;
bool busy; bool busy;
bool in_use; bool in_use;
u32 raw_tfr;
u32 raw_block;
}; };
static inline struct intel_mid_dma_chan *to_intel_mid_dma_chan( static inline struct intel_mid_dma_chan *to_intel_mid_dma_chan(
...@@ -247,6 +256,11 @@ struct intel_mid_dma_desc { ...@@ -247,6 +256,11 @@ struct intel_mid_dma_desc {
u32 cfg_lo; u32 cfg_lo;
u32 ctl_lo; u32 ctl_lo;
u32 ctl_hi; u32 ctl_hi;
struct pci_pool *lli_pool;
struct intel_mid_dma_lli *lli;
dma_addr_t lli_phys;
unsigned int lli_length;
unsigned int current_lli;
dma_addr_t next; dma_addr_t next;
enum dma_data_direction dirn; enum dma_data_direction dirn;
enum dma_status status; enum dma_status status;
...@@ -255,6 +269,14 @@ struct intel_mid_dma_desc { ...@@ -255,6 +269,14 @@ struct intel_mid_dma_desc {
}; };
struct intel_mid_dma_lli {
dma_addr_t sar;
dma_addr_t dar;
dma_addr_t llp;
u32 ctl_lo;
u32 ctl_hi;
} __attribute__ ((packed));
static inline int test_ch_en(void __iomem *dma, u32 ch_no) static inline int test_ch_en(void __iomem *dma, u32 ch_no)
{ {
u32 en_reg = ioread32(dma + DMA_CHAN_EN); u32 en_reg = ioread32(dma + DMA_CHAN_EN);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#define DMA_PREP_CIRCULAR_LIST (1 << 10)
/*DMA transaction width, src and dstn width would be same /*DMA transaction width, src and dstn width would be same
The DMA length must be width aligned, The DMA length must be width aligned,
for 32 bit width the length must be 32 bit (4bytes) aligned only*/ for 32 bit width the length must be 32 bit (4bytes) aligned only*/
...@@ -69,6 +70,7 @@ enum intel_mid_dma_msize { ...@@ -69,6 +70,7 @@ enum intel_mid_dma_msize {
* @cfg_mode: DMA data transfer mode (per-per/mem-per/mem-mem) * @cfg_mode: DMA data transfer mode (per-per/mem-per/mem-mem)
* @src_msize: Source DMA burst size * @src_msize: Source DMA burst size
* @dst_msize: Dst DMA burst size * @dst_msize: Dst DMA burst size
* @per_addr: Periphral address
* @device_instance: DMA peripheral device instance, we can have multiple * @device_instance: DMA peripheral device instance, we can have multiple
* peripheral device connected to single DMAC * peripheral device connected to single DMAC
*/ */
...@@ -80,6 +82,7 @@ struct intel_mid_dma_slave { ...@@ -80,6 +82,7 @@ struct intel_mid_dma_slave {
enum intel_mid_dma_mode cfg_mode; /*mode configuration*/ enum intel_mid_dma_mode cfg_mode; /*mode configuration*/
enum intel_mid_dma_msize src_msize; /*size if src burst*/ enum intel_mid_dma_msize src_msize; /*size if src burst*/
enum intel_mid_dma_msize dst_msize; /*size of dst burst*/ enum intel_mid_dma_msize dst_msize; /*size of dst burst*/
dma_addr_t per_addr; /*Peripheral address*/
unsigned int device_instance; /*0, 1 for periphral instance*/ unsigned int device_instance; /*0, 1 for periphral instance*/
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment