/* * Copyright (C) 2005,7 STMicroelectronics Limited * Authors: Mark Glaisher * Stuart Menefy * * 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 #include #include #define NAME_MAX_LEN 22 /* "fdma__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