satip-axe/kernel/drivers/stm/fdma.h
2015-03-26 17:24:57 +01:00

218 lines
4.8 KiB
C

/*
* Copyright (C) 2005,7 STMicroelectronics Limited
* Authors: Mark Glaisher <Mark.Glaisher@st.com>
* Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*/
#ifndef __STM_FDMA_H
#define __STM_FDMA_H
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/stm/stm-dma.h>
#define NAME_MAX_LEN 22 /* "fdma_<cpu_subtype>_X.elf" */
#define CHAN_ALL_ENABLE 3
#define NODE_DATA_OFFSET 0x40
#define CMD_STAT_OFFSET 0x04
/**cmd stat vals*/
#define SET_NODE_COMP_PAUSE (1 << 30)
#define SET_NODE_COMP_IRQ (1 << 31)
#define NODE_ADDR_STATIC 0x01
#define NODE_ADDR_INCR 0x02
#define SOURCE_ADDR 0x05
#define DEST_ADDR 0x07
#define CMDSTAT_FDMA_CMD_MASK 0x1f
#define CMDSTAT_FDMA_START_CHANNEL 1
#define CMDSTAT_FDMA_RESTART_CHANNEL 0
#define FDMA_CHANS 16
#define FDMA_REQ_LINES 32
/*******************************/
/*MBOX SETUP VALUES*/
#define MBOX_CMD_FLUSH_CHANNEL 3
#define MBOX_CMD_PAUSE_CHANNEL 2
#define MBOX_CMD_START_CHANNEL 1
#define CLEAR_WORD 0XFFFFFFFF
#define CMD_STAT_REG(_chan_num) \
(fdma->io_base + fdma->regs.cmd_statn + \
(_chan_num * CMD_STAT_OFFSET))
#define FDMA_CHANNEL_IDLE 0
#define FDMA_CHANNEL_RUNNING 2
#define FDMA_CHANNEL_PAUSED 3
/*FDMA Channel FLAGS*/
/*values below D28 are reserved for REQ_LINE parameter*/
#define REQ_LINE_MASK 0x1f
#define CHAN_NUM(chan) ((chan) - chip.channel)
/* SLIM doesn't yet have an officially recognised ELF ID, so we use this */
#define EM_SLIM 102
/* Use the e_flags field of the ELF header to distinguish between SLIM usage */
#define EF_SLIM_FDMA 2
struct fdma_llu_entry {
u32 next_item;
u32 control;
u32 size_bytes;
u32 saddr;
u32 daddr;
u32 line_len;
u32 sstride;
u32 dstride;
};
struct fdma_llu_node {
struct fdma_llu_entry *virt_addr;
dma_addr_t dma_addr;
};
struct fdma_xfer_descriptor {
struct fdma_llu_node *(*extrapolate_fn)(struct stm_dma_params *xfer,
struct fdma_xfer_descriptor *desc,
struct fdma_llu_node *nodes);
int extrapolate_line_len;
struct fdma_llu_entry template_llu;
/* only used when this is the first parameter in a list */
struct fdma_llu_node *llu_nodes;
int alloced_nodes;
};
enum fdma_state {
FDMA_IDLE,
FDMA_CONFIGURED,
FDMA_RUNNING,
FDMA_STOPPING,
FDMA_PAUSING,
FDMA_PAUSED,
};
struct fdma;
struct stm_dma_req {
int req_line;
};
struct fdma_channel {
struct fdma *fdma;
int chan_num;
enum fdma_state sw_state;
struct dma_channel *dma_chan;
struct stm_dma_params *params;
struct tasklet_struct fdma_complete;
struct tasklet_struct fdma_error;
};
struct fdma_regs {
unsigned long id;
unsigned long ver;
unsigned long en;
unsigned long clk_gate;
unsigned long rev_id;
unsigned long cmd_statn;
unsigned long ptrn;
unsigned long cntn;
unsigned long saddrn;
unsigned long daddrn;
unsigned long req_ctln;
unsigned long sync_reg;
unsigned long cmd_sta;
unsigned long cmd_set;
unsigned long cmd_clr;
unsigned long cmd_mask;
unsigned long int_sta;
unsigned long int_set;
unsigned long int_clr;
unsigned long int_mask;
};
#define FDMA_NAME_LEN 20
struct fdma_segment_pm {
void *data;
unsigned long size;
unsigned long offset;
};
struct fdma {
char name[FDMA_NAME_LEN];
char fw_name[NAME_MAX_LEN + 1];
struct platform_device *pdev;
/*
* The FDMA-IP needs 4 clocks
* - a T1 port
* - a T2 port (High priority)
* - a T2 port (Low priority)
* - a slim clock
*/
struct clk *clks[4];
struct dma_info dma_info;
struct fdma_channel channels[FDMA_CHANS];
spinlock_t channels_lock; /* protects channels array */
struct resource *phys_mem;
void __iomem *io_base;
struct stm_dma_req reqs[FDMA_REQ_LINES];
unsigned long reqs_used_mask;
spinlock_t reqs_lock; /* protects reqs_used_mask */
u32 firmware_loaded;
u8 ch_min;
u8 ch_max;
u8 irq;
u8 fdma_num;
u32 ch_status_mask;
struct dma_pool *llu_pool;
wait_queue_head_t fw_load_q;
struct stm_plat_fdma_hw *hw;
struct stm_plat_fdma_fw_regs *fw;
#ifdef CONFIG_HIBERNATION
struct fdma_segment_pm segment_pm[2]; /* saved segment (text/data) */
#endif
struct fdma_regs regs;
};
struct fdma_req_router {
int (*route)(struct fdma_req_router *router, int input_req_line,
int fdma, int fdma_req_line);
};
int fdma_register_req_router(struct fdma_req_router *router);
void fdma_unregister_req_router(struct fdma_req_router *router);
typedef volatile unsigned long device_t;
#define fdma_printk(level, fd, format, arg...) \
dev_printk(level, &fd->dma_info.pdev->dev, format, ## arg);
#define fdma_info(fd, format, arg...) \
fdma_printk(KERN_INFO, fd, format, ## arg)
#if defined(CONFIG_STM_DMA_DEBUG)
#define fdma_dbg(fd, format, arg...) \
fdma_printk(KERN_DEBUG, fd, format, ## arg)
#else
#define fdma_dbg(fd, format, arg...) do { } while (0)
#endif
#endif