mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
![Tony Lindgren](/assets/img/avatar_default.png)
Based on earlier discussions[1] we attempted to find a suitable
location for the omap DMA header in commit 2b6c4e73
(ARM: OMAP:
DMA: Move plat/dma.h to plat-omap/dma-omap.h) until the conversion
to dmaengine is complete.
Unfortunately that was before I was able to try to test compile
of the ARM multiplatform builds for omap2+, and the end result
was not very good.
So I'm creating yet another all over the place patch to cut the
last dependency for building omap2+ for ARM multiplatform. After
this, we have finally removed the driver dependencies to the
arch/arm code, except for few drivers that are being worked on.
The other option was to make the <plat-omap/dma-omap.h> path
to work, but we'd have to add some new header directory to for
multiplatform builds.
Or we would have to manually include arch/arm/plat-omap/include
again from arch/arm/Makefile for omap2+.
Neither of these alternatives sound appealing as they will
likely lead addition of various other headers exposed to the
drivers, which we want to avoid for the multiplatform kernels.
Since we already have a minimal include/linux/omap-dma.h,
let's just use that instead and add a note to it to not
use the custom omap DMA functions any longer where possible.
Note that converting omap DMA to dmaengine depends on
dmaengine supporting automatically incrementing the FIFO
address at the device end, and converting all the remaining
legacy drivers. So it's going to be few more merge windows.
[1] https://patchwork.kernel.org/patch/1519591/#
cc: Russell King <linux@arm.linux.org.uk>
cc: Kevin Hilman <khilman@ti.com>
cc: "Benoît Cousson" <b-cousson@ti.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: "David S. Miller" <davem@davemloft.net>
cc: Vinod Koul <vinod.koul@intel.com>
cc: Dan Williams <djbw@fb.com>
cc: Mauro Carvalho Chehab <mchehab@infradead.org>
cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
cc: David Woodhouse <dwmw2@infradead.org>
cc: Kyungmin Park <kyungmin.park@samsung.com>
cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
cc: Hans Verkuil <hans.verkuil@cisco.com>
cc: Vaibhav Hiremath <hvaibhav@ti.com>
cc: Lokesh Vutla <lokeshvutla@ti.com>
cc: Rusty Russell <rusty@rustcorp.com.au>
cc: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
cc: Afzal Mohammed <afzal@ti.com>
cc: linux-crypto@vger.kernel.org
cc: linux-media@vger.kernel.org
cc: linux-mtd@lists.infradead.org
cc: linux-usb@vger.kernel.org
cc: linux-fbdev@vger.kernel.org
Acked-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
388 lines
12 KiB
C
388 lines
12 KiB
C
/*
|
|
* OMAP DMA Engine support
|
|
*
|
|
* 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 __LINUX_OMAP_DMA_H
|
|
#define __LINUX_OMAP_DMA_H
|
|
|
|
struct dma_chan;
|
|
|
|
#if defined(CONFIG_DMA_OMAP) || defined(CONFIG_DMA_OMAP_MODULE)
|
|
bool omap_dma_filter_fn(struct dma_chan *, void *);
|
|
#else
|
|
static inline bool omap_dma_filter_fn(struct dma_chan *c, void *d)
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Legacy OMAP DMA handling defines and functions
|
|
*
|
|
* NOTE: Do not use these any longer.
|
|
*
|
|
* Use the generic dmaengine functions as defined in
|
|
* include/linux/dmaengine.h.
|
|
*
|
|
* Copyright (C) 2003 Nokia Corporation
|
|
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
|
|
*
|
|
*/
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#define INT_DMA_LCD 25
|
|
|
|
#define OMAP1_DMA_TOUT_IRQ (1 << 0)
|
|
#define OMAP_DMA_DROP_IRQ (1 << 1)
|
|
#define OMAP_DMA_HALF_IRQ (1 << 2)
|
|
#define OMAP_DMA_FRAME_IRQ (1 << 3)
|
|
#define OMAP_DMA_LAST_IRQ (1 << 4)
|
|
#define OMAP_DMA_BLOCK_IRQ (1 << 5)
|
|
#define OMAP1_DMA_SYNC_IRQ (1 << 6)
|
|
#define OMAP2_DMA_PKT_IRQ (1 << 7)
|
|
#define OMAP2_DMA_TRANS_ERR_IRQ (1 << 8)
|
|
#define OMAP2_DMA_SECURE_ERR_IRQ (1 << 9)
|
|
#define OMAP2_DMA_SUPERVISOR_ERR_IRQ (1 << 10)
|
|
#define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11)
|
|
|
|
#define OMAP_DMA_CCR_EN (1 << 7)
|
|
#define OMAP_DMA_CCR_RD_ACTIVE (1 << 9)
|
|
#define OMAP_DMA_CCR_WR_ACTIVE (1 << 10)
|
|
#define OMAP_DMA_CCR_SEL_SRC_DST_SYNC (1 << 24)
|
|
#define OMAP_DMA_CCR_BUFFERING_DISABLE (1 << 25)
|
|
|
|
#define OMAP_DMA_DATA_TYPE_S8 0x00
|
|
#define OMAP_DMA_DATA_TYPE_S16 0x01
|
|
#define OMAP_DMA_DATA_TYPE_S32 0x02
|
|
|
|
#define OMAP_DMA_SYNC_ELEMENT 0x00
|
|
#define OMAP_DMA_SYNC_FRAME 0x01
|
|
#define OMAP_DMA_SYNC_BLOCK 0x02
|
|
#define OMAP_DMA_SYNC_PACKET 0x03
|
|
|
|
#define OMAP_DMA_DST_SYNC_PREFETCH 0x02
|
|
#define OMAP_DMA_SRC_SYNC 0x01
|
|
#define OMAP_DMA_DST_SYNC 0x00
|
|
|
|
#define OMAP_DMA_PORT_EMIFF 0x00
|
|
#define OMAP_DMA_PORT_EMIFS 0x01
|
|
#define OMAP_DMA_PORT_OCP_T1 0x02
|
|
#define OMAP_DMA_PORT_TIPB 0x03
|
|
#define OMAP_DMA_PORT_OCP_T2 0x04
|
|
#define OMAP_DMA_PORT_MPUI 0x05
|
|
|
|
#define OMAP_DMA_AMODE_CONSTANT 0x00
|
|
#define OMAP_DMA_AMODE_POST_INC 0x01
|
|
#define OMAP_DMA_AMODE_SINGLE_IDX 0x02
|
|
#define OMAP_DMA_AMODE_DOUBLE_IDX 0x03
|
|
|
|
#define DMA_DEFAULT_FIFO_DEPTH 0x10
|
|
#define DMA_DEFAULT_ARB_RATE 0x01
|
|
/* Pass THREAD_RESERVE ORed with THREAD_FIFO for tparams */
|
|
#define DMA_THREAD_RESERVE_NORM (0x00 << 12) /* Def */
|
|
#define DMA_THREAD_RESERVE_ONET (0x01 << 12)
|
|
#define DMA_THREAD_RESERVE_TWOT (0x02 << 12)
|
|
#define DMA_THREAD_RESERVE_THREET (0x03 << 12)
|
|
#define DMA_THREAD_FIFO_NONE (0x00 << 14) /* Def */
|
|
#define DMA_THREAD_FIFO_75 (0x01 << 14)
|
|
#define DMA_THREAD_FIFO_25 (0x02 << 14)
|
|
#define DMA_THREAD_FIFO_50 (0x03 << 14)
|
|
|
|
/* DMA4_OCP_SYSCONFIG bits */
|
|
#define DMA_SYSCONFIG_MIDLEMODE_MASK (3 << 12)
|
|
#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK (3 << 8)
|
|
#define DMA_SYSCONFIG_EMUFREE (1 << 5)
|
|
#define DMA_SYSCONFIG_SIDLEMODE_MASK (3 << 3)
|
|
#define DMA_SYSCONFIG_SOFTRESET (1 << 2)
|
|
#define DMA_SYSCONFIG_AUTOIDLE (1 << 0)
|
|
|
|
#define DMA_SYSCONFIG_MIDLEMODE(n) ((n) << 12)
|
|
#define DMA_SYSCONFIG_SIDLEMODE(n) ((n) << 3)
|
|
|
|
#define DMA_IDLEMODE_SMARTIDLE 0x2
|
|
#define DMA_IDLEMODE_NO_IDLE 0x1
|
|
#define DMA_IDLEMODE_FORCE_IDLE 0x0
|
|
|
|
/* Chaining modes*/
|
|
#ifndef CONFIG_ARCH_OMAP1
|
|
#define OMAP_DMA_STATIC_CHAIN 0x1
|
|
#define OMAP_DMA_DYNAMIC_CHAIN 0x2
|
|
#define OMAP_DMA_CHAIN_ACTIVE 0x1
|
|
#define OMAP_DMA_CHAIN_INACTIVE 0x0
|
|
#endif
|
|
|
|
#define DMA_CH_PRIO_HIGH 0x1
|
|
#define DMA_CH_PRIO_LOW 0x0 /* Def */
|
|
|
|
/* Errata handling */
|
|
#define IS_DMA_ERRATA(id) (errata & (id))
|
|
#define SET_DMA_ERRATA(id) (errata |= (id))
|
|
|
|
#define DMA_ERRATA_IFRAME_BUFFERING BIT(0x0)
|
|
#define DMA_ERRATA_PARALLEL_CHANNELS BIT(0x1)
|
|
#define DMA_ERRATA_i378 BIT(0x2)
|
|
#define DMA_ERRATA_i541 BIT(0x3)
|
|
#define DMA_ERRATA_i88 BIT(0x4)
|
|
#define DMA_ERRATA_3_3 BIT(0x5)
|
|
#define DMA_ROMCODE_BUG BIT(0x6)
|
|
|
|
/* Attributes for OMAP DMA Contrller */
|
|
#define DMA_LINKED_LCH BIT(0x0)
|
|
#define GLOBAL_PRIORITY BIT(0x1)
|
|
#define RESERVE_CHANNEL BIT(0x2)
|
|
#define IS_CSSA_32 BIT(0x3)
|
|
#define IS_CDSA_32 BIT(0x4)
|
|
#define IS_RW_PRIORITY BIT(0x5)
|
|
#define ENABLE_1510_MODE BIT(0x6)
|
|
#define SRC_PORT BIT(0x7)
|
|
#define DST_PORT BIT(0x8)
|
|
#define SRC_INDEX BIT(0x9)
|
|
#define DST_INDEX BIT(0xa)
|
|
#define IS_BURST_ONLY4 BIT(0xb)
|
|
#define CLEAR_CSR_ON_READ BIT(0xc)
|
|
#define IS_WORD_16 BIT(0xd)
|
|
#define ENABLE_16XX_MODE BIT(0xe)
|
|
#define HS_CHANNELS_RESERVED BIT(0xf)
|
|
|
|
/* Defines for DMA Capabilities */
|
|
#define DMA_HAS_TRANSPARENT_CAPS (0x1 << 18)
|
|
#define DMA_HAS_CONSTANT_FILL_CAPS (0x1 << 19)
|
|
#define DMA_HAS_DESCRIPTOR_CAPS (0x3 << 20)
|
|
|
|
enum omap_reg_offsets {
|
|
|
|
GCR, GSCR, GRST1, HW_ID,
|
|
PCH2_ID, PCH0_ID, PCH1_ID, PCHG_ID,
|
|
PCHD_ID, CAPS_0, CAPS_1, CAPS_2,
|
|
CAPS_3, CAPS_4, PCH2_SR, PCH0_SR,
|
|
PCH1_SR, PCHD_SR, REVISION, IRQSTATUS_L0,
|
|
IRQSTATUS_L1, IRQSTATUS_L2, IRQSTATUS_L3, IRQENABLE_L0,
|
|
IRQENABLE_L1, IRQENABLE_L2, IRQENABLE_L3, SYSSTATUS,
|
|
OCP_SYSCONFIG,
|
|
|
|
/* omap1+ specific */
|
|
CPC, CCR2, LCH_CTRL,
|
|
|
|
/* Common registers for all omap's */
|
|
CSDP, CCR, CICR, CSR,
|
|
CEN, CFN, CSFI, CSEI,
|
|
CSAC, CDAC, CDEI,
|
|
CDFI, CLNK_CTRL,
|
|
|
|
/* Channel specific registers */
|
|
CSSA, CDSA, COLOR,
|
|
CCEN, CCFN,
|
|
|
|
/* omap3630 and omap4 specific */
|
|
CDP, CNDP, CCDN,
|
|
|
|
};
|
|
|
|
enum omap_dma_burst_mode {
|
|
OMAP_DMA_DATA_BURST_DIS = 0,
|
|
OMAP_DMA_DATA_BURST_4,
|
|
OMAP_DMA_DATA_BURST_8,
|
|
OMAP_DMA_DATA_BURST_16,
|
|
};
|
|
|
|
enum end_type {
|
|
OMAP_DMA_LITTLE_ENDIAN = 0,
|
|
OMAP_DMA_BIG_ENDIAN
|
|
};
|
|
|
|
enum omap_dma_color_mode {
|
|
OMAP_DMA_COLOR_DIS = 0,
|
|
OMAP_DMA_CONSTANT_FILL,
|
|
OMAP_DMA_TRANSPARENT_COPY
|
|
};
|
|
|
|
enum omap_dma_write_mode {
|
|
OMAP_DMA_WRITE_NON_POSTED = 0,
|
|
OMAP_DMA_WRITE_POSTED,
|
|
OMAP_DMA_WRITE_LAST_NON_POSTED
|
|
};
|
|
|
|
enum omap_dma_channel_mode {
|
|
OMAP_DMA_LCH_2D = 0,
|
|
OMAP_DMA_LCH_G,
|
|
OMAP_DMA_LCH_P,
|
|
OMAP_DMA_LCH_PD
|
|
};
|
|
|
|
struct omap_dma_channel_params {
|
|
int data_type; /* data type 8,16,32 */
|
|
int elem_count; /* number of elements in a frame */
|
|
int frame_count; /* number of frames in a element */
|
|
|
|
int src_port; /* Only on OMAP1 REVISIT: Is this needed? */
|
|
int src_amode; /* constant, post increment, indexed,
|
|
double indexed */
|
|
unsigned long src_start; /* source address : physical */
|
|
int src_ei; /* source element index */
|
|
int src_fi; /* source frame index */
|
|
|
|
int dst_port; /* Only on OMAP1 REVISIT: Is this needed? */
|
|
int dst_amode; /* constant, post increment, indexed,
|
|
double indexed */
|
|
unsigned long dst_start; /* source address : physical */
|
|
int dst_ei; /* source element index */
|
|
int dst_fi; /* source frame index */
|
|
|
|
int trigger; /* trigger attached if the channel is
|
|
synchronized */
|
|
int sync_mode; /* sycn on element, frame , block or packet */
|
|
int src_or_dst_synch; /* source synch(1) or destination synch(0) */
|
|
|
|
int ie; /* interrupt enabled */
|
|
|
|
unsigned char read_prio;/* read priority */
|
|
unsigned char write_prio;/* write priority */
|
|
|
|
#ifndef CONFIG_ARCH_OMAP1
|
|
enum omap_dma_burst_mode burst_mode; /* Burst mode 4/8/16 words */
|
|
#endif
|
|
};
|
|
|
|
struct omap_dma_lch {
|
|
int next_lch;
|
|
int dev_id;
|
|
u16 saved_csr;
|
|
u16 enabled_irqs;
|
|
const char *dev_name;
|
|
void (*callback)(int lch, u16 ch_status, void *data);
|
|
void *data;
|
|
long flags;
|
|
/* required for Dynamic chaining */
|
|
int prev_linked_ch;
|
|
int next_linked_ch;
|
|
int state;
|
|
int chain_id;
|
|
int status;
|
|
};
|
|
|
|
struct omap_dma_dev_attr {
|
|
u32 dev_caps;
|
|
u16 lch_count;
|
|
u16 chan_count;
|
|
struct omap_dma_lch *chan;
|
|
};
|
|
|
|
/* System DMA platform data structure */
|
|
struct omap_system_dma_plat_info {
|
|
struct omap_dma_dev_attr *dma_attr;
|
|
u32 errata;
|
|
void (*disable_irq_lch)(int lch);
|
|
void (*show_dma_caps)(void);
|
|
void (*clear_lch_regs)(int lch);
|
|
void (*clear_dma)(int lch);
|
|
void (*dma_write)(u32 val, int reg, int lch);
|
|
u32 (*dma_read)(int reg, int lch);
|
|
};
|
|
|
|
#ifdef CONFIG_ARCH_OMAP2PLUS
|
|
#define dma_omap2plus() 1
|
|
#else
|
|
#define dma_omap2plus() 0
|
|
#endif
|
|
#define dma_omap1() (!dma_omap2plus())
|
|
#define dma_omap15xx() ((dma_omap1() && (d->dev_caps & ENABLE_1510_MODE)))
|
|
#define dma_omap16xx() ((dma_omap1() && (d->dev_caps & ENABLE_16XX_MODE)))
|
|
|
|
extern void omap_set_dma_priority(int lch, int dst_port, int priority);
|
|
extern int omap_request_dma(int dev_id, const char *dev_name,
|
|
void (*callback)(int lch, u16 ch_status, void *data),
|
|
void *data, int *dma_ch);
|
|
extern void omap_enable_dma_irq(int ch, u16 irq_bits);
|
|
extern void omap_disable_dma_irq(int ch, u16 irq_bits);
|
|
extern void omap_free_dma(int ch);
|
|
extern void omap_start_dma(int lch);
|
|
extern void omap_stop_dma(int lch);
|
|
extern void omap_set_dma_transfer_params(int lch, int data_type,
|
|
int elem_count, int frame_count,
|
|
int sync_mode,
|
|
int dma_trigger, int src_or_dst_synch);
|
|
extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
|
|
u32 color);
|
|
extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
|
|
extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
|
|
|
|
extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
|
|
unsigned long src_start,
|
|
int src_ei, int src_fi);
|
|
extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
|
|
extern void omap_set_dma_src_data_pack(int lch, int enable);
|
|
extern void omap_set_dma_src_burst_mode(int lch,
|
|
enum omap_dma_burst_mode burst_mode);
|
|
|
|
extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
|
|
unsigned long dest_start,
|
|
int dst_ei, int dst_fi);
|
|
extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
|
|
extern void omap_set_dma_dest_data_pack(int lch, int enable);
|
|
extern void omap_set_dma_dest_burst_mode(int lch,
|
|
enum omap_dma_burst_mode burst_mode);
|
|
|
|
extern void omap_set_dma_params(int lch,
|
|
struct omap_dma_channel_params *params);
|
|
|
|
extern void omap_dma_link_lch(int lch_head, int lch_queue);
|
|
extern void omap_dma_unlink_lch(int lch_head, int lch_queue);
|
|
|
|
extern int omap_set_dma_callback(int lch,
|
|
void (*callback)(int lch, u16 ch_status, void *data),
|
|
void *data);
|
|
extern dma_addr_t omap_get_dma_src_pos(int lch);
|
|
extern dma_addr_t omap_get_dma_dst_pos(int lch);
|
|
extern void omap_clear_dma(int lch);
|
|
extern int omap_get_dma_active_status(int lch);
|
|
extern int omap_dma_running(void);
|
|
extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
|
|
int tparams);
|
|
extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
|
|
unsigned char write_prio);
|
|
extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
|
|
extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
|
|
extern int omap_get_dma_index(int lch, int *ei, int *fi);
|
|
|
|
void omap_dma_global_context_save(void);
|
|
void omap_dma_global_context_restore(void);
|
|
|
|
extern void omap_dma_disable_irq(int lch);
|
|
|
|
/* Chaining APIs */
|
|
#ifndef CONFIG_ARCH_OMAP1
|
|
extern int omap_request_dma_chain(int dev_id, const char *dev_name,
|
|
void (*callback) (int lch, u16 ch_status,
|
|
void *data),
|
|
int *chain_id, int no_of_chans,
|
|
int chain_mode,
|
|
struct omap_dma_channel_params params);
|
|
extern int omap_free_dma_chain(int chain_id);
|
|
extern int omap_dma_chain_a_transfer(int chain_id, int src_start,
|
|
int dest_start, int elem_count,
|
|
int frame_count, void *callbk_data);
|
|
extern int omap_start_dma_chain_transfers(int chain_id);
|
|
extern int omap_stop_dma_chain_transfers(int chain_id);
|
|
extern int omap_get_dma_chain_index(int chain_id, int *ei, int *fi);
|
|
extern int omap_get_dma_chain_dst_pos(int chain_id);
|
|
extern int omap_get_dma_chain_src_pos(int chain_id);
|
|
|
|
extern int omap_modify_dma_chain_params(int chain_id,
|
|
struct omap_dma_channel_params params);
|
|
extern int omap_dma_chain_status(int chain_id);
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_FB_OMAP)
|
|
#include <mach/lcd_dma.h>
|
|
#else
|
|
static inline int omap_lcd_dma_running(void)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#endif /* __LINUX_OMAP_DMA_H */
|