android_kernel_modules_leno.../drivers/lpss/lpss_dma.h

180 lines
3.9 KiB
C

/*
* Intel LPSS DMA Internal Header File
*
* Copyright (C) 2014, Intel Corporation
* Authors: Huiquan Zhong <huiquan.zhong@intel.com>
*
* 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.
*/
#ifndef __LPSS_DMA_H__
#define __LPSS_DMA_H__
#include <linux/interrupt.h>
#include <linux/dma-direction.h>
#include <linux/lpss_dma.h>
#define INT_MASK_WE 0x8
#define EN_CHAN(ch) \
((BIT(8) << ch) | (BIT(0) << ch))
#define DIS_CHAN(ch) \
(BIT(8) << ch)
#define UNMASK_INT(ch) \
((BIT(8) << ch) | (BIT(0) << ch))
#define MASK_INT(ch) \
(BIT(8) << ch)
#define LPSS_DMA_CH_SIZE 0x58
/* lpss dma register and bits*/
#define LPSS_SAR 0x00 /* Source Address Register*/
#define LPSS_DAR 0x08 /* Destination Address Register*/
#define LPSS_LLP 0x10 /* Linked List Pointer Register*/
#define LPSS_CTL_LO 0x18 /* Control Register*/
#define LPSS_CTL_HI 0x1C /* Control Register*/
#define LPSS_CFG_LO 0x40 /* Configuration Register Low*/
#define LPSS_CFG_HI 0x44 /* Configuration Register high*/
#define LPSS_STATUS_TFR 0x2E8
#define LPSS_STATUS_BLOCK 0x2F0
#define LPSS_STATUS_ERR 0x308
#define LPSS_RAW_TFR 0x2C0
#define LPSS_RAW_BLOCK 0x2C8
#define LPSS_RAW_ERR 0x2E0
#define LPSS_MASK_TFR 0x310
#define LPSS_MASK_BLOCK 0x318
#define LPSS_MASK_SRC_TRAN 0x320
#define LPSS_MASK_DST_TRAN 0x328
#define LPSS_MASK_ERR 0x330
#define LPSS_CLEAR_TFR 0x338
#define LPSS_CLEAR_BLOCK 0x340
#define LPSS_CLEAR_SRC_TRAN 0x348
#define LPSS_CLEAR_DST_TRAN 0x350
#define LPSS_CLEAR_ERR 0x358
#define LPSS_INTR_STATUS 0x360
#define LPSS_DMA_CFG 0x398
#define LPSS_DMA_CHAN_EN 0x3A0
#define DST_WIDTH_OFF 1
#define SRC_WIDTH_OFF 4
#define DSR_MSIZE_OFF 11
#define SRC_MSIZE_OFF 14
#define LPSS_MEM_TO_PER (BIT(8) | BIT(20))
#define LPSS_PER_TO_MEM (BIT(10) | BIT(21))
#define FIFO_MODE BIT(1)
#define PROTCTL_OFF 2
#define SRC_PER_OFF_V1 7
#define DST_PER_OFF_V1 11
#define DST_BURST_ALIGN BIT(0)
#define SRC_BURST_ALIGN BIT(1)
#define SRC_PER_OFF_V2 0
#define DST_PER_OFF_V2 4
#define CH_SUSPEND (BIT(8))
#define CH_DRAIN (BIT(10))
#define FIFO_EMPTY (BIT(9))
struct lpss_dma_chan_dev {
struct lpss_dma_chan *chan;
struct device device;
int dev_id;
atomic_t *idr_ref;
};
enum lpss_dma_direction {
LPSS_DMA_TX = 0,
LPSS_DMA_RX = 1,
};
struct lpss_dma_chan {
void __iomem *ch_regs;
int ch_id;
enum lpss_dma_direction dir;
enum lpss_dma_buswidth dma_buswidth;
enum lpss_dma_msize dma_burstsize;
dma_addr_t src_addr;
dma_addr_t dst_addr;
size_t len;
u32 ctl_lo;
u32 ctl_hi;
u32 cfg_lo;
u32 cfg_hi;
spinlock_t lock;
bool busy;
size_t complete_len;
unsigned int dma_cnt;
struct lpss_dma_chan_dev *dev;
lpss_dma_tx_callback callback;
void *callback_param;
struct completion *chan_comp;
};
enum {
flag_inited = 0,
flag_suspend,
};
struct lpss_dma {
struct device *dev;
unsigned int irq;
void __iomem *dma_base;
unsigned long len;
int ch_base;
int dma_version;
unsigned long flags;
unsigned long intr_mask;
struct lpss_dma_chan tx_chan;
struct lpss_dma_chan rx_chan;
struct tasklet_struct tasklet;
char dma_name[DMA_NAME_SIZE];
};
static inline struct lpss_dma *chan_to_lpss_dma(struct lpss_dma_chan *chan)
{
if (chan->dir == LPSS_DMA_TX)
return container_of(chan, struct lpss_dma, tx_chan);
else
return container_of(chan, struct lpss_dma, rx_chan);
}
void lpss_dma_complete(struct lpss_dma_chan *chan, bool call);
int lpss_dma_setup(struct lpss_dma *dma);
int lpss_dma_hw_start(struct lpss_dma_chan *chan);
void lpss_dma_hw_stop(struct lpss_dma_chan *chan);
u32 lpss_dma_get_src_addr(struct lpss_dma_chan *txc);
u32 lpss_dma_get_dst_addr(struct lpss_dma_chan *rxc);
void enable_lpss_dma(struct lpss_dma *dma);
void lpss_chan_prepare(struct lpss_dma_chan *chan);
#endif