218 lines
4.8 KiB
C
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
|