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 @@
* OneNAND features.
*/
#ifndef ASM_PL080_H
#define ASM_PL080_H
#define PL080_INT_STATUS (0x00)
#define PL080_TC_STATUS (0x04)
#define PL080_TC_CLEAR (0x08)
...
...
@@ -138,3 +141,4 @@ struct pl080s_lli {
u32
control1
;
};
#endif
/* ASM_PL080_H */
arch/arm/mach-exynos4/Kconfig
浏览文件 @
59ca37f7
...
...
@@ -11,7 +11,7 @@ if ARCH_EXYNOS4
config CPU_EXYNOS4210
bool
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
help
Enable EXYNOS4210 CPU support
...
...
arch/arm/mach-exynos4/clock.c
浏览文件 @
59ca37f7
...
...
@@ -43,6 +43,11 @@ static struct clk clk_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
)
{
return
s5p_gatectrl
(
S5P_CLKSRC_MASK_TOP
,
clk
,
enable
);
...
...
@@ -454,13 +459,13 @@ static struct clk init_clocks_off[] = {
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
ctrlbit
=
(
1
<<
10
),
},
{
.
name
=
"
p
dma"
,
.
devname
=
"
s3c
-pl330.0"
,
.
name
=
"dma"
,
.
devname
=
"
dma
-pl330.0"
,
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
ctrlbit
=
(
1
<<
0
),
},
{
.
name
=
"
p
dma"
,
.
devname
=
"
s3c
-pl330.1"
,
.
name
=
"dma"
,
.
devname
=
"
dma
-pl330.1"
,
.
enable
=
exynos4_clk_ip_fsys_ctrl
,
.
ctrlbit
=
(
1
<<
1
),
},
{
...
...
@@ -1208,5 +1213,7 @@ void __init exynos4_register_clocks(void)
s3c_register_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
();
}
arch/arm/mach-exynos4/dma.c
浏览文件 @
59ca37f7
...
...
@@ -21,151 +21,229 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/platform_device.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/irqs.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <plat/s3c-pl330-pdata.h>
#include <mach/dma.h>
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
resource
exynos4_pdma0_resource
[]
=
{
[
0
]
=
{
.
start
=
EXYNOS4_PA_PDMA0
,
.
end
=
EXYNOS4_PA_PDMA0
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_PDMA0
,
.
end
=
IRQ_PDMA0
,
.
flags
=
IORESOURCE_IRQ
,
struct
dma_pl330_peri
pdma0_peri
[
28
]
=
{
{
.
peri_id
=
(
u8
)
DMACH_PCM0_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM0_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
peri_id
=
(
u8
)
DMACH_PCM2_RX
,
.
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
=
{
.
peri
=
{
[
0
]
=
DMACH_PCM0_RX
,
[
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
,
},
struct
dma_pl330_platdata
exynos4_pdma0_pdata
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma0_peri
),
.
peri
=
pdma0_peri
,
};
static
struct
platform_device
exynos4_device_pdma0
=
{
.
name
=
"s3c-pl330"
,
.
id
=
0
,
.
num_resources
=
ARRAY_SIZE
(
exynos4_pdma0_resource
),
.
resource
=
exynos4_pdma0_resource
,
struct
amba_device
exynos4_device_pdma0
=
{
.
dev
=
{
.
init_name
=
"dma-pl330.0"
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
exynos4_pdma0_pdata
,
},
};
static
struct
resource
exynos4_pdma1_resource
[]
=
{
[
0
]
=
{
.
start
=
EXYNOS4_PA_PDMA1
,
.
end
=
EXYNOS4_PA_PDMA1
+
SZ_4K
,
.
res
=
{
.
start
=
EXYNOS4_PA_PDMA0
,
.
end
=
EXYNOS4_PA_PDMA0
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_PDMA1
,
.
end
=
IRQ_PDMA1
,
.
flags
=
IORESOURCE_IRQ
,
},
.
irq
=
{
IRQ_PDMA0
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
static
struct
s3c_pl330_platdata
exynos4_pdma1_pdata
=
{
.
peri
=
{
[
0
]
=
DMACH_PCM0_RX
,
[
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
,
struct
dma_pl330_peri
pdma1_peri
[
25
]
=
{
{
.
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_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
platform_device
exynos4_device_pdma1
=
{
.
name
=
"s3c-pl330"
,
.
id
=
1
,
.
num_resources
=
ARRAY_SIZE
(
exynos4_pdma1_resource
),
.
resource
=
exynos4_pdma1_resource
,
struct
dma_pl330_platdata
exynos4_pdma1_pdata
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma1_peri
),
.
peri
=
pdma1_peri
,
};
struct
amba_device
exynos4_device_pdma1
=
{
.
dev
=
{
.
init_name
=
"dma-pl330.1"
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
exynos4_pdma1_pdata
,
},
};
static
struct
platform_device
*
exynos4_dmacs
[]
__initdata
=
{
&
exynos4_device_pdma0
,
&
exynos4_device_pdma1
,
.
res
=
{
.
start
=
EXYNOS4_PA_PDMA1
,
.
end
=
EXYNOS4_PA_PDMA1
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
.
irq
=
{
IRQ_PDMA1
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
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
;
}
...
...
arch/arm/mach-exynos4/include/mach/dma.h
浏览文件 @
59ca37f7
...
...
@@ -20,7 +20,7 @@
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common
S3C
DMA API driver for PL330 */
#include <plat/
s3c-
dma-pl330.h>
/* This platform uses the common DMA API driver for PL330 */
#include <plat/dma-pl330.h>
#endif
/* __MACH_DMA_H */
arch/arm/mach-s3c2410/include/mach/dma.h
浏览文件 @
59ca37f7
...
...
@@ -13,7 +13,6 @@
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H __FILE__
#include <plat/dma.h>
#include <linux/sysdev.h>
#define MAX_DMA_TRANSFER_SIZE 0x100000
/* Data Unit is half word */
...
...
@@ -51,6 +50,18 @@ enum dma_ch {
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 */
/* we have 4 dma channels */
...
...
@@ -163,7 +174,7 @@ struct s3c2410_dma_chan {
struct
s3c2410_dma_client
*
client
;
/* channel configuration */
enum
s3c2410_dmasrc
source
;
enum
dma_data_direction
source
;
enum
dma_ch
req_ch
;
unsigned
long
dev_addr
;
unsigned
long
load_timeout
;
...
...
@@ -196,9 +207,4 @@ struct s3c2410_dma_chan {
typedef
unsigned
long
dma_device_t
;
static
inline
bool
s3c_dma_has_circular
(
void
)
{
return
false
;
}
#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[] = {
static
void
s3c2412_dma_direction
(
struct
s3c2410_dma_chan
*
chan
,
struct
s3c24xx_dma_map
*
map
,
enum
s3c2410_dmasrc
dir
)
enum
dma_data_direction
dir
)
{
unsigned
long
chsel
;
if
(
dir
==
S3C2410_DMASRC_HW
)
if
(
dir
==
DMA_FROM_DEVICE
)
chsel
=
map
->
channels_rx
[
0
];
else
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,
u32
control0
,
control1
;
switch
(
chan
->
source
)
{
case
S3C2410_DMASRC_HW
:
case
DMA_FROM_DEVICE
:
src
=
chan
->
dev_addr
;
dst
=
data
;
control0
=
PL080_CONTROL_SRC_AHB2
;
control0
|=
PL080_CONTROL_DST_INCR
;
break
;
case
S3C2410_DMASRC_MEM
:
case
DMA_TO_DEVICE
:
src
=
data
;
dst
=
chan
->
dev_addr
;
control0
=
PL080_CONTROL_DST_AHB2
;
...
...
@@ -416,7 +416,7 @@ EXPORT_SYMBOL(s3c2410_dma_enqueue);
int
s3c2410_dma_devconfig
(
enum
dma_ch
channel
,
enum
s3c2410_dmasrc
source
,
enum
dma_data_direction
source
,
unsigned
long
devaddr
)
{
struct
s3c2410_dma_chan
*
chan
=
s3c_dma_lookup_channel
(
channel
);
...
...
@@ -437,11 +437,11 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
pr_debug
(
"%s: peripheral %d
\n
"
,
__func__
,
peripheral
);
switch
(
source
)
{
case
S3C2410_DMASRC_HW
:
case
DMA_FROM_DEVICE
:
config
=
2
<<
PL080_CONFIG_FLOW_CONTROL_SHIFT
;
config
|=
peripheral
<<
PL080_CONFIG_SRC_SEL_SHIFT
;
break
;
case
S3C2410_DMASRC_MEM
:
case
DMA_TO_DEVICE
:
config
=
1
<<
PL080_CONFIG_FLOW_CONTROL_SHIFT
;
config
|=
peripheral
<<
PL080_CONFIG_DST_SEL_SHIFT
;
break
;
...
...
arch/arm/mach-s3c64xx/include/mach/dma.h
浏览文件 @
59ca37f7
...
...
@@ -58,11 +58,15 @@ enum dma_ch {
DMACH_MAX
/* the end */
};
static
__inline__
bool
s3c
_dma_has_circular
(
void
)
static
inline
bool
samsung
_dma_has_circular
(
void
)
{
return
true
;
}
static
inline
bool
samsung_dma_is_dmadev
(
void
)
{
return
false
;
}
#define S3C2410_DMAF_CIRCULAR (1 << 0)
#include <plat/dma.h>
...
...
@@ -95,7 +99,7 @@ struct s3c2410_dma_chan {
unsigned
char
peripheral
;
unsigned
int
flags
;
enum
s3c2410_dmasrc
source
;
enum
dma_data_direction
source
;
dma_addr_t
dev_addr
;
...
...
arch/arm/mach-s5p64x0/Kconfig
浏览文件 @
59ca37f7
...
...
@@ -9,14 +9,14 @@ if ARCH_S5P64X0
config CPU_S5P6440
bool
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
select S5P_HRT
help
Enable S5P6440 CPU support
config CPU_S5P6450
bool
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
select S5P_HRT
help
Enable S5P6450 CPU support
...
...
arch/arm/mach-s5p64x0/clock-s5p6440.c
浏览文件 @
59ca37f7
...
...
@@ -146,7 +146,8 @@ static struct clk init_clocks_off[] = {
.
enable
=
s5p64x0_hclk0_ctrl
,
.
ctrlbit
=
(
1
<<
8
),
},
{
.
name
=
"pdma"
,
.
name
=
"dma"
,
.
devname
=
"dma-pl330"
,
.
parent
=
&
clk_hclk_low
.
clk
,
.
enable
=
s5p64x0_hclk0_ctrl
,
.
ctrlbit
=
(
1
<<
12
),
...
...
@@ -499,6 +500,11 @@ static struct clksrc_clk *sysclks[] = {
&
clk_pclk_low
,
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
void
__init_or_cpufreq
s5p6440_setup_clocks
(
void
)
{
struct
clk
*
xtal_clk
;
...
...
@@ -581,5 +587,7 @@ void __init s5p6440_register_clocks(void)
s3c_register_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
();
}
arch/arm/mach-s5p64x0/clock-s5p6450.c
浏览文件 @
59ca37f7
...
...
@@ -179,7 +179,8 @@ static struct clk init_clocks_off[] = {
.
enable
=
s5p64x0_hclk0_ctrl
,
.
ctrlbit
=
(
1
<<
3
),
},
{
.
name
=
"pdma"
,
.
name
=
"dma"
,
.
devname
=
"dma-pl330"
,
.
parent
=
&
clk_hclk_low
.
clk
,
.
enable
=
s5p64x0_hclk0_ctrl
,
.
ctrlbit
=
(
1
<<
12
),
...
...
@@ -553,6 +554,11 @@ static struct clksrc_clk *sysclks[] = {
&
clk_sclk_audio0
,
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
void
__init_or_cpufreq
s5p6450_setup_clocks
(
void
)
{
struct
clk
*
xtal_clk
;
...
...
@@ -632,5 +638,7 @@ void __init s5p6450_register_clocks(void)
s3c_register_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
();
}
arch/arm/mach-s5p64x0/dma.c
浏览文件 @
59ca37f7
...
...
@@ -21,128 +21,219 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/platform_device.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/irqs.h>
#include <mach/regs-clock.h>
#include <mach/dma.h>
#include <plat/devs.h>
#include <plat/
s3c-pl330-pdata
.h>
#include <plat/
irqs
.h>
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
resource
s5p64x0_pdma_resource
[]
=
{
[
0
]
=
{
.
start
=
S5P64X0_PA_PDMA
,
.
end
=
S5P64X0_PA_PDMA
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_DMA0
,
.
end
=
IRQ_DMA0
,
.
flags
=
IORESOURCE_IRQ
,
struct
dma_pl330_peri
s5p6440_pdma_peri
[
22
]
=
{
{
.
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_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
=
{
.
peri
=
{
[
0
]
=
DMACH_UART0_RX
,
[
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
,
},
struct
dma_pl330_platdata
s5p6440_pdma_pdata
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
s5p6440_pdma_peri
),
.
peri
=
s5p6440_pdma_peri
,
};
static
struct
s3c_pl330_platdata
s5p6450_pdma_pdata
=
{
.
peri
=
{
[
0
]
=
DMACH_UART0_RX
,
[
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_UART4_RX
,
[
9
]
=
DMACH_UART4_TX
,
[
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_PCM1_TX
,
[
17
]
=
DMACH_PCM1_RX
,
[
18
]
=
DMACH_PCM2_TX
,
[
19
]
=
DMACH_PCM2_RX
,
[
20
]
=
DMACH_SPI1_TX
,
[
21
]
=
DMACH_SPI1_RX
,
[
22
]
=
DMACH_USI_TX
,
[
23
]
=
DMACH_USI_RX
,
[
24
]
=
DMACH_MAX
,
[
25
]
=
DMACH_I2S1_TX
,
[
26
]
=
DMACH_I2S1_RX
,
[
27
]
=
DMACH_I2S2_TX
,
[
28
]
=
DMACH_I2S2_RX
,
[
29
]
=
DMACH_PWM
,
[
30
]
=
DMACH_UART5_RX
,
[
31
]
=
DMACH_UART5_TX
,
struct
dma_pl330_peri
s5p6450_pdma_peri
[
32
]
=
{
{
.
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_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
=
(
u8
)
DMACH_UART4_RX
,
.
rqtype
=
DEVTOMEM
,
},
{
.
peri_id
=
(
u8
)
DMACH_UART4_TX
,
.
rqtype
=
MEMTODEV
,
},
{
.
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_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
=
{
.
name
=
"s3c-pl330"
,
.
id
=
-
1
,
.
num_resources
=
ARRAY_SIZE
(
s5p64x0_pdma_resource
),
.
resource
=
s5p64x0_pdma_resource
,
struct
dma_pl330_platdata
s5p6450_pdma_pdata
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
s5p6450_pdma_peri
),
.
peri
=
s5p6450_pdma_peri
,
};
struct
amba_device
s5p64x0_device_pdma
=
{
.
dev
=
{
.
init_name
=
"dma-pl330"
,
.
dma_mask
=
&
dma_dmamask
,
.
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
)
{
unsigned
int
id
;
id
=
__raw_readl
(
S5P64X0_SYS_ID
)
&
0xFF000
;
unsigned
int
id
=
__raw_readl
(
S5P64X0_SYS_ID
)
&
0xFF000
;
if
(
id
==
0x50000
)
s5p64x0_device_pdma
.
dev
.
platform_data
=
&
s5p6450_pdma_pdata
;
else
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
;
}
...
...
arch/arm/mach-s5p64x0/include/mach/dma.h
浏览文件 @
59ca37f7
...
...
@@ -20,7 +20,7 @@
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common
S3C
DMA API driver for PL330 */
#include <plat/
s3c-
dma-pl330.h>
/* This platform uses the common
common
DMA API driver for PL330 */
#include <plat/dma-pl330.h>
#endif
/* __MACH_DMA_H */
arch/arm/mach-s5pc100/Kconfig
浏览文件 @
59ca37f7
...
...
@@ -10,7 +10,7 @@ if ARCH_S5PC100
config CPU_S5PC100
bool
select S5P_EXT_INT
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
help
Enable S5PC100 CPU support
...
...
arch/arm/mach-s5pc100/clock.c
浏览文件 @
59ca37f7
...
...
@@ -33,6 +33,11 @@ static struct clk s5p_clk_otgphy = {
.
name
=
"otg_phy"
,
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
static
struct
clk
*
clk_src_mout_href_list
[]
=
{
[
0
]
=
&
s5p_clk_27m
,
[
1
]
=
&
clk_fin_hpll
,
...
...
@@ -454,14 +459,14 @@ static struct clk init_clocks_off[] = {
.
enable
=
s5pc100_d1_0_ctrl
,
.
ctrlbit
=
(
1
<<
2
),
},
{
.
name
=
"
p
dma"
,
.
devname
=
"
s3c
-pl330.1"
,
.
name
=
"dma"
,
.
devname
=
"
dma
-pl330.1"
,
.
parent
=
&
clk_div_d1_bus
.
clk
,
.
enable
=
s5pc100_d1_0_ctrl
,
.
ctrlbit
=
(
1
<<
1
),
},
{
.
name
=
"
p
dma"
,
.
devname
=
"
s3c
-pl330.0"
,
.
name
=
"dma"
,
.
devname
=
"
dma
-pl330.0"
,
.
parent
=
&
clk_div_d1_bus
.
clk
,
.
enable
=
s5pc100_d1_0_ctrl
,
.
ctrlbit
=
(
1
<<
0
),
...
...
@@ -1276,5 +1281,7 @@ void __init s5pc100_register_clocks(void)
s3c_register_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
();
}
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.
* Jaswinder Singh <jassi.brar@samsung.com>
*
...
...
@@ -17,150 +21,246 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/platform_device.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/irqs.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <plat/s3c-pl330-pdata.h>
#include <mach/dma.h>
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
resource
s5pc100_pdma0_resource
[]
=
{
[
0
]
=
{
.
start
=
S5PC100_PA_PDMA0
,
.
end
=
S5PC100_PA_PDMA0
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_PDMA0
,
.
end
=
IRQ_PDMA0
,
.
flags
=
IORESOURCE_IRQ
,
struct
dma_pl330_peri
pdma0_peri
[
30
]
=
{
{
.
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_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
=
{
.
peri
=
{
[
0
]
=
DMACH_UART0_RX
,
[
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
,
},
struct
dma_pl330_platdata
s5pc100_pdma0_pdata
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma0_peri
),
.
peri
=
pdma0_peri
,
};
static
struct
platform_device
s5pc100_device_pdma0
=
{
.
name
=
"s3c-pl330"
,
.
id
=
0
,
.
num_resources
=
ARRAY_SIZE
(
s5pc100_pdma0_resource
),
.
resource
=
s5pc100_pdma0_resource
,
struct
amba_device
s5pc100_device_pdma0
=
{
.
dev
=
{
.
init_name
=
"dma-pl330.0"
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
s5pc100_pdma0_pdata
,
},
};
static
struct
resource
s5pc100_pdma1_resource
[]
=
{
[
0
]
=
{
.
start
=
S5PC100_PA_PDMA1
,
.
end
=
S5PC100_PA_PDMA1
+
SZ_4K
,
.
res
=
{
.
start
=
S5PC100_PA_PDMA0
,
.
end
=
S5PC100_PA_PDMA0
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_PDMA1
,
.
end
=
IRQ_PDMA1
,
.
flags
=
IORESOURCE_IRQ
,
},
.
irq
=
{
IRQ_PDMA0
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
static
struct
s3c_pl330_platdata
s5pc100_pdma1_pdata
=
{
.
peri
=
{
[
0
]
=
DMACH_UART0_RX
,
[
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_PCM0_RX
,
[
23
]
=
DMACH_PCM0_TX
,
[
24
]
=
DMACH_PCM1_RX
,
[
25
]
=
DMACH_PCM1_TX
,
[
26
]
=
DMACH_MSM_REQ0
,
[
27
]
=
DMACH_MSM_REQ1
,
[
28
]
=
DMACH_MSM_REQ2
,
[
29
]
=
DMACH_MSM_REQ3
,
[
30
]
=
DMACH_MAX
,
[
31
]
=
DMACH_MAX
,
struct
dma_pl330_peri
pdma1_peri
[
30
]
=
{
{
.
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_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_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
=
{
.
name
=
"s3c-pl330"
,
.
id
=
1
,
.
num_resources
=
ARRAY_SIZE
(
s5pc100_pdma1_resource
),
.
resource
=
s5pc100_pdma1_resource
,
struct
dma_pl330_platdata
s5pc100_pdma1_pdata
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma1_peri
),
.
peri
=
pdma1_peri
,
};
struct
amba_device
s5pc100_device_pdma1
=
{
.
dev
=
{
.
init_name
=
"dma-pl330.1"
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
s5pc100_pdma1_pdata
,
},
};
static
struct
platform_device
*
s5pc100_dmacs
[]
__initdata
=
{
&
s5pc100_device_pdma0
,
&
s5pc100_device_pdma1
,
.
res
=
{
.
start
=
S5PC100_PA_PDMA1
,
.
end
=
S5PC100_PA_PDMA1
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
.
irq
=
{
IRQ_PDMA1
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
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
;
}
...
...
arch/arm/mach-s5pc100/include/mach/dma.h
浏览文件 @
59ca37f7
...
...
@@ -20,7 +20,7 @@
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common
S3C
DMA API driver for PL330 */
#include <plat/
s3c-
dma-pl330.h>
/* This platform uses the common DMA API driver for PL330 */
#include <plat/dma-pl330.h>
#endif
/* __MACH_DMA_H */
arch/arm/mach-s5pv210/Kconfig
浏览文件 @
59ca37f7
...
...
@@ -11,7 +11,7 @@ if ARCH_S5PV210
config CPU_S5PV210
bool
select S
3C_PL330_DMA
select S
AMSUNG_DMADEV
select S5P_EXT_INT
select S5P_HRT
select S5PV210_PM if PM
...
...
arch/arm/mach-s5pv210/clock.c
浏览文件 @
59ca37f7
...
...
@@ -203,6 +203,11 @@ static struct clk clk_pcmcdclk2 = {
.
name
=
"pcmcdclk"
,
};
static
struct
clk
dummy_apb_pclk
=
{
.
name
=
"apb_pclk"
,
.
id
=
-
1
,
};
static
struct
clk
*
clkset_vpllsrc_list
[]
=
{
[
0
]
=
&
clk_fin_vpll
,
[
1
]
=
&
clk_sclk_hdmi27m
,
...
...
@@ -289,14 +294,14 @@ static struct clk_ops clk_fout_apll_ops = {
static
struct
clk
init_clocks_off
[]
=
{
{
.
name
=
"
p
dma"
,
.
devname
=
"
s3c
-pl330.0"
,
.
name
=
"dma"
,
.
devname
=
"
dma
-pl330.0"
,
.
parent
=
&
clk_hclk_psys
.
clk
,
.
enable
=
s5pv210_clk_ip0_ctrl
,
.
ctrlbit
=
(
1
<<
3
),
},
{
.
name
=
"
p
dma"
,
.
devname
=
"
s3c
-pl330.1"
,
.
name
=
"dma"
,
.
devname
=
"
dma
-pl330.1"
,
.
parent
=
&
clk_hclk_psys
.
clk
,
.
enable
=
s5pv210_clk_ip0_ctrl
,
.
ctrlbit
=
(
1
<<
4
),
...
...
@@ -1159,5 +1164,6 @@ void __init s5pv210_register_clocks(void)
s3c_register_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
();
}
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.
* Jaswinder Singh <jassi.brar@samsung.com>
*
...
...
@@ -17,151 +21,240 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/platform_device.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/irqs.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <plat/s3c-pl330-pdata.h>
#include <mach/dma.h>
static
u64
dma_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
resource
s5pv210_pdma0_resource
[]
=
{
[
0
]
=
{
.
start
=
S5PV210_PA_PDMA0
,
.
end
=
S5PV210_PA_PDMA0
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_PDMA0
,
.
end
=
IRQ_PDMA0
,
.
flags
=
IORESOURCE_IRQ
,
struct
dma_pl330_peri
pdma0_peri
[
28
]
=
{
{
.
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_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
=
{
.
peri
=
{
[
0
]
=
DMACH_UART0_RX
,
[
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
,
},
struct
dma_pl330_platdata
s5pv210_pdma0_pdata
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma0_peri
),
.
peri
=
pdma0_peri
,
};
static
struct
platform_device
s5pv210_device_pdma0
=
{
.
name
=
"s3c-pl330"
,
.
id
=
0
,
.
num_resources
=
ARRAY_SIZE
(
s5pv210_pdma0_resource
),
.
resource
=
s5pv210_pdma0_resource
,
struct
amba_device
s5pv210_device_pdma0
=
{
.
dev
=
{
.
init_name
=
"dma-pl330.0"
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
s5pv210_pdma0_pdata
,
},
};
static
struct
resource
s5pv210_pdma1_resource
[]
=
{
[
0
]
=
{
.
start
=
S5PV210_PA_PDMA1
,
.
end
=
S5PV210_PA_PDMA1
+
SZ_4K
,
.
res
=
{
.
start
=
S5PV210_PA_PDMA0
,
.
end
=
S5PV210_PA_PDMA0
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_PDMA1
,
.
end
=
IRQ_PDMA1
,
.
flags
=
IORESOURCE_IRQ
,
},
.
irq
=
{
IRQ_PDMA0
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
static
struct
s3c_pl330_platdata
s5pv210_pdma1_pdata
=
{
.
peri
=
{
[
0
]
=
DMACH_UART0_RX
,
[
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_I2S2_RX
,
[
15
]
=
DMACH_I2S2_TX
,
[
16
]
=
DMACH_SPI0_RX
,
[
17
]
=
DMACH_SPI0_TX
,
[
18
]
=
DMACH_SPI1_RX
,
[
19
]
=
DMACH_SPI1_TX
,
[
20
]
=
DMACH_MAX
,
[
21
]
=
DMACH_MAX
,
[
22
]
=
DMACH_PCM0_RX
,
[
23
]
=
DMACH_PCM0_TX
,
[
24
]
=
DMACH_PCM1_RX
,
[
25
]
=
DMACH_PCM1_TX
,
[
26
]
=
DMACH_MSM_REQ0
,
[
27
]
=
DMACH_MSM_REQ1
,
[
28
]
=
DMACH_MSM_REQ2
,
[
29
]
=
DMACH_MSM_REQ3
,
[
30
]
=
DMACH_PCM2_RX
,
[
31
]
=
DMACH_PCM2_TX
,
struct
dma_pl330_peri
pdma1_peri
[
32
]
=
{
{
.
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_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_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
=
{
.
name
=
"s3c-pl330"
,
.
id
=
1
,
.
num_resources
=
ARRAY_SIZE
(
s5pv210_pdma1_resource
),
.
resource
=
s5pv210_pdma1_resource
,
struct
dma_pl330_platdata
s5pv210_pdma1_pdata
=
{
.
nr_valid_peri
=
ARRAY_SIZE
(
pdma1_peri
),
.
peri
=
pdma1_peri
,
};
struct
amba_device
s5pv210_device_pdma1
=
{
.
dev
=
{
.
init_name
=
"dma-pl330.1"
,
.
dma_mask
=
&
dma_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
s5pv210_pdma1_pdata
,
},
};
static
struct
platform_device
*
s5pv210_dmacs
[]
__initdata
=
{
&
s5pv210_device_pdma0
,
&
s5pv210_device_pdma1
,
.
res
=
{
.
start
=
S5PV210_PA_PDMA1
,
.
end
=
S5PV210_PA_PDMA1
+
SZ_4K
,
.
flags
=
IORESOURCE_MEM
,
},
.
irq
=
{
IRQ_PDMA1
,
NO_IRQ
},
.
periphid
=
0x00041330
,
};
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
;
}
...
...
arch/arm/mach-s5pv210/include/mach/dma.h
浏览文件 @
59ca37f7
...
...
@@ -20,7 +20,7 @@
#ifndef __MACH_DMA_H
#define __MACH_DMA_H
/* This platform uses the common
S3C
DMA API driver for PL330 */
#include <plat/
s3c-
dma-pl330.h>
/* This platform uses the common DMA API driver for PL330 */
#include <plat/dma-pl330.h>
#endif
/* __MACH_DMA_H */
arch/arm/plat-s3c24xx/dma.c
浏览文件 @
59ca37f7
...
...
@@ -1094,14 +1094,14 @@ EXPORT_SYMBOL(s3c2410_dma_config);
*
* configure the dma source/destination hardware type and address
*
* source:
S3C2410_DMASRC_HW
: source is hardware
*
S3C2410_DMASRC_MEM
: source is memory
* source:
DMA_FROM_DEVICE
: source is hardware
*
DMA_TO_DEVICE
: source is memory
*
* devaddr: physical address of the source
*/
int
s3c2410_dma_devconfig
(
enum
dma_ch
channel
,
enum
s3c2410_dmasrc
source
,
enum
dma_data_direction
source
,
unsigned
long
devaddr
)
{
struct
s3c2410_dma_chan
*
chan
=
s3c_dma_lookup_channel
(
channel
);
...
...
@@ -1131,7 +1131,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
hwcfg
|=
S3C2410_DISRCC_INC
;
switch
(
source
)
{
case
S3C2410_DMASRC_HW
:
case
DMA_FROM_DEVICE
:
/* source is hardware */
pr_debug
(
"%s: hw source, devaddr=%08lx, hwcfg=%d
\n
"
,
__func__
,
devaddr
,
hwcfg
);
...
...
@@ -1142,7 +1142,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
chan
->
addr_reg
=
dma_regaddr
(
chan
,
S3C2410_DMA_DIDST
);
break
;
case
S3C2410_DMASRC_MEM
:
case
DMA_TO_DEVICE
:
/* source is memory */
pr_debug
(
"%s: mem source, devaddr=%08lx, hwcfg=%d
\n
"
,
__func__
,
devaddr
,
hwcfg
);
...
...
arch/arm/plat-samsung/Kconfig
浏览文件 @
59ca37f7
...
...
@@ -300,11 +300,14 @@ config S3C_DMA
help
Internal configuration for S3C DMA core
config S
3C_PL330_DMA
config S
AMSUNG_DMADEV
bool
select PL330
select DMADEVICES
select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \
CPU_S5P6450 || CPU_S5P6440)
select ARM_AMBA
help
S3C DMA API Driver
for PL330 DMAC.
Use DMA device engine
for PL330 DMAC.
comment "Power management"
...
...
arch/arm/plat-samsung/Makefile
浏览文件 @
59ca37f7
...
...
@@ -63,9 +63,9 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
# 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
...
...
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 @@
* (at your option) any later version.
*/
#ifndef __S3C_DMA_PL330_H_
#define __S3C_DMA_PL330_H_
#define S3C2410_DMAF_AUTOSTART (1 << 0)
#define S3C2410_DMAF_CIRCULAR (1 << 1)
#ifndef __DMA_PL330_H_
#define __DMA_PL330_H_ __FILE__
/*
* PL330 can assign any channel to communicate with
...
...
@@ -20,7 +17,7 @@
* For the sake of consistency across client drivers,
* We keep the channel names unchanged and only add
* 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.
*/
enum
dma_ch
{
...
...
@@ -88,11 +85,20 @@ enum dma_ch {
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
;
}
#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 {
void
(
*
direction
)(
struct
s3c2410_dma_chan
*
chan
,
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
);
...
...
arch/arm/plat-samsung/include/plat/dma.h
浏览文件 @
59ca37f7
...
...
@@ -10,17 +10,14 @@
* published by the Free Software Foundation.
*/
#include <linux/dma-mapping.h>
enum
s3c2410_dma_buffresult
{
S3C2410_RES_OK
,
S3C2410_RES_ERR
,
S3C2410_RES_ABORT
};
enum
s3c2410_dmasrc
{
S3C2410_DMASRC_HW
,
/* source is memory */
S3C2410_DMASRC_MEM
/* source is hardware */
};
/* enum s3c2410_chan_op
*
* 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);
*/
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
*
...
...
@@ -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
);
#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
config PL330_DMA
tristate "DMA API Driver for PL330"
select DMA_ENGINE
depends on PL330
depends on ARM_AMBA
select PL330
help
Select if your platform has one or more PL330 DMACs.
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)
{
struct
at_desc
*
desc
,
*
_desc
;
struct
at_desc
*
ret
=
NULL
;
unsigned
long
flags
;
unsigned
int
i
=
0
;
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
)
{
i
++
;
if
(
async_tx_test_ack
(
&
desc
->
txd
))
{
...
...
@@ -121,7 +122,7 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
dev_dbg
(
chan2dev
(
&
atchan
->
chan_common
),
"desc %p not ACKed
\n
"
,
desc
);
}
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
"scanned %u descriptors on freelist
\n
"
,
i
);
...
...
@@ -129,9 +130,9 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
if
(
!
ret
)
{
ret
=
atc_alloc_descriptor
(
&
atchan
->
chan_common
,
GFP_ATOMIC
);
if
(
ret
)
{
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
atchan
->
descs_allocated
++
;
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
else
{
dev_err
(
chan2dev
(
&
atchan
->
chan_common
),
"not enough descriptors available
\n
"
);
...
...
@@ -150,8 +151,9 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
{
if
(
desc
)
{
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
)
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
"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)
dev_vdbg
(
chan2dev
(
&
atchan
->
chan_common
),
"moving desc %p to freelist
\n
"
,
desc
);
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)
/* for cyclic transfers,
* 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
;
void
*
param
=
txd
->
callback_param
;
...
...
@@ -471,16 +473,17 @@ static void atc_handle_cyclic(struct at_dma_chan *atchan)
static
void
atc_tasklet
(
unsigned
long
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
))
atc_handle_error
(
atchan
);
else
if
(
test_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
))
else
if
(
atc_chan_is_cyclic
(
atchan
))
atc_handle_cyclic
(
atchan
);
else
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
)
...
...
@@ -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_dma_chan
*
atchan
=
to_at_dma_chan
(
tx
->
chan
);
dma_cookie_t
cookie
;
unsigned
long
flags
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
cookie
=
atc_assign_cookie
(
atchan
,
desc
);
if
(
list_empty
(
&
atchan
->
active_list
))
{
...
...
@@ -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
);
}
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
return
cookie
;
}
...
...
@@ -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
*
atdma
=
to_at_dma
(
chan
->
device
);
int
chan_id
=
atchan
->
chan_common
.
chan_id
;
unsigned
long
flags
;
LIST_HEAD
(
list
);
dev_vdbg
(
chan2dev
(
chan
),
"atc_control (%d)
\n
"
,
cmd
);
if
(
cmd
==
DMA_PAUSE
)
{
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
dma_writel
(
atdma
,
CHER
,
AT_DMA_SUSP
(
chan_id
));
set_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
);
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
else
if
(
cmd
==
DMA_RESUME
)
{
if
(
!
test_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
))
if
(
!
atc_chan_is_paused
(
atchan
))
return
0
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
dma_writel
(
atdma
,
CHDR
,
AT_DMA_RES
(
chan_id
));
clear_bit
(
ATC_IS_PAUSED
,
&
atchan
->
status
);
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
else
if
(
cmd
==
DMA_TERMINATE_ALL
)
{
struct
at_desc
*
desc
,
*
_desc
;
/*
...
...
@@ -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
* to AHB/HSB limitations.
*/
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
/* disabling channel: must also remove suspend state */
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,
/* if channel dedicated to cyclic operations, free it */
clear_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
);
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
}
else
{
return
-
ENXIO
;
}
...
...
@@ -1004,9 +1009,10 @@ atc_tx_status(struct dma_chan *chan,
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
dma_cookie_t
last_used
;
dma_cookie_t
last_complete
;
unsigned
long
flags
;
enum
dma_status
ret
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
last_complete
=
atchan
->
completed_cookie
;
last_used
=
chan
->
cookie
;
...
...
@@ -1021,7 +1027,7 @@ atc_tx_status(struct dma_chan *chan,
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
)
dma_set_tx_state
(
txstate
,
last_complete
,
last_used
,
...
...
@@ -1029,7 +1035,7 @@ atc_tx_status(struct dma_chan *chan,
else
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
;
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,
static
void
atc_issue_pending
(
struct
dma_chan
*
chan
)
{
struct
at_dma_chan
*
atchan
=
to_at_dma_chan
(
chan
);
unsigned
long
flags
;
dev_vdbg
(
chan2dev
(
chan
),
"issue_pending
\n
"
);
/* Not needed for cyclic transfers */
if
(
test_bit
(
ATC_IS_CYCLIC
,
&
atchan
->
status
))
if
(
atc_chan_is_cyclic
(
atchan
))
return
;
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
if
(
!
atc_chan_is_enabled
(
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)
struct
at_dma
*
atdma
=
to_at_dma
(
chan
->
device
);
struct
at_desc
*
desc
;
struct
at_dma_slave
*
atslave
;
unsigned
long
flags
;
int
i
;
u32
cfg
;
LIST_HEAD
(
tmp_list
);
...
...
@@ -1116,11 +1124,11 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
list_add_tail
(
&
desc
->
desc_node
,
&
tmp_list
);
}
spin_lock_
bh
(
&
atchan
->
lock
);
spin_lock_
irqsave
(
&
atchan
->
lock
,
flags
);
atchan
->
descs_allocated
=
i
;
list_splice
(
&
tmp_list
,
&
atchan
->
free_list
);
atchan
->
completed_cookie
=
chan
->
cookie
=
1
;
spin_unlock_
bh
(
&
atchan
->
lock
);
spin_unlock_
irqrestore
(
&
atchan
->
lock
,
flags
);
/* channel parameters */
channel_writel
(
atchan
,
CFG
,
cfg
);
...
...
@@ -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
))
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
;
if
(
dma_has_cap
(
DMA_CYCLIC
,
atdma
->
dma_common
.
cap_mask
))
/* controller can do slave DMA: can trigger cyclic transfers */
dma_cap_set
(
DMA_CYCLIC
,
atdma
->
dma_common
.
cap_mask
);
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
;
}
dma_writel
(
atdma
,
EN
,
AT_DMA_ENABLE
);
...
...
@@ -1377,27 +1383,112 @@ static void at_dma_shutdown(struct platform_device *pdev)
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
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
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
);
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
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
at_dma
*
atdma
=
platform_get_drvdata
(
pdev
);
struct
dma_chan
*
chan
,
*
_chan
;
/* bring back DMA controller */
clk_enable
(
atdma
->
clk
);
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
;
}
static
const
struct
dev_pm_ops
at_dma_dev_pm_ops
=
{
.
prepare
=
at_dma_prepare
,
.
suspend_noirq
=
at_dma_suspend_noirq
,
.
resume_noirq
=
at_dma_resume_noirq
,
};
...
...
drivers/dma/at_hdmac_regs.h
浏览文件 @
59ca37f7
...
...
@@ -204,6 +204,9 @@ enum atc_status {
* @status: transmit status information from irq/prep* functions
* to tasklet (use atomic operations)
* @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
* @completed_cookie: identifier for the most recently completed operation
* @active_list: list of descriptors dmaengine is being running on
...
...
@@ -218,6 +221,8 @@ struct at_dma_chan {
u8
mask
;
unsigned
long
status
;
struct
tasklet_struct
tasklet
;
u32
save_cfg
;
u32
save_dscr
;
spinlock_t
lock
;
...
...
@@ -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
* @ch_regs: memory mapped register base
* @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
* @dma_desc_pool: base of DMA descriptor region (DMA address)
* @chan: channels table to store at_dma_chan structures
...
...
@@ -256,6 +262,7 @@ struct at_dma {
struct
dma_device
dma_common
;
void
__iomem
*
regs
;
struct
clk
*
clk
;
u32
save_imr
;
u8
all_chan_mask
;
...
...
@@ -355,6 +362,23 @@ static inline int atc_chan_is_enabled(struct at_dma_chan *atchan)
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
...
...
drivers/dma/dmatest.c
浏览文件 @
59ca37f7
...
...
@@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/freezer.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/module.h>
...
...
@@ -251,6 +252,7 @@ static int dmatest_func(void *data)
int
i
;
thread_name
=
current
->
comm
;
set_freezable_with_signal
();
ret
=
-
ENOMEM
;
...
...
@@ -305,7 +307,8 @@ static int dmatest_func(void *data)
dma_addr_t
dma_srcs
[
src_cnt
];
dma_addr_t
dma_dsts
[
dst_cnt
];
struct
completion
cmp
;
unsigned
long
tmo
=
msecs_to_jiffies
(
timeout
);
unsigned
long
start
,
tmo
,
end
=
0
/* compiler... */
;
bool
reload
=
true
;
u8
align
=
0
;
total_tests
++
;
...
...
@@ -404,7 +407,17 @@ static int dmatest_func(void *data)
}
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
);
if
(
tmo
==
0
)
{
...
...
@@ -477,6 +490,8 @@ static int dmatest_func(void *data)
pr_notice
(
"%s: terminating after %u tests, %u failures (status %d)
\n
"
,
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
)
while
(
!
kthread_should_stop
())
{
DECLARE_WAIT_QUEUE_HEAD_ONSTACK
(
wait_dmatest_exit
);
...
...
@@ -499,6 +514,10 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
list_del
(
&
thread
->
node
);
kfree
(
thread
);
}
/* terminate all transfers on specified channels */
dtc
->
chan
->
device
->
device_control
(
dtc
->
chan
,
DMA_TERMINATE_ALL
,
0
);
kfree
(
dtc
);
}
...
...
drivers/dma/imx-sdma.c
浏览文件 @
59ca37f7
...
...
@@ -318,6 +318,7 @@ struct sdma_engine {
dma_addr_t
context_phys
;
struct
dma_device
dma_device
;
struct
clk
*
clk
;
struct
mutex
channel_0_lock
;
struct
sdma_script_start_addrs
*
script_addrs
;
};
...
...
@@ -415,11 +416,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
dma_addr_t
buf_phys
;
int
ret
;
mutex_lock
(
&
sdma
->
channel_0_lock
);
buf_virt
=
dma_alloc_coherent
(
NULL
,
size
,
&
buf_phys
,
GFP_KERNEL
);
if
(
!
buf_virt
)
return
-
ENOMEM
;
if
(
!
buf_virt
)
{
ret
=
-
ENOMEM
;
goto
err_out
;
}
bd0
->
mode
.
command
=
C0_SETPM
;
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,
dma_free_coherent
(
NULL
,
size
,
buf_virt
,
buf_phys
);
err_out:
mutex_unlock
(
&
sdma
->
channel_0_lock
);
return
ret
;
}
...
...
@@ -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_mask1 = 0x%08x
\n
"
,
sdmac
->
event_mask1
);
mutex_lock
(
&
sdma
->
channel_0_lock
);
memset
(
context
,
0
,
sizeof
(
*
context
));
context
->
channel_state
.
pc
=
load_address
;
...
...
@@ -676,6 +686,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
ret
=
sdma_run_channel
(
&
sdma
->
channel
[
0
]);
mutex_unlock
(
&
sdma
->
channel_0_lock
);
return
ret
;
}
...
...
@@ -1131,18 +1143,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
saddr_arr
[
i
]
=
addr_arr
[
i
];
}
static
int
__init
sdma_get_firmware
(
struct
sdma_engine
*
sdma
,
const
char
*
fw_name
)
static
void
sdma_load_firmware
(
const
struct
firmware
*
fw
,
void
*
context
)
{
const
struct
firmware
*
fw
;
struct
sdma_engine
*
sdma
=
context
;
const
struct
sdma_firmware_header
*
header
;
int
ret
;
const
struct
sdma_script_start_addrs
*
addr
;
unsigned
short
*
ram_code
;
ret
=
request_firmware
(
&
fw
,
fw_name
,
sdma
->
dev
);
if
(
ret
)
return
ret
;
if
(
!
fw
)
{
dev_err
(
sdma
->
dev
,
"firmware not found
\n
"
);
return
;
}
if
(
fw
->
size
<
sizeof
(
*
header
))
goto
err_firmware
;
...
...
@@ -1172,6 +1183,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
err_firmware:
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
;
}
...
...
@@ -1269,11 +1290,14 @@ static int __init sdma_probe(struct platform_device *pdev)
struct
sdma_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
int
i
;
struct
sdma_engine
*
sdma
;
s32
*
saddr_arr
;
sdma
=
kzalloc
(
sizeof
(
*
sdma
),
GFP_KERNEL
);
if
(
!
sdma
)
return
-
ENOMEM
;
mutex_init
(
&
sdma
->
channel_0_lock
);
sdma
->
dev
=
&
pdev
->
dev
;
iores
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
...
...
@@ -1310,6 +1334,11 @@ static int __init sdma_probe(struct platform_device *pdev)
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
)
pdev
->
id_entry
=
of_id
->
data
;
sdma
->
devtype
=
pdev
->
id_entry
->
driver_data
;
...
...
drivers/dma/mxs-dma.c
浏览文件 @
59ca37f7
...
...
@@ -130,6 +130,23 @@ struct mxs_dma_engine {
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
)
{
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)
struct
mxs_dma_engine
*
mxs_dma
=
mxs_chan
->
mxs_dma
;
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 */
writel
(
mxs_chan
->
ccw_phys
,
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 */
writel
(
1
,
mxs_dma
->
base
+
HW_APBHX_CHn_SEMA
(
chan_id
));
}
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 */
if
(
dma_is_apbh
())
{
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_dma_clkgate
(
mxs_chan
,
0
);
mxs_chan
->
status
=
DMA_SUCCESS
;
}
...
...
@@ -338,7 +338,10 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
if
(
ret
)
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_clkgate
(
mxs_chan
,
0
);
dma_async_tx_descriptor_init
(
&
mxs_chan
->
desc
,
chan
);
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)
}
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
;
if
(
last_source
==
source
)
...
...
@@ -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
);
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
);
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 {
* @muxval: a number usually used to poke into some mux regiser to
* mux in the signal to this channel
* @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,
* 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
...
...
@@ -65,6 +68,7 @@ struct pl08x_channel_data {
int
max_signal
;
u32
muxval
;
u32
cctl
;
bool
device_fc
;
dma_addr_t
addr
;
bool
circular_buffer
;
bool
single
;
...
...
@@ -77,13 +81,11 @@ struct pl08x_channel_data {
* @addr: current address
* @maxwidth: the maximum width of a transfer on this bus
* @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
{
dma_addr_t
addr
;
u8
maxwidth
;
u8
buswidth
;
size_t
fill_bytes
;
};
/**
...
...
@@ -105,8 +107,16 @@ struct pl08x_phy_chan {
/**
* 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_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
dma_async_tx_descriptor
tx
;
...
...
include/linux/amba/pl330.h
浏览文件 @
59ca37f7
...
...
@@ -19,12 +19,8 @@ struct dma_pl330_peri {
* Peri_Req i/f of the DMAC that is
* peripheral could be reached from.
*/
u8
peri_id
;
/*
{0, 31}
*/
u8
peri_id
;
/*
specific dma id
*/
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
{
...
...
include/linux/dmaengine.h
浏览文件 @
59ca37f7
...
...
@@ -24,8 +24,7 @@
#include <linux/device.h>
#include <linux/uio.h>
#include <linux/dma-direction.h>
struct
scatterlist
;
#include <linux/scatterlist.h>
/**
* typedef dma_cookie_t - an opaque DMA cookie
...
...
@@ -519,6 +518,16 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
(
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
)
{
return
dmaengine_device_control
(
chan
,
DMA_TERMINATE_ALL
,
0
);
...
...
sound/soc/samsung/ac97.c
浏览文件 @
59ca37f7
...
...
@@ -271,7 +271,10 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
writel
(
ac_glbctrl
,
s3c_ac97
.
regs
+
S3C_AC97_GLBCTRL
);
s3c2410_dma_ctrl
(
dma_data
->
channel
,
S3C2410_DMAOP_STARTED
);
if
(
!
dma_data
->
ops
)
dma_data
->
ops
=
samsung_dma_get_ops
();
dma_data
->
ops
->
started
(
dma_data
->
channel
);
return
0
;
}
...
...
@@ -317,7 +320,10 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
writel
(
ac_glbctrl
,
s3c_ac97
.
regs
+
S3C_AC97_GLBCTRL
);
s3c2410_dma_ctrl
(
dma_data
->
channel
,
S3C2410_DMAOP_STARTED
);
if
(
!
dma_data
->
ops
)
dma_data
->
ops
=
samsung_dma_get_ops
();
dma_data
->
ops
->
started
(
dma_data
->
channel
);
return
0
;
}
...
...
sound/soc/samsung/dma.c
浏览文件 @
59ca37f7
此差异已折叠。
点击以展开。
sound/soc/samsung/dma.h
浏览文件 @
59ca37f7
...
...
@@ -6,7 +6,7 @@
* Free Software Foundation; either version 2 of the License, or (at your
* 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
...
...
@@ -17,6 +17,8 @@ struct s3c_dma_params {
int
channel
;
/* Channel ID */
dma_addr_t
dma_addr
;
int
dma_size
;
/* Size of the DMA transfer */
unsigned
ch
;
struct
samsung_dma_ops
*
ops
;
};
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录