Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
59ca37f7
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
59ca37f7
编写于
10月 04, 2011
作者:
K
Kukjin Kim
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'next/topic-dma-samsung' into next-samsung-devel
上级
7d84b3e9
c9312209
变更
49
展开全部
隐藏空白更改
内联
并排
Showing
49 changed file
with
2066 addition
and
2302 deletion
+2066
-2302
arch/arm/include/asm/hardware/pl080.h
arch/arm/include/asm/hardware/pl080.h
+4
-0
arch/arm/mach-exynos4/Kconfig
arch/arm/mach-exynos4/Kconfig
+1
-1
arch/arm/mach-exynos4/clock.c
arch/arm/mach-exynos4/clock.c
+11
-4
arch/arm/mach-exynos4/dma.c
arch/arm/mach-exynos4/dma.c
+189
-111
arch/arm/mach-exynos4/include/mach/dma.h
arch/arm/mach-exynos4/include/mach/dma.h
+2
-2
arch/arm/mach-s3c2410/include/mach/dma.h
arch/arm/mach-s3c2410/include/mach/dma.h
+13
-7
arch/arm/mach-s3c2412/dma.c
arch/arm/mach-s3c2412/dma.c
+2
-2
arch/arm/mach-s3c64xx/dma.c
arch/arm/mach-s3c64xx/dma.c
+5
-5
arch/arm/mach-s3c64xx/include/mach/dma.h
arch/arm/mach-s3c64xx/include/mach/dma.h
+6
-2
arch/arm/mach-s5p64x0/Kconfig
arch/arm/mach-s5p64x0/Kconfig
+2
-2
arch/arm/mach-s5p64x0/clock-s5p6440.c
arch/arm/mach-s5p64x0/clock-s5p6440.c
+9
-1
arch/arm/mach-s5p64x0/clock-s5p6450.c
arch/arm/mach-s5p64x0/clock-s5p6450.c
+9
-1
arch/arm/mach-s5p64x0/dma.c
arch/arm/mach-s5p64x0/dma.c
+182
-91
arch/arm/mach-s5p64x0/include/mach/dma.h
arch/arm/mach-s5p64x0/include/mach/dma.h
+2
-2
arch/arm/mach-s5pc100/Kconfig
arch/arm/mach-s5pc100/Kconfig
+1
-1
arch/arm/mach-s5pc100/clock.c
arch/arm/mach-s5pc100/clock.c
+11
-4
arch/arm/mach-s5pc100/dma.c
arch/arm/mach-s5pc100/dma.c
+212
-112
arch/arm/mach-s5pc100/include/mach/dma.h
arch/arm/mach-s5pc100/include/mach/dma.h
+2
-2
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Kconfig
+1
-1
arch/arm/mach-s5pv210/clock.c
arch/arm/mach-s5pv210/clock.c
+10
-4
arch/arm/mach-s5pv210/dma.c
arch/arm/mach-s5pv210/dma.c
+205
-112
arch/arm/mach-s5pv210/include/mach/dma.h
arch/arm/mach-s5pv210/include/mach/dma.h
+2
-2
arch/arm/plat-s3c24xx/dma.c
arch/arm/plat-s3c24xx/dma.c
+5
-5
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Kconfig
+6
-3
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/Makefile
+2
-2
arch/arm/plat-samsung/dma-ops.c
arch/arm/plat-samsung/dma-ops.c
+131
-0
arch/arm/plat-samsung/include/plat/dma-ops.h
arch/arm/plat-samsung/include/plat/dma-ops.h
+63
-0
arch/arm/plat-samsung/include/plat/dma-pl330.h
arch/arm/plat-samsung/include/plat/dma-pl330.h
+15
-9
arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
+1
-1
arch/arm/plat-samsung/include/plat/dma.h
arch/arm/plat-samsung/include/plat/dma.h
+4
-6
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
+0
-32
arch/arm/plat-samsung/s3c-dma-ops.c
arch/arm/plat-samsung/s3c-dma-ops.c
+130
-0
arch/arm/plat-samsung/s3c-pl330.c
arch/arm/plat-samsung/s3c-pl330.c
+0
-1244
drivers/dma/Kconfig
drivers/dma/Kconfig
+2
-1
drivers/dma/amba-pl08x.c
drivers/dma/amba-pl08x.c
+197
-258
drivers/dma/at_hdmac.c
drivers/dma/at_hdmac.c
+125
-34
drivers/dma/at_hdmac_regs.h
drivers/dma/at_hdmac_regs.h
+24
-0
drivers/dma/dmatest.c
drivers/dma/dmatest.c
+21
-2
drivers/dma/imx-sdma.c
drivers/dma/imx-sdma.c
+38
-9
drivers/dma/mxs-dma.c
drivers/dma/mxs-dma.c
+24
-21
drivers/dma/pl330.c
drivers/dma/pl330.c
+207
-22
drivers/mmc/host/s3cmci.c
drivers/mmc/host/s3cmci.c
+3
-3
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-s3c64xx.c
+92
-83
include/linux/amba/pl08x.h
include/linux/amba/pl08x.h
+12
-2
include/linux/amba/pl330.h
include/linux/amba/pl330.h
+1
-5
include/linux/dmaengine.h
include/linux/dmaengine.h
+11
-2
sound/soc/samsung/ac97.c
sound/soc/samsung/ac97.c
+8
-2
sound/soc/samsung/dma.c
sound/soc/samsung/dma.c
+60
-86
sound/soc/samsung/dma.h
sound/soc/samsung/dma.h
+3
-1
未找到文件。
arch/arm/include/asm/hardware/pl080.h
浏览文件 @
59ca37f7
...
@@ -21,6 +21,9 @@
...
@@ -21,6 +21,9 @@
* OneNAND features.
* OneNAND features.
*/
*/
#ifndef ASM_PL080_H
#define ASM_PL080_H
#define PL080_INT_STATUS (0x00)
#define PL080_INT_STATUS (0x00)
#define PL080_TC_STATUS (0x04)
#define PL080_TC_STATUS (0x04)
#define PL080_TC_CLEAR (0x08)
#define PL080_TC_CLEAR (0x08)
...
@@ -138,3 +141,4 @@ struct pl080s_lli {
...
@@ -138,3 +141,4 @@ struct pl080s_lli {
u32
control1
;
u32
control1
;
};
};
#endif
/* ASM_PL080_H */
arch/arm/mach-exynos4/Kconfig
浏览文件 @
59ca37f7
...
@@ -11,7 +11,7 @@ if ARCH_EXYNOS4
...
@@ -11,7 +11,7 @@ if ARCH_EXYNOS4
config CPU_EXYNOS4210
config CPU_EXYNOS4210
bool
bool
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
help
help
Enable EXYNOS4210 CPU support
Enable EXYNOS4210 CPU support
...
...
arch/arm/mach-exynos4/clock.c
浏览文件 @
59ca37f7
...
@@ -43,6 +43,11 @@ static struct clk clk_sclk_usbphy1 = {
...
@@ -43,6 +43,11 @@ static struct clk clk_sclk_usbphy1 = {
.
name
=
"sclk_usbphy1"
,
.
name
=
"sclk_usbphy1"
,
};
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
static
int
exynos4_clksrc_mask_top_ctrl
(
struct
clk
*
clk
,
int
enable
)
static
int
exynos4_clksrc_mask_top_ctrl
(
struct
clk
*
clk
,
int
enable
)
{
{
return
s5p_gatectrl
(
S5P_CLKSRC_MASK_TOP
,
clk
,
enable
);
return
s5p_gatectrl
(
S5P_CLKSRC_MASK_TOP
,
clk
,
enable
);
...
@@ -454,13 +459,13 @@ static struct clk init_clocks_off[] = {
...
@@ -454,13 +459,13 @@ static struct clk init_clocks_off[] = {
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
ctrlbit
=
(
1
<<
10
),
.
ctrlbit
=
(
1
<<
10
),
},
{
},
{
.
name
=
"
p
dma"
,
.
name
=
"dma"
,
.
devname
=
"
s3c
-pl330.0"
,
.
devname
=
"
dma
-pl330.0"
,
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
ctrlbit
=
(
1
<<
0
),
.
ctrlbit
=
(
1
<<
0
),
},
{
},
{
.
name
=
"
p
dma"
,
.
name
=
"dma"
,
.
devname
=
"
s3c
-pl330.1"
,
.
devname
=
"
dma
-pl330.1"
,
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
ctrlbit
=
(
1
<<
1
),
.
ctrlbit
=
(
1
<<
1
),
},
{
},
{
...
@@ -1208,5 +1213,7 @@ void __init exynos4_register_clocks(void)
...
@@ -1208,5 +1213,7 @@ void __init exynos4_register_clocks(void)
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c24xx_register_clock
(
&
dummy_apb_pclk
);
s3c_pwmclk_init
();
s3c_pwmclk_init
();
}
}
arch/arm/mach-exynos4/dma.c
浏览文件 @
59ca37f7
...
@@ -21,151 +21,229 @@
...
@@ -21,151 +21,229 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl330.h>
#include <asm/irq.h>
#include <plat/devs.h>
#include <plat/devs.h>
#include <plat/irqs.h>
#include <plat/irqs.h>
#include <mach/map.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <mach/irqs.h>
#include <mach/dma.h>
#include <plat/s3c-pl330-pdata.h>
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
resource
exynos4_pdma0_resource
[]
=
{
struct
dma_pl330_peri
pdma0_peri
[
28
]
=
{
[
0
]
=
{
{
.
start
=
EXYNOS4_PA_PDMA0
,
.
peri_id
=
(
u8
)
DMACH_PCM0_RX
,
.
end
=
EXYNOS4_PA_PDMA0
+
SZ_4K
,
.
rqtype
=
DEVTOMEM
,
.
flags
=
IORESOURCE_MEM
,
},
{
},
.
peri_id
=
(
u8
)
DMACH_PCM0_TX
,
[
1
]
=
{
.
rqtype
=
MEMTODEV
,
.
start
=
IRQ_PDMA0
,
},
{
.
end
=
IRQ_PDMA0
,
.
peri_id
=
(
u8
)
DMACH_PCM2_RX
,
.
flags
=
IORESOURCE_IRQ
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ0
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ2
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0S_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART4_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART4_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS4_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS4_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_MICIN
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_PCMIN
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_PCMOUT
,
.
rqtype
=
MEMTODEV
,
},
},
};
};
static
struct
s3c_pl330_platdata
exynos4_pdma0_pdata
=
{
struct
dma_pl330_platdata
exynos4_pdma0_pdata
=
{
.
peri
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma0_peri
),
[
0
]
=
DMACH_PCM0_RX
,
.
peri
=
pdma0_peri
,
[
1
]
=
DMACH_PCM0_TX
,
[
2
]
=
DMACH_PCM2_RX
,
[
3
]
=
DMACH_PCM2_TX
,
[
4
]
=
DMACH_MSM_REQ0
,
[
5
]
=
DMACH_MSM_REQ2
,
[
6
]
=
DMACH_SPI0_RX
,
[
7
]
=
DMACH_SPI0_TX
,
[
8
]
=
DMACH_SPI2_RX
,
[
9
]
=
DMACH_SPI2_TX
,
[
10
]
=
DMACH_I2S0S_TX
,
[
11
]
=
DMACH_I2S0_RX
,
[
12
]
=
DMACH_I2S0_TX
,
[
13
]
=
DMACH_I2S2_RX
,
[
14
]
=
DMACH_I2S2_TX
,
[
15
]
=
DMACH_UART0_RX
,
[
16
]
=
DMACH_UART0_TX
,
[
17
]
=
DMACH_UART2_RX
,
[
18
]
=
DMACH_UART2_TX
,
[
19
]
=
DMACH_UART4_RX
,
[
20
]
=
DMACH_UART4_TX
,
[
21
]
=
DMACH_SLIMBUS0_RX
,
[
22
]
=
DMACH_SLIMBUS0_TX
,
[
23
]
=
DMACH_SLIMBUS2_RX
,
[
24
]
=
DMACH_SLIMBUS2_TX
,
[
25
]
=
DMACH_SLIMBUS4_RX
,
[
26
]
=
DMACH_SLIMBUS4_TX
,
[
27
]
=
DMACH_AC97_MICIN
,
[
28
]
=
DMACH_AC97_PCMIN
,
[
29
]
=
DMACH_AC97_PCMOUT
,
[
30
]
=
DMACH_MAX
,
[
31
]
=
DMACH_MAX
,
},
};
};
static
struct
platform_device
exynos4_device_pdma0
=
{
struct
amba_device
exynos4_device_pdma0
=
{
.
name
=
"s3c-pl330"
,
.
dev
=
{
.
id
=
0
,
.
init_name
=
"dma-pl330.0"
,
.
num_resources
=
ARRAY_SIZE
(
exynos4_pdma0_resource
),
.
resource
=
exynos4_pdma0_resource
,
.
dev
=
{
.
dma_mask
=
&
dma_dmamask
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
exynos4_pdma0_pdata
,
.
platform_data
=
&
exynos4_pdma0_pdata
,
},
},
.
res
=
{
.
start
=
EXYNOS4_PA_PDMA0
,
.
end
=
EXYNOS4_PA_PDMA0
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
.
irq
=
{
IRQ_PDMA0
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
};
static
struct
resource
exynos4_pdma1_resource
[]
=
{
struct
dma_pl330_peri
pdma1_peri
[
25
]
=
{
[
0
]
=
{
{
.
start
=
EXYNOS4_PA_PDMA1
,
.
peri_id
=
(
u8
)
DMACH_PCM0_RX
,
.
end
=
EXYNOS4_PA_PDMA1
+
SZ_4K
,
.
rqtype
=
DEVTOMEM
,
.
flags
=
IORESOURCE_MEM
,
},
{
},
.
peri_id
=
(
u8
)
DMACH_PCM0_TX
,
[
1
]
=
{
.
rqtype
=
MEMTODEV
,
.
start
=
IRQ_PDMA1
,
},
{
.
end
=
IRQ_PDMA1
,
.
peri_id
=
(
u8
)
DMACH_PCM1_RX
,
.
flags
=
IORESOURCE_IRQ
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ1
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ3
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0S_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART3_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART3_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS3_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS3_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS5_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SLIMBUS5_TX
,
.
rqtype
=
MEMTODEV
,
},
},
};
};
static
struct
s3c_pl330_platdata
exynos4_pdma1_pdata
=
{
struct
dma_pl330_platdata
exynos4_pdma1_pdata
=
{
.
peri
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma1_peri
),
[
0
]
=
DMACH_PCM0_RX
,
.
peri
=
pdma1_peri
,
[
1
]
=
DMACH_PCM0_TX
,
[
2
]
=
DMACH_PCM1_RX
,
[
3
]
=
DMACH_PCM1_TX
,
[
4
]
=
DMACH_MSM_REQ1
,
[
5
]
=
DMACH_MSM_REQ3
,
[
6
]
=
DMACH_SPI1_RX
,
[
7
]
=
DMACH_SPI1_TX
,
[
8
]
=
DMACH_I2S0S_TX
,
[
9
]
=
DMACH_I2S0_RX
,
[
10
]
=
DMACH_I2S0_TX
,
[
11
]
=
DMACH_I2S1_RX
,
[
12
]
=
DMACH_I2S1_TX
,
[
13
]
=
DMACH_UART0_RX
,
[
14
]
=
DMACH_UART0_TX
,
[
15
]
=
DMACH_UART1_RX
,
[
16
]
=
DMACH_UART1_TX
,
[
17
]
=
DMACH_UART3_RX
,
[
18
]
=
DMACH_UART3_TX
,
[
19
]
=
DMACH_SLIMBUS1_RX
,
[
20
]
=
DMACH_SLIMBUS1_TX
,
[
21
]
=
DMACH_SLIMBUS3_RX
,
[
22
]
=
DMACH_SLIMBUS3_TX
,
[
23
]
=
DMACH_SLIMBUS5_RX
,
[
24
]
=
DMACH_SLIMBUS5_TX
,
[
25
]
=
DMACH_SLIMBUS0AUX_RX
,
[
26
]
=
DMACH_SLIMBUS0AUX_TX
,
[
27
]
=
DMACH_SPDIF
,
[
28
]
=
DMACH_MAX
,
[
29
]
=
DMACH_MAX
,
[
30
]
=
DMACH_MAX
,
[
31
]
=
DMACH_MAX
,
},
};
};
static
struct
platform_device
exynos4_device_pdma1
=
{
struct
amba_device
exynos4_device_pdma1
=
{
.
name
=
"s3c-pl330"
,
.
dev
=
{
.
id
=
1
,
.
init_name
=
"dma-pl330.1"
,
.
num_resources
=
ARRAY_SIZE
(
exynos4_pdma1_resource
),
.
resource
=
exynos4_pdma1_resource
,
.
dev
=
{
.
dma_mask
=
&
dma_dmamask
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
exynos4_pdma1_pdata
,
.
platform_data
=
&
exynos4_pdma1_pdata
,
},
},
};
.
res
=
{
.
start
=
EXYNOS4_PA_PDMA1
,
static
struct
platform_device
*
exynos4_dmacs
[]
__initdata
=
{
.
end
=
EXYNOS4_PA_PDMA1
+
SZ_4K
,
&
exynos4_device_pdma0
,
.
flags
=
IORESOURCE_MEM
,
&
exynos4_device_pdma1
,
},
.
irq
=
{
IRQ_PDMA1
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
};
static
int
__init
exynos4_dma_init
(
void
)
static
int
__init
exynos4_dma_init
(
void
)
{
{
platform_add_devices
(
exynos4_dmacs
,
ARRAY_SIZE
(
exynos4_dmacs
));
amba_device_register
(
&
exynos4_device_pdma0
,
&
iomem_resource
);
amba_device_register
(
&
exynos4_device_pdma1
,
&
iomem_resource
);
return
0
;
return
0
;
}
}
...
...
arch/arm/mach-exynos4/include/mach/dma.h
浏览文件 @
59ca37f7
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
#ifndef __MACH_DMA_H
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common
S3C
DMA API driver for PL330 */
/* This platform uses the common DMA API driver for PL330 */
#include <plat/
s3c-
dma-pl330.h>
#include <plat/dma-pl330.h>
#endif
/* __MACH_DMA_H */
#endif
/* __MACH_DMA_H */
arch/arm/mach-s3c2410/include/mach/dma.h
浏览文件 @
59ca37f7
...
@@ -13,7 +13,6 @@
...
@@ -13,7 +13,6 @@
#ifndef __ASM_ARCH_DMA_H
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H __FILE__
#define __ASM_ARCH_DMA_H __FILE__
#include <plat/dma.h>
#include <linux/sysdev.h>
#include <linux/sysdev.h>
#define MAX_DMA_TRANSFER_SIZE 0x100000
/* Data Unit is half word */
#define MAX_DMA_TRANSFER_SIZE 0x100000
/* Data Unit is half word */
...
@@ -51,6 +50,18 @@ enum dma_ch {
...
@@ -51,6 +50,18 @@ enum dma_ch {
DMACH_MAX
,
/* the end entry */
DMACH_MAX
,
/* the end entry */
};
};
static
inline
bool
samsung_dma_has_circular
(
void
)
{
return
false
;
}
static
inline
bool
samsung_dma_is_dmadev
(
void
)
{
return
false
;
}
#include <plat/dma.h>
#define DMACH_LOW_LEVEL (1<<28)
/* use this to specifiy hardware ch no */
#define DMACH_LOW_LEVEL (1<<28)
/* use this to specifiy hardware ch no */
/* we have 4 dma channels */
/* we have 4 dma channels */
...
@@ -163,7 +174,7 @@ struct s3c2410_dma_chan {
...
@@ -163,7 +174,7 @@ struct s3c2410_dma_chan {
struct
s3c2410_dma_client
*
client
;
struct
s3c2410_dma_client
*
client
;
/* channel configuration */
/* channel configuration */
enum
s3c2410_dmasrc
source
;
enum
dma_data_direction
source
;
enum
dma_ch
req_ch
;
enum
dma_ch
req_ch
;
unsigned
long
dev_addr
;
unsigned
long
dev_addr
;
unsigned
long
load_timeout
;
unsigned
long
load_timeout
;
...
@@ -196,9 +207,4 @@ struct s3c2410_dma_chan {
...
@@ -196,9 +207,4 @@ struct s3c2410_dma_chan {
typedef
unsigned
long
dma_device_t
;
typedef
unsigned
long
dma_device_t
;
static
inline
bool
s3c_dma_has_circular
(
void
)
{
return
false
;
}
#endif
/* __ASM_ARCH_DMA_H */
#endif
/* __ASM_ARCH_DMA_H */
arch/arm/mach-s3c2412/dma.c
浏览文件 @
59ca37f7
...
@@ -148,11 +148,11 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
...
@@ -148,11 +148,11 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
static
void
s3c2412_dma_direction
(
struct
s3c2410_dma_chan
*
chan
,
static
void
s3c2412_dma_direction
(
struct
s3c2410_dma_chan
*
chan
,
struct
s3c24xx_dma_map
*
map
,
struct
s3c24xx_dma_map
*
map
,
enum
s3c2410_dmasrc
dir
)
enum
dma_data_direction
dir
)
{
{
unsigned
long
chsel
;
unsigned
long
chsel
;
if
(
dir
==
S3C2410_DMASRC_HW
)
if
(
dir
==
DMA_FROM_DEVICE
)
chsel
=
map
->
channels_rx
[
0
];
chsel
=
map
->
channels_rx
[
0
];
else
else
chsel
=
map
->
channels
[
0
];
chsel
=
map
->
channels
[
0
];
...
...
arch/arm/mach-s3c64xx/dma.c
浏览文件 @
59ca37f7
...
@@ -147,14 +147,14 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
...
@@ -147,14 +147,14 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
u32
control0
,
control1
;
u32
control0
,
control1
;
switch
(
chan
->
source
)
{
switch
(
chan
->
source
)
{
case
S3C2410_DMASRC_HW
:
case
DMA_FROM_DEVICE
:
src
=
chan
->
dev_addr
;
src
=
chan
->
dev_addr
;
dst
=
data
;
dst
=
data
;
control0
=
PL080_CONTROL_SRC_AHB2
;
control0
=
PL080_CONTROL_SRC_AHB2
;
control0
|=
PL080_CONTROL_DST_INCR
;
control0
|=
PL080_CONTROL_DST_INCR
;
break
;
break
;
case
S3C2410_DMASRC_MEM
:
case
DMA_TO_DEVICE
:
src
=
data
;
src
=
data
;
dst
=
chan
->
dev_addr
;
dst
=
chan
->
dev_addr
;
control0
=
PL080_CONTROL_DST_AHB2
;
control0
=
PL080_CONTROL_DST_AHB2
;
...
@@ -416,7 +416,7 @@ EXPORT_SYMBOL(s3c2410_dma_enqueue);
...
@@ -416,7 +416,7 @@ EXPORT_SYMBOL(s3c2410_dma_enqueue);
int
s3c2410_dma_devconfig
(
enum
dma_ch
channel
,
int
s3c2410_dma_devconfig
(
enum
dma_ch
channel
,
enum
s3c2410_dmasrc
source
,
enum
dma_data_direction
source
,
unsigned
long
devaddr
)
unsigned
long
devaddr
)
{
{
struct
s3c2410_dma_chan
*
chan
=
s3c_dma_lookup_channel
(
channel
);
struct
s3c2410_dma_chan
*
chan
=
s3c_dma_lookup_channel
(
channel
);
...
@@ -437,11 +437,11 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
...
@@ -437,11 +437,11 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
pr_debug
(
"%s: peripheral %d
\n
"
,
__func__
,
peripheral
);
pr_debug
(
"%s: peripheral %d
\n
"
,
__func__
,
peripheral
);
switch
(
source
)
{
switch
(
source
)
{
case
S3C2410_DMASRC_HW
:
case
DMA_FROM_DEVICE
:
config
=
2
<<
PL080_CONFIG_FLOW_CONTROL_SHIFT
;
config
=
2
<<
PL080_CONFIG_FLOW_CONTROL_SHIFT
;
config
|=
peripheral
<<
PL080_CONFIG_SRC_SEL_SHIFT
;
config
|=
peripheral
<<
PL080_CONFIG_SRC_SEL_SHIFT
;
break
;
break
;
case
S3C2410_DMASRC_MEM
:
case
DMA_TO_DEVICE
:
config
=
1
<<
PL080_CONFIG_FLOW_CONTROL_SHIFT
;
config
=
1
<<
PL080_CONFIG_FLOW_CONTROL_SHIFT
;
config
|=
peripheral
<<
PL080_CONFIG_DST_SEL_SHIFT
;
config
|=
peripheral
<<
PL080_CONFIG_DST_SEL_SHIFT
;
break
;
break
;
...
...
arch/arm/mach-s3c64xx/include/mach/dma.h
浏览文件 @
59ca37f7
...
@@ -58,11 +58,15 @@ enum dma_ch {
...
@@ -58,11 +58,15 @@ enum dma_ch {
DMACH_MAX
/* the end */
DMACH_MAX
/* the end */
};
};
static
__inline__
bool
s3c
_dma_has_circular
(
void
)
static
inline
bool
samsung
_dma_has_circular
(
void
)
{
{
return
true
;
return
true
;
}
}
static
inline
bool
samsung_dma_is_dmadev
(
void
)
{
return
false
;
}
#define S3C2410_DMAF_CIRCULAR (1 << 0)
#define S3C2410_DMAF_CIRCULAR (1 << 0)
#include <plat/dma.h>
#include <plat/dma.h>
...
@@ -95,7 +99,7 @@ struct s3c2410_dma_chan {
...
@@ -95,7 +99,7 @@ struct s3c2410_dma_chan {
unsigned
char
peripheral
;
unsigned
char
peripheral
;
unsigned
int
flags
;
unsigned
int
flags
;
enum
s3c2410_dmasrc
source
;
enum
dma_data_direction
source
;
dma_addr_t
dev_addr
;
dma_addr_t
dev_addr
;
...
...
arch/arm/mach-s5p64x0/Kconfig
浏览文件 @
59ca37f7
...
@@ -9,14 +9,14 @@ if ARCH_S5P64X0
...
@@ -9,14 +9,14 @@ if ARCH_S5P64X0
config CPU_S5P6440
config CPU_S5P6440
bool
bool
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
select S5P_HRT
select S5P_HRT
help
help
Enable S5P6440 CPU support
Enable S5P6440 CPU support
config CPU_S5P6450
config CPU_S5P6450
bool
bool
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
select S5P_HRT
select S5P_HRT
help
help
Enable S5P6450 CPU support
Enable S5P6450 CPU support
...
...
arch/arm/mach-s5p64x0/clock-s5p6440.c
浏览文件 @
59ca37f7
...
@@ -146,7 +146,8 @@ static struct clk init_clocks_off[] = {
...
@@ -146,7 +146,8 @@ static struct clk init_clocks_off[] = {
.
enable
=
s5p64x0_hclk0_ctrl
,
.
enable
=
s5p64x0_hclk0_ctrl
,
.
ctrlbit
=
(
1
<<
8
),
.
ctrlbit
=
(
1
<<
8
),
},
{
},
{
.
name
=
"pdma"
,
.
name
=
"dma"
,
.
devname
=
"dma-pl330"
,
.
parent
=
&
clk_hclk_low
.
clk
,
.
parent
=
&
clk_hclk_low
.
clk
,
.
enable
=
s5p64x0_hclk0_ctrl
,
.
enable
=
s5p64x0_hclk0_ctrl
,
.
ctrlbit
=
(
1
<<
12
),
.
ctrlbit
=
(
1
<<
12
),
...
@@ -499,6 +500,11 @@ static struct clksrc_clk *sysclks[] = {
...
@@ -499,6 +500,11 @@ static struct clksrc_clk *sysclks[] = {
&
clk_pclk_low
,
&
clk_pclk_low
,
};
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
void
__init_or_cpufreq
s5p6440_setup_clocks
(
void
)
void
__init_or_cpufreq
s5p6440_setup_clocks
(
void
)
{
{
struct
clk
*
xtal_clk
;
struct
clk
*
xtal_clk
;
...
@@ -581,5 +587,7 @@ void __init s5p6440_register_clocks(void)
...
@@ -581,5 +587,7 @@ void __init s5p6440_register_clocks(void)
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c24xx_register_clock
(
&
dummy_apb_pclk
);
s3c_pwmclk_init
();
s3c_pwmclk_init
();
}
}
arch/arm/mach-s5p64x0/clock-s5p6450.c
浏览文件 @
59ca37f7
...
@@ -179,7 +179,8 @@ static struct clk init_clocks_off[] = {
...
@@ -179,7 +179,8 @@ static struct clk init_clocks_off[] = {
.
enable
=
s5p64x0_hclk0_ctrl
,
.
enable
=
s5p64x0_hclk0_ctrl
,
.
ctrlbit
=
(
1
<<
3
),
.
ctrlbit
=
(
1
<<
3
),
},
{
},
{
.
name
=
"pdma"
,
.
name
=
"dma"
,
.
devname
=
"dma-pl330"
,
.
parent
=
&
clk_hclk_low
.
clk
,
.
parent
=
&
clk_hclk_low
.
clk
,
.
enable
=
s5p64x0_hclk0_ctrl
,
.
enable
=
s5p64x0_hclk0_ctrl
,
.
ctrlbit
=
(
1
<<
12
),
.
ctrlbit
=
(
1
<<
12
),
...
@@ -553,6 +554,11 @@ static struct clksrc_clk *sysclks[] = {
...
@@ -553,6 +554,11 @@ static struct clksrc_clk *sysclks[] = {
&
clk_sclk_audio0
,
&
clk_sclk_audio0
,
};
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
void
__init_or_cpufreq
s5p6450_setup_clocks
(
void
)
void
__init_or_cpufreq
s5p6450_setup_clocks
(
void
)
{
{
struct
clk
*
xtal_clk
;
struct
clk
*
xtal_clk
;
...
@@ -632,5 +638,7 @@ void __init s5p6450_register_clocks(void)
...
@@ -632,5 +638,7 @@ void __init s5p6450_register_clocks(void)
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c24xx_register_clock
(
&
dummy_apb_pclk
);
s3c_pwmclk_init
();
s3c_pwmclk_init
();
}
}
arch/arm/mach-s5p64x0/dma.c
浏览文件 @
59ca37f7
...
@@ -21,128 +21,219 @@
...
@@ -21,128 +21,219 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl330.h>
#include <asm/irq.h>
#include <mach/map.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <mach/irqs.h>
#include <mach/regs-clock.h>
#include <mach/regs-clock.h>
#include <mach/dma.h>
#include <plat/devs.h>
#include <plat/devs.h>
#include <plat/
s3c-pl330-pdata
.h>
#include <plat/
irqs
.h>
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
resource
s5p64x0_pdma_resource
[]
=
{
struct
dma_pl330_peri
s5p6440_pdma_peri
[
22
]
=
{
[
0
]
=
{
{
.
start
=
S5P64X0_PA_PDMA
,
.
peri_id
=
(
u8
)
DMACH_UART0_RX
,
.
end
=
S5P64X0_PA_PDMA
+
SZ_4K
,
.
rqtype
=
DEVTOMEM
,
.
flags
=
IORESOURCE_MEM
,
},
{
},
.
peri_id
=
(
u8
)
DMACH_UART0_TX
,
[
1
]
=
{
.
rqtype
=
MEMTODEV
,
.
start
=
IRQ_DMA0
,
},
{
.
end
=
IRQ_DMA0
,
.
peri_id
=
(
u8
)
DMACH_UART1_RX
,
.
flags
=
IORESOURCE_IRQ
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART3_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART3_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
DMACH_MAX
,
},
{
.
peri_id
=
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_RX
,
.
rqtype
=
DEVTOMEM
,
},
},
};
};
static
struct
s3c_pl330_platdata
s5p6440_pdma_pdata
=
{
struct
dma_pl330_platdata
s5p6440_pdma_pdata
=
{
.
peri
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
s5p6440_pdma_peri
),
[
0
]
=
DMACH_UART0_RX
,
.
peri
=
s5p6440_pdma_peri
,
[
1
]
=
DMACH_UART0_TX
,
[
2
]
=
DMACH_UART1_RX
,
[
3
]
=
DMACH_UART1_TX
,
[
4
]
=
DMACH_UART2_RX
,
[
5
]
=
DMACH_UART2_TX
,
[
6
]
=
DMACH_UART3_RX
,
[
7
]
=
DMACH_UART3_TX
,
[
8
]
=
DMACH_MAX
,
[
9
]
=
DMACH_MAX
,
[
10
]
=
DMACH_PCM0_TX
,
[
11
]
=
DMACH_PCM0_RX
,
[
12
]
=
DMACH_I2S0_TX
,
[
13
]
=
DMACH_I2S0_RX
,
[
14
]
=
DMACH_SPI0_TX
,
[
15
]
=
DMACH_SPI0_RX
,
[
16
]
=
DMACH_MAX
,
[
17
]
=
DMACH_MAX
,
[
18
]
=
DMACH_MAX
,
[
19
]
=
DMACH_MAX
,
[
20
]
=
DMACH_SPI1_TX
,
[
21
]
=
DMACH_SPI1_RX
,
[
22
]
=
DMACH_MAX
,
[
23
]
=
DMACH_MAX
,
[
24
]
=
DMACH_MAX
,
[
25
]
=
DMACH_MAX
,
[
26
]
=
DMACH_MAX
,
[
27
]
=
DMACH_MAX
,
[
28
]
=
DMACH_MAX
,
[
29
]
=
DMACH_PWM
,
[
30
]
=
DMACH_MAX
,
[
31
]
=
DMACH_MAX
,
},
};
};
static
struct
s3c_pl330_platdata
s5p6450_pdma_pdata
=
{
struct
dma_pl330_peri
s5p6450_pdma_peri
[
32
]
=
{
.
peri
=
{
{
[
0
]
=
DMACH_UART0_RX
,
.
peri_id
=
(
u8
)
DMACH_UART0_RX
,
[
1
]
=
DMACH_UART0_TX
,
.
rqtype
=
DEVTOMEM
,
[
2
]
=
DMACH_UART1_RX
,
},
{
[
3
]
=
DMACH_UART1_TX
,
.
peri_id
=
(
u8
)
DMACH_UART0_TX
,
[
4
]
=
DMACH_UART2_RX
,
.
rqtype
=
MEMTODEV
,
[
5
]
=
DMACH_UART2_TX
,
},
{
[
6
]
=
DMACH_UART3_RX
,
.
peri_id
=
(
u8
)
DMACH_UART1_RX
,
[
7
]
=
DMACH_UART3_TX
,
.
rqtype
=
DEVTOMEM
,
[
8
]
=
DMACH_UART4_RX
,
},
{
[
9
]
=
DMACH_UART4_TX
,
.
peri_id
=
(
u8
)
DMACH_UART1_TX
,
[
10
]
=
DMACH_PCM0_TX
,
.
rqtype
=
MEMTODEV
,
[
11
]
=
DMACH_PCM0_RX
,
},
{
[
12
]
=
DMACH_I2S0_TX
,
.
peri_id
=
(
u8
)
DMACH_UART2_RX
,
[
13
]
=
DMACH_I2S0_RX
,
.
rqtype
=
DEVTOMEM
,
[
14
]
=
DMACH_SPI0_TX
,
},
{
[
15
]
=
DMACH_SPI0_RX
,
.
peri_id
=
(
u8
)
DMACH_UART2_TX
,
[
16
]
=
DMACH_PCM1_TX
,
.
rqtype
=
MEMTODEV
,
[
17
]
=
DMACH_PCM1_RX
,
},
{
[
18
]
=
DMACH_PCM2_TX
,
.
peri_id
=
(
u8
)
DMACH_UART3_RX
,
[
19
]
=
DMACH_PCM2_RX
,
.
rqtype
=
DEVTOMEM
,
[
20
]
=
DMACH_SPI1_TX
,
},
{
[
21
]
=
DMACH_SPI1_RX
,
.
peri_id
=
(
u8
)
DMACH_UART3_TX
,
[
22
]
=
DMACH_USI_TX
,
.
rqtype
=
MEMTODEV
,
[
23
]
=
DMACH_USI_RX
,
},
{
[
24
]
=
DMACH_MAX
,
.
peri_id
=
(
u8
)
DMACH_UART4_RX
,
[
25
]
=
DMACH_I2S1_TX
,
.
rqtype
=
DEVTOMEM
,
[
26
]
=
DMACH_I2S1_RX
,
},
{
[
27
]
=
DMACH_I2S2_TX
,
.
peri_id
=
(
u8
)
DMACH_UART4_TX
,
[
28
]
=
DMACH_I2S2_RX
,
.
rqtype
=
MEMTODEV
,
[
29
]
=
DMACH_PWM
,
},
{
[
30
]
=
DMACH_UART5_RX
,
.
peri_id
=
(
u8
)
DMACH_PCM0_TX
,
[
31
]
=
DMACH_UART5_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_USI_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_USI_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PWM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART5_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART5_TX
,
.
rqtype
=
MEMTODEV
,
},
},
};
};
static
struct
platform_device
s5p64x0_device_pdma
=
{
struct
dma_pl330_platdata
s5p6450_pdma_pdata
=
{
.
name
=
"s3c-pl330"
,
.
nr_valid_peri
=
ARRAY_SIZE
(
s5p6450_pdma_peri
),
.
id
=
-
1
,
.
peri
=
s5p6450_pdma_peri
,
.
num_resources
=
ARRAY_SIZE
(
s5p64x0_pdma_resource
),
};
.
resource
=
s5p64x0_pdma_resource
,
.
dev
=
{
struct
amba_device
s5p64x0_device_pdma
=
{
.
dev
=
{
.
init_name
=
"dma-pl330"
,
.
dma_mask
=
&
dma_dmamask
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
},
},
.
res
=
{
.
start
=
S5P64X0_PA_PDMA
,
.
end
=
S5P64X0_PA_PDMA
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
.
irq
=
{
IRQ_DMA0
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
};
static
int
__init
s5p64x0_dma_init
(
void
)
static
int
__init
s5p64x0_dma_init
(
void
)
{
{
unsigned
int
id
;
unsigned
int
id
=
__raw_readl
(
S5P64X0_SYS_ID
)
&
0xFF000
;
id
=
__raw_readl
(
S5P64X0_SYS_ID
)
&
0xFF000
;
if
(
id
==
0x50000
)
if
(
id
==
0x50000
)
s5p64x0_device_pdma
.
dev
.
platform_data
=
&
s5p6450_pdma_pdata
;
s5p64x0_device_pdma
.
dev
.
platform_data
=
&
s5p6450_pdma_pdata
;
else
else
s5p64x0_device_pdma
.
dev
.
platform_data
=
&
s5p6440_pdma_pdata
;
s5p64x0_device_pdma
.
dev
.
platform_data
=
&
s5p6440_pdma_pdata
;
platform_device_register
(
&
s5p64x0_device_pdma
);
amba_device_register
(
&
s5p64x0_device_pdma
,
&
iomem_resource
);
return
0
;
return
0
;
}
}
...
...
arch/arm/mach-s5p64x0/include/mach/dma.h
浏览文件 @
59ca37f7
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
#ifndef __MACH_DMA_H
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common
S3C
DMA API driver for PL330 */
/* This platform uses the common
common
DMA API driver for PL330 */
#include <plat/
s3c-
dma-pl330.h>
#include <plat/dma-pl330.h>
#endif
/* __MACH_DMA_H */
#endif
/* __MACH_DMA_H */
arch/arm/mach-s5pc100/Kconfig
浏览文件 @
59ca37f7
...
@@ -10,7 +10,7 @@ if ARCH_S5PC100
...
@@ -10,7 +10,7 @@ if ARCH_S5PC100
config CPU_S5PC100
config CPU_S5PC100
bool
bool
select S5P_EXT_INT
select S5P_EXT_INT
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
help
help
Enable S5PC100 CPU support
Enable S5PC100 CPU support
...
...
arch/arm/mach-s5pc100/clock.c
浏览文件 @
59ca37f7
...
@@ -33,6 +33,11 @@ static struct clk s5p_clk_otgphy = {
...
@@ -33,6 +33,11 @@ static struct clk s5p_clk_otgphy = {
.
name
=
"otg_phy"
,
.
name
=
"otg_phy"
,
};
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
static
struct
clk
*
clk_src_mout_href_list
[]
=
{
static
struct
clk
*
clk_src_mout_href_list
[]
=
{
[
0
]
=
&
s5p_clk_27m
,
[
0
]
=
&
s5p_clk_27m
,
[
1
]
=
&
clk_fin_hpll
,
[
1
]
=
&
clk_fin_hpll
,
...
@@ -454,14 +459,14 @@ static struct clk init_clocks_off[] = {
...
@@ -454,14 +459,14 @@ static struct clk init_clocks_off[] = {
.
enable
=
s5pc100_d1_0_ctrl
,
.
enable
=
s5pc100_d1_0_ctrl
,
.
ctrlbit
=
(
1
<<
2
),
.
ctrlbit
=
(
1
<<
2
),
},
{
},
{
.
name
=
"
p
dma"
,
.
name
=
"dma"
,
.
devname
=
"
s3c
-pl330.1"
,
.
devname
=
"
dma
-pl330.1"
,
.
parent
=
&
clk_div_d1_bus
.
clk
,
.
parent
=
&
clk_div_d1_bus
.
clk
,
.
enable
=
s5pc100_d1_0_ctrl
,
.
enable
=
s5pc100_d1_0_ctrl
,
.
ctrlbit
=
(
1
<<
1
),
.
ctrlbit
=
(
1
<<
1
),
},
{
},
{
.
name
=
"
p
dma"
,
.
name
=
"dma"
,
.
devname
=
"
s3c
-pl330.0"
,
.
devname
=
"
dma
-pl330.0"
,
.
parent
=
&
clk_div_d1_bus
.
clk
,
.
parent
=
&
clk_div_d1_bus
.
clk
,
.
enable
=
s5pc100_d1_0_ctrl
,
.
enable
=
s5pc100_d1_0_ctrl
,
.
ctrlbit
=
(
1
<<
0
),
.
ctrlbit
=
(
1
<<
0
),
...
@@ -1276,5 +1281,7 @@ void __init s5pc100_register_clocks(void)
...
@@ -1276,5 +1281,7 @@ void __init s5pc100_register_clocks(void)
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c24xx_register_clock
(
&
dummy_apb_pclk
);
s3c_pwmclk_init
();
s3c_pwmclk_init
();
}
}
arch/arm/mach-s5pc100/dma.c
浏览文件 @
59ca37f7
/*
/* linux/arch/arm/mach-s5pc100/dma.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Copyright (C) 2010 Samsung Electronics Co. Ltd.
* Copyright (C) 2010 Samsung Electronics Co. Ltd.
* Jaswinder Singh <jassi.brar@samsung.com>
* Jaswinder Singh <jassi.brar@samsung.com>
*
*
...
@@ -17,150 +21,246 @@
...
@@ -17,150 +21,246 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl330.h>
#include <asm/irq.h>
#include <plat/devs.h>
#include <plat/devs.h>
#include <plat/irqs.h>
#include <mach/map.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <mach/irqs.h>
#include <mach/dma.h>
#include <plat/s3c-pl330-pdata.h>
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
resource
s5pc100_pdma0_resource
[]
=
{
struct
dma_pl330_peri
pdma0_peri
[
30
]
=
{
[
0
]
=
{
{
.
start
=
S5PC100_PA_PDMA0
,
.
peri_id
=
(
u8
)
DMACH_UART0_RX
,
.
end
=
S5PC100_PA_PDMA0
+
SZ_4K
,
.
rqtype
=
DEVTOMEM
,
.
flags
=
IORESOURCE_MEM
,
},
{
},
.
peri_id
=
(
u8
)
DMACH_UART0_TX
,
[
1
]
=
{
.
rqtype
=
MEMTODEV
,
.
start
=
IRQ_PDMA0
,
},
{
.
end
=
IRQ_PDMA0
,
.
peri_id
=
(
u8
)
DMACH_UART1_RX
,
.
flags
=
IORESOURCE_IRQ
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART3_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART3_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
DMACH_IRDA
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0S_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_MICIN
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_PCMIN
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_PCMOUT
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_EXTERNAL
,
},
{
.
peri_id
=
(
u8
)
DMACH_PWM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPDIF
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_HSI_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_HSI_TX
,
.
rqtype
=
MEMTODEV
,
},
},
};
};
static
struct
s3c_pl330_platdata
s5pc100_pdma0_pdata
=
{
struct
dma_pl330_platdata
s5pc100_pdma0_pdata
=
{
.
peri
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma0_peri
),
[
0
]
=
DMACH_UART0_RX
,
.
peri
=
pdma0_peri
,
[
1
]
=
DMACH_UART0_TX
,
[
2
]
=
DMACH_UART1_RX
,
[
3
]
=
DMACH_UART1_TX
,
[
4
]
=
DMACH_UART2_RX
,
[
5
]
=
DMACH_UART2_TX
,
[
6
]
=
DMACH_UART3_RX
,
[
7
]
=
DMACH_UART3_TX
,
[
8
]
=
DMACH_IRDA
,
[
9
]
=
DMACH_I2S0_RX
,
[
10
]
=
DMACH_I2S0_TX
,
[
11
]
=
DMACH_I2S0S_TX
,
[
12
]
=
DMACH_I2S1_RX
,
[
13
]
=
DMACH_I2S1_TX
,
[
14
]
=
DMACH_I2S2_RX
,
[
15
]
=
DMACH_I2S2_TX
,
[
16
]
=
DMACH_SPI0_RX
,
[
17
]
=
DMACH_SPI0_TX
,
[
18
]
=
DMACH_SPI1_RX
,
[
19
]
=
DMACH_SPI1_TX
,
[
20
]
=
DMACH_SPI2_RX
,
[
21
]
=
DMACH_SPI2_TX
,
[
22
]
=
DMACH_AC97_MICIN
,
[
23
]
=
DMACH_AC97_PCMIN
,
[
24
]
=
DMACH_AC97_PCMOUT
,
[
25
]
=
DMACH_EXTERNAL
,
[
26
]
=
DMACH_PWM
,
[
27
]
=
DMACH_SPDIF
,
[
28
]
=
DMACH_HSI_RX
,
[
29
]
=
DMACH_HSI_TX
,
[
30
]
=
DMACH_MAX
,
[
31
]
=
DMACH_MAX
,
},
};
};
static
struct
platform_device
s5pc100_device_pdma0
=
{
struct
amba_device
s5pc100_device_pdma0
=
{
.
name
=
"s3c-pl330"
,
.
dev
=
{
.
id
=
0
,
.
init_name
=
"dma-pl330.0"
,
.
num_resources
=
ARRAY_SIZE
(
s5pc100_pdma0_resource
),
.
resource
=
s5pc100_pdma0_resource
,
.
dev
=
{
.
dma_mask
=
&
dma_dmamask
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
s5pc100_pdma0_pdata
,
.
platform_data
=
&
s5pc100_pdma0_pdata
,
},
},
};
.
res
=
{
.
start
=
S5PC100_PA_PDMA0
,
static
struct
resource
s5pc100_pdma1_resource
[]
=
{
.
end
=
S5PC100_PA_PDMA0
+
SZ_4K
,
[
0
]
=
{
.
start
=
S5PC100_PA_PDMA1
,
.
end
=
S5PC100_PA_PDMA1
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
.
flags
=
IORESOURCE_MEM
,
},
},
[
1
]
=
{
.
irq
=
{
IRQ_PDMA0
,
NO_IRQ
},
.
start
=
IRQ_PDMA1
,
.
periphid
=
0x00041330
,
.
end
=
IRQ_PDMA1
,
.
flags
=
IORESOURCE_IRQ
,
},
};
};
static
struct
s3c_pl330_platdata
s5pc100_pdma1_pdata
=
{
struct
dma_pl330_peri
pdma1_peri
[
30
]
=
{
.
peri
=
{
{
[
0
]
=
DMACH_UART0_RX
,
.
peri_id
=
(
u8
)
DMACH_UART0_RX
,
[
1
]
=
DMACH_UART0_TX
,
.
rqtype
=
DEVTOMEM
,
[
2
]
=
DMACH_UART1_RX
,
},
{
[
3
]
=
DMACH_UART1_TX
,
.
peri_id
=
(
u8
)
DMACH_UART0_TX
,
[
4
]
=
DMACH_UART2_RX
,
.
rqtype
=
MEMTODEV
,
[
5
]
=
DMACH_UART2_TX
,
},
{
[
6
]
=
DMACH_UART3_RX
,
.
peri_id
=
(
u8
)
DMACH_UART1_RX
,
[
7
]
=
DMACH_UART3_TX
,
.
rqtype
=
DEVTOMEM
,
[
8
]
=
DMACH_IRDA
,
},
{
[
9
]
=
DMACH_I2S0_RX
,
.
peri_id
=
(
u8
)
DMACH_UART1_TX
,
[
10
]
=
DMACH_I2S0_TX
,
.
rqtype
=
MEMTODEV
,
[
11
]
=
DMACH_I2S0S_TX
,
},
{
[
12
]
=
DMACH_I2S1_RX
,
.
peri_id
=
(
u8
)
DMACH_UART2_RX
,
[
13
]
=
DMACH_I2S1_TX
,
.
rqtype
=
DEVTOMEM
,
[
14
]
=
DMACH_I2S2_RX
,
},
{
[
15
]
=
DMACH_I2S2_TX
,
.
peri_id
=
(
u8
)
DMACH_UART2_TX
,
[
16
]
=
DMACH_SPI0_RX
,
.
rqtype
=
MEMTODEV
,
[
17
]
=
DMACH_SPI0_TX
,
},
{
[
18
]
=
DMACH_SPI1_RX
,
.
peri_id
=
(
u8
)
DMACH_UART3_RX
,
[
19
]
=
DMACH_SPI1_TX
,
.
rqtype
=
DEVTOMEM
,
[
20
]
=
DMACH_SPI2_RX
,
},
{
[
21
]
=
DMACH_SPI2_TX
,
.
peri_id
=
(
u8
)
DMACH_UART3_TX
,
[
22
]
=
DMACH_PCM0_RX
,
.
rqtype
=
MEMTODEV
,
[
23
]
=
DMACH_PCM0_TX
,
},
{
[
24
]
=
DMACH_PCM1_RX
,
.
peri_id
=
DMACH_IRDA
,
[
25
]
=
DMACH_PCM1_TX
,
},
{
[
26
]
=
DMACH_MSM_REQ0
,
.
peri_id
=
(
u8
)
DMACH_I2S0_RX
,
[
27
]
=
DMACH_MSM_REQ1
,
.
rqtype
=
DEVTOMEM
,
[
28
]
=
DMACH_MSM_REQ2
,
},
{
[
29
]
=
DMACH_MSM_REQ3
,
.
peri_id
=
(
u8
)
DMACH_I2S0_TX
,
[
30
]
=
DMACH_MAX
,
.
rqtype
=
MEMTODEV
,
[
31
]
=
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0S_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ0
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ1
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ2
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ3
,
},
},
};
};
static
struct
platform_device
s5pc100_device_pdma1
=
{
struct
dma_pl330_platdata
s5pc100_pdma1_pdata
=
{
.
name
=
"s3c-pl330"
,
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma1_peri
),
.
id
=
1
,
.
peri
=
pdma1_peri
,
.
num_resources
=
ARRAY_SIZE
(
s5pc100_pdma1_resource
),
};
.
resource
=
s5pc100_pdma1_resource
,
.
dev
=
{
struct
amba_device
s5pc100_device_pdma1
=
{
.
dev
=
{
.
init_name
=
"dma-pl330.1"
,
.
dma_mask
=
&
dma_dmamask
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
s5pc100_pdma1_pdata
,
.
platform_data
=
&
s5pc100_pdma1_pdata
,
},
},
};
.
res
=
{
.
start
=
S5PC100_PA_PDMA1
,
static
struct
platform_device
*
s5pc100_dmacs
[]
__initdata
=
{
.
end
=
S5PC100_PA_PDMA1
+
SZ_4K
,
&
s5pc100_device_pdma0
,
.
flags
=
IORESOURCE_MEM
,
&
s5pc100_device_pdma1
,
},
.
irq
=
{
IRQ_PDMA1
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
};
static
int
__init
s5pc100_dma_init
(
void
)
static
int
__init
s5pc100_dma_init
(
void
)
{
{
platform_add_devices
(
s5pc100_dmacs
,
ARRAY_SIZE
(
s5pc100_dmacs
));
amba_device_register
(
&
s5pc100_device_pdma0
,
&
iomem_resource
);
amba_device_register
(
&
s5pc100_device_pdma1
,
&
iomem_resource
);
return
0
;
return
0
;
}
}
...
...
arch/arm/mach-s5pc100/include/mach/dma.h
浏览文件 @
59ca37f7
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
#ifndef __MACH_DMA_H
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common
S3C
DMA API driver for PL330 */
/* This platform uses the common DMA API driver for PL330 */
#include <plat/
s3c-
dma-pl330.h>
#include <plat/dma-pl330.h>
#endif
/* __MACH_DMA_H */
#endif
/* __MACH_DMA_H */
arch/arm/mach-s5pv210/Kconfig
浏览文件 @
59ca37f7
...
@@ -11,7 +11,7 @@ if ARCH_S5PV210
...
@@ -11,7 +11,7 @@ if ARCH_S5PV210
config CPU_S5PV210
config CPU_S5PV210
bool
bool
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
select S5P_EXT_INT
select S5P_EXT_INT
select S5P_HRT
select S5P_HRT
select S5PV210_PM if PM
select S5PV210_PM if PM
...
...
arch/arm/mach-s5pv210/clock.c
浏览文件 @
59ca37f7
...
@@ -203,6 +203,11 @@ static struct clk clk_pcmcdclk2 = {
...
@@ -203,6 +203,11 @@ static struct clk clk_pcmcdclk2 = {
.
name
=
"pcmcdclk"
,
.
name
=
"pcmcdclk"
,
};
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
static
struct
clk
*
clkset_vpllsrc_list
[]
=
{
static
struct
clk
*
clkset_vpllsrc_list
[]
=
{
[
0
]
=
&
clk_fin_vpll
,
[
0
]
=
&
clk_fin_vpll
,
[
1
]
=
&
clk_sclk_hdmi27m
,
[
1
]
=
&
clk_sclk_hdmi27m
,
...
@@ -289,14 +294,14 @@ static struct clk_ops clk_fout_apll_ops = {
...
@@ -289,14 +294,14 @@ static struct clk_ops clk_fout_apll_ops = {
static
struct
clk
init_clocks_off
[]
=
{
static
struct
clk
init_clocks_off
[]
=
{
{
{
.
name
=
"
p
dma"
,
.
name
=
"dma"
,
.
devname
=
"
s3c
-pl330.0"
,
.
devname
=
"
dma
-pl330.0"
,
.
parent
=
&
clk_hclk_psys
.
clk
,
.
parent
=
&
clk_hclk_psys
.
clk
,
.
enable
=
s5pv210_clk_ip0_ctrl
,
.
enable
=
s5pv210_clk_ip0_ctrl
,
.
ctrlbit
=
(
1
<<
3
),
.
ctrlbit
=
(
1
<<
3
),
},
{
},
{
.
name
=
"
p
dma"
,
.
name
=
"dma"
,
.
devname
=
"
s3c
-pl330.1"
,
.
devname
=
"
dma
-pl330.1"
,
.
parent
=
&
clk_hclk_psys
.
clk
,
.
parent
=
&
clk_hclk_psys
.
clk
,
.
enable
=
s5pv210_clk_ip0_ctrl
,
.
enable
=
s5pv210_clk_ip0_ctrl
,
.
ctrlbit
=
(
1
<<
4
),
.
ctrlbit
=
(
1
<<
4
),
...
@@ -1159,5 +1164,6 @@ void __init s5pv210_register_clocks(void)
...
@@ -1159,5 +1164,6 @@ void __init s5pv210_register_clocks(void)
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c24xx_register_clock
(
&
dummy_apb_pclk
);
s3c_pwmclk_init
();
s3c_pwmclk_init
();
}
}
arch/arm/mach-s5pv210/dma.c
浏览文件 @
59ca37f7
/*
/* linux/arch/arm/mach-s5pv210/dma.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Copyright (C) 2010 Samsung Electronics Co. Ltd.
* Copyright (C) 2010 Samsung Electronics Co. Ltd.
* Jaswinder Singh <jassi.brar@samsung.com>
* Jaswinder Singh <jassi.brar@samsung.com>
*
*
...
@@ -17,151 +21,240 @@
...
@@ -17,151 +21,240 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl330.h>
#include <asm/irq.h>
#include <plat/devs.h>
#include <plat/devs.h>
#include <plat/irqs.h>
#include <plat/irqs.h>
#include <mach/map.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <mach/irqs.h>
#include <mach/dma.h>
#include <plat/s3c-pl330-pdata.h>
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
resource
s5pv210_pdma0_resource
[]
=
{
struct
dma_pl330_peri
pdma0_peri
[
28
]
=
{
[
0
]
=
{
{
.
start
=
S5PV210_PA_PDMA0
,
.
peri_id
=
(
u8
)
DMACH_UART0_RX
,
.
end
=
S5PV210_PA_PDMA0
+
SZ_4K
,
.
rqtype
=
DEVTOMEM
,
.
flags
=
IORESOURCE_MEM
,
},
{
},
.
peri_id
=
(
u8
)
DMACH_UART0_TX
,
[
1
]
=
{
.
rqtype
=
MEMTODEV
,
.
start
=
IRQ_PDMA0
,
},
{
.
end
=
IRQ_PDMA0
,
.
peri_id
=
(
u8
)
DMACH_UART1_RX
,
.
flags
=
IORESOURCE_IRQ
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART3_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART3_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0S_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_MICIN
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_PCMIN
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_AC97_PCMOUT
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_PWM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPDIF
,
.
rqtype
=
MEMTODEV
,
},
},
};
};
static
struct
s3c_pl330_platdata
s5pv210_pdma0_pdata
=
{
struct
dma_pl330_platdata
s5pv210_pdma0_pdata
=
{
.
peri
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma0_peri
),
[
0
]
=
DMACH_UART0_RX
,
.
peri
=
pdma0_peri
,
[
1
]
=
DMACH_UART0_TX
,
[
2
]
=
DMACH_UART1_RX
,
[
3
]
=
DMACH_UART1_TX
,
[
4
]
=
DMACH_UART2_RX
,
[
5
]
=
DMACH_UART2_TX
,
[
6
]
=
DMACH_UART3_RX
,
[
7
]
=
DMACH_UART3_TX
,
[
8
]
=
DMACH_MAX
,
[
9
]
=
DMACH_I2S0_RX
,
[
10
]
=
DMACH_I2S0_TX
,
[
11
]
=
DMACH_I2S0S_TX
,
[
12
]
=
DMACH_I2S1_RX
,
[
13
]
=
DMACH_I2S1_TX
,
[
14
]
=
DMACH_MAX
,
[
15
]
=
DMACH_MAX
,
[
16
]
=
DMACH_SPI0_RX
,
[
17
]
=
DMACH_SPI0_TX
,
[
18
]
=
DMACH_SPI1_RX
,
[
19
]
=
DMACH_SPI1_TX
,
[
20
]
=
DMACH_MAX
,
[
21
]
=
DMACH_MAX
,
[
22
]
=
DMACH_AC97_MICIN
,
[
23
]
=
DMACH_AC97_PCMIN
,
[
24
]
=
DMACH_AC97_PCMOUT
,
[
25
]
=
DMACH_MAX
,
[
26
]
=
DMACH_PWM
,
[
27
]
=
DMACH_SPDIF
,
[
28
]
=
DMACH_MAX
,
[
29
]
=
DMACH_MAX
,
[
30
]
=
DMACH_MAX
,
[
31
]
=
DMACH_MAX
,
},
};
};
static
struct
platform_device
s5pv210_device_pdma0
=
{
struct
amba_device
s5pv210_device_pdma0
=
{
.
name
=
"s3c-pl330"
,
.
dev
=
{
.
id
=
0
,
.
init_name
=
"dma-pl330.0"
,
.
num_resources
=
ARRAY_SIZE
(
s5pv210_pdma0_resource
),
.
resource
=
s5pv210_pdma0_resource
,
.
dev
=
{
.
dma_mask
=
&
dma_dmamask
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
s5pv210_pdma0_pdata
,
.
platform_data
=
&
s5pv210_pdma0_pdata
,
},
},
};
.
res
=
{
.
start
=
S5PV210_PA_PDMA0
,
static
struct
resource
s5pv210_pdma1_resource
[]
=
{
.
end
=
S5PV210_PA_PDMA0
+
SZ_4K
,
[
0
]
=
{
.
start
=
S5PV210_PA_PDMA1
,
.
end
=
S5PV210_PA_PDMA1
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
.
flags
=
IORESOURCE_MEM
,
},
},
[
1
]
=
{
.
irq
=
{
IRQ_PDMA0
,
NO_IRQ
},
.
start
=
IRQ_PDMA1
,
.
periphid
=
0x00041330
,
.
end
=
IRQ_PDMA1
,
.
flags
=
IORESOURCE_IRQ
,
},
};
};
static
struct
s3c_pl330_platdata
s5pv210_pdma1_pdata
=
{
struct
dma_pl330_peri
pdma1_peri
[
32
]
=
{
.
peri
=
{
{
[
0
]
=
DMACH_UART0_RX
,
.
peri_id
=
(
u8
)
DMACH_UART0_RX
,
[
1
]
=
DMACH_UART0_TX
,
.
rqtype
=
DEVTOMEM
,
[
2
]
=
DMACH_UART1_RX
,
},
{
[
3
]
=
DMACH_UART1_TX
,
.
peri_id
=
(
u8
)
DMACH_UART0_TX
,
[
4
]
=
DMACH_UART2_RX
,
.
rqtype
=
MEMTODEV
,
[
5
]
=
DMACH_UART2_TX
,
},
{
[
6
]
=
DMACH_UART3_RX
,
.
peri_id
=
(
u8
)
DMACH_UART1_RX
,
[
7
]
=
DMACH_UART3_TX
,
.
rqtype
=
DEVTOMEM
,
[
8
]
=
DMACH_MAX
,
},
{
[
9
]
=
DMACH_I2S0_RX
,
.
peri_id
=
(
u8
)
DMACH_UART1_TX
,
[
10
]
=
DMACH_I2S0_TX
,
.
rqtype
=
MEMTODEV
,
[
11
]
=
DMACH_I2S0S_TX
,
},
{
[
12
]
=
DMACH_I2S1_RX
,
.
peri_id
=
(
u8
)
DMACH_UART2_RX
,
[
13
]
=
DMACH_I2S1_TX
,
.
rqtype
=
DEVTOMEM
,
[
14
]
=
DMACH_I2S2_RX
,
},
{
[
15
]
=
DMACH_I2S2_TX
,
.
peri_id
=
(
u8
)
DMACH_UART2_TX
,
[
16
]
=
DMACH_SPI0_RX
,
.
rqtype
=
MEMTODEV
,
[
17
]
=
DMACH_SPI0_TX
,
},
{
[
18
]
=
DMACH_SPI1_RX
,
.
peri_id
=
(
u8
)
DMACH_UART3_RX
,
[
19
]
=
DMACH_SPI1_TX
,
.
rqtype
=
DEVTOMEM
,
[
20
]
=
DMACH_MAX
,
},
{
[
21
]
=
DMACH_MAX
,
.
peri_id
=
(
u8
)
DMACH_UART3_TX
,
[
22
]
=
DMACH_PCM0_RX
,
.
rqtype
=
MEMTODEV
,
[
23
]
=
DMACH_PCM0_TX
,
},
{
[
24
]
=
DMACH_PCM1_RX
,
.
peri_id
=
DMACH_MAX
,
[
25
]
=
DMACH_PCM1_TX
,
},
{
[
26
]
=
DMACH_MSM_REQ0
,
.
peri_id
=
(
u8
)
DMACH_I2S0_RX
,
[
27
]
=
DMACH_MSM_REQ1
,
.
rqtype
=
DEVTOMEM
,
[
28
]
=
DMACH_MSM_REQ2
,
},
{
[
29
]
=
DMACH_MSM_REQ3
,
.
peri_id
=
(
u8
)
DMACH_I2S0_TX
,
[
30
]
=
DMACH_PCM2_RX
,
.
rqtype
=
MEMTODEV
,
[
31
]
=
DMACH_PCM2_TX
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S0S_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_I2S2_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_SPI1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_MAX
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM1_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM1_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ0
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ1
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ2
,
},
{
.
peri_id
=
(
u8
)
DMACH_MSM_REQ3
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM2_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM2_TX
,
.
rqtype
=
MEMTODEV
,
},
},
};
};
static
struct
platform_device
s5pv210_device_pdma1
=
{
struct
dma_pl330_platdata
s5pv210_pdma1_pdata
=
{
.
name
=
"s3c-pl330"
,
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma1_peri
),
.
id
=
1
,
.
peri
=
pdma1_peri
,
.
num_resources
=
ARRAY_SIZE
(
s5pv210_pdma1_resource
),
};
.
resource
=
s5pv210_pdma1_resource
,
.
dev
=
{
struct
amba_device
s5pv210_device_pdma1
=
{
.
dev
=
{
.
init_name
=
"dma-pl330.1"
,
.
dma_mask
=
&
dma_dmamask
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
s5pv210_pdma1_pdata
,
.
platform_data
=
&
s5pv210_pdma1_pdata
,
},
},
};
.
res
=
{
.
start
=
S5PV210_PA_PDMA1
,
static
struct
platform_device
*
s5pv210_dmacs
[]
__initdata
=
{
.
end
=
S5PV210_PA_PDMA1
+
SZ_4K
,
&
s5pv210_device_pdma0
,
.
flags
=
IORESOURCE_MEM
,
&
s5pv210_device_pdma1
,
},
.
irq
=
{
IRQ_PDMA1
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
};
static
int
__init
s5pv210_dma_init
(
void
)
static
int
__init
s5pv210_dma_init
(
void
)
{
{
platform_add_devices
(
s5pv210_dmacs
,
ARRAY_SIZE
(
s5pv210_dmacs
));
amba_device_register
(
&
s5pv210_device_pdma0
,
&
iomem_resource
);
amba_device_register
(
&
s5pv210_device_pdma1
,
&
iomem_resource
);
return
0
;
return
0
;
}
}
...
...
arch/arm/mach-s5pv210/include/mach/dma.h
浏览文件 @
59ca37f7
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
#ifndef __MACH_DMA_H
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common
S3C
DMA API driver for PL330 */
/* This platform uses the common DMA API driver for PL330 */
#include <plat/
s3c-
dma-pl330.h>
#include <plat/dma-pl330.h>
#endif
/* __MACH_DMA_H */
#endif
/* __MACH_DMA_H */
arch/arm/plat-s3c24xx/dma.c
浏览文件 @
59ca37f7
...
@@ -1094,14 +1094,14 @@ EXPORT_SYMBOL(s3c2410_dma_config);
...
@@ -1094,14 +1094,14 @@ EXPORT_SYMBOL(s3c2410_dma_config);
*
*
* configure the dma source/destination hardware type and address
* configure the dma source/destination hardware type and address
*
*
* source:
S3C2410_DMASRC_HW
: source is hardware
* source:
DMA_FROM_DEVICE
: source is hardware
*
S3C2410_DMASRC_MEM
: source is memory
*
DMA_TO_DEVICE
: source is memory
*
*
* devaddr: physical address of the source
* devaddr: physical address of the source
*/
*/
int
s3c2410_dma_devconfig
(
enum
dma_ch
channel
,
int
s3c2410_dma_devconfig
(
enum
dma_ch
channel
,
enum
s3c2410_dmasrc
source
,
enum
dma_data_direction
source
,
unsigned
long
devaddr
)
unsigned
long
devaddr
)
{
{
struct
s3c2410_dma_chan
*
chan
=
s3c_dma_lookup_channel
(
channel
);
struct
s3c2410_dma_chan
*
chan
=
s3c_dma_lookup_channel
(
channel
);
...
@@ -1131,7 +1131,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
...
@@ -1131,7 +1131,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
hwcfg
|=
S3C2410_DISRCC_INC
;
hwcfg
|=
S3C2410_DISRCC_INC
;
switch
(
source
)
{
switch
(
source
)
{
case
S3C2410_DMASRC_HW
:
case
DMA_FROM_DEVICE
:
/* source is hardware */
/* source is hardware */
pr_debug
(
"%s: hw source, devaddr=%08lx, hwcfg=%d
\n
"
,
pr_debug
(
"%s: hw source, devaddr=%08lx, hwcfg=%d
\n
"
,
__func__
,
devaddr
,
hwcfg
);
__func__
,
devaddr
,
hwcfg
);
...
@@ -1142,7 +1142,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
...
@@ -1142,7 +1142,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
chan
->
addr_reg
=
dma_regaddr
(
chan
,
S3C2410_DMA_DIDST
);
chan
->
addr_reg
=
dma_regaddr
(
chan
,
S3C2410_DMA_DIDST
);
break
;
break
;
case
S3C2410_DMASRC_MEM
:
case
DMA_TO_DEVICE
:
/* source is memory */
/* source is memory */
pr_debug
(
"%s: mem source, devaddr=%08lx, hwcfg=%d
\n
"
,
pr_debug
(
"%s: mem source, devaddr=%08lx, hwcfg=%d
\n
"
,
__func__
,
devaddr
,
hwcfg
);
__func__
,
devaddr
,
hwcfg
);
...
...
arch/arm/plat-samsung/Kconfig
浏览文件 @
59ca37f7
...
@@ -300,11 +300,14 @@ config S3C_DMA
...
@@ -300,11 +300,14 @@ config S3C_DMA
help
help
Internal configuration for S3C DMA core
Internal configuration for S3C DMA core
config S
3C_PL330_DMA
config S
AMSUNG_DMADEV
bool
bool
select PL330
select DMADEVICES
select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \
CPU_S5P6450 || CPU_S5P6440)
select ARM_AMBA
help
help
S3C DMA API Driver
for PL330 DMAC.
Use DMA device engine
for PL330 DMAC.
comment "Power management"
comment "Power management"
...
...
arch/arm/plat-samsung/Makefile
浏览文件 @
59ca37f7
...
@@ -63,9 +63,9 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
...
@@ -63,9 +63,9 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
# DMA support
# DMA support
obj-$(CONFIG_S3C_DMA)
+=
dma.o
obj-$(CONFIG_S3C_DMA)
+=
dma.o
s3c-dma-ops.o
obj-$(CONFIG_S
3C_PL330_DMA)
+=
s3c-pl330
.o
obj-$(CONFIG_S
AMSUNG_DMADEV)
+=
dma-ops
.o
# PM support
# PM support
...
...
arch/arm/plat-samsung/dma-ops.c
0 → 100644
浏览文件 @
59ca37f7
/* linux/arch/arm/plat-samsung/dma-ops.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Samsung DMA Operations
*
* 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/kernel.h>
#include <linux/errno.h>
#include <linux/amba/pl330.h>
#include <linux/scatterlist.h>
#include <mach/dma.h>
static
inline
bool
pl330_filter
(
struct
dma_chan
*
chan
,
void
*
param
)
{
struct
dma_pl330_peri
*
peri
=
chan
->
private
;
return
peri
->
peri_id
==
(
unsigned
)
param
;
}
static
unsigned
samsung_dmadev_request
(
enum
dma_ch
dma_ch
,
struct
samsung_dma_info
*
info
)
{
struct
dma_chan
*
chan
;
dma_cap_mask_t
mask
;
struct
dma_slave_config
slave_config
;
dma_cap_zero
(
mask
);
dma_cap_set
(
info
->
cap
,
mask
);
chan
=
dma_request_channel
(
mask
,
pl330_filter
,
(
void
*
)
dma_ch
);
if
(
info
->
direction
==
DMA_FROM_DEVICE
)
{
memset
(
&
slave_config
,
0
,
sizeof
(
struct
dma_slave_config
));
slave_config
.
direction
=
info
->
direction
;
slave_config
.
src_addr
=
info
->
fifo
;
slave_config
.
src_addr_width
=
info
->
width
;
slave_config
.
src_maxburst
=
1
;
dmaengine_slave_config
(
chan
,
&
slave_config
);
}
else
if
(
info
->
direction
==
DMA_TO_DEVICE
)
{
memset
(
&
slave_config
,
0
,
sizeof
(
struct
dma_slave_config
));
slave_config
.
direction
=
info
->
direction
;
slave_config
.
dst_addr
=
info
->
fifo
;
slave_config
.
dst_addr_width
=
info
->
width
;
slave_config
.
dst_maxburst
=
1
;
dmaengine_slave_config
(
chan
,
&
slave_config
);
}
return
(
unsigned
)
chan
;
}
static
int
samsung_dmadev_release
(
unsigned
ch
,
struct
s3c2410_dma_client
*
client
)
{
dma_release_channel
((
struct
dma_chan
*
)
ch
);
return
0
;
}
static
int
samsung_dmadev_prepare
(
unsigned
ch
,
struct
samsung_dma_prep_info
*
info
)
{
struct
scatterlist
sg
;
struct
dma_chan
*
chan
=
(
struct
dma_chan
*
)
ch
;
struct
dma_async_tx_descriptor
*
desc
;
switch
(
info
->
cap
)
{
case
DMA_SLAVE
:
sg_init_table
(
&
sg
,
1
);
sg_dma_len
(
&
sg
)
=
info
->
len
;
sg_set_page
(
&
sg
,
pfn_to_page
(
PFN_DOWN
(
info
->
buf
)),
info
->
len
,
offset_in_page
(
info
->
buf
));
sg_dma_address
(
&
sg
)
=
info
->
buf
;
desc
=
chan
->
device
->
device_prep_slave_sg
(
chan
,
&
sg
,
1
,
info
->
direction
,
DMA_PREP_INTERRUPT
);
break
;
case
DMA_CYCLIC
:
desc
=
chan
->
device
->
device_prep_dma_cyclic
(
chan
,
info
->
buf
,
info
->
len
,
info
->
period
,
info
->
direction
);
break
;
default:
dev_err
(
&
chan
->
dev
->
device
,
"unsupported format
\n
"
);
return
-
EFAULT
;
}
if
(
!
desc
)
{
dev_err
(
&
chan
->
dev
->
device
,
"cannot prepare cyclic dma
\n
"
);
return
-
EFAULT
;
}
desc
->
callback
=
info
->
fp
;
desc
->
callback_param
=
info
->
fp_param
;
dmaengine_submit
((
struct
dma_async_tx_descriptor
*
)
desc
);
return
0
;
}
static
inline
int
samsung_dmadev_trigger
(
unsigned
ch
)
{
dma_async_issue_pending
((
struct
dma_chan
*
)
ch
);
return
0
;
}
static
inline
int
samsung_dmadev_flush
(
unsigned
ch
)
{
return
dmaengine_terminate_all
((
struct
dma_chan
*
)
ch
);
}
struct
samsung_dma_ops
dmadev_ops
=
{
.
request
=
samsung_dmadev_request
,
.
release
=
samsung_dmadev_release
,
.
prepare
=
samsung_dmadev_prepare
,
.
trigger
=
samsung_dmadev_trigger
,
.
started
=
NULL
,
.
flush
=
samsung_dmadev_flush
,
.
stop
=
samsung_dmadev_flush
,
};
void
*
samsung_dmadev_get_ops
(
void
)
{
return
&
dmadev_ops
;
}
EXPORT_SYMBOL
(
samsung_dmadev_get_ops
);
arch/arm/plat-samsung/include/plat/dma-ops.h
0 → 100644
浏览文件 @
59ca37f7
/* arch/arm/plat-samsung/include/plat/dma-ops.h
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Samsung DMA 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 __SAMSUNG_DMA_OPS_H_
#define __SAMSUNG_DMA_OPS_H_ __FILE__
#include <linux/dmaengine.h>
struct
samsung_dma_prep_info
{
enum
dma_transaction_type
cap
;
enum
dma_data_direction
direction
;
dma_addr_t
buf
;
unsigned
long
period
;
unsigned
long
len
;
void
(
*
fp
)(
void
*
data
);
void
*
fp_param
;
};
struct
samsung_dma_info
{
enum
dma_transaction_type
cap
;
enum
dma_data_direction
direction
;
enum
dma_slave_buswidth
width
;
dma_addr_t
fifo
;
struct
s3c2410_dma_client
*
client
;
};
struct
samsung_dma_ops
{
unsigned
(
*
request
)(
enum
dma_ch
ch
,
struct
samsung_dma_info
*
info
);
int
(
*
release
)(
unsigned
ch
,
struct
s3c2410_dma_client
*
client
);
int
(
*
prepare
)(
unsigned
ch
,
struct
samsung_dma_prep_info
*
info
);
int
(
*
trigger
)(
unsigned
ch
);
int
(
*
started
)(
unsigned
ch
);
int
(
*
flush
)(
unsigned
ch
);
int
(
*
stop
)(
unsigned
ch
);
};
extern
void
*
samsung_dmadev_get_ops
(
void
);
extern
void
*
s3c_dma_get_ops
(
void
);
static
inline
void
*
__samsung_dma_get_ops
(
void
)
{
if
(
samsung_dma_is_dmadev
())
return
samsung_dmadev_get_ops
();
else
return
s3c_dma_get_ops
();
}
/*
* samsung_dma_get_ops
* get the set of samsung dma operations
*/
#define samsung_dma_get_ops() __samsung_dma_get_ops()
#endif
/* __SAMSUNG_DMA_OPS_H_ */
arch/arm/plat-samsung/include/plat/
s3c-
dma-pl330.h
→
arch/arm/plat-samsung/include/plat/dma-pl330.h
浏览文件 @
59ca37f7
...
@@ -8,11 +8,8 @@
...
@@ -8,11 +8,8 @@
* (at your option) any later version.
* (at your option) any later version.
*/
*/
#ifndef __S3C_DMA_PL330_H_
#ifndef __DMA_PL330_H_
#define __S3C_DMA_PL330_H_
#define __DMA_PL330_H_ __FILE__
#define S3C2410_DMAF_AUTOSTART (1 << 0)
#define S3C2410_DMAF_CIRCULAR (1 << 1)
/*
/*
* PL330 can assign any channel to communicate with
* PL330 can assign any channel to communicate with
...
@@ -20,7 +17,7 @@
...
@@ -20,7 +17,7 @@
* For the sake of consistency across client drivers,
* For the sake of consistency across client drivers,
* We keep the channel names unchanged and only add
* We keep the channel names unchanged and only add
* missing peripherals are added.
* missing peripherals are added.
* Order is not important since
S3C
PL330 API driver
* Order is not important since
DMA
PL330 API driver
* use these just as IDs.
* use these just as IDs.
*/
*/
enum
dma_ch
{
enum
dma_ch
{
...
@@ -88,11 +85,20 @@ enum dma_ch {
...
@@ -88,11 +85,20 @@ enum dma_ch {
DMACH_MAX
,
DMACH_MAX
,
};
};
static
inline
bool
s3c_dma_has_circular
(
void
)
struct
s3c2410_dma_client
{
char
*
name
;
};
static
inline
bool
samsung_dma_has_circular
(
void
)
{
return
true
;
}
static
inline
bool
samsung_dma_is_dmadev
(
void
)
{
{
return
true
;
return
true
;
}
}
#include <plat/dma.h>
#include <plat/dma
-ops
.h>
#endif
/* __
S3C_
DMA_PL330_H_ */
#endif
/* __DMA_PL330_H_ */
arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
浏览文件 @
59ca37f7
...
@@ -47,7 +47,7 @@ struct s3c24xx_dma_selection {
...
@@ -47,7 +47,7 @@ struct s3c24xx_dma_selection {
void
(
*
direction
)(
struct
s3c2410_dma_chan
*
chan
,
void
(
*
direction
)(
struct
s3c2410_dma_chan
*
chan
,
struct
s3c24xx_dma_map
*
map
,
struct
s3c24xx_dma_map
*
map
,
enum
s3c2410_dmasrc
dir
);
enum
dma_data_direction
dir
);
};
};
extern
int
s3c24xx_dma_init_map
(
struct
s3c24xx_dma_selection
*
sel
);
extern
int
s3c24xx_dma_init_map
(
struct
s3c24xx_dma_selection
*
sel
);
...
...
arch/arm/plat-samsung/include/plat/dma.h
浏览文件 @
59ca37f7
...
@@ -10,17 +10,14 @@
...
@@ -10,17 +10,14 @@
* published by the Free Software Foundation.
* published by the Free Software Foundation.
*/
*/
#include <linux/dma-mapping.h>
enum
s3c2410_dma_buffresult
{
enum
s3c2410_dma_buffresult
{
S3C2410_RES_OK
,
S3C2410_RES_OK
,
S3C2410_RES_ERR
,
S3C2410_RES_ERR
,
S3C2410_RES_ABORT
S3C2410_RES_ABORT
};
};
enum
s3c2410_dmasrc
{
S3C2410_DMASRC_HW
,
/* source is memory */
S3C2410_DMASRC_MEM
/* source is hardware */
};
/* enum s3c2410_chan_op
/* enum s3c2410_chan_op
*
*
* operation codes passed to the DMA code by the user, and also used
* operation codes passed to the DMA code by the user, and also used
...
@@ -112,7 +109,7 @@ extern int s3c2410_dma_config(enum dma_ch channel, int xferunit);
...
@@ -112,7 +109,7 @@ extern int s3c2410_dma_config(enum dma_ch channel, int xferunit);
*/
*/
extern
int
s3c2410_dma_devconfig
(
enum
dma_ch
channel
,
extern
int
s3c2410_dma_devconfig
(
enum
dma_ch
channel
,
enum
s3c2410_dmasrc
source
,
unsigned
long
devaddr
);
enum
dma_data_direction
source
,
unsigned
long
devaddr
);
/* s3c2410_dma_getposition
/* s3c2410_dma_getposition
*
*
...
@@ -126,3 +123,4 @@ extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn);
...
@@ -126,3 +123,4 @@ extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn);
extern
int
s3c2410_dma_set_buffdone_fn
(
enum
dma_ch
,
s3c2410_dma_cbfn_t
rtn
);
extern
int
s3c2410_dma_set_buffdone_fn
(
enum
dma_ch
,
s3c2410_dma_cbfn_t
rtn
);
#include <plat/dma-ops.h>
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
已删除
100644 → 0
浏览文件 @
7d84b3e9
/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
*
* Copyright (C) 2010 Samsung Electronics Co. Ltd.
* Jaswinder Singh <jassi.brar@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __S3C_PL330_PDATA_H
#define __S3C_PL330_PDATA_H
#include <plat/s3c-dma-pl330.h>
/*
* Every PL330 DMAC has max 32 peripheral interfaces,
* of which some may be not be really used in your
* DMAC's configuration.
* Populate this array of 32 peri i/fs with relevant
* channel IDs for used peri i/f and DMACH_MAX for
* those unused.
*
* The platforms just need to provide this info
* to the S3C DMA API driver for PL330.
*/
struct
s3c_pl330_platdata
{
enum
dma_ch
peri
[
32
];
};
#endif
/* __S3C_PL330_PDATA_H */
arch/arm/plat-samsung/s3c-dma-ops.c
0 → 100644
浏览文件 @
59ca37f7
/* linux/arch/arm/plat-samsung/s3c-dma-ops.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Samsung S3C-DMA Operations
*
* 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/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <mach/dma.h>
struct
cb_data
{
void
(
*
fp
)
(
void
*
);
void
*
fp_param
;
unsigned
ch
;
struct
list_head
node
;
};
static
LIST_HEAD
(
dma_list
);
static
void
s3c_dma_cb
(
struct
s3c2410_dma_chan
*
channel
,
void
*
param
,
int
size
,
enum
s3c2410_dma_buffresult
res
)
{
struct
cb_data
*
data
=
param
;
data
->
fp
(
data
->
fp_param
);
}
static
unsigned
s3c_dma_request
(
enum
dma_ch
dma_ch
,
struct
samsung_dma_info
*
info
)
{
struct
cb_data
*
data
;
if
(
s3c2410_dma_request
(
dma_ch
,
info
->
client
,
NULL
)
<
0
)
{
s3c2410_dma_free
(
dma_ch
,
info
->
client
);
return
0
;
}
data
=
kzalloc
(
sizeof
(
struct
cb_data
),
GFP_KERNEL
);
data
->
ch
=
dma_ch
;
list_add_tail
(
&
data
->
node
,
&
dma_list
);
s3c2410_dma_devconfig
(
dma_ch
,
info
->
direction
,
info
->
fifo
);
if
(
info
->
cap
==
DMA_CYCLIC
)
s3c2410_dma_setflags
(
dma_ch
,
S3C2410_DMAF_CIRCULAR
);
s3c2410_dma_config
(
dma_ch
,
info
->
width
);
return
(
unsigned
)
dma_ch
;
}
static
int
s3c_dma_release
(
unsigned
ch
,
struct
s3c2410_dma_client
*
client
)
{
struct
cb_data
*
data
;
list_for_each_entry
(
data
,
&
dma_list
,
node
)
if
(
data
->
ch
==
ch
)
break
;
list_del
(
&
data
->
node
);
s3c2410_dma_free
(
ch
,
client
);
kfree
(
data
);
return
0
;
}
static
int
s3c_dma_prepare
(
unsigned
ch
,
struct
samsung_dma_prep_info
*
info
)
{
struct
cb_data
*
data
;
int
len
=
(
info
->
cap
==
DMA_CYCLIC
)
?
info
->
period
:
info
->
len
;
list_for_each_entry
(
data
,
&
dma_list
,
node
)
if
(
data
->
ch
==
ch
)
break
;
if
(
!
data
->
fp
)
{
s3c2410_dma_set_buffdone_fn
(
ch
,
s3c_dma_cb
);
data
->
fp
=
info
->
fp
;
data
->
fp_param
=
info
->
fp_param
;
}
s3c2410_dma_enqueue
(
ch
,
(
void
*
)
data
,
info
->
buf
,
len
);
return
0
;
}
static
inline
int
s3c_dma_trigger
(
unsigned
ch
)
{
return
s3c2410_dma_ctrl
(
ch
,
S3C2410_DMAOP_START
);
}
static
inline
int
s3c_dma_started
(
unsigned
ch
)
{
return
s3c2410_dma_ctrl
(
ch
,
S3C2410_DMAOP_STARTED
);
}
static
inline
int
s3c_dma_flush
(
unsigned
ch
)
{
return
s3c2410_dma_ctrl
(
ch
,
S3C2410_DMAOP_FLUSH
);
}
static
inline
int
s3c_dma_stop
(
unsigned
ch
)
{
return
s3c2410_dma_ctrl
(
ch
,
S3C2410_DMAOP_STOP
);
}
static
struct
samsung_dma_ops
s3c_dma_ops
=
{
.
request
=
s3c_dma_request
,
.
release
=
s3c_dma_release
,
.
prepare
=
s3c_dma_prepare
,
.
trigger
=
s3c_dma_trigger
,
.
started
=
s3c_dma_started
,
.
flush
=
s3c_dma_flush
,
.
stop
=
s3c_dma_stop
,
};
void
*
s3c_dma_get_ops
(
void
)
{
return
&
s3c_dma_ops
;
}
EXPORT_SYMBOL
(
s3c_dma_get_ops
);
arch/arm/plat-samsung/s3c-pl330.c
已删除
100644 → 0
浏览文件 @
7d84b3e9
此差异已折叠。
点击以展开。
drivers/dma/Kconfig
浏览文件 @
59ca37f7
...
@@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
...
@@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
config PL330_DMA
config PL330_DMA
tristate "DMA API Driver for PL330"
tristate "DMA API Driver for PL330"
select DMA_ENGINE
select DMA_ENGINE
depends on PL330
depends on ARM_AMBA
select PL330
help
help
Select if your platform has one or more PL330 DMACs.
Select if your platform has one or more PL330 DMACs.
You need to provide platform specific settings via
You need to provide platform specific settings via
...
...
drivers/dma/amba-pl08x.c
浏览文件 @
59ca37f7
此差异已折叠。
点击以展开。
drivers/dma/at_hdmac.c
浏览文件 @
59ca37f7
...
@@ -107,10 +107,11 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
...
@@ -107,10 +107,11 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
{
{
struct
at_desc
*
desc
,
*
_desc
;
struct
at_desc
*
desc
,
*
_desc
;
struct
at_desc
*
ret
=
NULL
;
struct
at_desc
*
ret
=
NULL
;
unsigned
long
flags
;
unsigned
int
i
=
0
;
unsigned
int
i
=
0
;
LIST_HEAD
(
tmp_list
);
LIST_HEAD
(
tmp_list
);
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
list_for_each_entry_safe
(
desc
,
_desc
,
&
atchan
->
free_list
,
desc_node
)
{
list_for_each_entry_safe
(
desc
,
_desc
,
&
atchan
->
free_list
,
desc_node
)
{
i
++
;
i
++
;
if
(
async_tx_test_ack
(
&
desc
->
txd
))
{
if
(
async_tx_test_ack
(
&
desc
->
txd
))
{
...
@@ -121,7 +122,7 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
...
@@ -121,7 +122,7 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
dev_dbg
(
chan2dev
(
&
atchan
->
chan_common
),
dev_dbg
(
chan2dev
(
&
atchan
->
chan_common
),
"desc %p not ACKed
\n
"
,
desc
);
"desc %p not ACKed
\n
"
,
desc
);
}
}
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
"scanned %u descriptors on freelist
\n
"
,
i
);
"scanned %u descriptors on freelist
\n
"
,
i
);
...
@@ -129,9 +130,9 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
...
@@ -129,9 +130,9 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
if
(
!
ret
)
{
if
(
!
ret
)
{
ret
=
atc_alloc_descriptor
(
&
atchan
->
chan_common
,
GFP_ATOMIC
);
ret
=
atc_alloc_descriptor
(
&
atchan
->
chan_common
,
GFP_ATOMIC
);
if
(
ret
)
{
if
(
ret
)
{
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
atchan
->
descs_allocated
++
;
atchan
->
descs_allocated
++
;
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
else
{
}
else
{
dev_err
(
chan2dev
(
&
atchan
->
chan_common
),
dev_err
(
chan2dev
(
&
atchan
->
chan_common
),
"not enough descriptors available
\n
"
);
"not enough descriptors available
\n
"
);
...
@@ -150,8 +151,9 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
...
@@ -150,8 +151,9 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
{
{
if
(
desc
)
{
if
(
desc
)
{
struct
at_desc
*
child
;
struct
at_desc
*
child
;
unsigned
long
flags
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
list_for_each_entry
(
child
,
&
desc
->
tx_list
,
desc_node
)
list_for_each_entry
(
child
,
&
desc
->
tx_list
,
desc_node
)
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
"moving child desc %p to freelist
\n
"
,
"moving child desc %p to freelist
\n
"
,
...
@@ -160,7 +162,7 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
...
@@ -160,7 +162,7 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
"moving desc %p to freelist
\n
"
,
desc
);
"moving desc %p to freelist
\n
"
,
desc
);
list_add
(
&
desc
->
desc_node
,
&
atchan
->
free_list
);
list_add
(
&
desc
->
desc_node
,
&
atchan
->
free_list
);
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
}
}
}
...
@@ -299,7 +301,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
...
@@ -299,7 +301,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
/* for cyclic transfers,
/* for cyclic transfers,
* no need to replay callback function while stopping */
* no need to replay callback function while stopping */
if
(
!
test_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
))
{
if
(
!
atc_chan_is_cyclic
(
atchan
))
{
dma_async_tx_callback
callback
=
txd
->
callback
;
dma_async_tx_callback
callback
=
txd
->
callback
;
void
*
param
=
txd
->
callback_param
;
void
*
param
=
txd
->
callback_param
;
...
@@ -471,16 +473,17 @@ static void atc_handle_cyclic(struct at_dma_chan *atchan)
...
@@ -471,16 +473,17 @@ static void atc_handle_cyclic(struct at_dma_chan *atchan)
static
void
atc_tasklet
(
unsigned
long
data
)
static
void
atc_tasklet
(
unsigned
long
data
)
{
{
struct
at_dma_chan
*
atchan
=
(
struct
at_dma_chan
*
)
data
;
struct
at_dma_chan
*
atchan
=
(
struct
at_dma_chan
*
)
data
;
unsigned
long
flags
;
spin_lock
(
&
atchan
->
lock
);
spin_lock
_irqsave
(
&
atchan
->
lock
,
flags
);
if
(
test_and_clear_bit
(
ATC_IS_ERROR
,
&
atchan
->
status
))
if
(
test_and_clear_bit
(
ATC_IS_ERROR
,
&
atchan
->
status
))
atc_handle_error
(
atchan
);
atc_handle_error
(
atchan
);
else
if
(
test_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
))
else
if
(
atc_chan_is_cyclic
(
atchan
))
atc_handle_cyclic
(
atchan
);
atc_handle_cyclic
(
atchan
);
else
else
atc_advance_work
(
atchan
);
atc_advance_work
(
atchan
);
spin_unlock
(
&
atchan
->
lock
);
spin_unlock
_irqrestore
(
&
atchan
->
lock
,
flags
);
}
}
static
irqreturn_t
at_dma_interrupt
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
at_dma_interrupt
(
int
irq
,
void
*
dev_id
)
...
@@ -539,8 +542,9 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
...
@@ -539,8 +542,9 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
struct
at_desc
*
desc
=
txd_to_at_desc
(
tx
);
struct
at_desc
*
desc
=
txd_to_at_desc
(
tx
);
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
tx
->
chan
);
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
tx
->
chan
);
dma_cookie_t
cookie
;
dma_cookie_t
cookie
;
unsigned
long
flags
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
cookie
=
atc_assign_cookie
(
atchan
,
desc
);
cookie
=
atc_assign_cookie
(
atchan
,
desc
);
if
(
list_empty
(
&
atchan
->
active_list
))
{
if
(
list_empty
(
&
atchan
->
active_list
))
{
...
@@ -554,7 +558,7 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
...
@@ -554,7 +558,7 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
list_add_tail
(
&
desc
->
desc_node
,
&
atchan
->
queue
);
list_add_tail
(
&
desc
->
desc_node
,
&
atchan
->
queue
);
}
}
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
return
cookie
;
return
cookie
;
}
}
...
@@ -927,28 +931,29 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
...
@@ -927,28 +931,29 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
struct
at_dma
*
atdma
=
to_at_dma
(
chan
->
device
);
struct
at_dma
*
atdma
=
to_at_dma
(
chan
->
device
);
int
chan_id
=
atchan
->
chan_common
.
chan_id
;
int
chan_id
=
atchan
->
chan_common
.
chan_id
;
unsigned
long
flags
;
LIST_HEAD
(
list
);
LIST_HEAD
(
list
);
dev_vdbg
(
chan2dev
(
chan
),
"atc_control (%d)
\n
"
,
cmd
);
dev_vdbg
(
chan2dev
(
chan
),
"atc_control (%d)
\n
"
,
cmd
);
if
(
cmd
==
DMA_PAUSE
)
{
if
(
cmd
==
DMA_PAUSE
)
{
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
dma_writel
(
atdma
,
CHER
,
AT_DMA_SUSP
(
chan_id
));
dma_writel
(
atdma
,
CHER
,
AT_DMA_SUSP
(
chan_id
));
set_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
);
set_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
);
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
else
if
(
cmd
==
DMA_RESUME
)
{
}
else
if
(
cmd
==
DMA_RESUME
)
{
if
(
!
test_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
))
if
(
!
atc_chan_is_paused
(
atchan
))
return
0
;
return
0
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
dma_writel
(
atdma
,
CHDR
,
AT_DMA_RES
(
chan_id
));
dma_writel
(
atdma
,
CHDR
,
AT_DMA_RES
(
chan_id
));
clear_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
);
clear_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
);
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
else
if
(
cmd
==
DMA_TERMINATE_ALL
)
{
}
else
if
(
cmd
==
DMA_TERMINATE_ALL
)
{
struct
at_desc
*
desc
,
*
_desc
;
struct
at_desc
*
desc
,
*
_desc
;
/*
/*
...
@@ -957,7 +962,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
...
@@ -957,7 +962,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
* channel. We still have to poll the channel enable bit due
* channel. We still have to poll the channel enable bit due
* to AHB/HSB limitations.
* to AHB/HSB limitations.
*/
*/
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
/* disabling channel: must also remove suspend state */
/* disabling channel: must also remove suspend state */
dma_writel
(
atdma
,
CHDR
,
AT_DMA_RES
(
chan_id
)
|
atchan
->
mask
);
dma_writel
(
atdma
,
CHDR
,
AT_DMA_RES
(
chan_id
)
|
atchan
->
mask
);
...
@@ -978,7 +983,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
...
@@ -978,7 +983,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
/* if channel dedicated to cyclic operations, free it */
/* if channel dedicated to cyclic operations, free it */
clear_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
);
clear_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
);
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
else
{
}
else
{
return
-
ENXIO
;
return
-
ENXIO
;
}
}
...
@@ -1004,9 +1009,10 @@ atc_tx_status(struct dma_chan *chan,
...
@@ -1004,9 +1009,10 @@ atc_tx_status(struct dma_chan *chan,
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
dma_cookie_t
last_used
;
dma_cookie_t
last_used
;
dma_cookie_t
last_complete
;
dma_cookie_t
last_complete
;
unsigned
long
flags
;
enum
dma_status
ret
;
enum
dma_status
ret
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
last_complete
=
atchan
->
completed_cookie
;
last_complete
=
atchan
->
completed_cookie
;
last_used
=
chan
->
cookie
;
last_used
=
chan
->
cookie
;
...
@@ -1021,7 +1027,7 @@ atc_tx_status(struct dma_chan *chan,
...
@@ -1021,7 +1027,7 @@ atc_tx_status(struct dma_chan *chan,
ret
=
dma_async_is_complete
(
cookie
,
last_complete
,
last_used
);
ret
=
dma_async_is_complete
(
cookie
,
last_complete
,
last_used
);
}
}
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
if
(
ret
!=
DMA_SUCCESS
)
if
(
ret
!=
DMA_SUCCESS
)
dma_set_tx_state
(
txstate
,
last_complete
,
last_used
,
dma_set_tx_state
(
txstate
,
last_complete
,
last_used
,
...
@@ -1029,7 +1035,7 @@ atc_tx_status(struct dma_chan *chan,
...
@@ -1029,7 +1035,7 @@ atc_tx_status(struct dma_chan *chan,
else
else
dma_set_tx_state
(
txstate
,
last_complete
,
last_used
,
0
);
dma_set_tx_state
(
txstate
,
last_complete
,
last_used
,
0
);
if
(
test_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
))
if
(
atc_chan_is_paused
(
atchan
))
ret
=
DMA_PAUSED
;
ret
=
DMA_PAUSED
;
dev_vdbg
(
chan2dev
(
chan
),
"tx_status %d: cookie = %d (d%d, u%d)
\n
"
,
dev_vdbg
(
chan2dev
(
chan
),
"tx_status %d: cookie = %d (d%d, u%d)
\n
"
,
...
@@ -1046,18 +1052,19 @@ atc_tx_status(struct dma_chan *chan,
...
@@ -1046,18 +1052,19 @@ atc_tx_status(struct dma_chan *chan,
static
void
atc_issue_pending
(
struct
dma_chan
*
chan
)
static
void
atc_issue_pending
(
struct
dma_chan
*
chan
)
{
{
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
unsigned
long
flags
;
dev_vdbg
(
chan2dev
(
chan
),
"issue_pending
\n
"
);
dev_vdbg
(
chan2dev
(
chan
),
"issue_pending
\n
"
);
/* Not needed for cyclic transfers */
/* Not needed for cyclic transfers */
if
(
test_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
))
if
(
atc_chan_is_cyclic
(
atchan
))
return
;
return
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
if
(
!
atc_chan_is_enabled
(
atchan
))
{
if
(
!
atc_chan_is_enabled
(
atchan
))
{
atc_advance_work
(
atchan
);
atc_advance_work
(
atchan
);
}
}
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
}
/**
/**
...
@@ -1073,6 +1080,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
...
@@ -1073,6 +1080,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
struct
at_dma
*
atdma
=
to_at_dma
(
chan
->
device
);
struct
at_dma
*
atdma
=
to_at_dma
(
chan
->
device
);
struct
at_desc
*
desc
;
struct
at_desc
*
desc
;
struct
at_dma_slave
*
atslave
;
struct
at_dma_slave
*
atslave
;
unsigned
long
flags
;
int
i
;
int
i
;
u32
cfg
;
u32
cfg
;
LIST_HEAD
(
tmp_list
);
LIST_HEAD
(
tmp_list
);
...
@@ -1116,11 +1124,11 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
...
@@ -1116,11 +1124,11 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
list_add_tail
(
&
desc
->
desc_node
,
&
tmp_list
);
list_add_tail
(
&
desc
->
desc_node
,
&
tmp_list
);
}
}
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
atchan
->
descs_allocated
=
i
;
atchan
->
descs_allocated
=
i
;
list_splice
(
&
tmp_list
,
&
atchan
->
free_list
);
list_splice
(
&
tmp_list
,
&
atchan
->
free_list
);
atchan
->
completed_cookie
=
chan
->
cookie
=
1
;
atchan
->
completed_cookie
=
chan
->
cookie
=
1
;
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
/* channel parameters */
/* channel parameters */
channel_writel
(
atchan
,
CFG
,
cfg
);
channel_writel
(
atchan
,
CFG
,
cfg
);
...
@@ -1293,15 +1301,13 @@ static int __init at_dma_probe(struct platform_device *pdev)
...
@@ -1293,15 +1301,13 @@ static int __init at_dma_probe(struct platform_device *pdev)
if
(
dma_has_cap
(
DMA_MEMCPY
,
atdma
->
dma_common
.
cap_mask
))
if
(
dma_has_cap
(
DMA_MEMCPY
,
atdma
->
dma_common
.
cap_mask
))
atdma
->
dma_common
.
device_prep_dma_memcpy
=
atc_prep_dma_memcpy
;
atdma
->
dma_common
.
device_prep_dma_memcpy
=
atc_prep_dma_memcpy
;
if
(
dma_has_cap
(
DMA_SLAVE
,
atdma
->
dma_common
.
cap_mask
))
if
(
dma_has_cap
(
DMA_SLAVE
,
atdma
->
dma_common
.
cap_mask
))
{
atdma
->
dma_common
.
device_prep_slave_sg
=
atc_prep_slave_sg
;
atdma
->
dma_common
.
device_prep_slave_sg
=
atc_prep_slave_sg
;
/* controller can do slave DMA: can trigger cyclic transfers */
if
(
dma_has_cap
(
DMA_CYCLIC
,
atdma
->
dma_common
.
cap_mask
))
dma_cap_set
(
DMA_CYCLIC
,
atdma
->
dma_common
.
cap_mask
);
atdma
->
dma_common
.
device_prep_dma_cyclic
=
atc_prep_dma_cyclic
;
atdma
->
dma_common
.
device_prep_dma_cyclic
=
atc_prep_dma_cyclic
;
if
(
dma_has_cap
(
DMA_SLAVE
,
atdma
->
dma_common
.
cap_mask
)
||
dma_has_cap
(
DMA_CYCLIC
,
atdma
->
dma_common
.
cap_mask
))
atdma
->
dma_common
.
device_control
=
atc_control
;
atdma
->
dma_common
.
device_control
=
atc_control
;
}
dma_writel
(
atdma
,
EN
,
AT_DMA_ENABLE
);
dma_writel
(
atdma
,
EN
,
AT_DMA_ENABLE
);
...
@@ -1377,27 +1383,112 @@ static void at_dma_shutdown(struct platform_device *pdev)
...
@@ -1377,27 +1383,112 @@ static void at_dma_shutdown(struct platform_device *pdev)
clk_disable
(
atdma
->
clk
);
clk_disable
(
atdma
->
clk
);
}
}
static
int
at_dma_prepare
(
struct
device
*
dev
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
at_dma
*
atdma
=
platform_get_drvdata
(
pdev
);
struct
dma_chan
*
chan
,
*
_chan
;
list_for_each_entry_safe
(
chan
,
_chan
,
&
atdma
->
dma_common
.
channels
,
device_node
)
{
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
/* wait for transaction completion (except in cyclic case) */
if
(
atc_chan_is_enabled
(
atchan
)
&&
!
atc_chan_is_cyclic
(
atchan
))
return
-
EAGAIN
;
}
return
0
;
}
static
void
atc_suspend_cyclic
(
struct
at_dma_chan
*
atchan
)
{
struct
dma_chan
*
chan
=
&
atchan
->
chan_common
;
/* Channel should be paused by user
* do it anyway even if it is not done already */
if
(
!
atc_chan_is_paused
(
atchan
))
{
dev_warn
(
chan2dev
(
chan
),
"cyclic channel not paused, should be done by channel user
\n
"
);
atc_control
(
chan
,
DMA_PAUSE
,
0
);
}
/* now preserve additional data for cyclic operations */
/* next descriptor address in the cyclic list */
atchan
->
save_dscr
=
channel_readl
(
atchan
,
DSCR
);
vdbg_dump_regs
(
atchan
);
}
static
int
at_dma_suspend_noirq
(
struct
device
*
dev
)
static
int
at_dma_suspend_noirq
(
struct
device
*
dev
)
{
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
at_dma
*
atdma
=
platform_get_drvdata
(
pdev
);
struct
at_dma
*
atdma
=
platform_get_drvdata
(
pdev
);
struct
dma_chan
*
chan
,
*
_chan
;
at_dma_off
(
platform_get_drvdata
(
pdev
));
/* preserve data */
list_for_each_entry_safe
(
chan
,
_chan
,
&
atdma
->
dma_common
.
channels
,
device_node
)
{
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
if
(
atc_chan_is_cyclic
(
atchan
))
atc_suspend_cyclic
(
atchan
);
atchan
->
save_cfg
=
channel_readl
(
atchan
,
CFG
);
}
atdma
->
save_imr
=
dma_readl
(
atdma
,
EBCIMR
);
/* disable DMA controller */
at_dma_off
(
atdma
);
clk_disable
(
atdma
->
clk
);
clk_disable
(
atdma
->
clk
);
return
0
;
return
0
;
}
}
static
void
atc_resume_cyclic
(
struct
at_dma_chan
*
atchan
)
{
struct
at_dma
*
atdma
=
to_at_dma
(
atchan
->
chan_common
.
device
);
/* restore channel status for cyclic descriptors list:
* next descriptor in the cyclic list at the time of suspend */
channel_writel
(
atchan
,
SADDR
,
0
);
channel_writel
(
atchan
,
DADDR
,
0
);
channel_writel
(
atchan
,
CTRLA
,
0
);
channel_writel
(
atchan
,
CTRLB
,
0
);
channel_writel
(
atchan
,
DSCR
,
atchan
->
save_dscr
);
dma_writel
(
atdma
,
CHER
,
atchan
->
mask
);
/* channel pause status should be removed by channel user
* We cannot take the initiative to do it here */
vdbg_dump_regs
(
atchan
);
}
static
int
at_dma_resume_noirq
(
struct
device
*
dev
)
static
int
at_dma_resume_noirq
(
struct
device
*
dev
)
{
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
at_dma
*
atdma
=
platform_get_drvdata
(
pdev
);
struct
at_dma
*
atdma
=
platform_get_drvdata
(
pdev
);
struct
dma_chan
*
chan
,
*
_chan
;
/* bring back DMA controller */
clk_enable
(
atdma
->
clk
);
clk_enable
(
atdma
->
clk
);
dma_writel
(
atdma
,
EN
,
AT_DMA_ENABLE
);
dma_writel
(
atdma
,
EN
,
AT_DMA_ENABLE
);
/* clear any pending interrupt */
while
(
dma_readl
(
atdma
,
EBCISR
))
cpu_relax
();
/* restore saved data */
dma_writel
(
atdma
,
EBCIER
,
atdma
->
save_imr
);
list_for_each_entry_safe
(
chan
,
_chan
,
&
atdma
->
dma_common
.
channels
,
device_node
)
{
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
channel_writel
(
atchan
,
CFG
,
atchan
->
save_cfg
);
if
(
atc_chan_is_cyclic
(
atchan
))
atc_resume_cyclic
(
atchan
);
}
return
0
;
return
0
;
}
}
static
const
struct
dev_pm_ops
at_dma_dev_pm_ops
=
{
static
const
struct
dev_pm_ops
at_dma_dev_pm_ops
=
{
.
prepare
=
at_dma_prepare
,
.
suspend_noirq
=
at_dma_suspend_noirq
,
.
suspend_noirq
=
at_dma_suspend_noirq
,
.
resume_noirq
=
at_dma_resume_noirq
,
.
resume_noirq
=
at_dma_resume_noirq
,
};
};
...
...
drivers/dma/at_hdmac_regs.h
浏览文件 @
59ca37f7
...
@@ -204,6 +204,9 @@ enum atc_status {
...
@@ -204,6 +204,9 @@ enum atc_status {
* @status: transmit status information from irq/prep* functions
* @status: transmit status information from irq/prep* functions
* to tasklet (use atomic operations)
* to tasklet (use atomic operations)
* @tasklet: bottom half to finish transaction work
* @tasklet: bottom half to finish transaction work
* @save_cfg: configuration register that is saved on suspend/resume cycle
* @save_dscr: for cyclic operations, preserve next descriptor address in
* the cyclic list on suspend/resume cycle
* @lock: serializes enqueue/dequeue operations to descriptors lists
* @lock: serializes enqueue/dequeue operations to descriptors lists
* @completed_cookie: identifier for the most recently completed operation
* @completed_cookie: identifier for the most recently completed operation
* @active_list: list of descriptors dmaengine is being running on
* @active_list: list of descriptors dmaengine is being running on
...
@@ -218,6 +221,8 @@ struct at_dma_chan {
...
@@ -218,6 +221,8 @@ struct at_dma_chan {
u8
mask
;
u8
mask
;
unsigned
long
status
;
unsigned
long
status
;
struct
tasklet_struct
tasklet
;
struct
tasklet_struct
tasklet
;
u32
save_cfg
;
u32
save_dscr
;
spinlock_t
lock
;
spinlock_t
lock
;
...
@@ -248,6 +253,7 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
...
@@ -248,6 +253,7 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
* @chan_common: common dmaengine dma_device object members
* @chan_common: common dmaengine dma_device object members
* @ch_regs: memory mapped register base
* @ch_regs: memory mapped register base
* @clk: dma controller clock
* @clk: dma controller clock
* @save_imr: interrupt mask register that is saved on suspend/resume cycle
* @all_chan_mask: all channels availlable in a mask
* @all_chan_mask: all channels availlable in a mask
* @dma_desc_pool: base of DMA descriptor region (DMA address)
* @dma_desc_pool: base of DMA descriptor region (DMA address)
* @chan: channels table to store at_dma_chan structures
* @chan: channels table to store at_dma_chan structures
...
@@ -256,6 +262,7 @@ struct at_dma {
...
@@ -256,6 +262,7 @@ struct at_dma {
struct
dma_device
dma_common
;
struct
dma_device
dma_common
;
void
__iomem
*
regs
;
void
__iomem
*
regs
;
struct
clk
*
clk
;
struct
clk
*
clk
;
u32
save_imr
;
u8
all_chan_mask
;
u8
all_chan_mask
;
...
@@ -355,6 +362,23 @@ static inline int atc_chan_is_enabled(struct at_dma_chan *atchan)
...
@@ -355,6 +362,23 @@ static inline int atc_chan_is_enabled(struct at_dma_chan *atchan)
return
!!
(
dma_readl
(
atdma
,
CHSR
)
&
atchan
->
mask
);
return
!!
(
dma_readl
(
atdma
,
CHSR
)
&
atchan
->
mask
);
}
}
/**
* atc_chan_is_paused - test channel pause/resume status
* @atchan: channel we want to test status
*/
static
inline
int
atc_chan_is_paused
(
struct
at_dma_chan
*
atchan
)
{
return
test_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
);
}
/**
* atc_chan_is_cyclic - test if given channel has cyclic property set
* @atchan: channel we want to test status
*/
static
inline
int
atc_chan_is_cyclic
(
struct
at_dma_chan
*
atchan
)
{
return
test_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
);
}
/**
/**
* set_desc_eol - set end-of-link to descriptor so it will end transfer
* set_desc_eol - set end-of-link to descriptor so it will end transfer
...
...
drivers/dma/dmatest.c
浏览文件 @
59ca37f7
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/dmaengine.h>
#include <linux/freezer.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/module.h>
...
@@ -251,6 +252,7 @@ static int dmatest_func(void *data)
...
@@ -251,6 +252,7 @@ static int dmatest_func(void *data)
int
i
;
int
i
;
thread_name
=
current
->
comm
;
thread_name
=
current
->
comm
;
set_freezable_with_signal
();
ret
=
-
ENOMEM
;
ret
=
-
ENOMEM
;
...
@@ -305,7 +307,8 @@ static int dmatest_func(void *data)
...
@@ -305,7 +307,8 @@ static int dmatest_func(void *data)
dma_addr_t
dma_srcs
[
src_cnt
];
dma_addr_t
dma_srcs
[
src_cnt
];
dma_addr_t
dma_dsts
[
dst_cnt
];
dma_addr_t
dma_dsts
[
dst_cnt
];
struct
completion
cmp
;
struct
completion
cmp
;
unsigned
long
tmo
=
msecs_to_jiffies
(
timeout
);
unsigned
long
start
,
tmo
,
end
=
0
/* compiler... */
;
bool
reload
=
true
;
u8
align
=
0
;
u8
align
=
0
;
total_tests
++
;
total_tests
++
;
...
@@ -404,7 +407,17 @@ static int dmatest_func(void *data)
...
@@ -404,7 +407,17 @@ static int dmatest_func(void *data)
}
}
dma_async_issue_pending
(
chan
);
dma_async_issue_pending
(
chan
);
tmo
=
wait_for_completion_timeout
(
&
cmp
,
tmo
);
do
{
start
=
jiffies
;
if
(
reload
)
end
=
start
+
msecs_to_jiffies
(
timeout
);
else
if
(
end
<=
start
)
end
=
start
+
1
;
tmo
=
wait_for_completion_interruptible_timeout
(
&
cmp
,
end
-
start
);
reload
=
try_to_freeze
();
}
while
(
tmo
==
-
ERESTARTSYS
);
status
=
dma_async_is_tx_complete
(
chan
,
cookie
,
NULL
,
NULL
);
status
=
dma_async_is_tx_complete
(
chan
,
cookie
,
NULL
,
NULL
);
if
(
tmo
==
0
)
{
if
(
tmo
==
0
)
{
...
@@ -477,6 +490,8 @@ static int dmatest_func(void *data)
...
@@ -477,6 +490,8 @@ static int dmatest_func(void *data)
pr_notice
(
"%s: terminating after %u tests, %u failures (status %d)
\n
"
,
pr_notice
(
"%s: terminating after %u tests, %u failures (status %d)
\n
"
,
thread_name
,
total_tests
,
failed_tests
,
ret
);
thread_name
,
total_tests
,
failed_tests
,
ret
);
/* terminate all transfers on specified channels */
chan
->
device
->
device_control
(
chan
,
DMA_TERMINATE_ALL
,
0
);
if
(
iterations
>
0
)
if
(
iterations
>
0
)
while
(
!
kthread_should_stop
())
{
while
(
!
kthread_should_stop
())
{
DECLARE_WAIT_QUEUE_HEAD_ONSTACK
(
wait_dmatest_exit
);
DECLARE_WAIT_QUEUE_HEAD_ONSTACK
(
wait_dmatest_exit
);
...
@@ -499,6 +514,10 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
...
@@ -499,6 +514,10 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
list_del
(
&
thread
->
node
);
list_del
(
&
thread
->
node
);
kfree
(
thread
);
kfree
(
thread
);
}
}
/* terminate all transfers on specified channels */
dtc
->
chan
->
device
->
device_control
(
dtc
->
chan
,
DMA_TERMINATE_ALL
,
0
);
kfree
(
dtc
);
kfree
(
dtc
);
}
}
...
...
drivers/dma/imx-sdma.c
浏览文件 @
59ca37f7
...
@@ -318,6 +318,7 @@ struct sdma_engine {
...
@@ -318,6 +318,7 @@ struct sdma_engine {
dma_addr_t
context_phys
;
dma_addr_t
context_phys
;
struct
dma_device
dma_device
;
struct
dma_device
dma_device
;
struct
clk
*
clk
;
struct
clk
*
clk
;
struct
mutex
channel_0_lock
;
struct
sdma_script_start_addrs
*
script_addrs
;
struct
sdma_script_start_addrs
*
script_addrs
;
};
};
...
@@ -415,11 +416,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
...
@@ -415,11 +416,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
dma_addr_t
buf_phys
;
dma_addr_t
buf_phys
;
int
ret
;
int
ret
;
mutex_lock
(
&
sdma
->
channel_0_lock
);
buf_virt
=
dma_alloc_coherent
(
NULL
,
buf_virt
=
dma_alloc_coherent
(
NULL
,
size
,
size
,
&
buf_phys
,
GFP_KERNEL
);
&
buf_phys
,
GFP_KERNEL
);
if
(
!
buf_virt
)
if
(
!
buf_virt
)
{
return
-
ENOMEM
;
ret
=
-
ENOMEM
;
goto
err_out
;
}
bd0
->
mode
.
command
=
C0_SETPM
;
bd0
->
mode
.
command
=
C0_SETPM
;
bd0
->
mode
.
status
=
BD_DONE
|
BD_INTR
|
BD_WRAP
|
BD_EXTD
;
bd0
->
mode
.
status
=
BD_DONE
|
BD_INTR
|
BD_WRAP
|
BD_EXTD
;
...
@@ -433,6 +438,9 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
...
@@ -433,6 +438,9 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
dma_free_coherent
(
NULL
,
size
,
buf_virt
,
buf_phys
);
dma_free_coherent
(
NULL
,
size
,
buf_virt
,
buf_phys
);
err_out:
mutex_unlock
(
&
sdma
->
channel_0_lock
);
return
ret
;
return
ret
;
}
}
...
@@ -656,6 +664,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
...
@@ -656,6 +664,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
dev_dbg
(
sdma
->
dev
,
"event_mask0 = 0x%08x
\n
"
,
sdmac
->
event_mask0
);
dev_dbg
(
sdma
->
dev
,
"event_mask0 = 0x%08x
\n
"
,
sdmac
->
event_mask0
);
dev_dbg
(
sdma
->
dev
,
"event_mask1 = 0x%08x
\n
"
,
sdmac
->
event_mask1
);
dev_dbg
(
sdma
->
dev
,
"event_mask1 = 0x%08x
\n
"
,
sdmac
->
event_mask1
);
mutex_lock
(
&
sdma
->
channel_0_lock
);
memset
(
context
,
0
,
sizeof
(
*
context
));
memset
(
context
,
0
,
sizeof
(
*
context
));
context
->
channel_state
.
pc
=
load_address
;
context
->
channel_state
.
pc
=
load_address
;
...
@@ -676,6 +686,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
...
@@ -676,6 +686,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
ret
=
sdma_run_channel
(
&
sdma
->
channel
[
0
]);
ret
=
sdma_run_channel
(
&
sdma
->
channel
[
0
]);
mutex_unlock
(
&
sdma
->
channel_0_lock
);
return
ret
;
return
ret
;
}
}
...
@@ -1131,18 +1143,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
...
@@ -1131,18 +1143,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
saddr_arr
[
i
]
=
addr_arr
[
i
];
saddr_arr
[
i
]
=
addr_arr
[
i
];
}
}
static
int
__init
sdma_get_firmware
(
struct
sdma_engine
*
sdma
,
static
void
sdma_load_firmware
(
const
struct
firmware
*
fw
,
void
*
context
)
const
char
*
fw_name
)
{
{
const
struct
firmware
*
fw
;
struct
sdma_engine
*
sdma
=
context
;
const
struct
sdma_firmware_header
*
header
;
const
struct
sdma_firmware_header
*
header
;
int
ret
;
const
struct
sdma_script_start_addrs
*
addr
;
const
struct
sdma_script_start_addrs
*
addr
;
unsigned
short
*
ram_code
;
unsigned
short
*
ram_code
;
ret
=
request_firmware
(
&
fw
,
fw_name
,
sdma
->
dev
);
if
(
!
fw
)
{
if
(
ret
)
dev_err
(
sdma
->
dev
,
"firmware not found
\n
"
);
return
ret
;
return
;
}
if
(
fw
->
size
<
sizeof
(
*
header
))
if
(
fw
->
size
<
sizeof
(
*
header
))
goto
err_firmware
;
goto
err_firmware
;
...
@@ -1172,6 +1183,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
...
@@ -1172,6 +1183,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
err_firmware:
err_firmware:
release_firmware
(
fw
);
release_firmware
(
fw
);
}
static
int
__init
sdma_get_firmware
(
struct
sdma_engine
*
sdma
,
const
char
*
fw_name
)
{
int
ret
;
ret
=
request_firmware_nowait
(
THIS_MODULE
,
FW_ACTION_HOTPLUG
,
fw_name
,
sdma
->
dev
,
GFP_KERNEL
,
sdma
,
sdma_load_firmware
);
return
ret
;
return
ret
;
}
}
...
@@ -1269,11 +1290,14 @@ static int __init sdma_probe(struct platform_device *pdev)
...
@@ -1269,11 +1290,14 @@ static int __init sdma_probe(struct platform_device *pdev)
struct
sdma_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
sdma_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
int
i
;
int
i
;
struct
sdma_engine
*
sdma
;
struct
sdma_engine
*
sdma
;
s32
*
saddr_arr
;
sdma
=
kzalloc
(
sizeof
(
*
sdma
),
GFP_KERNEL
);
sdma
=
kzalloc
(
sizeof
(
*
sdma
),
GFP_KERNEL
);
if
(
!
sdma
)
if
(
!
sdma
)
return
-
ENOMEM
;
return
-
ENOMEM
;
mutex_init
(
&
sdma
->
channel_0_lock
);
sdma
->
dev
=
&
pdev
->
dev
;
sdma
->
dev
=
&
pdev
->
dev
;
iores
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
iores
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
...
@@ -1310,6 +1334,11 @@ static int __init sdma_probe(struct platform_device *pdev)
...
@@ -1310,6 +1334,11 @@ static int __init sdma_probe(struct platform_device *pdev)
goto
err_alloc
;
goto
err_alloc
;
}
}
/* initially no scripts available */
saddr_arr
=
(
s32
*
)
sdma
->
script_addrs
;
for
(
i
=
0
;
i
<
SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1
;
i
++
)
saddr_arr
[
i
]
=
-
EINVAL
;
if
(
of_id
)
if
(
of_id
)
pdev
->
id_entry
=
of_id
->
data
;
pdev
->
id_entry
=
of_id
->
data
;
sdma
->
devtype
=
pdev
->
id_entry
->
driver_data
;
sdma
->
devtype
=
pdev
->
id_entry
->
driver_data
;
...
...
drivers/dma/mxs-dma.c
浏览文件 @
59ca37f7
...
@@ -130,6 +130,23 @@ struct mxs_dma_engine {
...
@@ -130,6 +130,23 @@ struct mxs_dma_engine {
struct
mxs_dma_chan
mxs_chans
[
MXS_DMA_CHANNELS
];
struct
mxs_dma_chan
mxs_chans
[
MXS_DMA_CHANNELS
];
};
};
static
inline
void
mxs_dma_clkgate
(
struct
mxs_dma_chan
*
mxs_chan
,
int
enable
)
{
struct
mxs_dma_engine
*
mxs_dma
=
mxs_chan
->
mxs_dma
;
int
chan_id
=
mxs_chan
->
chan
.
chan_id
;
int
set_clr
=
enable
?
MXS_CLR_ADDR
:
MXS_SET_ADDR
;
/* enable apbh channel clock */
if
(
dma_is_apbh
())
{
if
(
apbh_is_old
())
writel
(
1
<<
(
chan_id
+
BP_APBH_CTRL0_CLKGATE_CHANNEL
),
mxs_dma
->
base
+
HW_APBHX_CTRL0
+
set_clr
);
else
writel
(
1
<<
chan_id
,
mxs_dma
->
base
+
HW_APBHX_CTRL0
+
set_clr
);
}
}
static
void
mxs_dma_reset_chan
(
struct
mxs_dma_chan
*
mxs_chan
)
static
void
mxs_dma_reset_chan
(
struct
mxs_dma_chan
*
mxs_chan
)
{
{
struct
mxs_dma_engine
*
mxs_dma
=
mxs_chan
->
mxs_dma
;
struct
mxs_dma_engine
*
mxs_dma
=
mxs_chan
->
mxs_dma
;
...
@@ -148,38 +165,21 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
...
@@ -148,38 +165,21 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
struct
mxs_dma_engine
*
mxs_dma
=
mxs_chan
->
mxs_dma
;
struct
mxs_dma_engine
*
mxs_dma
=
mxs_chan
->
mxs_dma
;
int
chan_id
=
mxs_chan
->
chan
.
chan_id
;
int
chan_id
=
mxs_chan
->
chan
.
chan_id
;
/* clkgate needs to be enabled before writing other registers */
mxs_dma_clkgate
(
mxs_chan
,
1
);
/* set cmd_addr up */
/* set cmd_addr up */
writel
(
mxs_chan
->
ccw_phys
,
writel
(
mxs_chan
->
ccw_phys
,
mxs_dma
->
base
+
HW_APBHX_CHn_NXTCMDAR
(
chan_id
));
mxs_dma
->
base
+
HW_APBHX_CHn_NXTCMDAR
(
chan_id
));
/* enable apbh channel clock */
if
(
dma_is_apbh
())
{
if
(
apbh_is_old
())
writel
(
1
<<
(
chan_id
+
BP_APBH_CTRL0_CLKGATE_CHANNEL
),
mxs_dma
->
base
+
HW_APBHX_CTRL0
+
MXS_CLR_ADDR
);
else
writel
(
1
<<
chan_id
,
mxs_dma
->
base
+
HW_APBHX_CTRL0
+
MXS_CLR_ADDR
);
}
/* write 1 to SEMA to kick off the channel */
/* write 1 to SEMA to kick off the channel */
writel
(
1
,
mxs_dma
->
base
+
HW_APBHX_CHn_SEMA
(
chan_id
));
writel
(
1
,
mxs_dma
->
base
+
HW_APBHX_CHn_SEMA
(
chan_id
));
}
}
static
void
mxs_dma_disable_chan
(
struct
mxs_dma_chan
*
mxs_chan
)
static
void
mxs_dma_disable_chan
(
struct
mxs_dma_chan
*
mxs_chan
)
{
{
struct
mxs_dma_engine
*
mxs_dma
=
mxs_chan
->
mxs_dma
;
int
chan_id
=
mxs_chan
->
chan
.
chan_id
;
/* disable apbh channel clock */
/* disable apbh channel clock */
if
(
dma_is_apbh
())
{
mxs_dma_clkgate
(
mxs_chan
,
0
);
if
(
apbh_is_old
())
writel
(
1
<<
(
chan_id
+
BP_APBH_CTRL0_CLKGATE_CHANNEL
),
mxs_dma
->
base
+
HW_APBHX_CTRL0
+
MXS_SET_ADDR
);
else
writel
(
1
<<
chan_id
,
mxs_dma
->
base
+
HW_APBHX_CTRL0
+
MXS_SET_ADDR
);
}
mxs_chan
->
status
=
DMA_SUCCESS
;
mxs_chan
->
status
=
DMA_SUCCESS
;
}
}
...
@@ -338,7 +338,10 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
...
@@ -338,7 +338,10 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
if
(
ret
)
if
(
ret
)
goto
err_clk
;
goto
err_clk
;
/* clkgate needs to be enabled for reset to finish */
mxs_dma_clkgate
(
mxs_chan
,
1
);
mxs_dma_reset_chan
(
mxs_chan
);
mxs_dma_reset_chan
(
mxs_chan
);
mxs_dma_clkgate
(
mxs_chan
,
0
);
dma_async_tx_descriptor_init
(
&
mxs_chan
->
desc
,
chan
);
dma_async_tx_descriptor_init
(
&
mxs_chan
->
desc
,
chan
);
mxs_chan
->
desc
.
tx_submit
=
mxs_dma_tx_submit
;
mxs_chan
->
desc
.
tx_submit
=
mxs_dma_tx_submit
;
...
...
drivers/dma/pl330.c
浏览文件 @
59ca37f7
此差异已折叠。
点击以展开。
drivers/mmc/host/s3cmci.c
浏览文件 @
59ca37f7
...
@@ -913,9 +913,9 @@ static void finalize_request(struct s3cmci_host *host)
...
@@ -913,9 +913,9 @@ static void finalize_request(struct s3cmci_host *host)
}
}
static
void
s3cmci_dma_setup
(
struct
s3cmci_host
*
host
,
static
void
s3cmci_dma_setup
(
struct
s3cmci_host
*
host
,
enum
s3c2410_dmasrc
source
)
enum
dma_data_direction
source
)
{
{
static
enum
s3c2410_dmasrc
last_source
=
-
1
;
static
enum
dma_data_direction
last_source
=
-
1
;
static
int
setup_ok
;
static
int
setup_ok
;
if
(
last_source
==
source
)
if
(
last_source
==
source
)
...
@@ -1087,7 +1087,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
...
@@ -1087,7 +1087,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
BUG_ON
((
data
->
flags
&
BOTH_DIR
)
==
BOTH_DIR
);
BUG_ON
((
data
->
flags
&
BOTH_DIR
)
==
BOTH_DIR
);
s3cmci_dma_setup
(
host
,
rw
?
S3C2410_DMASRC_MEM
:
S3C2410_DMASRC_HW
);
s3cmci_dma_setup
(
host
,
rw
?
DMA_TO_DEVICE
:
DMA_FROM_DEVICE
);
s3c2410_dma_ctrl
(
host
->
dma
,
S3C2410_DMAOP_FLUSH
);
s3c2410_dma_ctrl
(
host
->
dma
,
S3C2410_DMAOP_FLUSH
);
dma_len
=
dma_map_sg
(
mmc_dev
(
host
->
mmc
),
data
->
sg
,
data
->
sg_len
,
dma_len
=
dma_map_sg
(
mmc_dev
(
host
->
mmc
),
data
->
sg
,
data
->
sg_len
,
...
...
drivers/spi/spi-s3c64xx.c
浏览文件 @
59ca37f7
此差异已折叠。
点击以展开。
include/linux/amba/pl08x.h
浏览文件 @
59ca37f7
...
@@ -47,6 +47,9 @@ enum {
...
@@ -47,6 +47,9 @@ enum {
* @muxval: a number usually used to poke into some mux regiser to
* @muxval: a number usually used to poke into some mux regiser to
* mux in the signal to this channel
* mux in the signal to this channel
* @cctl_opt: default options for the channel control register
* @cctl_opt: default options for the channel control register
* @device_fc: Flow Controller Settings for ccfg register. Only valid for slave
* channels. Fill with 'true' if peripheral should be flow controller. Direction
* will be selected at Runtime.
* @addr: source/target address in physical memory for this DMA channel,
* @addr: source/target address in physical memory for this DMA channel,
* can be the address of a FIFO register for burst requests for example.
* can be the address of a FIFO register for burst requests for example.
* This can be left undefined if the PrimeCell API is used for configuring
* This can be left undefined if the PrimeCell API is used for configuring
...
@@ -65,6 +68,7 @@ struct pl08x_channel_data {
...
@@ -65,6 +68,7 @@ struct pl08x_channel_data {
int
max_signal
;
int
max_signal
;
u32
muxval
;
u32
muxval
;
u32
cctl
;
u32
cctl
;
bool
device_fc
;
dma_addr_t
addr
;
dma_addr_t
addr
;
bool
circular_buffer
;
bool
circular_buffer
;
bool
single
;
bool
single
;
...
@@ -77,13 +81,11 @@ struct pl08x_channel_data {
...
@@ -77,13 +81,11 @@ struct pl08x_channel_data {
* @addr: current address
* @addr: current address
* @maxwidth: the maximum width of a transfer on this bus
* @maxwidth: the maximum width of a transfer on this bus
* @buswidth: the width of this bus in bytes: 1, 2 or 4
* @buswidth: the width of this bus in bytes: 1, 2 or 4
* @fill_bytes: bytes required to fill to the next bus memory boundary
*/
*/
struct
pl08x_bus_data
{
struct
pl08x_bus_data
{
dma_addr_t
addr
;
dma_addr_t
addr
;
u8
maxwidth
;
u8
maxwidth
;
u8
buswidth
;
u8
buswidth
;
size_t
fill_bytes
;
};
};
/**
/**
...
@@ -105,8 +107,16 @@ struct pl08x_phy_chan {
...
@@ -105,8 +107,16 @@ struct pl08x_phy_chan {
/**
/**
* struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
* struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
* @tx: async tx descriptor
* @node: node for txd list for channels
* @src_addr: src address of txd
* @dst_addr: dst address of txd
* @len: transfer len in bytes
* @direction: direction of transfer
* @llis_bus: DMA memory address (physical) start for the LLIs
* @llis_bus: DMA memory address (physical) start for the LLIs
* @llis_va: virtual memory address start for the LLIs
* @llis_va: virtual memory address start for the LLIs
* @cctl: control reg values for current txd
* @ccfg: config reg values for current txd
*/
*/
struct
pl08x_txd
{
struct
pl08x_txd
{
struct
dma_async_tx_descriptor
tx
;
struct
dma_async_tx_descriptor
tx
;
...
...
include/linux/amba/pl330.h
浏览文件 @
59ca37f7
...
@@ -19,12 +19,8 @@ struct dma_pl330_peri {
...
@@ -19,12 +19,8 @@ struct dma_pl330_peri {
* Peri_Req i/f of the DMAC that is
* Peri_Req i/f of the DMAC that is
* peripheral could be reached from.
* peripheral could be reached from.
*/
*/
u8
peri_id
;
/*
{0, 31}
*/
u8
peri_id
;
/*
specific dma id
*/
enum
pl330_reqtype
rqtype
;
enum
pl330_reqtype
rqtype
;
/* For M->D and D->M Channels */
int
burst_sz
;
/* in power of 2 */
dma_addr_t
fifo_addr
;
};
};
struct
dma_pl330_platdata
{
struct
dma_pl330_platdata
{
...
...
include/linux/dmaengine.h
浏览文件 @
59ca37f7
...
@@ -24,8 +24,7 @@
...
@@ -24,8 +24,7 @@
#include <linux/device.h>
#include <linux/device.h>
#include <linux/uio.h>
#include <linux/uio.h>
#include <linux/dma-direction.h>
#include <linux/dma-direction.h>
#include <linux/scatterlist.h>
struct
scatterlist
;
/**
/**
* typedef dma_cookie_t - an opaque DMA cookie
* typedef dma_cookie_t - an opaque DMA cookie
...
@@ -519,6 +518,16 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
...
@@ -519,6 +518,16 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
(
unsigned
long
)
config
);
(
unsigned
long
)
config
);
}
}
static
inline
struct
dma_async_tx_descriptor
*
dmaengine_prep_slave_single
(
struct
dma_chan
*
chan
,
void
*
buf
,
size_t
len
,
enum
dma_data_direction
dir
,
unsigned
long
flags
)
{
struct
scatterlist
sg
;
sg_init_one
(
&
sg
,
buf
,
len
);
return
chan
->
device
->
device_prep_slave_sg
(
chan
,
&
sg
,
1
,
dir
,
flags
);
}
static
inline
int
dmaengine_terminate_all
(
struct
dma_chan
*
chan
)
static
inline
int
dmaengine_terminate_all
(
struct
dma_chan
*
chan
)
{
{
return
dmaengine_device_control
(
chan
,
DMA_TERMINATE_ALL
,
0
);
return
dmaengine_device_control
(
chan
,
DMA_TERMINATE_ALL
,
0
);
...
...
sound/soc/samsung/ac97.c
浏览文件 @
59ca37f7
此差异已折叠。
点击以展开。
sound/soc/samsung/dma.c
浏览文件 @
59ca37f7
此差异已折叠。
点击以展开。
sound/soc/samsung/dma.h
浏览文件 @
59ca37f7
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Free Software Foundation; either version 2 of the License, or (at your
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
* option) any later version.
*
*
* ALSA PCM interface for the Samsung S
3C24xx CPU
* ALSA PCM interface for the Samsung S
oC
*/
*/
#ifndef _S3C_AUDIO_H
#ifndef _S3C_AUDIO_H
...
@@ -17,6 +17,8 @@ struct s3c_dma_params {
...
@@ -17,6 +17,8 @@ struct s3c_dma_params {
int
channel
;
/* Channel ID */
int
channel
;
/* Channel ID */
dma_addr_t
dma_addr
;
dma_addr_t
dma_addr
;
int
dma_size
;
/* Size of the DMA transfer */
int
dma_size
;
/* Size of the DMA transfer */
unsigned
ch
;
struct
samsung_dma_ops
*
ops
;
};
};
#endif
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录