Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
6971071c
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
6971071c
编写于
12月 21, 2010
作者:
T
Tony Lindgren
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'devel-dma' into omap-for-linus
上级
4584acc3
f31cc962
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
1451 addition
and
540 deletion
+1451
-540
arch/arm/mach-omap1/Makefile
arch/arm/mach-omap1/Makefile
+1
-1
arch/arm/mach-omap1/dma.c
arch/arm/mach-omap1/dma.c
+390
-0
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/Makefile
+1
-1
arch/arm/mach-omap2/dma.c
arch/arm/mach-omap2/dma.c
+297
-0
arch/arm/mach-omap2/omap_hwmod_2420_data.c
arch/arm/mach-omap2/omap_hwmod_2420_data.c
+86
-0
arch/arm/mach-omap2/omap_hwmod_2430_data.c
arch/arm/mach-omap2/omap_hwmod_2430_data.c
+86
-0
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+97
-0
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+102
-0
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/dma.c
+292
-405
arch/arm/plat-omap/include/plat/dma.h
arch/arm/plat-omap/include/plat/dma.h
+99
-133
未找到文件。
arch/arm/mach-omap1/Makefile
浏览文件 @
6971071c
...
...
@@ -3,7 +3,7 @@
#
# Common support
obj-y
:=
io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o
obj-y
:=
io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o
dma.o
obj-y
+=
clock.o clock_data.o opp_data.o
obj-$(CONFIG_OMAP_MCBSP)
+=
mcbsp.o
...
...
arch/arm/mach-omap1/dma.c
0 → 100644
浏览文件 @
6971071c
/*
* OMAP1/OMAP7xx - specific DMA driver
*
* Copyright (C) 2003 - 2008 Nokia Corporation
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
* DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
* Graphics DMA and LCD DMA graphics tranformations
* by Imre Deak <imre.deak@nokia.com>
* OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
* Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
* Converted DMA library into platform driver
* - G, Manjunath Kondaiah <manjugk@ti.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.
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <plat/dma.h>
#include <plat/tc.h>
#include <plat/irqs.h>
#define OMAP1_DMA_BASE (0xfffed800)
#define OMAP1_LOGICAL_DMA_CH_COUNT 17
#define OMAP1_DMA_STRIDE 0x40
static
u32
errata
;
static
u32
enable_1510_mode
;
static
u8
dma_stride
;
static
enum
omap_reg_offsets
dma_common_ch_start
,
dma_common_ch_end
;
static
u16
reg_map
[]
=
{
[
GCR
]
=
0x400
,
[
GSCR
]
=
0x404
,
[
GRST1
]
=
0x408
,
[
HW_ID
]
=
0x442
,
[
PCH2_ID
]
=
0x444
,
[
PCH0_ID
]
=
0x446
,
[
PCH1_ID
]
=
0x448
,
[
PCHG_ID
]
=
0x44a
,
[
PCHD_ID
]
=
0x44c
,
[
CAPS_0
]
=
0x44e
,
[
CAPS_1
]
=
0x452
,
[
CAPS_2
]
=
0x456
,
[
CAPS_3
]
=
0x458
,
[
CAPS_4
]
=
0x45a
,
[
PCH2_SR
]
=
0x460
,
[
PCH0_SR
]
=
0x480
,
[
PCH1_SR
]
=
0x482
,
[
PCHD_SR
]
=
0x4c0
,
/* Common Registers */
[
CSDP
]
=
0x00
,
[
CCR
]
=
0x02
,
[
CICR
]
=
0x04
,
[
CSR
]
=
0x06
,
[
CEN
]
=
0x10
,
[
CFN
]
=
0x12
,
[
CSFI
]
=
0x14
,
[
CSEI
]
=
0x16
,
[
CPC
]
=
0x18
,
/* 15xx only */
[
CSAC
]
=
0x18
,
[
CDAC
]
=
0x1a
,
[
CDEI
]
=
0x1c
,
[
CDFI
]
=
0x1e
,
[
CLNK_CTRL
]
=
0x28
,
/* Channel specific register offsets */
[
CSSA
]
=
0x08
,
[
CDSA
]
=
0x0c
,
[
COLOR
]
=
0x20
,
[
CCR2
]
=
0x24
,
[
LCH_CTRL
]
=
0x2a
,
};
static
struct
resource
res
[]
__initdata
=
{
[
0
]
=
{
.
start
=
OMAP1_DMA_BASE
,
.
end
=
OMAP1_DMA_BASE
+
SZ_2K
-
1
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
name
=
"0"
,
.
start
=
INT_DMA_CH0_6
,
.
flags
=
IORESOURCE_IRQ
,
},
[
2
]
=
{
.
name
=
"1"
,
.
start
=
INT_DMA_CH1_7
,
.
flags
=
IORESOURCE_IRQ
,
},
[
3
]
=
{
.
name
=
"2"
,
.
start
=
INT_DMA_CH2_8
,
.
flags
=
IORESOURCE_IRQ
,
},
[
4
]
=
{
.
name
=
"3"
,
.
start
=
INT_DMA_CH3
,
.
flags
=
IORESOURCE_IRQ
,
},
[
5
]
=
{
.
name
=
"4"
,
.
start
=
INT_DMA_CH4
,
.
flags
=
IORESOURCE_IRQ
,
},
[
6
]
=
{
.
name
=
"5"
,
.
start
=
INT_DMA_CH5
,
.
flags
=
IORESOURCE_IRQ
,
},
/* Handled in lcd_dma.c */
[
7
]
=
{
.
name
=
"6"
,
.
start
=
INT_1610_DMA_CH6
,
.
flags
=
IORESOURCE_IRQ
,
},
/* irq's for omap16xx and omap7xx */
[
8
]
=
{
.
name
=
"7"
,
.
start
=
INT_1610_DMA_CH7
,
.
flags
=
IORESOURCE_IRQ
,
},
[
9
]
=
{
.
name
=
"8"
,
.
start
=
INT_1610_DMA_CH8
,
.
flags
=
IORESOURCE_IRQ
,
},
[
10
]
=
{
.
name
=
"9"
,
.
start
=
INT_1610_DMA_CH9
,
.
flags
=
IORESOURCE_IRQ
,
},
[
11
]
=
{
.
name
=
"10"
,
.
start
=
INT_1610_DMA_CH10
,
.
flags
=
IORESOURCE_IRQ
,
},
[
12
]
=
{
.
name
=
"11"
,
.
start
=
INT_1610_DMA_CH11
,
.
flags
=
IORESOURCE_IRQ
,
},
[
13
]
=
{
.
name
=
"12"
,
.
start
=
INT_1610_DMA_CH12
,
.
flags
=
IORESOURCE_IRQ
,
},
[
14
]
=
{
.
name
=
"13"
,
.
start
=
INT_1610_DMA_CH13
,
.
flags
=
IORESOURCE_IRQ
,
},
[
15
]
=
{
.
name
=
"14"
,
.
start
=
INT_1610_DMA_CH14
,
.
flags
=
IORESOURCE_IRQ
,
},
[
16
]
=
{
.
name
=
"15"
,
.
start
=
INT_1610_DMA_CH15
,
.
flags
=
IORESOURCE_IRQ
,
},
[
17
]
=
{
.
name
=
"16"
,
.
start
=
INT_DMA_LCD
,
.
flags
=
IORESOURCE_IRQ
,
},
};
static
void
__iomem
*
dma_base
;
static
inline
void
dma_write
(
u32
val
,
int
reg
,
int
lch
)
{
u8
stride
;
u32
offset
;
stride
=
(
reg
>=
dma_common_ch_start
)
?
dma_stride
:
0
;
offset
=
reg_map
[
reg
]
+
(
stride
*
lch
);
__raw_writew
(
val
,
dma_base
+
offset
);
if
((
reg
>
CLNK_CTRL
&&
reg
<
CCEN
)
||
(
reg
>
PCHD_ID
&&
reg
<
CAPS_2
))
{
u32
offset2
=
reg_map
[
reg
]
+
2
+
(
stride
*
lch
);
__raw_writew
(
val
>>
16
,
dma_base
+
offset2
);
}
}
static
inline
u32
dma_read
(
int
reg
,
int
lch
)
{
u8
stride
;
u32
offset
,
val
;
stride
=
(
reg
>=
dma_common_ch_start
)
?
dma_stride
:
0
;
offset
=
reg_map
[
reg
]
+
(
stride
*
lch
);
val
=
__raw_readw
(
dma_base
+
offset
);
if
((
reg
>
CLNK_CTRL
&&
reg
<
CCEN
)
||
(
reg
>
PCHD_ID
&&
reg
<
CAPS_2
))
{
u16
upper
;
u32
offset2
=
reg_map
[
reg
]
+
2
+
(
stride
*
lch
);
upper
=
__raw_readw
(
dma_base
+
offset2
);
val
|=
(
upper
<<
16
);
}
return
val
;
}
static
void
omap1_clear_lch_regs
(
int
lch
)
{
int
i
=
dma_common_ch_start
;
for
(;
i
<=
dma_common_ch_end
;
i
+=
1
)
dma_write
(
0
,
i
,
lch
);
}
static
void
omap1_clear_dma
(
int
lch
)
{
u32
l
;
l
=
dma_read
(
CCR
,
lch
);
l
&=
~
OMAP_DMA_CCR_EN
;
dma_write
(
l
,
CCR
,
lch
);
/* Clear pending interrupts */
l
=
dma_read
(
CSR
,
lch
);
}
static
void
omap1_show_dma_caps
(
void
)
{
if
(
enable_1510_mode
)
{
printk
(
KERN_INFO
"DMA support for OMAP15xx initialized
\n
"
);
}
else
{
u16
w
;
printk
(
KERN_INFO
"OMAP DMA hardware version %d
\n
"
,
dma_read
(
HW_ID
,
0
));
printk
(
KERN_INFO
"DMA capabilities: %08x:%08x:%04x:%04x:%04x
\n
"
,
dma_read
(
CAPS_0
,
0
),
dma_read
(
CAPS_1
,
0
),
dma_read
(
CAPS_2
,
0
),
dma_read
(
CAPS_3
,
0
),
dma_read
(
CAPS_4
,
0
));
/* Disable OMAP 3.0/3.1 compatibility mode. */
w
=
dma_read
(
GSCR
,
0
);
w
|=
1
<<
3
;
dma_write
(
w
,
GSCR
,
0
);
}
return
;
}
static
u32
configure_dma_errata
(
void
)
{
/*
* Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
if
(
!
cpu_is_omap15xx
())
SET_DMA_ERRATA
(
DMA_ERRATA_3_3
);
return
errata
;
}
static
int
__init
omap1_system_dma_init
(
void
)
{
struct
omap_system_dma_plat_info
*
p
;
struct
omap_dma_dev_attr
*
d
;
struct
platform_device
*
pdev
;
int
ret
;
pdev
=
platform_device_alloc
(
"omap_dma_system"
,
0
);
if
(
!
pdev
)
{
pr_err
(
"%s: Unable to device alloc for dma
\n
"
,
__func__
);
return
-
ENOMEM
;
}
dma_base
=
ioremap
(
res
[
0
].
start
,
resource_size
(
&
res
[
0
]));
if
(
!
dma_base
)
{
pr_err
(
"%s: Unable to ioremap
\n
"
,
__func__
);
return
-
ENODEV
;
}
ret
=
platform_device_add_resources
(
pdev
,
res
,
ARRAY_SIZE
(
res
));
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to add resources for %s%d
\n
"
,
__func__
,
pdev
->
name
,
pdev
->
id
);
goto
exit_device_del
;
}
p
=
kzalloc
(
sizeof
(
struct
omap_system_dma_plat_info
),
GFP_KERNEL
);
if
(
!
p
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to allocate 'p' for %s
\n
"
,
__func__
,
pdev
->
name
);
ret
=
-
ENOMEM
;
goto
exit_device_put
;
}
d
=
kzalloc
(
sizeof
(
struct
omap_dma_dev_attr
),
GFP_KERNEL
);
if
(
!
d
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to allocate 'd' for %s
\n
"
,
__func__
,
pdev
->
name
);
ret
=
-
ENOMEM
;
goto
exit_release_p
;
}
d
->
lch_count
=
OMAP1_LOGICAL_DMA_CH_COUNT
;
/* Valid attributes for omap1 plus processors */
if
(
cpu_is_omap15xx
())
d
->
dev_caps
=
ENABLE_1510_MODE
;
enable_1510_mode
=
d
->
dev_caps
&
ENABLE_1510_MODE
;
d
->
dev_caps
|=
SRC_PORT
;
d
->
dev_caps
|=
DST_PORT
;
d
->
dev_caps
|=
SRC_INDEX
;
d
->
dev_caps
|=
DST_INDEX
;
d
->
dev_caps
|=
IS_BURST_ONLY4
;
d
->
dev_caps
|=
CLEAR_CSR_ON_READ
;
d
->
dev_caps
|=
IS_WORD_16
;
d
->
chan
=
kzalloc
(
sizeof
(
struct
omap_dma_lch
)
*
(
d
->
lch_count
),
GFP_KERNEL
);
if
(
!
d
->
chan
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Memory allocation failed"
"for d->chan!!!
\n
"
,
__func__
);
goto
exit_release_d
;
}
if
(
cpu_is_omap15xx
())
d
->
chan_count
=
9
;
else
if
(
cpu_is_omap16xx
()
||
cpu_is_omap7xx
())
{
if
(
!
(
d
->
dev_caps
&
ENABLE_1510_MODE
))
d
->
chan_count
=
16
;
else
d
->
chan_count
=
9
;
}
p
->
dma_attr
=
d
;
p
->
show_dma_caps
=
omap1_show_dma_caps
;
p
->
clear_lch_regs
=
omap1_clear_lch_regs
;
p
->
clear_dma
=
omap1_clear_dma
;
p
->
dma_write
=
dma_write
;
p
->
dma_read
=
dma_read
;
p
->
disable_irq_lch
=
NULL
;
p
->
errata
=
configure_dma_errata
();
ret
=
platform_device_add_data
(
pdev
,
p
,
sizeof
(
*
p
));
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to add resources for %s%d
\n
"
,
__func__
,
pdev
->
name
,
pdev
->
id
);
goto
exit_release_chan
;
}
ret
=
platform_device_add
(
pdev
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"%s: Unable to add resources for %s%d
\n
"
,
__func__
,
pdev
->
name
,
pdev
->
id
);
goto
exit_release_chan
;
}
dma_stride
=
OMAP1_DMA_STRIDE
;
dma_common_ch_start
=
CPC
;
dma_common_ch_end
=
COLOR
;
return
ret
;
exit_release_chan:
kfree
(
d
->
chan
);
exit_release_d:
kfree
(
d
);
exit_release_p:
kfree
(
p
);
exit_device_put:
platform_device_put
(
pdev
);
exit_device_del:
platform_device_del
(
pdev
);
return
ret
;
}
arch_initcall
(
omap1_system_dma_init
);
arch/arm/mach-omap2/Makefile
浏览文件 @
6971071c
...
...
@@ -4,7 +4,7 @@
# Common support
obj-y
:=
id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o
\
common.o gpio.o
common.o gpio.o
dma.o
omap-2-3-common
=
irq.o sdrc.o prm2xxx_3xxx.o
hwmod-common
=
omap_hwmod.o
\
...
...
arch/arm/mach-omap2/dma.c
0 → 100644
浏览文件 @
6971071c
/*
* OMAP2+ DMA driver
*
* Copyright (C) 2003 - 2008 Nokia Corporation
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
* DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
* Graphics DMA and LCD DMA graphics tranformations
* by Imre Deak <imre.deak@nokia.com>
* OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
* Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
*
* Copyright (C) 2009 Texas Instruments
* Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
* Converted DMA library into platform driver
* - G, Manjunath Kondaiah <manjugk@ti.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.
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
#include <plat/dma.h>
#define OMAP2_DMA_STRIDE 0x60
static
u32
errata
;
static
u8
dma_stride
;
static
struct
omap_dma_dev_attr
*
d
;
static
enum
omap_reg_offsets
dma_common_ch_start
,
dma_common_ch_end
;
static
u16
reg_map
[]
=
{
[
REVISION
]
=
0x00
,
[
GCR
]
=
0x78
,
[
IRQSTATUS_L0
]
=
0x08
,
[
IRQSTATUS_L1
]
=
0x0c
,
[
IRQSTATUS_L2
]
=
0x10
,
[
IRQSTATUS_L3
]
=
0x14
,
[
IRQENABLE_L0
]
=
0x18
,
[
IRQENABLE_L1
]
=
0x1c
,
[
IRQENABLE_L2
]
=
0x20
,
[
IRQENABLE_L3
]
=
0x24
,
[
SYSSTATUS
]
=
0x28
,
[
OCP_SYSCONFIG
]
=
0x2c
,
[
CAPS_0
]
=
0x64
,
[
CAPS_2
]
=
0x6c
,
[
CAPS_3
]
=
0x70
,
[
CAPS_4
]
=
0x74
,
/* Common register offsets */
[
CCR
]
=
0x80
,
[
CLNK_CTRL
]
=
0x84
,
[
CICR
]
=
0x88
,
[
CSR
]
=
0x8c
,
[
CSDP
]
=
0x90
,
[
CEN
]
=
0x94
,
[
CFN
]
=
0x98
,
[
CSEI
]
=
0xa4
,
[
CSFI
]
=
0xa8
,
[
CDEI
]
=
0xac
,
[
CDFI
]
=
0xb0
,
[
CSAC
]
=
0xb4
,
[
CDAC
]
=
0xb8
,
/* Channel specific register offsets */
[
CSSA
]
=
0x9c
,
[
CDSA
]
=
0xa0
,
[
CCEN
]
=
0xbc
,
[
CCFN
]
=
0xc0
,
[
COLOR
]
=
0xc4
,
/* OMAP4 specific registers */
[
CDP
]
=
0xd0
,
[
CNDP
]
=
0xd4
,
[
CCDN
]
=
0xd8
,
};
static
struct
omap_device_pm_latency
omap2_dma_latency
[]
=
{
{
.
deactivate_func
=
omap_device_idle_hwmods
,
.
activate_func
=
omap_device_enable_hwmods
,
.
flags
=
OMAP_DEVICE_LATENCY_AUTO_ADJUST
,
},
};
static
void
__iomem
*
dma_base
;
static
inline
void
dma_write
(
u32
val
,
int
reg
,
int
lch
)
{
u8
stride
;
u32
offset
;
stride
=
(
reg
>=
dma_common_ch_start
)
?
dma_stride
:
0
;
offset
=
reg_map
[
reg
]
+
(
stride
*
lch
);
__raw_writel
(
val
,
dma_base
+
offset
);
}
static
inline
u32
dma_read
(
int
reg
,
int
lch
)
{
u8
stride
;
u32
offset
,
val
;
stride
=
(
reg
>=
dma_common_ch_start
)
?
dma_stride
:
0
;
offset
=
reg_map
[
reg
]
+
(
stride
*
lch
);
val
=
__raw_readl
(
dma_base
+
offset
);
return
val
;
}
static
inline
void
omap2_disable_irq_lch
(
int
lch
)
{
u32
val
;
val
=
dma_read
(
IRQENABLE_L0
,
lch
);
val
&=
~
(
1
<<
lch
);
dma_write
(
val
,
IRQENABLE_L0
,
lch
);
}
static
void
omap2_clear_dma
(
int
lch
)
{
int
i
=
dma_common_ch_start
;
for
(;
i
<=
dma_common_ch_end
;
i
+=
1
)
dma_write
(
0
,
i
,
lch
);
}
static
void
omap2_show_dma_caps
(
void
)
{
u8
revision
=
dma_read
(
REVISION
,
0
)
&
0xff
;
printk
(
KERN_INFO
"OMAP DMA hardware revision %d.%d
\n
"
,
revision
>>
4
,
revision
&
0xf
);
return
;
}
static
u32
configure_dma_errata
(
void
)
{
/*
* Errata applicable for OMAP2430ES1.0 and all omap2420
*
* I.
* Erratum ID: Not Available
* Inter Frame DMA buffering issue DMA will wrongly
* buffer elements if packing and bursting is enabled. This might
* result in data gets stalled in FIFO at the end of the block.
* Workaround: DMA channels must have BUFFERING_DISABLED bit set to
* guarantee no data will stay in the DMA FIFO in case inter frame
* buffering occurs
*
* II.
* Erratum ID: Not Available
* DMA may hang when several channels are used in parallel
* In the following configuration, DMA channel hanging can occur:
* a. Channel i, hardware synchronized, is enabled
* b. Another channel (Channel x), software synchronized, is enabled.
* c. Channel i is disabled before end of transfer
* d. Channel i is reenabled.
* e. Steps 1 to 4 are repeated a certain number of times.
* f. A third channel (Channel y), software synchronized, is enabled.
* Channel x and Channel y may hang immediately after step 'f'.
* Workaround:
* For any channel used - make sure NextLCH_ID is set to the value j.
*/
if
(
cpu_is_omap2420
()
||
(
cpu_is_omap2430
()
&&
(
omap_type
()
==
OMAP2430_REV_ES1_0
)))
{
SET_DMA_ERRATA
(
DMA_ERRATA_IFRAME_BUFFERING
);
SET_DMA_ERRATA
(
DMA_ERRATA_PARALLEL_CHANNELS
);
}
/*
* Erratum ID: i378: OMAP2+: sDMA Channel is not disabled
* after a transaction error.
* Workaround: SW should explicitely disable the channel.
*/
if
(
cpu_class_is_omap2
())
SET_DMA_ERRATA
(
DMA_ERRATA_i378
);
/*
* Erratum ID: i541: sDMA FIFO draining does not finish
* If sDMA channel is disabled on the fly, sDMA enters standby even
* through FIFO Drain is still in progress
* Workaround: Put sDMA in NoStandby more before a logical channel is
* disabled, then put it back to SmartStandby right after the channel
* finishes FIFO draining.
*/
if
(
cpu_is_omap34xx
())
SET_DMA_ERRATA
(
DMA_ERRATA_i541
);
/*
* Erratum ID: i88 : Special programming model needed to disable DMA
* before end of block.
* Workaround: software must ensure that the DMA is configured in No
* Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
*/
if
(
omap_type
()
==
OMAP3430_REV_ES1_0
)
SET_DMA_ERRATA
(
DMA_ERRATA_i88
);
/*
* Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
SET_DMA_ERRATA
(
DMA_ERRATA_3_3
);
/*
* Erratum ID: Not Available
* A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
* after secure sram context save and restore.
* Work around: Hence we need to manually clear those IRQs to avoid
* spurious interrupts. This affects only secure devices.
*/
if
(
cpu_is_omap34xx
()
&&
(
omap_type
()
!=
OMAP2_DEVICE_TYPE_GP
))
SET_DMA_ERRATA
(
DMA_ROMCODE_BUG
);
return
errata
;
}
/* One time initializations */
static
int
__init
omap2_system_dma_init_dev
(
struct
omap_hwmod
*
oh
,
void
*
unused
)
{
struct
omap_device
*
od
;
struct
omap_system_dma_plat_info
*
p
;
struct
resource
*
mem
;
char
*
name
=
"omap_dma_system"
;
dma_stride
=
OMAP2_DMA_STRIDE
;
dma_common_ch_start
=
CSDP
;
if
(
cpu_is_omap3630
()
||
cpu_is_omap4430
())
dma_common_ch_end
=
CCDN
;
else
dma_common_ch_end
=
CCFN
;
p
=
kzalloc
(
sizeof
(
struct
omap_system_dma_plat_info
),
GFP_KERNEL
);
if
(
!
p
)
{
pr_err
(
"%s: Unable to allocate pdata for %s:%s
\n
"
,
__func__
,
name
,
oh
->
name
);
return
-
ENOMEM
;
}
p
->
dma_attr
=
(
struct
omap_dma_dev_attr
*
)
oh
->
dev_attr
;
p
->
disable_irq_lch
=
omap2_disable_irq_lch
;
p
->
show_dma_caps
=
omap2_show_dma_caps
;
p
->
clear_dma
=
omap2_clear_dma
;
p
->
dma_write
=
dma_write
;
p
->
dma_read
=
dma_read
;
p
->
clear_lch_regs
=
NULL
;
p
->
errata
=
configure_dma_errata
();
od
=
omap_device_build
(
name
,
0
,
oh
,
p
,
sizeof
(
*
p
),
omap2_dma_latency
,
ARRAY_SIZE
(
omap2_dma_latency
),
0
);
kfree
(
p
);
if
(
IS_ERR
(
od
))
{
pr_err
(
"%s: Cant build omap_device for %s:%s.
\n
"
,
__func__
,
name
,
oh
->
name
);
return
IS_ERR
(
od
);
}
mem
=
platform_get_resource
(
&
od
->
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
mem
)
{
dev_err
(
&
od
->
pdev
.
dev
,
"%s: no mem resource
\n
"
,
__func__
);
return
-
EINVAL
;
}
dma_base
=
ioremap
(
mem
->
start
,
resource_size
(
mem
));
if
(
!
dma_base
)
{
dev_err
(
&
od
->
pdev
.
dev
,
"%s: ioremap fail
\n
"
,
__func__
);
return
-
ENOMEM
;
}
d
=
oh
->
dev_attr
;
d
->
chan
=
kzalloc
(
sizeof
(
struct
omap_dma_lch
)
*
(
d
->
lch_count
),
GFP_KERNEL
);
if
(
!
d
->
chan
)
{
dev_err
(
&
od
->
pdev
.
dev
,
"%s: kzalloc fail
\n
"
,
__func__
);
return
-
ENOMEM
;
}
return
0
;
}
static
int
__init
omap2_system_dma_init
(
void
)
{
return
omap_hwmod_for_each_by_class
(
"dma"
,
omap2_system_dma_init_dev
,
NULL
);
}
arch_initcall
(
omap2_system_dma_init
);
arch/arm/mach-omap2/omap_hwmod_2420_data.c
浏览文件 @
6971071c
...
...
@@ -42,6 +42,7 @@ static struct omap_hwmod omap2420_gpio1_hwmod;
static
struct
omap_hwmod
omap2420_gpio2_hwmod
;
static
struct
omap_hwmod
omap2420_gpio3_hwmod
;
static
struct
omap_hwmod
omap2420_gpio4_hwmod
;
static
struct
omap_hwmod
omap2420_dma_system_hwmod
;
/* L3 -> L4_CORE interface */
static
struct
omap_hwmod_ocp_if
omap2420_l3_main__l4_core
=
{
...
...
@@ -779,6 +780,88 @@ static struct omap_hwmod omap2420_gpio4_hwmod = {
.
omap_chip
=
OMAP_CHIP_INIT
(
CHIP_IS_OMAP2420
),
};
/* system dma */
static
struct
omap_hwmod_class_sysconfig
omap2420_dma_sysc
=
{
.
rev_offs
=
0x0000
,
.
sysc_offs
=
0x002c
,
.
syss_offs
=
0x0028
,
.
sysc_flags
=
(
SYSC_HAS_SOFTRESET
|
SYSC_HAS_MIDLEMODE
|
SYSC_HAS_CLOCKACTIVITY
|
SYSC_HAS_EMUFREE
|
SYSC_HAS_AUTOIDLE
),
.
idlemodes
=
(
MSTANDBY_FORCE
|
MSTANDBY_NO
|
MSTANDBY_SMART
),
.
sysc_fields
=
&
omap_hwmod_sysc_type1
,
};
static
struct
omap_hwmod_class
omap2420_dma_hwmod_class
=
{
.
name
=
"dma"
,
.
sysc
=
&
omap2420_dma_sysc
,
};
/* dma attributes */
static
struct
omap_dma_dev_attr
dma_dev_attr
=
{
.
dev_caps
=
RESERVE_CHANNEL
|
DMA_LINKED_LCH
|
GLOBAL_PRIORITY
|
IS_CSSA_32
|
IS_CDSA_32
,
.
lch_count
=
32
,
};
static
struct
omap_hwmod_irq_info
omap2420_dma_system_irqs
[]
=
{
{
.
name
=
"0"
,
.
irq
=
12
},
/* INT_24XX_SDMA_IRQ0 */
{
.
name
=
"1"
,
.
irq
=
13
},
/* INT_24XX_SDMA_IRQ1 */
{
.
name
=
"2"
,
.
irq
=
14
},
/* INT_24XX_SDMA_IRQ2 */
{
.
name
=
"3"
,
.
irq
=
15
},
/* INT_24XX_SDMA_IRQ3 */
};
static
struct
omap_hwmod_addr_space
omap2420_dma_system_addrs
[]
=
{
{
.
pa_start
=
0x48056000
,
.
pa_end
=
0x4a0560ff
,
.
flags
=
ADDR_TYPE_RT
},
};
/* dma_system -> L3 */
static
struct
omap_hwmod_ocp_if
omap2420_dma_system__l3
=
{
.
master
=
&
omap2420_dma_system_hwmod
,
.
slave
=
&
omap2420_l3_main_hwmod
,
.
clk
=
"core_l3_ck"
,
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* dma_system master ports */
static
struct
omap_hwmod_ocp_if
*
omap2420_dma_system_masters
[]
=
{
&
omap2420_dma_system__l3
,
};
/* l4_core -> dma_system */
static
struct
omap_hwmod_ocp_if
omap2420_l4_core__dma_system
=
{
.
master
=
&
omap2420_l4_core_hwmod
,
.
slave
=
&
omap2420_dma_system_hwmod
,
.
clk
=
"sdma_ick"
,
.
addr
=
omap2420_dma_system_addrs
,
.
addr_cnt
=
ARRAY_SIZE
(
omap2420_dma_system_addrs
),
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* dma_system slave ports */
static
struct
omap_hwmod_ocp_if
*
omap2420_dma_system_slaves
[]
=
{
&
omap2420_l4_core__dma_system
,
};
static
struct
omap_hwmod
omap2420_dma_system_hwmod
=
{
.
name
=
"dma"
,
.
class
=
&
omap2420_dma_hwmod_class
,
.
mpu_irqs
=
omap2420_dma_system_irqs
,
.
mpu_irqs_cnt
=
ARRAY_SIZE
(
omap2420_dma_system_irqs
),
.
main_clk
=
"core_l3_ck"
,
.
slaves
=
omap2420_dma_system_slaves
,
.
slaves_cnt
=
ARRAY_SIZE
(
omap2420_dma_system_slaves
),
.
masters
=
omap2420_dma_system_masters
,
.
masters_cnt
=
ARRAY_SIZE
(
omap2420_dma_system_masters
),
.
dev_attr
=
&
dma_dev_attr
,
.
omap_chip
=
OMAP_CHIP_INIT
(
CHIP_IS_OMAP2420
),
.
flags
=
HWMOD_NO_IDLEST
,
};
static
__initdata
struct
omap_hwmod
*
omap2420_hwmods
[]
=
{
&
omap2420_l3_main_hwmod
,
&
omap2420_l4_core_hwmod
,
...
...
@@ -797,6 +880,9 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = {
&
omap2420_gpio2_hwmod
,
&
omap2420_gpio3_hwmod
,
&
omap2420_gpio4_hwmod
,
/* dma_system class*/
&
omap2420_dma_system_hwmod
,
NULL
,
};
...
...
arch/arm/mach-omap2/omap_hwmod_2430_data.c
浏览文件 @
6971071c
...
...
@@ -43,6 +43,7 @@ static struct omap_hwmod omap2430_gpio2_hwmod;
static
struct
omap_hwmod
omap2430_gpio3_hwmod
;
static
struct
omap_hwmod
omap2430_gpio4_hwmod
;
static
struct
omap_hwmod
omap2430_gpio5_hwmod
;
static
struct
omap_hwmod
omap2430_dma_system_hwmod
;
/* L3 -> L4_CORE interface */
static
struct
omap_hwmod_ocp_if
omap2430_l3_main__l4_core
=
{
...
...
@@ -838,6 +839,88 @@ static struct omap_hwmod omap2430_gpio5_hwmod = {
.
omap_chip
=
OMAP_CHIP_INIT
(
CHIP_IS_OMAP2430
),
};
/* dma_system */
static
struct
omap_hwmod_class_sysconfig
omap2430_dma_sysc
=
{
.
rev_offs
=
0x0000
,
.
sysc_offs
=
0x002c
,
.
syss_offs
=
0x0028
,
.
sysc_flags
=
(
SYSC_HAS_SOFTRESET
|
SYSC_HAS_MIDLEMODE
|
SYSC_HAS_CLOCKACTIVITY
|
SYSC_HAS_EMUFREE
|
SYSC_HAS_AUTOIDLE
),
.
idlemodes
=
(
MSTANDBY_FORCE
|
MSTANDBY_NO
|
MSTANDBY_SMART
),
.
sysc_fields
=
&
omap_hwmod_sysc_type1
,
};
static
struct
omap_hwmod_class
omap2430_dma_hwmod_class
=
{
.
name
=
"dma"
,
.
sysc
=
&
omap2430_dma_sysc
,
};
/* dma attributes */
static
struct
omap_dma_dev_attr
dma_dev_attr
=
{
.
dev_caps
=
RESERVE_CHANNEL
|
DMA_LINKED_LCH
|
GLOBAL_PRIORITY
|
IS_CSSA_32
|
IS_CDSA_32
|
IS_RW_PRIORITY
,
.
lch_count
=
32
,
};
static
struct
omap_hwmod_irq_info
omap2430_dma_system_irqs
[]
=
{
{
.
name
=
"0"
,
.
irq
=
12
},
/* INT_24XX_SDMA_IRQ0 */
{
.
name
=
"1"
,
.
irq
=
13
},
/* INT_24XX_SDMA_IRQ1 */
{
.
name
=
"2"
,
.
irq
=
14
},
/* INT_24XX_SDMA_IRQ2 */
{
.
name
=
"3"
,
.
irq
=
15
},
/* INT_24XX_SDMA_IRQ3 */
};
static
struct
omap_hwmod_addr_space
omap2430_dma_system_addrs
[]
=
{
{
.
pa_start
=
0x48056000
,
.
pa_end
=
0x4a0560ff
,
.
flags
=
ADDR_TYPE_RT
},
};
/* dma_system -> L3 */
static
struct
omap_hwmod_ocp_if
omap2430_dma_system__l3
=
{
.
master
=
&
omap2430_dma_system_hwmod
,
.
slave
=
&
omap2430_l3_main_hwmod
,
.
clk
=
"core_l3_ck"
,
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* dma_system master ports */
static
struct
omap_hwmod_ocp_if
*
omap2430_dma_system_masters
[]
=
{
&
omap2430_dma_system__l3
,
};
/* l4_core -> dma_system */
static
struct
omap_hwmod_ocp_if
omap2430_l4_core__dma_system
=
{
.
master
=
&
omap2430_l4_core_hwmod
,
.
slave
=
&
omap2430_dma_system_hwmod
,
.
clk
=
"sdma_ick"
,
.
addr
=
omap2430_dma_system_addrs
,
.
addr_cnt
=
ARRAY_SIZE
(
omap2430_dma_system_addrs
),
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* dma_system slave ports */
static
struct
omap_hwmod_ocp_if
*
omap2430_dma_system_slaves
[]
=
{
&
omap2430_l4_core__dma_system
,
};
static
struct
omap_hwmod
omap2430_dma_system_hwmod
=
{
.
name
=
"dma"
,
.
class
=
&
omap2430_dma_hwmod_class
,
.
mpu_irqs
=
omap2430_dma_system_irqs
,
.
mpu_irqs_cnt
=
ARRAY_SIZE
(
omap2430_dma_system_irqs
),
.
main_clk
=
"core_l3_ck"
,
.
slaves
=
omap2430_dma_system_slaves
,
.
slaves_cnt
=
ARRAY_SIZE
(
omap2430_dma_system_slaves
),
.
masters
=
omap2430_dma_system_masters
,
.
masters_cnt
=
ARRAY_SIZE
(
omap2430_dma_system_masters
),
.
dev_attr
=
&
dma_dev_attr
,
.
omap_chip
=
OMAP_CHIP_INIT
(
CHIP_IS_OMAP2430
),
.
flags
=
HWMOD_NO_IDLEST
,
};
static
__initdata
struct
omap_hwmod
*
omap2430_hwmods
[]
=
{
&
omap2430_l3_main_hwmod
,
&
omap2430_l4_core_hwmod
,
...
...
@@ -857,6 +940,9 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = {
&
omap2430_gpio3_hwmod
,
&
omap2430_gpio4_hwmod
,
&
omap2430_gpio5_hwmod
,
/* dma_system class*/
&
omap2430_dma_system_hwmod
,
NULL
,
};
...
...
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
浏览文件 @
6971071c
...
...
@@ -52,6 +52,8 @@ static struct omap_hwmod omap3xxx_gpio4_hwmod;
static
struct
omap_hwmod
omap3xxx_gpio5_hwmod
;
static
struct
omap_hwmod
omap3xxx_gpio6_hwmod
;
static
struct
omap_hwmod
omap3xxx_dma_system_hwmod
;
/* L3 -> L4_CORE interface */
static
struct
omap_hwmod_ocp_if
omap3xxx_l3_main__l4_core
=
{
.
master
=
&
omap3xxx_l3_main_hwmod
,
...
...
@@ -1090,6 +1092,98 @@ static struct omap_hwmod omap3xxx_gpio6_hwmod = {
.
omap_chip
=
OMAP_CHIP_INIT
(
CHIP_IS_OMAP3430
),
};
/* dma_system -> L3 */
static
struct
omap_hwmod_ocp_if
omap3xxx_dma_system__l3
=
{
.
master
=
&
omap3xxx_dma_system_hwmod
,
.
slave
=
&
omap3xxx_l3_main_hwmod
,
.
clk
=
"core_l3_ick"
,
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* dma attributes */
static
struct
omap_dma_dev_attr
dma_dev_attr
=
{
.
dev_caps
=
RESERVE_CHANNEL
|
DMA_LINKED_LCH
|
GLOBAL_PRIORITY
|
IS_CSSA_32
|
IS_CDSA_32
|
IS_RW_PRIORITY
,
.
lch_count
=
32
,
};
static
struct
omap_hwmod_class_sysconfig
omap3xxx_dma_sysc
=
{
.
rev_offs
=
0x0000
,
.
sysc_offs
=
0x002c
,
.
syss_offs
=
0x0028
,
.
sysc_flags
=
(
SYSC_HAS_SIDLEMODE
|
SYSC_HAS_SOFTRESET
|
SYSC_HAS_MIDLEMODE
|
SYSC_HAS_CLOCKACTIVITY
|
SYSC_HAS_EMUFREE
|
SYSC_HAS_AUTOIDLE
),
.
idlemodes
=
(
SIDLE_FORCE
|
SIDLE_NO
|
SIDLE_SMART
|
MSTANDBY_FORCE
|
MSTANDBY_NO
|
MSTANDBY_SMART
),
.
sysc_fields
=
&
omap_hwmod_sysc_type1
,
};
static
struct
omap_hwmod_class
omap3xxx_dma_hwmod_class
=
{
.
name
=
"dma"
,
.
sysc
=
&
omap3xxx_dma_sysc
,
};
/* dma_system */
static
struct
omap_hwmod_irq_info
omap3xxx_dma_system_irqs
[]
=
{
{
.
name
=
"0"
,
.
irq
=
12
},
/* INT_24XX_SDMA_IRQ0 */
{
.
name
=
"1"
,
.
irq
=
13
},
/* INT_24XX_SDMA_IRQ1 */
{
.
name
=
"2"
,
.
irq
=
14
},
/* INT_24XX_SDMA_IRQ2 */
{
.
name
=
"3"
,
.
irq
=
15
},
/* INT_24XX_SDMA_IRQ3 */
};
static
struct
omap_hwmod_addr_space
omap3xxx_dma_system_addrs
[]
=
{
{
.
pa_start
=
0x48056000
,
.
pa_end
=
0x4a0560ff
,
.
flags
=
ADDR_TYPE_RT
},
};
/* dma_system master ports */
static
struct
omap_hwmod_ocp_if
*
omap3xxx_dma_system_masters
[]
=
{
&
omap3xxx_dma_system__l3
,
};
/* l4_cfg -> dma_system */
static
struct
omap_hwmod_ocp_if
omap3xxx_l4_core__dma_system
=
{
.
master
=
&
omap3xxx_l4_core_hwmod
,
.
slave
=
&
omap3xxx_dma_system_hwmod
,
.
clk
=
"core_l4_ick"
,
.
addr
=
omap3xxx_dma_system_addrs
,
.
addr_cnt
=
ARRAY_SIZE
(
omap3xxx_dma_system_addrs
),
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* dma_system slave ports */
static
struct
omap_hwmod_ocp_if
*
omap3xxx_dma_system_slaves
[]
=
{
&
omap3xxx_l4_core__dma_system
,
};
static
struct
omap_hwmod
omap3xxx_dma_system_hwmod
=
{
.
name
=
"dma"
,
.
class
=
&
omap3xxx_dma_hwmod_class
,
.
mpu_irqs
=
omap3xxx_dma_system_irqs
,
.
mpu_irqs_cnt
=
ARRAY_SIZE
(
omap3xxx_dma_system_irqs
),
.
main_clk
=
"core_l3_ick"
,
.
prcm
=
{
.
omap2
=
{
.
module_offs
=
CORE_MOD
,
.
prcm_reg_id
=
1
,
.
module_bit
=
OMAP3430_ST_SDMA_SHIFT
,
.
idlest_reg_id
=
1
,
.
idlest_idle_bit
=
OMAP3430_ST_SDMA_SHIFT
,
},
},
.
slaves
=
omap3xxx_dma_system_slaves
,
.
slaves_cnt
=
ARRAY_SIZE
(
omap3xxx_dma_system_slaves
),
.
masters
=
omap3xxx_dma_system_masters
,
.
masters_cnt
=
ARRAY_SIZE
(
omap3xxx_dma_system_masters
),
.
dev_attr
=
&
dma_dev_attr
,
.
omap_chip
=
OMAP_CHIP_INIT
(
CHIP_IS_OMAP3430
),
.
flags
=
HWMOD_NO_IDLEST
,
};
static
__initdata
struct
omap_hwmod
*
omap3xxx_hwmods
[]
=
{
&
omap3xxx_l3_main_hwmod
,
&
omap3xxx_l4_core_hwmod
,
...
...
@@ -1113,6 +1207,9 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&
omap3xxx_gpio4_hwmod
,
&
omap3xxx_gpio5_hwmod
,
&
omap3xxx_gpio6_hwmod
,
/* dma_system class*/
&
omap3xxx_dma_system_hwmod
,
NULL
,
};
...
...
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
浏览文件 @
6971071c
...
...
@@ -23,6 +23,7 @@
#include <plat/omap_hwmod.h>
#include <plat/cpu.h>
#include <plat/gpio.h>
#include <plat/dma.h>
#include "omap_hwmod_common_data.h"
...
...
@@ -36,6 +37,7 @@
#define OMAP44XX_DMA_REQ_START 1
/* Backward references (IPs with Bus Master capability) */
static
struct
omap_hwmod
omap44xx_dma_system_hwmod
;
static
struct
omap_hwmod
omap44xx_dmm_hwmod
;
static
struct
omap_hwmod
omap44xx_emif_fw_hwmod
;
static
struct
omap_hwmod
omap44xx_l3_instr_hwmod
;
...
...
@@ -216,6 +218,14 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = {
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* dma_system -> l3_main_2 */
static
struct
omap_hwmod_ocp_if
omap44xx_dma_system__l3_main_2
=
{
.
master
=
&
omap44xx_dma_system_hwmod
,
.
slave
=
&
omap44xx_l3_main_2_hwmod
,
.
clk
=
"l3_div_ck"
,
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* l4_cfg -> l3_main_2 */
static
struct
omap_hwmod_ocp_if
omap44xx_l4_cfg__l3_main_2
=
{
.
master
=
&
omap44xx_l4_cfg_hwmod
,
...
...
@@ -226,6 +236,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = {
/* l3_main_2 slave ports */
static
struct
omap_hwmod_ocp_if
*
omap44xx_l3_main_2_slaves
[]
=
{
&
omap44xx_dma_system__l3_main_2
,
&
omap44xx_l3_main_1__l3_main_2
,
&
omap44xx_l4_cfg__l3_main_2
,
};
...
...
@@ -1376,6 +1387,93 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
.
slaves_cnt
=
ARRAY_SIZE
(
omap44xx_gpio6_slaves
),
.
omap_chip
=
OMAP_CHIP_INIT
(
CHIP_IS_OMAP4430
),
};
/*
* 'dma' class
* dma controller for data exchange between memory to memory (i.e. internal or
* external memory) and gp peripherals to memory or memory to gp peripherals
*/
static
struct
omap_hwmod_class_sysconfig
omap44xx_dma_sysc
=
{
.
rev_offs
=
0x0000
,
.
sysc_offs
=
0x002c
,
.
syss_offs
=
0x0028
,
.
sysc_flags
=
(
SYSC_HAS_AUTOIDLE
|
SYSC_HAS_CLOCKACTIVITY
|
SYSC_HAS_EMUFREE
|
SYSC_HAS_MIDLEMODE
|
SYSC_HAS_SIDLEMODE
|
SYSC_HAS_SOFTRESET
|
SYSS_HAS_RESET_STATUS
),
.
idlemodes
=
(
SIDLE_FORCE
|
SIDLE_NO
|
SIDLE_SMART
|
MSTANDBY_FORCE
|
MSTANDBY_NO
|
MSTANDBY_SMART
),
.
sysc_fields
=
&
omap_hwmod_sysc_type1
,
};
/* dma attributes */
static
struct
omap_dma_dev_attr
dma_dev_attr
=
{
.
dev_caps
=
RESERVE_CHANNEL
|
DMA_LINKED_LCH
|
GLOBAL_PRIORITY
|
IS_CSSA_32
|
IS_CDSA_32
|
IS_RW_PRIORITY
,
.
lch_count
=
32
,
};
static
struct
omap_hwmod_class
omap44xx_dma_hwmod_class
=
{
.
name
=
"dma"
,
.
sysc
=
&
omap44xx_dma_sysc
,
};
/* dma_system */
static
struct
omap_hwmod_irq_info
omap44xx_dma_system_irqs
[]
=
{
{
.
name
=
"0"
,
.
irq
=
12
+
OMAP44XX_IRQ_GIC_START
},
{
.
name
=
"1"
,
.
irq
=
13
+
OMAP44XX_IRQ_GIC_START
},
{
.
name
=
"2"
,
.
irq
=
14
+
OMAP44XX_IRQ_GIC_START
},
{
.
name
=
"3"
,
.
irq
=
15
+
OMAP44XX_IRQ_GIC_START
},
};
/* dma_system master ports */
static
struct
omap_hwmod_ocp_if
*
omap44xx_dma_system_masters
[]
=
{
&
omap44xx_dma_system__l3_main_2
,
};
static
struct
omap_hwmod_addr_space
omap44xx_dma_system_addrs
[]
=
{
{
.
pa_start
=
0x4a056000
,
.
pa_end
=
0x4a0560ff
,
.
flags
=
ADDR_TYPE_RT
},
};
/* l4_cfg -> dma_system */
static
struct
omap_hwmod_ocp_if
omap44xx_l4_cfg__dma_system
=
{
.
master
=
&
omap44xx_l4_cfg_hwmod
,
.
slave
=
&
omap44xx_dma_system_hwmod
,
.
clk
=
"l4_div_ck"
,
.
addr
=
omap44xx_dma_system_addrs
,
.
addr_cnt
=
ARRAY_SIZE
(
omap44xx_dma_system_addrs
),
.
user
=
OCP_USER_MPU
|
OCP_USER_SDMA
,
};
/* dma_system slave ports */
static
struct
omap_hwmod_ocp_if
*
omap44xx_dma_system_slaves
[]
=
{
&
omap44xx_l4_cfg__dma_system
,
};
static
struct
omap_hwmod
omap44xx_dma_system_hwmod
=
{
.
name
=
"dma_system"
,
.
class
=
&
omap44xx_dma_hwmod_class
,
.
mpu_irqs
=
omap44xx_dma_system_irqs
,
.
mpu_irqs_cnt
=
ARRAY_SIZE
(
omap44xx_dma_system_irqs
),
.
main_clk
=
"l3_div_ck"
,
.
prcm
=
{
.
omap4
=
{
.
clkctrl_reg
=
OMAP4430_CM_SDMA_SDMA_CLKCTRL
,
},
},
.
slaves
=
omap44xx_dma_system_slaves
,
.
slaves_cnt
=
ARRAY_SIZE
(
omap44xx_dma_system_slaves
),
.
masters
=
omap44xx_dma_system_masters
,
.
masters_cnt
=
ARRAY_SIZE
(
omap44xx_dma_system_masters
),
.
dev_attr
=
&
dma_dev_attr
,
.
omap_chip
=
OMAP_CHIP_INIT
(
CHIP_IS_OMAP4430
),
};
static
__initdata
struct
omap_hwmod
*
omap44xx_hwmods
[]
=
{
/* dmm class */
&
omap44xx_dmm_hwmod
,
...
...
@@ -1391,6 +1489,10 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
&
omap44xx_l4_cfg_hwmod
,
&
omap44xx_l4_per_hwmod
,
&
omap44xx_l4_wkup_hwmod
,
/* dma class */
&
omap44xx_dma_system_hwmod
,
/* i2c class */
&
omap44xx_i2c1_hwmod
,
&
omap44xx_i2c2_hwmod
,
...
...
arch/arm/plat-omap/dma.c
浏览文件 @
6971071c
...
...
@@ -15,6 +15,10 @@
*
* Support functions for the OMAP internal DMA channels.
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
* Converted DMA library into DMA platform driver.
* - G, Manjunath Kondaiah <manjugk@ti.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.
...
...
@@ -53,7 +57,11 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
static
struct
omap_system_dma_plat_info
*
p
;
static
struct
omap_dma_dev_attr
*
d
;
static
int
enable_1510_mode
;
static
u32
errata
;
static
struct
omap_dma_global_context_registers
{
u32
dma_irqenable_l0
;
...
...
@@ -61,27 +69,6 @@ static struct omap_dma_global_context_registers {
u32
dma_gcr
;
}
omap_dma_global_context
;
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
;
#ifndef CONFIG_ARCH_OMAP1
/* required for Dynamic chaining */
int
prev_linked_ch
;
int
next_linked_ch
;
int
state
;
int
chain_id
;
int
status
;
#endif
long
flags
;
};
struct
dma_link_info
{
int
*
linked_dmach_q
;
int
no_of_lchs_linked
;
...
...
@@ -137,15 +124,6 @@ static int omap_dma_reserve_channels;
static
spinlock_t
dma_chan_lock
;
static
struct
omap_dma_lch
*
dma_chan
;
static
void
__iomem
*
omap_dma_base
;
static
const
u8
omap1_dma_irq
[
OMAP1_LOGICAL_DMA_CH_COUNT
]
=
{
INT_DMA_CH0_6
,
INT_DMA_CH1_7
,
INT_DMA_CH2_8
,
INT_DMA_CH3
,
INT_DMA_CH4
,
INT_DMA_CH5
,
INT_1610_DMA_CH6
,
INT_1610_DMA_CH7
,
INT_1610_DMA_CH8
,
INT_1610_DMA_CH9
,
INT_1610_DMA_CH10
,
INT_1610_DMA_CH11
,
INT_1610_DMA_CH12
,
INT_1610_DMA_CH13
,
INT_1610_DMA_CH14
,
INT_1610_DMA_CH15
,
INT_DMA_LCD
};
static
inline
void
disable_lnk
(
int
lch
);
static
void
omap_disable_channel_irq
(
int
lch
);
...
...
@@ -154,27 +132,9 @@ static inline void omap_enable_channel_irq(int lch);
#define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \
__func__);
#define dma_read(reg) \
({ \
u32 __val; \
if (cpu_class_is_omap1()) \
__val = __raw_readw(omap_dma_base + OMAP1_DMA_##reg); \
else \
__val = __raw_readl(omap_dma_base + OMAP_DMA4_##reg); \
__val; \
})
#define dma_write(val, reg) \
({ \
if (cpu_class_is_omap1()) \
__raw_writew((u16)(val), omap_dma_base + OMAP1_DMA_##reg); \
else \
__raw_writel((val), omap_dma_base + OMAP_DMA4_##reg); \
})
#ifdef CONFIG_ARCH_OMAP15XX
/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
static
int
omap_dma_in_1510_mode
(
void
)
int
omap_dma_in_1510_mode
(
void
)
{
return
enable_1510_mode
;
}
...
...
@@ -206,16 +166,6 @@ static inline void set_gdma_dev(int req, int dev)
#define set_gdma_dev(req, dev) do {} while (0)
#endif
/* Omap1 only */
static
void
clear_lch_regs
(
int
lch
)
{
int
i
;
void
__iomem
*
lch_base
=
omap_dma_base
+
OMAP1_DMA_CH_BASE
(
lch
);
for
(
i
=
0
;
i
<
0x2c
;
i
+=
2
)
__raw_writew
(
0
,
lch_base
+
i
);
}
void
omap_set_dma_priority
(
int
lch
,
int
dst_port
,
int
priority
)
{
unsigned
long
reg
;
...
...
@@ -248,12 +198,12 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
if
(
cpu_class_is_omap2
())
{
u32
ccr
;
ccr
=
dma_read
(
CCR
(
lch
)
);
ccr
=
p
->
dma_read
(
CCR
,
lch
);
if
(
priority
)
ccr
|=
(
1
<<
6
);
else
ccr
&=
~
(
1
<<
6
);
dma_write
(
ccr
,
CCR
(
lch
)
);
p
->
dma_write
(
ccr
,
CCR
,
lch
);
}
}
EXPORT_SYMBOL
(
omap_set_dma_priority
);
...
...
@@ -264,31 +214,31 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
{
u32
l
;
l
=
dma_read
(
CSDP
(
lch
)
);
l
=
p
->
dma_read
(
CSDP
,
lch
);
l
&=
~
0x03
;
l
|=
data_type
;
dma_write
(
l
,
CSDP
(
lch
)
);
p
->
dma_write
(
l
,
CSDP
,
lch
);
if
(
cpu_class_is_omap1
())
{
u16
ccr
;
ccr
=
dma_read
(
CCR
(
lch
)
);
ccr
=
p
->
dma_read
(
CCR
,
lch
);
ccr
&=
~
(
1
<<
5
);
if
(
sync_mode
==
OMAP_DMA_SYNC_FRAME
)
ccr
|=
1
<<
5
;
dma_write
(
ccr
,
CCR
(
lch
)
);
p
->
dma_write
(
ccr
,
CCR
,
lch
);
ccr
=
dma_read
(
CCR2
(
lch
)
);
ccr
=
p
->
dma_read
(
CCR2
,
lch
);
ccr
&=
~
(
1
<<
2
);
if
(
sync_mode
==
OMAP_DMA_SYNC_BLOCK
)
ccr
|=
1
<<
2
;
dma_write
(
ccr
,
CCR2
(
lch
)
);
p
->
dma_write
(
ccr
,
CCR2
,
lch
);
}
if
(
cpu_class_is_omap2
()
&&
dma_trigger
)
{
u32
val
;
val
=
dma_read
(
CCR
(
lch
)
);
val
=
p
->
dma_read
(
CCR
,
lch
);
/* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
val
&=
~
((
1
<<
23
)
|
(
3
<<
19
)
|
0x1f
);
...
...
@@ -313,11 +263,11 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
}
else
{
val
&=
~
(
1
<<
24
);
/* dest synch */
}
dma_write
(
val
,
CCR
(
lch
)
);
p
->
dma_write
(
val
,
CCR
,
lch
);
}
dma_write
(
elem_count
,
CEN
(
lch
)
);
dma_write
(
frame_count
,
CFN
(
lch
)
);
p
->
dma_write
(
elem_count
,
CEN
,
lch
);
p
->
dma_write
(
frame_count
,
CFN
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_transfer_params
);
...
...
@@ -328,7 +278,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
if
(
cpu_class_is_omap1
())
{
u16
w
;
w
=
dma_read
(
CCR2
(
lch
)
);
w
=
p
->
dma_read
(
CCR2
,
lch
);
w
&=
~
0x03
;
switch
(
mode
)
{
...
...
@@ -343,23 +293,22 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG
();
}
dma_write
(
w
,
CCR2
(
lch
)
);
p
->
dma_write
(
w
,
CCR2
,
lch
);
w
=
dma_read
(
LCH_CTRL
(
lch
)
);
w
=
p
->
dma_read
(
LCH_CTRL
,
lch
);
w
&=
~
0x0f
;
/* Default is channel type 2D */
if
(
mode
)
{
dma_write
((
u16
)
color
,
COLOR_L
(
lch
));
dma_write
((
u16
)(
color
>>
16
),
COLOR_U
(
lch
));
p
->
dma_write
(
color
,
COLOR
,
lch
);
w
|=
1
;
/* Channel type G */
}
dma_write
(
w
,
LCH_CTRL
(
lch
)
);
p
->
dma_write
(
w
,
LCH_CTRL
,
lch
);
}
if
(
cpu_class_is_omap2
())
{
u32
val
;
val
=
dma_read
(
CCR
(
lch
)
);
val
=
p
->
dma_read
(
CCR
,
lch
);
val
&=
~
((
1
<<
17
)
|
(
1
<<
16
));
switch
(
mode
)
{
...
...
@@ -374,10 +323,10 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG
();
}
dma_write
(
val
,
CCR
(
lch
)
);
p
->
dma_write
(
val
,
CCR
,
lch
);
color
&=
0xffffff
;
dma_write
(
color
,
COLOR
(
lch
)
);
p
->
dma_write
(
color
,
COLOR
,
lch
);
}
}
EXPORT_SYMBOL
(
omap_set_dma_color_mode
);
...
...
@@ -387,10 +336,10 @@ void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
if
(
cpu_class_is_omap2
())
{
u32
csdp
;
csdp
=
dma_read
(
CSDP
(
lch
)
);
csdp
=
p
->
dma_read
(
CSDP
,
lch
);
csdp
&=
~
(
0x3
<<
16
);
csdp
|=
(
mode
<<
16
);
dma_write
(
csdp
,
CSDP
(
lch
)
);
p
->
dma_write
(
csdp
,
CSDP
,
lch
);
}
}
EXPORT_SYMBOL
(
omap_set_dma_write_mode
);
...
...
@@ -400,10 +349,10 @@ void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
if
(
cpu_class_is_omap1
()
&&
!
cpu_is_omap15xx
())
{
u32
l
;
l
=
dma_read
(
LCH_CTRL
(
lch
)
);
l
=
p
->
dma_read
(
LCH_CTRL
,
lch
);
l
&=
~
0x7
;
l
|=
mode
;
dma_write
(
l
,
LCH_CTRL
(
lch
)
);
p
->
dma_write
(
l
,
LCH_CTRL
,
lch
);
}
}
EXPORT_SYMBOL
(
omap_set_dma_channel_mode
);
...
...
@@ -418,27 +367,21 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
if
(
cpu_class_is_omap1
())
{
u16
w
;
w
=
dma_read
(
CSDP
(
lch
)
);
w
=
p
->
dma_read
(
CSDP
,
lch
);
w
&=
~
(
0x1f
<<
2
);
w
|=
src_port
<<
2
;
dma_write
(
w
,
CSDP
(
lch
)
);
p
->
dma_write
(
w
,
CSDP
,
lch
);
}
l
=
dma_read
(
CCR
(
lch
)
);
l
=
p
->
dma_read
(
CCR
,
lch
);
l
&=
~
(
0x03
<<
12
);
l
|=
src_amode
<<
12
;
dma_write
(
l
,
CCR
(
lch
));
if
(
cpu_class_is_omap1
())
{
dma_write
(
src_start
>>
16
,
CSSA_U
(
lch
));
dma_write
((
u16
)
src_start
,
CSSA_L
(
lch
));
}
p
->
dma_write
(
l
,
CCR
,
lch
);
if
(
cpu_class_is_omap2
())
dma_write
(
src_start
,
CSSA
(
lch
));
p
->
dma_write
(
src_start
,
CSSA
,
lch
);
dma_write
(
src_ei
,
CSEI
(
lch
)
);
dma_write
(
src_fi
,
CSFI
(
lch
)
);
p
->
dma_write
(
src_ei
,
CSEI
,
lch
);
p
->
dma_write
(
src_fi
,
CSFI
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_src_params
);
...
...
@@ -466,8 +409,8 @@ void omap_set_dma_src_index(int lch, int eidx, int fidx)
if
(
cpu_class_is_omap2
())
return
;
dma_write
(
eidx
,
CSEI
(
lch
)
);
dma_write
(
fidx
,
CSFI
(
lch
)
);
p
->
dma_write
(
eidx
,
CSEI
,
lch
);
p
->
dma_write
(
fidx
,
CSFI
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_src_index
);
...
...
@@ -475,11 +418,11 @@ void omap_set_dma_src_data_pack(int lch, int enable)
{
u32
l
;
l
=
dma_read
(
CSDP
(
lch
)
);
l
=
p
->
dma_read
(
CSDP
,
lch
);
l
&=
~
(
1
<<
6
);
if
(
enable
)
l
|=
(
1
<<
6
);
dma_write
(
l
,
CSDP
(
lch
)
);
p
->
dma_write
(
l
,
CSDP
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_src_data_pack
);
...
...
@@ -488,7 +431,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
unsigned
int
burst
=
0
;
u32
l
;
l
=
dma_read
(
CSDP
(
lch
)
);
l
=
p
->
dma_read
(
CSDP
,
lch
);
l
&=
~
(
0x03
<<
7
);
switch
(
burst_mode
)
{
...
...
@@ -524,7 +467,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
}
l
|=
(
burst
<<
7
);
dma_write
(
l
,
CSDP
(
lch
)
);
p
->
dma_write
(
l
,
CSDP
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_src_burst_mode
);
...
...
@@ -536,27 +479,21 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
u32
l
;
if
(
cpu_class_is_omap1
())
{
l
=
dma_read
(
CSDP
(
lch
)
);
l
=
p
->
dma_read
(
CSDP
,
lch
);
l
&=
~
(
0x1f
<<
9
);
l
|=
dest_port
<<
9
;
dma_write
(
l
,
CSDP
(
lch
)
);
p
->
dma_write
(
l
,
CSDP
,
lch
);
}
l
=
dma_read
(
CCR
(
lch
)
);
l
=
p
->
dma_read
(
CCR
,
lch
);
l
&=
~
(
0x03
<<
14
);
l
|=
dest_amode
<<
14
;
dma_write
(
l
,
CCR
(
lch
));
if
(
cpu_class_is_omap1
())
{
dma_write
(
dest_start
>>
16
,
CDSA_U
(
lch
));
dma_write
(
dest_start
,
CDSA_L
(
lch
));
}
p
->
dma_write
(
l
,
CCR
,
lch
);
if
(
cpu_class_is_omap2
())
dma_write
(
dest_start
,
CDSA
(
lch
));
p
->
dma_write
(
dest_start
,
CDSA
,
lch
);
dma_write
(
dst_ei
,
CDEI
(
lch
)
);
dma_write
(
dst_fi
,
CDFI
(
lch
)
);
p
->
dma_write
(
dst_ei
,
CDEI
,
lch
);
p
->
dma_write
(
dst_fi
,
CDFI
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_dest_params
);
...
...
@@ -565,8 +502,8 @@ void omap_set_dma_dest_index(int lch, int eidx, int fidx)
if
(
cpu_class_is_omap2
())
return
;
dma_write
(
eidx
,
CDEI
(
lch
)
);
dma_write
(
fidx
,
CDFI
(
lch
)
);
p
->
dma_write
(
eidx
,
CDEI
,
lch
);
p
->
dma_write
(
fidx
,
CDFI
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_dest_index
);
...
...
@@ -574,11 +511,11 @@ void omap_set_dma_dest_data_pack(int lch, int enable)
{
u32
l
;
l
=
dma_read
(
CSDP
(
lch
)
);
l
=
p
->
dma_read
(
CSDP
,
lch
);
l
&=
~
(
1
<<
13
);
if
(
enable
)
l
|=
1
<<
13
;
dma_write
(
l
,
CSDP
(
lch
)
);
p
->
dma_write
(
l
,
CSDP
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_dest_data_pack
);
...
...
@@ -587,7 +524,7 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
unsigned
int
burst
=
0
;
u32
l
;
l
=
dma_read
(
CSDP
(
lch
)
);
l
=
p
->
dma_read
(
CSDP
,
lch
);
l
&=
~
(
0x03
<<
14
);
switch
(
burst_mode
)
{
...
...
@@ -620,7 +557,7 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
return
;
}
l
|=
(
burst
<<
14
);
dma_write
(
l
,
CSDP
(
lch
)
);
p
->
dma_write
(
l
,
CSDP
,
lch
);
}
EXPORT_SYMBOL
(
omap_set_dma_dest_burst_mode
);
...
...
@@ -630,18 +567,18 @@ static inline void omap_enable_channel_irq(int lch)
/* Clear CSR */
if
(
cpu_class_is_omap1
())
status
=
dma_read
(
CSR
(
lch
)
);
status
=
p
->
dma_read
(
CSR
,
lch
);
else
if
(
cpu_class_is_omap2
())
dma_write
(
OMAP2_DMA_CSR_CLEAR_MASK
,
CSR
(
lch
)
);
p
->
dma_write
(
OMAP2_DMA_CSR_CLEAR_MASK
,
CSR
,
lch
);
/* Enable some nice interrupts. */
dma_write
(
dma_chan
[
lch
].
enabled_irqs
,
CICR
(
lch
)
);
p
->
dma_write
(
dma_chan
[
lch
].
enabled_irqs
,
CICR
,
lch
);
}
static
void
omap_disable_channel_irq
(
int
lch
)
{
if
(
cpu_class_is_omap2
())
dma_write
(
0
,
CICR
(
lch
)
);
p
->
dma_write
(
0
,
CICR
,
lch
);
}
void
omap_enable_dma_irq
(
int
lch
,
u16
bits
)
...
...
@@ -660,7 +597,7 @@ static inline void enable_lnk(int lch)
{
u32
l
;
l
=
dma_read
(
CLNK_CTRL
(
lch
)
);
l
=
p
->
dma_read
(
CLNK_CTRL
,
lch
);
if
(
cpu_class_is_omap1
())
l
&=
~
(
1
<<
14
);
...
...
@@ -675,18 +612,18 @@ static inline void enable_lnk(int lch)
l
=
dma_chan
[
lch
].
next_linked_ch
|
(
1
<<
15
);
#endif
dma_write
(
l
,
CLNK_CTRL
(
lch
)
);
p
->
dma_write
(
l
,
CLNK_CTRL
,
lch
);
}
static
inline
void
disable_lnk
(
int
lch
)
{
u32
l
;
l
=
dma_read
(
CLNK_CTRL
(
lch
)
);
l
=
p
->
dma_read
(
CLNK_CTRL
,
lch
);
/* Disable interrupts */
if
(
cpu_class_is_omap1
())
{
dma_write
(
0
,
CICR
(
lch
)
);
p
->
dma_write
(
0
,
CICR
,
lch
);
/* Set the STOP_LNK bit */
l
|=
1
<<
14
;
}
...
...
@@ -697,7 +634,7 @@ static inline void disable_lnk(int lch)
l
&=
~
(
1
<<
15
);
}
dma_write
(
l
,
CLNK_CTRL
(
lch
)
);
p
->
dma_write
(
l
,
CLNK_CTRL
,
lch
);
dma_chan
[
lch
].
flags
&=
~
OMAP_DMA_ACTIVE
;
}
...
...
@@ -710,9 +647,9 @@ static inline void omap2_enable_irq_lch(int lch)
return
;
spin_lock_irqsave
(
&
dma_chan_lock
,
flags
);
val
=
dma_read
(
IRQENABLE_L0
);
val
=
p
->
dma_read
(
IRQENABLE_L0
,
lch
);
val
|=
1
<<
lch
;
dma_write
(
val
,
IRQENABLE_L0
);
p
->
dma_write
(
val
,
IRQENABLE_L0
,
lch
);
spin_unlock_irqrestore
(
&
dma_chan_lock
,
flags
);
}
...
...
@@ -725,9 +662,9 @@ static inline void omap2_disable_irq_lch(int lch)
return
;
spin_lock_irqsave
(
&
dma_chan_lock
,
flags
);
val
=
dma_read
(
IRQENABLE_L0
);
val
=
p
->
dma_read
(
IRQENABLE_L0
,
lch
);
val
&=
~
(
1
<<
lch
);
dma_write
(
val
,
IRQENABLE_L0
);
p
->
dma_write
(
val
,
IRQENABLE_L0
,
lch
);
spin_unlock_irqrestore
(
&
dma_chan_lock
,
flags
);
}
...
...
@@ -754,8 +691,8 @@ int omap_request_dma(int dev_id, const char *dev_name,
chan
=
dma_chan
+
free_ch
;
chan
->
dev_id
=
dev_id
;
if
(
cpu_class_is_omap1
()
)
clear_lch_regs
(
free_ch
);
if
(
p
->
clear_lch_regs
)
p
->
clear_lch_regs
(
free_ch
);
if
(
cpu_class_is_omap2
())
omap_clear_dma
(
free_ch
);
...
...
@@ -792,17 +729,17 @@ int omap_request_dma(int dev_id, const char *dev_name,
* Disable the 1510 compatibility mode and set the sync device
* id.
*/
dma_write
(
dev_id
|
(
1
<<
10
),
CCR
(
free_ch
)
);
p
->
dma_write
(
dev_id
|
(
1
<<
10
),
CCR
,
free_ch
);
}
else
if
(
cpu_is_omap7xx
()
||
cpu_is_omap15xx
())
{
dma_write
(
dev_id
,
CCR
(
free_ch
)
);
p
->
dma_write
(
dev_id
,
CCR
,
free_ch
);
}
if
(
cpu_class_is_omap2
())
{
omap2_enable_irq_lch
(
free_ch
);
omap_enable_channel_irq
(
free_ch
);
/* Clear the CSR register and IRQ status register */
dma_write
(
OMAP2_DMA_CSR_CLEAR_MASK
,
CSR
(
free_ch
)
);
dma_write
(
1
<<
free_ch
,
IRQSTATUS_L
0
);
p
->
dma_write
(
OMAP2_DMA_CSR_CLEAR_MASK
,
CSR
,
free_ch
);
p
->
dma_write
(
1
<<
free_ch
,
IRQSTATUS_L0
,
0
);
}
*
dma_ch_out
=
free_ch
;
...
...
@@ -823,23 +760,23 @@ void omap_free_dma(int lch)
if
(
cpu_class_is_omap1
())
{
/* Disable all DMA interrupts for the channel. */
dma_write
(
0
,
CICR
(
lch
)
);
p
->
dma_write
(
0
,
CICR
,
lch
);
/* Make sure the DMA transfer is stopped. */
dma_write
(
0
,
CCR
(
lch
)
);
p
->
dma_write
(
0
,
CCR
,
lch
);
}
if
(
cpu_class_is_omap2
())
{
omap2_disable_irq_lch
(
lch
);
/* Clear the CSR register and IRQ status register */
dma_write
(
OMAP2_DMA_CSR_CLEAR_MASK
,
CSR
(
lch
)
);
dma_write
(
1
<<
lch
,
IRQSTATUS_L0
);
p
->
dma_write
(
OMAP2_DMA_CSR_CLEAR_MASK
,
CSR
,
lch
);
p
->
dma_write
(
1
<<
lch
,
IRQSTATUS_L0
,
lch
);
/* Disable all DMA interrupts for the channel. */
dma_write
(
0
,
CICR
(
lch
)
);
p
->
dma_write
(
0
,
CICR
,
lch
);
/* Make sure the DMA transfer is stopped. */
dma_write
(
0
,
CCR
(
lch
)
);
p
->
dma_write
(
0
,
CCR
,
lch
);
omap_clear_dma
(
lch
);
}
...
...
@@ -880,7 +817,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
reg
|=
(
0x3
&
tparams
)
<<
12
;
reg
|=
(
arb_rate
&
0xff
)
<<
16
;
dma_write
(
reg
,
GCR
);
p
->
dma_write
(
reg
,
GCR
,
0
);
}
EXPORT_SYMBOL
(
omap_dma_set_global_params
);
...
...
@@ -903,14 +840,14 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
printk
(
KERN_ERR
"Invalid channel id
\n
"
);
return
-
EINVAL
;
}
l
=
dma_read
(
CCR
(
lch
)
);
l
=
p
->
dma_read
(
CCR
,
lch
);
l
&=
~
((
1
<<
6
)
|
(
1
<<
26
));
if
(
cpu_is_omap2430
()
||
cpu_is_omap34xx
()
||
cpu_is_omap44xx
())
l
|=
((
read_prio
&
0x1
)
<<
6
)
|
((
write_prio
&
0x1
)
<<
26
);
else
l
|=
((
read_prio
&
0x1
)
<<
6
);
dma_write
(
l
,
CCR
(
lch
)
);
p
->
dma_write
(
l
,
CCR
,
lch
);
return
0
;
}
...
...
@@ -925,25 +862,7 @@ void omap_clear_dma(int lch)
unsigned
long
flags
;
local_irq_save
(
flags
);
if
(
cpu_class_is_omap1
())
{
u32
l
;
l
=
dma_read
(
CCR
(
lch
));
l
&=
~
OMAP_DMA_CCR_EN
;
dma_write
(
l
,
CCR
(
lch
));
/* Clear pending interrupts */
l
=
dma_read
(
CSR
(
lch
));
}
if
(
cpu_class_is_omap2
())
{
int
i
;
void
__iomem
*
lch_base
=
omap_dma_base
+
OMAP_DMA4_CH_BASE
(
lch
);
for
(
i
=
0
;
i
<
0x44
;
i
+=
4
)
__raw_writel
(
0
,
lch_base
+
i
);
}
p
->
clear_dma
(
lch
);
local_irq_restore
(
flags
);
}
EXPORT_SYMBOL
(
omap_clear_dma
);
...
...
@@ -957,13 +876,13 @@ void omap_start_dma(int lch)
* before starting dma transfer.
*/
if
(
cpu_is_omap15xx
())
dma_write
(
0
,
CPC
(
lch
)
);
p
->
dma_write
(
0
,
CPC
,
lch
);
else
dma_write
(
0
,
CDAC
(
lch
)
);
p
->
dma_write
(
0
,
CDAC
,
lch
);
if
(
!
omap_dma_in_1510_mode
()
&&
dma_chan
[
lch
].
next_lch
!=
-
1
)
{
int
next_lch
,
cur_lch
;
char
dma_chan_link_map
[
OMAP_DMA4_LOGICAL_DMA_CH_COUNT
];
char
dma_chan_link_map
[
dma_lch_count
];
dma_chan_link_map
[
lch
]
=
1
;
/* Set the link register of the first channel */
...
...
@@ -985,32 +904,18 @@ void omap_start_dma(int lch)
cur_lch
=
next_lch
;
}
while
(
next_lch
!=
-
1
);
}
else
if
(
cpu_is_omap242x
()
||
(
cpu_is_omap243x
()
&&
omap_type
()
<=
OMAP2430_REV_ES1_0
))
{
/* Errata: Need to write lch even if not using chaining */
dma_write
(
lch
,
CLNK_CTRL
(
lch
));
}
}
else
if
(
IS_DMA_ERRATA
(
DMA_ERRATA_PARALLEL_CHANNELS
))
p
->
dma_write
(
lch
,
CLNK_CTRL
,
lch
);
omap_enable_channel_irq
(
lch
);
l
=
dma_read
(
CCR
(
lch
));
/*
* Errata: Inter Frame DMA buffering issue (All OMAP2420 and
* OMAP2430ES1.0): DMA will wrongly buffer elements if packing and
* bursting is enabled. This might result in data gets stalled in
* FIFO at the end of the block.
* Workaround: DMA channels must have BUFFERING_DISABLED bit set to
* guarantee no data will stay in the DMA FIFO in case inter frame
* buffering occurs.
*/
if
(
cpu_is_omap2420
()
||
(
cpu_is_omap2430
()
&&
(
omap_type
()
==
OMAP2430_REV_ES1_0
)))
l
|=
OMAP_DMA_CCR_BUFFERING_DISABLE
;
l
=
p
->
dma_read
(
CCR
,
lch
);
if
(
IS_DMA_ERRATA
(
DMA_ERRATA_IFRAME_BUFFERING
))
l
|=
OMAP_DMA_CCR_BUFFERING_DISABLE
;
l
|=
OMAP_DMA_CCR_EN
;
dma_write
(
l
,
CCR
(
lch
));
p
->
dma_write
(
l
,
CCR
,
lch
);
dma_chan
[
lch
].
flags
|=
OMAP_DMA_ACTIVE
;
}
...
...
@@ -1022,46 +927,46 @@ void omap_stop_dma(int lch)
/* Disable all interrupts on the channel */
if
(
cpu_class_is_omap1
())
dma_write
(
0
,
CICR
(
lch
)
);
p
->
dma_write
(
0
,
CICR
,
lch
);
l
=
dma_read
(
CCR
(
lch
)
);
/* OMAP3 Errata i541: sDMA FIFO draining does not finish */
if
(
cpu_is_omap34xx
()
&&
(
l
&
OMAP_DMA_CCR_SEL_SRC_DST_SYNC
))
{
l
=
p
->
dma_read
(
CCR
,
lch
);
if
(
IS_DMA_ERRATA
(
DMA_ERRATA_i541
)
&&
(
l
&
OMAP_DMA_CCR_SEL_SRC_DST_SYNC
))
{
int
i
=
0
;
u32
sys_cf
;
/* Configure No-Standby */
l
=
dma_read
(
OCP_SYSCONFIG
);
l
=
p
->
dma_read
(
OCP_SYSCONFIG
,
lch
);
sys_cf
=
l
;
l
&=
~
DMA_SYSCONFIG_MIDLEMODE_MASK
;
l
|=
DMA_SYSCONFIG_MIDLEMODE
(
DMA_IDLEMODE_NO_IDLE
);
dma_write
(
l
,
OCP_SYSCONFIG
);
p
->
dma_write
(
l
,
OCP_SYSCONFIG
,
0
);
l
=
dma_read
(
CCR
(
lch
)
);
l
=
p
->
dma_read
(
CCR
,
lch
);
l
&=
~
OMAP_DMA_CCR_EN
;
dma_write
(
l
,
CCR
(
lch
)
);
p
->
dma_write
(
l
,
CCR
,
lch
);
/* Wait for sDMA FIFO drain */
l
=
dma_read
(
CCR
(
lch
)
);
l
=
p
->
dma_read
(
CCR
,
lch
);
while
(
i
<
100
&&
(
l
&
(
OMAP_DMA_CCR_RD_ACTIVE
|
OMAP_DMA_CCR_WR_ACTIVE
)))
{
udelay
(
5
);
i
++
;
l
=
dma_read
(
CCR
(
lch
)
);
l
=
p
->
dma_read
(
CCR
,
lch
);
}
if
(
i
>=
100
)
printk
(
KERN_ERR
"DMA drain did not complete on "
"lch %d
\n
"
,
lch
);
/* Restore OCP_SYSCONFIG */
dma_write
(
sys_cf
,
OCP_SYSCONFIG
);
p
->
dma_write
(
sys_cf
,
OCP_SYSCONFIG
,
lch
);
}
else
{
l
&=
~
OMAP_DMA_CCR_EN
;
dma_write
(
l
,
CCR
(
lch
)
);
p
->
dma_write
(
l
,
CCR
,
lch
);
}
if
(
!
omap_dma_in_1510_mode
()
&&
dma_chan
[
lch
].
next_lch
!=
-
1
)
{
int
next_lch
,
cur_lch
=
lch
;
char
dma_chan_link_map
[
OMAP_DMA4_LOGICAL_DMA_CH_COUNT
];
char
dma_chan_link_map
[
dma_lch_count
];
memset
(
dma_chan_link_map
,
0
,
sizeof
(
dma_chan_link_map
));
do
{
...
...
@@ -1122,19 +1027,15 @@ dma_addr_t omap_get_dma_src_pos(int lch)
dma_addr_t
offset
=
0
;
if
(
cpu_is_omap15xx
())
offset
=
dma_read
(
CPC
(
lch
)
);
offset
=
p
->
dma_read
(
CPC
,
lch
);
else
offset
=
dma_read
(
CSAC
(
lch
)
);
offset
=
p
->
dma_read
(
CSAC
,
lch
);
/*
* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
if
(
!
cpu_is_omap15xx
()
&&
offset
==
0
)
offset
=
dma_read
(
CSAC
(
lch
));
if
(
IS_DMA_ERRATA
(
DMA_ERRATA_3_3
)
&&
offset
==
0
)
offset
=
p
->
dma_read
(
CSAC
,
lch
);
if
(
cpu_class_is_omap1
())
offset
|=
(
dma_read
(
CSSA_U
(
lch
))
<<
16
);
offset
|=
(
p
->
dma_read
(
CSSA
,
lch
)
&
0xFFFF0000
);
return
offset
;
}
...
...
@@ -1153,19 +1054,19 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
dma_addr_t
offset
=
0
;
if
(
cpu_is_omap15xx
())
offset
=
dma_read
(
CPC
(
lch
)
);
offset
=
p
->
dma_read
(
CPC
,
lch
);
else
offset
=
dma_read
(
CDAC
(
lch
)
);
offset
=
p
->
dma_read
(
CDAC
,
lch
);
/*
* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
* read before the DMA controller finished disabling the channel.
*/
if
(
!
cpu_is_omap15xx
()
&&
offset
==
0
)
offset
=
dma_read
(
CDAC
(
lch
)
);
offset
=
p
->
dma_read
(
CDAC
,
lch
);
if
(
cpu_class_is_omap1
())
offset
|=
(
dma_read
(
CDSA_U
(
lch
))
<<
16
);
offset
|=
(
p
->
dma_read
(
CDSA
,
lch
)
&
0xFFFF0000
);
return
offset
;
}
...
...
@@ -1173,7 +1074,7 @@ EXPORT_SYMBOL(omap_get_dma_dst_pos);
int
omap_get_dma_active_status
(
int
lch
)
{
return
(
dma_read
(
CCR
(
lch
)
)
&
OMAP_DMA_CCR_EN
)
!=
0
;
return
(
p
->
dma_read
(
CCR
,
lch
)
&
OMAP_DMA_CCR_EN
)
!=
0
;
}
EXPORT_SYMBOL
(
omap_get_dma_active_status
);
...
...
@@ -1186,7 +1087,7 @@ int omap_dma_running(void)
return
1
;
for
(
lch
=
0
;
lch
<
dma_chan_count
;
lch
++
)
if
(
dma_read
(
CCR
(
lch
)
)
&
OMAP_DMA_CCR_EN
)
if
(
p
->
dma_read
(
CCR
,
lch
)
&
OMAP_DMA_CCR_EN
)
return
1
;
return
0
;
...
...
@@ -1201,8 +1102,8 @@ void omap_dma_link_lch(int lch_head, int lch_queue)
{
if
(
omap_dma_in_1510_mode
())
{
if
(
lch_head
==
lch_queue
)
{
dma_write
(
dma_read
(
CCR
(
lch_head
)
)
|
(
3
<<
8
),
CCR
(
lch_head
)
);
p
->
dma_write
(
p
->
dma_read
(
CCR
,
lch_head
)
|
(
3
<<
8
),
CCR
,
lch_head
);
return
;
}
printk
(
KERN_ERR
"DMA linking is not supported in 1510 mode
\n
"
);
...
...
@@ -1228,8 +1129,8 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
{
if
(
omap_dma_in_1510_mode
())
{
if
(
lch_head
==
lch_queue
)
{
dma_write
(
dma_read
(
CCR
(
lch_head
)
)
&
~
(
3
<<
8
),
CCR
(
lch_head
)
);
p
->
dma_write
(
p
->
dma_read
(
CCR
,
lch_head
)
&
~
(
3
<<
8
),
CCR
,
lch_head
);
return
;
}
printk
(
KERN_ERR
"DMA linking is not supported in 1510 mode
\n
"
);
...
...
@@ -1255,8 +1156,6 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
}
EXPORT_SYMBOL
(
omap_dma_unlink_lch
);
/*----------------------------------------------------------------------------*/
#ifndef CONFIG_ARCH_OMAP1
/* Create chain of DMA channesls */
static
void
create_dma_lch_chain
(
int
lch_head
,
int
lch_queue
)
...
...
@@ -1281,15 +1180,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
lch_queue
;
}
l
=
dma_read
(
CLNK_CTRL
(
lch_head
)
);
l
=
p
->
dma_read
(
CLNK_CTRL
,
lch_head
);
l
&=
~
(
0x1f
);
l
|=
lch_queue
;
dma_write
(
l
,
CLNK_CTRL
(
lch_head
)
);
p
->
dma_write
(
l
,
CLNK_CTRL
,
lch_head
);
l
=
dma_read
(
CLNK_CTRL
(
lch_queue
)
);
l
=
p
->
dma_read
(
CLNK_CTRL
,
lch_queue
);
l
&=
~
(
0x1f
);
l
|=
(
dma_chan
[
lch_queue
].
next_linked_ch
);
dma_write
(
l
,
CLNK_CTRL
(
lch_queue
)
);
p
->
dma_write
(
l
,
CLNK_CTRL
,
lch_queue
);
}
/**
...
...
@@ -1565,13 +1464,13 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
/* Set the params to the free channel */
if
(
src_start
!=
0
)
dma_write
(
src_start
,
CSSA
(
lch
)
);
p
->
dma_write
(
src_start
,
CSSA
,
lch
);
if
(
dest_start
!=
0
)
dma_write
(
dest_start
,
CDSA
(
lch
)
);
p
->
dma_write
(
dest_start
,
CDSA
,
lch
);
/* Write the buffer size */
dma_write
(
elem_count
,
CEN
(
lch
)
);
dma_write
(
frame_count
,
CFN
(
lch
)
);
p
->
dma_write
(
elem_count
,
CEN
,
lch
);
p
->
dma_write
(
frame_count
,
CFN
,
lch
);
/*
* If the chain is dynamically linked,
...
...
@@ -1604,8 +1503,8 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
enable_lnk
(
dma_chan
[
lch
].
prev_linked_ch
);
dma_chan
[
lch
].
state
=
DMA_CH_QUEUED
;
start_dma
=
0
;
if
(
0
==
((
1
<<
7
)
&
dma_read
(
CCR
(
dma_chan
[
lch
].
prev_linked_ch
)
)))
{
if
(
0
==
((
1
<<
7
)
&
p
->
dma_read
(
CCR
,
dma_chan
[
lch
].
prev_linked_ch
)))
{
disable_lnk
(
dma_chan
[
lch
].
prev_linked_ch
);
pr_debug
(
"
\n
prev ch is stopped
\n
"
);
...
...
@@ -1621,7 +1520,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
}
omap_enable_channel_irq
(
lch
);
l
=
dma_read
(
CCR
(
lch
)
);
l
=
p
->
dma_read
(
CCR
,
lch
);
if
((
0
==
(
l
&
(
1
<<
24
))))
l
&=
~
(
1
<<
25
);
...
...
@@ -1632,12 +1531,12 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
l
|=
(
1
<<
7
);
dma_chan
[
lch
].
state
=
DMA_CH_STARTED
;
pr_debug
(
"starting %d
\n
"
,
lch
);
dma_write
(
l
,
CCR
(
lch
)
);
p
->
dma_write
(
l
,
CCR
,
lch
);
}
else
start_dma
=
0
;
}
else
{
if
(
0
==
(
l
&
(
1
<<
7
)))
dma_write
(
l
,
CCR
(
lch
)
);
p
->
dma_write
(
l
,
CCR
,
lch
);
}
dma_chan
[
lch
].
flags
|=
OMAP_DMA_ACTIVE
;
}
...
...
@@ -1682,7 +1581,7 @@ int omap_start_dma_chain_transfers(int chain_id)
omap_enable_channel_irq
(
channels
[
0
]);
}
l
=
dma_read
(
CCR
(
channels
[
0
])
);
l
=
p
->
dma_read
(
CCR
,
channels
[
0
]
);
l
|=
(
1
<<
7
);
dma_linked_lch
[
chain_id
].
chain_state
=
DMA_CHAIN_STARTED
;
dma_chan
[
channels
[
0
]].
state
=
DMA_CH_STARTED
;
...
...
@@ -1691,7 +1590,7 @@ int omap_start_dma_chain_transfers(int chain_id)
l
&=
~
(
1
<<
25
);
else
l
|=
(
1
<<
25
);
dma_write
(
l
,
CCR
(
channels
[
0
])
);
p
->
dma_write
(
l
,
CCR
,
channels
[
0
]
);
dma_chan
[
channels
[
0
]].
flags
|=
OMAP_DMA_ACTIVE
;
...
...
@@ -1711,7 +1610,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
{
int
*
channels
;
u32
l
,
i
;
u32
sys_cf
;
u32
sys_cf
=
0
;
/* Check for input params */
if
(
unlikely
((
chain_id
<
0
||
chain_id
>=
dma_lch_count
)))
{
...
...
@@ -1726,22 +1625,20 @@ int omap_stop_dma_chain_transfers(int chain_id)
}
channels
=
dma_linked_lch
[
chain_id
].
linked_dmach_q
;
/*
* DMA Errata:
* Special programming model needed to disable DMA before end of block
*/
sys_cf
=
dma_read
(
OCP_SYSCONFIG
);
l
=
sys_cf
;
/* Middle mode reg set no Standby */
l
&=
~
((
1
<<
12
)
|
(
1
<<
13
));
dma_write
(
l
,
OCP_SYSCONFIG
);
if
(
IS_DMA_ERRATA
(
DMA_ERRATA_i88
))
{
sys_cf
=
p
->
dma_read
(
OCP_SYSCONFIG
,
0
);
l
=
sys_cf
;
/* Middle mode reg set no Standby */
l
&=
~
((
1
<<
12
)
|
(
1
<<
13
));
p
->
dma_write
(
l
,
OCP_SYSCONFIG
,
0
);
}
for
(
i
=
0
;
i
<
dma_linked_lch
[
chain_id
].
no_of_lchs_linked
;
i
++
)
{
/* Stop the Channel transmission */
l
=
dma_read
(
CCR
(
channels
[
i
])
);
l
=
p
->
dma_read
(
CCR
,
channels
[
i
]
);
l
&=
~
(
1
<<
7
);
dma_write
(
l
,
CCR
(
channels
[
i
])
);
p
->
dma_write
(
l
,
CCR
,
channels
[
i
]
);
/* Disable the link in all the channels */
disable_lnk
(
channels
[
i
]);
...
...
@@ -1753,8 +1650,8 @@ int omap_stop_dma_chain_transfers(int chain_id)
/* Reset the Queue pointers */
OMAP_DMA_CHAIN_QINIT
(
chain_id
);
/* Errata - put in the old value */
dma_write
(
sys_cf
,
OCP_SYSCONFIG
);
if
(
IS_DMA_ERRATA
(
DMA_ERRATA_i88
))
p
->
dma_write
(
sys_cf
,
OCP_SYSCONFIG
,
0
);
return
0
;
}
...
...
@@ -1796,8 +1693,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
/* Get the current channel */
lch
=
channels
[
dma_linked_lch
[
chain_id
].
q_head
];
*
ei
=
dma_read
(
CCEN
(
lch
)
);
*
fi
=
dma_read
(
CCFN
(
lch
)
);
*
ei
=
p
->
dma_read
(
CCEN
,
lch
);
*
fi
=
p
->
dma_read
(
CCFN
,
lch
);
return
0
;
}
...
...
@@ -1834,7 +1731,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
/* Get the current channel */
lch
=
channels
[
dma_linked_lch
[
chain_id
].
q_head
];
return
dma_read
(
CDAC
(
lch
)
);
return
p
->
dma_read
(
CDAC
,
lch
);
}
EXPORT_SYMBOL
(
omap_get_dma_chain_dst_pos
);
...
...
@@ -1868,7 +1765,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
/* Get the current channel */
lch
=
channels
[
dma_linked_lch
[
chain_id
].
q_head
];
return
dma_read
(
CSAC
(
lch
)
);
return
p
->
dma_read
(
CSAC
,
lch
);
}
EXPORT_SYMBOL
(
omap_get_dma_chain_src_pos
);
#endif
/* ifndef CONFIG_ARCH_OMAP1 */
...
...
@@ -1885,7 +1782,7 @@ static int omap1_dma_handle_ch(int ch)
csr
=
dma_chan
[
ch
].
saved_csr
;
dma_chan
[
ch
].
saved_csr
=
0
;
}
else
csr
=
dma_read
(
CSR
(
ch
)
);
csr
=
p
->
dma_read
(
CSR
,
ch
);
if
(
enable_1510_mode
&&
ch
<=
2
&&
(
csr
>>
7
)
!=
0
)
{
dma_chan
[
ch
+
6
].
saved_csr
=
csr
>>
7
;
csr
&=
0x7f
;
...
...
@@ -1938,13 +1835,13 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
static
int
omap2_dma_handle_ch
(
int
ch
)
{
u32
status
=
dma_read
(
CSR
(
ch
)
);
u32
status
=
p
->
dma_read
(
CSR
,
ch
);
if
(
!
status
)
{
if
(
printk_ratelimit
())
printk
(
KERN_WARNING
"Spurious DMA IRQ for lch %d
\n
"
,
ch
);
dma_write
(
1
<<
ch
,
IRQSTATUS_L0
);
p
->
dma_write
(
1
<<
ch
,
IRQSTATUS_L0
,
ch
);
return
0
;
}
if
(
unlikely
(
dma_chan
[
ch
].
dev_id
==
-
1
))
{
...
...
@@ -1960,17 +1857,12 @@ static int omap2_dma_handle_ch(int ch)
if
(
unlikely
(
status
&
OMAP2_DMA_TRANS_ERR_IRQ
))
{
printk
(
KERN_INFO
"DMA transaction error with device %d
\n
"
,
dma_chan
[
ch
].
dev_id
);
if
(
cpu_class_is_omap2
())
{
/*
* Errata: sDMA Channel is not disabled
* after a transaction error. So we explicitely
* disable the channel
*/
if
(
IS_DMA_ERRATA
(
DMA_ERRATA_i378
))
{
u32
ccr
;
ccr
=
dma_read
(
CCR
(
ch
)
);
ccr
=
p
->
dma_read
(
CCR
,
ch
);
ccr
&=
~
OMAP_DMA_CCR_EN
;
dma_write
(
ccr
,
CCR
(
ch
)
);
p
->
dma_write
(
ccr
,
CCR
,
ch
);
dma_chan
[
ch
].
flags
&=
~
OMAP_DMA_ACTIVE
;
}
}
...
...
@@ -1981,16 +1873,16 @@ static int omap2_dma_handle_ch(int ch)
printk
(
KERN_INFO
"DMA misaligned error with device %d
\n
"
,
dma_chan
[
ch
].
dev_id
);
dma_write
(
OMAP2_DMA_CSR_CLEAR_MASK
,
CSR
(
ch
)
);
dma_write
(
1
<<
ch
,
IRQSTATUS_L0
);
p
->
dma_write
(
OMAP2_DMA_CSR_CLEAR_MASK
,
CSR
,
ch
);
p
->
dma_write
(
1
<<
ch
,
IRQSTATUS_L0
,
ch
);
/* read back the register to flush the write */
dma_read
(
IRQSTATUS_L0
);
p
->
dma_read
(
IRQSTATUS_L0
,
ch
);
/* If the ch is not chained then chain_id will be -1 */
if
(
dma_chan
[
ch
].
chain_id
!=
-
1
)
{
int
chain_id
=
dma_chan
[
ch
].
chain_id
;
dma_chan
[
ch
].
state
=
DMA_CH_NOTSTARTED
;
if
(
dma_read
(
CLNK_CTRL
(
ch
)
)
&
(
1
<<
15
))
if
(
p
->
dma_read
(
CLNK_CTRL
,
ch
)
&
(
1
<<
15
))
dma_chan
[
dma_chan
[
ch
].
next_linked_ch
].
state
=
DMA_CH_STARTED
;
if
(
dma_linked_lch
[
chain_id
].
chain_mode
==
...
...
@@ -2000,10 +1892,10 @@ static int omap2_dma_handle_ch(int ch)
if
(
!
OMAP_DMA_CHAIN_QEMPTY
(
chain_id
))
OMAP_DMA_CHAIN_INCQHEAD
(
chain_id
);
status
=
dma_read
(
CSR
(
ch
)
);
status
=
p
->
dma_read
(
CSR
,
ch
);
}
dma_write
(
status
,
CSR
(
ch
)
);
p
->
dma_write
(
status
,
CSR
,
ch
);
if
(
likely
(
dma_chan
[
ch
].
callback
!=
NULL
))
dma_chan
[
ch
].
callback
(
ch
,
status
,
dma_chan
[
ch
].
data
);
...
...
@@ -2017,13 +1909,13 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
u32
val
,
enable_reg
;
int
i
;
val
=
dma_read
(
IRQSTATUS_L
0
);
val
=
p
->
dma_read
(
IRQSTATUS_L0
,
0
);
if
(
val
==
0
)
{
if
(
printk_ratelimit
())
printk
(
KERN_WARNING
"Spurious DMA IRQ
\n
"
);
return
IRQ_HANDLED
;
}
enable_reg
=
dma_read
(
IRQENABLE_L
0
);
enable_reg
=
p
->
dma_read
(
IRQENABLE_L0
,
0
);
val
&=
enable_reg
;
/* Dispatch only relevant interrupts */
for
(
i
=
0
;
i
<
dma_lch_count
&&
val
!=
0
;
i
++
)
{
if
(
val
&
1
)
...
...
@@ -2049,119 +1941,66 @@ static struct irqaction omap24xx_dma_irq;
void
omap_dma_global_context_save
(
void
)
{
omap_dma_global_context
.
dma_irqenable_l0
=
dma_read
(
IRQENABLE_L
0
);
p
->
dma_read
(
IRQENABLE_L0
,
0
);
omap_dma_global_context
.
dma_ocp_sysconfig
=
dma_read
(
OCP_SYSCONFIG
);
omap_dma_global_context
.
dma_gcr
=
dma_read
(
GCR
);
p
->
dma_read
(
OCP_SYSCONFIG
,
0
);
omap_dma_global_context
.
dma_gcr
=
p
->
dma_read
(
GCR
,
0
);
}
void
omap_dma_global_context_restore
(
void
)
{
int
ch
;
dma_write
(
omap_dma_global_context
.
dma_gcr
,
GCR
);
dma_write
(
omap_dma_global_context
.
dma_ocp_sysconfig
,
OCP_SYSCONFIG
);
dma_write
(
omap_dma_global_context
.
dma_irqenable_l0
,
IRQENABLE_L0
);
p
->
dma_write
(
omap_dma_global_context
.
dma_gcr
,
GCR
,
0
);
p
->
dma_write
(
omap_dma_global_context
.
dma_ocp_sysconfig
,
OCP_SYSCONFIG
,
0
);
p
->
dma_write
(
omap_dma_global_context
.
dma_irqenable_l0
,
IRQENABLE_L0
,
0
);
/*
* A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
* after secure sram context save and restore. Hence we need to
* manually clear those IRQs to avoid spurious interrupts. This
* affects only secure devices.
*/
if
(
cpu_is_omap34xx
()
&&
(
omap_type
()
!=
OMAP2_DEVICE_TYPE_GP
))
dma_write
(
0x3
,
IRQSTATUS_L0
);
if
(
IS_DMA_ERRATA
(
DMA_ROMCODE_BUG
))
p
->
dma_write
(
0x3
,
IRQSTATUS_L0
,
0
);
for
(
ch
=
0
;
ch
<
dma_chan_count
;
ch
++
)
if
(
dma_chan
[
ch
].
dev_id
!=
-
1
)
omap_clear_dma
(
ch
);
}
/*----------------------------------------------------------------------------*/
static
int
__init
omap_init_dma
(
void
)
static
int
__devinit
omap_system_dma_probe
(
struct
platform_device
*
pdev
)
{
unsigned
long
base
;
int
ch
,
r
;
if
(
cpu_class_is_omap1
())
{
base
=
OMAP1_DMA_BASE
;
dma_lch_count
=
OMAP1_LOGICAL_DMA_CH_COUNT
;
}
else
if
(
cpu_is_omap24xx
())
{
base
=
OMAP24XX_DMA4_BASE
;
dma_lch_count
=
OMAP_DMA4_LOGICAL_DMA_CH_COUNT
;
}
else
if
(
cpu_is_omap34xx
())
{
base
=
OMAP34XX_DMA4_BASE
;
dma_lch_count
=
OMAP_DMA4_LOGICAL_DMA_CH_COUNT
;
}
else
if
(
cpu_is_omap44xx
())
{
base
=
OMAP44XX_DMA4_BASE
;
dma_lch_count
=
OMAP_DMA4_LOGICAL_DMA_CH_COUNT
;
}
else
{
pr_err
(
"DMA init failed for unsupported omap
\n
"
);
return
-
ENODEV
;
int
ch
,
ret
=
0
;
int
dma_irq
;
char
irq_name
[
4
];
int
irq_rel
;
p
=
pdev
->
dev
.
platform_data
;
if
(
!
p
)
{
dev_err
(
&
pdev
->
dev
,
"%s: System DMA initialized without"
"platform data
\n
"
,
__func__
);
return
-
EINVAL
;
}
omap_dma_base
=
ioremap
(
base
,
SZ_4K
)
;
BUG_ON
(
!
omap_dma_base
)
;
d
=
p
->
dma_attr
;
errata
=
p
->
errata
;
if
(
cpu_class_is_omap2
(
)
&&
omap_dma_reserve_channels
if
(
(
d
->
dev_caps
&
RESERVE_CHANNEL
)
&&
omap_dma_reserve_channels
&&
(
omap_dma_reserve_channels
<=
dma_lch_count
))
d
ma_lch_count
=
omap_dma_reserve_channels
;
d
->
lch_count
=
omap_dma_reserve_channels
;
dma_chan
=
kzalloc
(
sizeof
(
struct
omap_dma_lch
)
*
dma_lch_count
,
GFP_KERNEL
);
if
(
!
dma_chan
)
{
r
=
-
ENOMEM
;
goto
out_unmap
;
}
dma_lch_count
=
d
->
lch_count
;
dma_chan_count
=
dma_lch_count
;
dma_chan
=
d
->
chan
;
enable_1510_mode
=
d
->
dev_caps
&
ENABLE_1510_MODE
;
if
(
cpu_class_is_omap2
())
{
dma_linked_lch
=
kzalloc
(
sizeof
(
struct
dma_link_info
)
*
dma_lch_count
,
GFP_KERNEL
);
if
(
!
dma_linked_lch
)
{
r
=
-
ENOMEM
;
goto
out_free
;
r
et
=
-
ENOMEM
;
goto
exit_dma_lch_fail
;
}
}
if
(
cpu_is_omap15xx
())
{
printk
(
KERN_INFO
"DMA support for OMAP15xx initialized
\n
"
);
dma_chan_count
=
9
;
enable_1510_mode
=
1
;
}
else
if
(
cpu_is_omap16xx
()
||
cpu_is_omap7xx
())
{
printk
(
KERN_INFO
"OMAP DMA hardware version %d
\n
"
,
dma_read
(
HW_ID
));
printk
(
KERN_INFO
"DMA capabilities: %08x:%08x:%04x:%04x:%04x
\n
"
,
(
dma_read
(
CAPS_0_U
)
<<
16
)
|
dma_read
(
CAPS_0_L
),
(
dma_read
(
CAPS_1_U
)
<<
16
)
|
dma_read
(
CAPS_1_L
),
dma_read
(
CAPS_2
),
dma_read
(
CAPS_3
),
dma_read
(
CAPS_4
));
if
(
!
enable_1510_mode
)
{
u16
w
;
/* Disable OMAP 3.0/3.1 compatibility mode. */
w
=
dma_read
(
GSCR
);
w
|=
1
<<
3
;
dma_write
(
w
,
GSCR
);
dma_chan_count
=
16
;
}
else
dma_chan_count
=
9
;
}
else
if
(
cpu_class_is_omap2
())
{
u8
revision
=
dma_read
(
REVISION
)
&
0xff
;
printk
(
KERN_INFO
"OMAP DMA hardware revision %d.%d
\n
"
,
revision
>>
4
,
revision
&
0xf
);
dma_chan_count
=
dma_lch_count
;
}
else
{
dma_chan_count
=
0
;
return
0
;
}
spin_lock_init
(
&
dma_chan_lock
);
for
(
ch
=
0
;
ch
<
dma_chan_count
;
ch
++
)
{
omap_clear_dma
(
ch
);
if
(
cpu_class_is_omap2
())
...
...
@@ -2178,20 +2017,23 @@ static int __init omap_init_dma(void)
* request_irq() doesn't like dev_id (ie. ch) being
* zero, so we have to kludge around this.
*/
r
=
request_irq
(
omap1_dma_irq
[
ch
],
sprintf
(
&
irq_name
[
0
],
"%d"
,
ch
);
dma_irq
=
platform_get_irq_byname
(
pdev
,
irq_name
);
if
(
dma_irq
<
0
)
{
ret
=
dma_irq
;
goto
exit_dma_irq_fail
;
}
/* INT_DMA_LCD is handled in lcd_dma.c */
if
(
dma_irq
==
INT_DMA_LCD
)
continue
;
ret
=
request_irq
(
dma_irq
,
omap1_dma_irq_handler
,
0
,
"DMA"
,
(
void
*
)
(
ch
+
1
));
if
(
r
!=
0
)
{
int
i
;
printk
(
KERN_ERR
"unable to request IRQ %d "
"for DMA (error %d)
\n
"
,
omap1_dma_irq
[
ch
],
r
);
for
(
i
=
0
;
i
<
ch
;
i
++
)
free_irq
(
omap1_dma_irq
[
i
],
(
void
*
)
(
i
+
1
));
goto
out_free
;
}
if
(
ret
!=
0
)
goto
exit_dma_irq_fail
;
}
}
...
...
@@ -2200,46 +2042,91 @@ static int __init omap_init_dma(void)
DMA_DEFAULT_FIFO_DEPTH
,
0
);
if
(
cpu_class_is_omap2
())
{
int
irq
;
if
(
cpu_is_omap44xx
())
irq
=
OMAP44XX_IRQ_SDMA_0
;
else
irq
=
INT_24XX_SDMA_IRQ0
;
setup_irq
(
irq
,
&
omap24xx_dma_irq
);
}
if
(
cpu_is_omap34xx
()
||
cpu_is_omap44xx
())
{
/* Enable smartidle idlemodes and autoidle */
u32
v
=
dma_read
(
OCP_SYSCONFIG
);
v
&=
~
(
DMA_SYSCONFIG_MIDLEMODE_MASK
|
DMA_SYSCONFIG_SIDLEMODE_MASK
|
DMA_SYSCONFIG_AUTOIDLE
);
v
|=
(
DMA_SYSCONFIG_MIDLEMODE
(
DMA_IDLEMODE_SMARTIDLE
)
|
DMA_SYSCONFIG_SIDLEMODE
(
DMA_IDLEMODE_SMARTIDLE
)
|
DMA_SYSCONFIG_AUTOIDLE
);
dma_write
(
v
,
OCP_SYSCONFIG
);
/* reserve dma channels 0 and 1 in high security devices */
if
(
cpu_is_omap34xx
()
&&
(
omap_type
()
!=
OMAP2_DEVICE_TYPE_GP
))
{
printk
(
KERN_INFO
"Reserving DMA channels 0 and 1 for "
"HS ROM code
\n
"
);
dma_chan
[
0
].
dev_id
=
0
;
dma_chan
[
1
].
dev_id
=
1
;
strcpy
(
irq_name
,
"0"
);
dma_irq
=
platform_get_irq_byname
(
pdev
,
irq_name
);
if
(
dma_irq
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"failed: request IRQ %d"
,
dma_irq
);
goto
exit_dma_lch_fail
;
}
ret
=
setup_irq
(
dma_irq
,
&
omap24xx_dma_irq
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"set_up failed for IRQ %d"
"for DMA (error %d)
\n
"
,
dma_irq
,
ret
);
goto
exit_dma_lch_fail
;
}
}
/* reserve dma channels 0 and 1 in high security devices */
if
(
cpu_is_omap34xx
()
&&
(
omap_type
()
!=
OMAP2_DEVICE_TYPE_GP
))
{
printk
(
KERN_INFO
"Reserving DMA channels 0 and 1 for "
"HS ROM code
\n
"
);
dma_chan
[
0
].
dev_id
=
0
;
dma_chan
[
1
].
dev_id
=
1
;
}
p
->
show_dma_caps
();
return
0
;
out_free:
exit_dma_irq_fail:
dev_err
(
&
pdev
->
dev
,
"unable to request IRQ %d"
"for DMA (error %d)
\n
"
,
dma_irq
,
ret
);
for
(
irq_rel
=
0
;
irq_rel
<
ch
;
irq_rel
++
)
{
dma_irq
=
platform_get_irq
(
pdev
,
irq_rel
);
free_irq
(
dma_irq
,
(
void
*
)(
irq_rel
+
1
));
}
exit_dma_lch_fail:
kfree
(
p
);
kfree
(
d
);
kfree
(
dma_chan
);
return
ret
;
}
out_unmap:
iounmap
(
omap_dma_base
);
static
int
__devexit
omap_system_dma_remove
(
struct
platform_device
*
pdev
)
{
int
dma_irq
;
return
r
;
if
(
cpu_class_is_omap2
())
{
char
irq_name
[
4
];
strcpy
(
irq_name
,
"0"
);
dma_irq
=
platform_get_irq_byname
(
pdev
,
irq_name
);
remove_irq
(
dma_irq
,
&
omap24xx_dma_irq
);
}
else
{
int
irq_rel
=
0
;
for
(
;
irq_rel
<
dma_chan_count
;
irq_rel
++
)
{
dma_irq
=
platform_get_irq
(
pdev
,
irq_rel
);
free_irq
(
dma_irq
,
(
void
*
)(
irq_rel
+
1
));
}
}
kfree
(
p
);
kfree
(
d
);
kfree
(
dma_chan
);
return
0
;
}
static
struct
platform_driver
omap_system_dma_driver
=
{
.
probe
=
omap_system_dma_probe
,
.
remove
=
omap_system_dma_remove
,
.
driver
=
{
.
name
=
"omap_dma_system"
},
};
static
int
__init
omap_system_dma_init
(
void
)
{
return
platform_driver_register
(
&
omap_system_dma_driver
);
}
arch_initcall
(
omap_system_dma_init
);
static
void
__exit
omap_system_dma_exit
(
void
)
{
platform_driver_unregister
(
&
omap_system_dma_driver
);
}
arch_initcall
(
omap_init_dma
);
MODULE_DESCRIPTION
(
"OMAP SYSTEM DMA DRIVER"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS
(
"platform:"
DRIVER_NAME
);
MODULE_AUTHOR
(
"Texas Instruments Inc"
);
/*
* Reserve the omap SDMA channels using cmdline bootarg
...
...
arch/arm/plat-omap/include/plat/dma.h
浏览文件 @
6971071c
...
...
@@ -21,141 +21,15 @@
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
/* Move omap4 specific defines to dma-44xx.h */
#include "dma-44xx.h"
#include <linux/platform_device.h>
/* Hardware registers for omap1 */
#define OMAP1_DMA_BASE (0xfffed800)
#define OMAP1_DMA_GCR 0x400
#define OMAP1_DMA_GSCR 0x404
#define OMAP1_DMA_GRST 0x408
#define OMAP1_DMA_HW_ID 0x442
#define OMAP1_DMA_PCH2_ID 0x444
#define OMAP1_DMA_PCH0_ID 0x446
#define OMAP1_DMA_PCH1_ID 0x448
#define OMAP1_DMA_PCHG_ID 0x44a
#define OMAP1_DMA_PCHD_ID 0x44c
#define OMAP1_DMA_CAPS_0_U 0x44e
#define OMAP1_DMA_CAPS_0_L 0x450
#define OMAP1_DMA_CAPS_1_U 0x452
#define OMAP1_DMA_CAPS_1_L 0x454
#define OMAP1_DMA_CAPS_2 0x456
#define OMAP1_DMA_CAPS_3 0x458
#define OMAP1_DMA_CAPS_4 0x45a
#define OMAP1_DMA_PCH2_SR 0x460
#define OMAP1_DMA_PCH0_SR 0x480
#define OMAP1_DMA_PCH1_SR 0x482
#define OMAP1_DMA_PCHD_SR 0x4c0
/* Hardware registers for omap2 and omap3 */
#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000)
#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000)
#define OMAP44XX_DMA4_BASE (L4_44XX_BASE + 0x56000)
#define OMAP_DMA4_REVISION 0x00
#define OMAP_DMA4_GCR 0x78
#define OMAP_DMA4_IRQSTATUS_L0 0x08
#define OMAP_DMA4_IRQSTATUS_L1 0x0c
#define OMAP_DMA4_IRQSTATUS_L2 0x10
#define OMAP_DMA4_IRQSTATUS_L3 0x14
#define OMAP_DMA4_IRQENABLE_L0 0x18
#define OMAP_DMA4_IRQENABLE_L1 0x1c
#define OMAP_DMA4_IRQENABLE_L2 0x20
#define OMAP_DMA4_IRQENABLE_L3 0x24
#define OMAP_DMA4_SYSSTATUS 0x28
#define OMAP_DMA4_OCP_SYSCONFIG 0x2c
#define OMAP_DMA4_CAPS_0 0x64
#define OMAP_DMA4_CAPS_2 0x6c
#define OMAP_DMA4_CAPS_3 0x70
#define OMAP_DMA4_CAPS_4 0x74
#define OMAP1_LOGICAL_DMA_CH_COUNT 17
#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32
/* REVISIT: Is this 32 + 2? */
/* Common channel specific registers for omap1 */
#define OMAP1_DMA_CH_BASE(n) (0x40 * (n) + 0x00)
#define OMAP1_DMA_CSDP(n) (0x40 * (n) + 0x00)
#define OMAP1_DMA_CCR(n) (0x40 * (n) + 0x02)
#define OMAP1_DMA_CICR(n) (0x40 * (n) + 0x04)
#define OMAP1_DMA_CSR(n) (0x40 * (n) + 0x06)
#define OMAP1_DMA_CEN(n) (0x40 * (n) + 0x10)
#define OMAP1_DMA_CFN(n) (0x40 * (n) + 0x12)
#define OMAP1_DMA_CSFI(n) (0x40 * (n) + 0x14)
#define OMAP1_DMA_CSEI(n) (0x40 * (n) + 0x16)
#define OMAP1_DMA_CPC(n) (0x40 * (n) + 0x18)
/* 15xx only */
#define OMAP1_DMA_CSAC(n) (0x40 * (n) + 0x18)
#define OMAP1_DMA_CDAC(n) (0x40 * (n) + 0x1a)
#define OMAP1_DMA_CDEI(n) (0x40 * (n) + 0x1c)
#define OMAP1_DMA_CDFI(n) (0x40 * (n) + 0x1e)
#define OMAP1_DMA_CLNK_CTRL(n) (0x40 * (n) + 0x28)
/* Common channel specific registers for omap2 */
#define OMAP_DMA4_CH_BASE(n) (0x60 * (n) + 0x80)
#define OMAP_DMA4_CCR(n) (0x60 * (n) + 0x80)
#define OMAP_DMA4_CLNK_CTRL(n) (0x60 * (n) + 0x84)
#define OMAP_DMA4_CICR(n) (0x60 * (n) + 0x88)
#define OMAP_DMA4_CSR(n) (0x60 * (n) + 0x8c)
#define OMAP_DMA4_CSDP(n) (0x60 * (n) + 0x90)
#define OMAP_DMA4_CEN(n) (0x60 * (n) + 0x94)
#define OMAP_DMA4_CFN(n) (0x60 * (n) + 0x98)
#define OMAP_DMA4_CSEI(n) (0x60 * (n) + 0xa4)
#define OMAP_DMA4_CSFI(n) (0x60 * (n) + 0xa8)
#define OMAP_DMA4_CDEI(n) (0x60 * (n) + 0xac)
#define OMAP_DMA4_CDFI(n) (0x60 * (n) + 0xb0)
#define OMAP_DMA4_CSAC(n) (0x60 * (n) + 0xb4)
#define OMAP_DMA4_CDAC(n) (0x60 * (n) + 0xb8)
/* Channel specific registers only on omap1 */
#define OMAP1_DMA_CSSA_L(n) (0x40 * (n) + 0x08)
#define OMAP1_DMA_CSSA_U(n) (0x40 * (n) + 0x0a)
#define OMAP1_DMA_CDSA_L(n) (0x40 * (n) + 0x0c)
#define OMAP1_DMA_CDSA_U(n) (0x40 * (n) + 0x0e)
#define OMAP1_DMA_COLOR_L(n) (0x40 * (n) + 0x20)
#define OMAP1_DMA_COLOR_U(n) (0x40 * (n) + 0x22)
#define OMAP1_DMA_CCR2(n) (0x40 * (n) + 0x24)
#define OMAP1_DMA_LCH_CTRL(n) (0x40 * (n) + 0x2a)
/* not on 15xx */
#define OMAP1_DMA_CCEN(n) 0
#define OMAP1_DMA_CCFN(n) 0
/* Channel specific registers only on omap2 */
#define OMAP_DMA4_CSSA(n) (0x60 * (n) + 0x9c)
#define OMAP_DMA4_CDSA(n) (0x60 * (n) + 0xa0)
#define OMAP_DMA4_CCEN(n) (0x60 * (n) + 0xbc)
#define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0)
#define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4)
/* Additional registers available on OMAP4 */
#define OMAP_DMA4_CDP(n) (0x60 * (n) + 0xd0)
#define OMAP_DMA4_CNDP(n) (0x60 * (n) + 0xd4)
#define OMAP_DMA4_CCDN(n) (0x60 * (n) + 0xd8)
/* Dummy defines to keep multi-omap compiles happy */
#define OMAP1_DMA_REVISION 0
#define OMAP1_DMA_IRQSTATUS_L0 0
#define OMAP1_DMA_IRQENABLE_L0 0
#define OMAP1_DMA_OCP_SYSCONFIG 0
#define OMAP_DMA4_HW_ID 0
#define OMAP_DMA4_CAPS_0_L 0
#define OMAP_DMA4_CAPS_0_U 0
#define OMAP_DMA4_CAPS_1_L 0
#define OMAP_DMA4_CAPS_1_U 0
#define OMAP_DMA4_GSCR 0
#define OMAP_DMA4_CPC(n) 0
#define OMAP_DMA4_LCH_CTRL(n) 0
#define OMAP_DMA4_COLOR_L(n) 0
#define OMAP_DMA4_COLOR_U(n) 0
#define OMAP_DMA4_CCR2(n) 0
#define OMAP1_DMA_CSSA(n) 0
#define OMAP1_DMA_CDSA(n) 0
#define OMAP_DMA4_CSSA_L(n) 0
#define OMAP_DMA4_CSSA_U(n) 0
#define OMAP_DMA4_CDSA_L(n) 0
#define OMAP_DMA4_CDSA_U(n) 0
#define OMAP1_DMA_COLOR(n) 0
/*
* TODO: These dma channel defines should go away once all
* the omap drivers hwmod adapted.
*/
/*----------------------------------------------------------------------------*/
/* Move omap4 specific defines to dma-44xx.h */
#include "dma-44xx.h"
/* DMA channels for omap1 */
#define OMAP_DMA_NO_DEVICE 0
...
...
@@ -405,6 +279,63 @@
#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)
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
,
...
...
@@ -470,6 +401,41 @@ struct omap_dma_channel_params {
#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
);
};
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
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录