Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
8a3ec583
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看板
提交
8a3ec583
编写于
2月 21, 2017
作者:
V
Vinod Koul
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/stm32-dma' into for-linus
上级
25036f2a
5df4eb45
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
63 addition
and
37 deletion
+63
-37
Documentation/devicetree/bindings/dma/stm32-dma.txt
Documentation/devicetree/bindings/dma/stm32-dma.txt
+2
-3
drivers/dma/Kconfig
drivers/dma/Kconfig
+1
-1
drivers/dma/stm32-dma.c
drivers/dma/stm32-dma.c
+60
-33
未找到文件。
Documentation/devicetree/bindings/dma/stm32-dma.txt
浏览文件 @
8a3ec583
...
@@ -40,8 +40,7 @@ Example:
...
@@ -40,8 +40,7 @@ Example:
DMA clients connected to the STM32 DMA controller must use the format
DMA clients connected to the STM32 DMA controller must use the format
described in the dma.txt file, using a five-cell specifier for each
described in the dma.txt file, using a five-cell specifier for each
channel: a phandle plus four integer cells.
channel: a phandle to the DMA controller plus the following four integer cells:
The four cells in order are:
1. The channel id
1. The channel id
2. The request line number
2. The request line number
...
@@ -61,7 +60,7 @@ The four cells in order are:
...
@@ -61,7 +60,7 @@ The four cells in order are:
0x1: medium
0x1: medium
0x2: high
0x2: high
0x3: very high
0x3: very high
5
. A 32bit mask specifying the DMA FIFO threshold configuration which are device
4
. A 32bit mask specifying the DMA FIFO threshold configuration which are device
dependent:
dependent:
-bit 0-1: Fifo threshold
-bit 0-1: Fifo threshold
0x0: 1/4 full FIFO
0x0: 1/4 full FIFO
...
...
drivers/dma/Kconfig
浏览文件 @
8a3ec583
...
@@ -458,7 +458,7 @@ config STM32_DMA
...
@@ -458,7 +458,7 @@ config STM32_DMA
help
help
Enable support for the on-chip DMA controller on STMicroelectronics
Enable support for the on-chip DMA controller on STMicroelectronics
STM32 MCUs.
STM32 MCUs.
If you have a board based on such a MCU and wish to use DMA say Y
or M
If you have a board based on such a MCU and wish to use DMA say Y
here.
here.
config S3C24XX_DMAC
config S3C24XX_DMAC
...
...
drivers/dma/stm32-dma.c
浏览文件 @
8a3ec583
...
@@ -114,6 +114,7 @@
...
@@ -114,6 +114,7 @@
#define STM32_DMA_MAX_CHANNELS 0x08
#define STM32_DMA_MAX_CHANNELS 0x08
#define STM32_DMA_MAX_REQUEST_ID 0x08
#define STM32_DMA_MAX_REQUEST_ID 0x08
#define STM32_DMA_MAX_DATA_PARAM 0x03
#define STM32_DMA_MAX_DATA_PARAM 0x03
#define STM32_DMA_MAX_BURST 16
enum
stm32_dma_width
{
enum
stm32_dma_width
{
STM32_DMA_BYTE
,
STM32_DMA_BYTE
,
...
@@ -403,6 +404,13 @@ static int stm32_dma_terminate_all(struct dma_chan *c)
...
@@ -403,6 +404,13 @@ static int stm32_dma_terminate_all(struct dma_chan *c)
return
0
;
return
0
;
}
}
static
void
stm32_dma_synchronize
(
struct
dma_chan
*
c
)
{
struct
stm32_dma_chan
*
chan
=
to_stm32_dma_chan
(
c
);
vchan_synchronize
(
&
chan
->
vchan
);
}
static
void
stm32_dma_dump_reg
(
struct
stm32_dma_chan
*
chan
)
static
void
stm32_dma_dump_reg
(
struct
stm32_dma_chan
*
chan
)
{
{
struct
stm32_dma_device
*
dmadev
=
stm32_dma_get_dev
(
chan
);
struct
stm32_dma_device
*
dmadev
=
stm32_dma_get_dev
(
chan
);
...
@@ -421,7 +429,7 @@ static void stm32_dma_dump_reg(struct stm32_dma_chan *chan)
...
@@ -421,7 +429,7 @@ static void stm32_dma_dump_reg(struct stm32_dma_chan *chan)
dev_dbg
(
chan2dev
(
chan
),
"SFCR: 0x%08x
\n
"
,
sfcr
);
dev_dbg
(
chan2dev
(
chan
),
"SFCR: 0x%08x
\n
"
,
sfcr
);
}
}
static
int
stm32_dma_start_transfer
(
struct
stm32_dma_chan
*
chan
)
static
void
stm32_dma_start_transfer
(
struct
stm32_dma_chan
*
chan
)
{
{
struct
stm32_dma_device
*
dmadev
=
stm32_dma_get_dev
(
chan
);
struct
stm32_dma_device
*
dmadev
=
stm32_dma_get_dev
(
chan
);
struct
virt_dma_desc
*
vdesc
;
struct
virt_dma_desc
*
vdesc
;
...
@@ -432,12 +440,12 @@ static int stm32_dma_start_transfer(struct stm32_dma_chan *chan)
...
@@ -432,12 +440,12 @@ static int stm32_dma_start_transfer(struct stm32_dma_chan *chan)
ret
=
stm32_dma_disable_chan
(
chan
);
ret
=
stm32_dma_disable_chan
(
chan
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
;
if
(
!
chan
->
desc
)
{
if
(
!
chan
->
desc
)
{
vdesc
=
vchan_next_desc
(
&
chan
->
vchan
);
vdesc
=
vchan_next_desc
(
&
chan
->
vchan
);
if
(
!
vdesc
)
if
(
!
vdesc
)
return
-
EPERM
;
return
;
chan
->
desc
=
to_stm32_dma_desc
(
vdesc
);
chan
->
desc
=
to_stm32_dma_desc
(
vdesc
);
chan
->
next_sg
=
0
;
chan
->
next_sg
=
0
;
...
@@ -471,7 +479,7 @@ static int stm32_dma_start_transfer(struct stm32_dma_chan *chan)
...
@@ -471,7 +479,7 @@ static int stm32_dma_start_transfer(struct stm32_dma_chan *chan)
chan
->
busy
=
true
;
chan
->
busy
=
true
;
return
0
;
dev_dbg
(
chan2dev
(
chan
),
"vchan %p: started
\n
"
,
&
chan
->
vchan
)
;
}
}
static
void
stm32_dma_configure_next_sg
(
struct
stm32_dma_chan
*
chan
)
static
void
stm32_dma_configure_next_sg
(
struct
stm32_dma_chan
*
chan
)
...
@@ -500,8 +508,6 @@ static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan)
...
@@ -500,8 +508,6 @@ static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan)
dev_dbg
(
chan2dev
(
chan
),
"CT=0 <=> SM1AR: 0x%08x
\n
"
,
dev_dbg
(
chan2dev
(
chan
),
"CT=0 <=> SM1AR: 0x%08x
\n
"
,
stm32_dma_read
(
dmadev
,
STM32_DMA_SM1AR
(
id
)));
stm32_dma_read
(
dmadev
,
STM32_DMA_SM1AR
(
id
)));
}
}
chan
->
next_sg
++
;
}
}
}
}
...
@@ -510,6 +516,7 @@ static void stm32_dma_handle_chan_done(struct stm32_dma_chan *chan)
...
@@ -510,6 +516,7 @@ static void stm32_dma_handle_chan_done(struct stm32_dma_chan *chan)
if
(
chan
->
desc
)
{
if
(
chan
->
desc
)
{
if
(
chan
->
desc
->
cyclic
)
{
if
(
chan
->
desc
->
cyclic
)
{
vchan_cyclic_callback
(
&
chan
->
desc
->
vdesc
);
vchan_cyclic_callback
(
&
chan
->
desc
->
vdesc
);
chan
->
next_sg
++
;
stm32_dma_configure_next_sg
(
chan
);
stm32_dma_configure_next_sg
(
chan
);
}
else
{
}
else
{
chan
->
busy
=
false
;
chan
->
busy
=
false
;
...
@@ -552,16 +559,14 @@ static void stm32_dma_issue_pending(struct dma_chan *c)
...
@@ -552,16 +559,14 @@ static void stm32_dma_issue_pending(struct dma_chan *c)
{
{
struct
stm32_dma_chan
*
chan
=
to_stm32_dma_chan
(
c
);
struct
stm32_dma_chan
*
chan
=
to_stm32_dma_chan
(
c
);
unsigned
long
flags
;
unsigned
long
flags
;
int
ret
;
spin_lock_irqsave
(
&
chan
->
vchan
.
lock
,
flags
);
spin_lock_irqsave
(
&
chan
->
vchan
.
lock
,
flags
);
if
(
!
chan
->
busy
)
{
if
(
vchan_issue_pending
(
&
chan
->
vchan
)
&&
!
chan
->
desc
&&
!
chan
->
busy
)
{
if
(
vchan_issue_pending
(
&
chan
->
vchan
)
&&
!
chan
->
desc
)
{
dev_dbg
(
chan2dev
(
chan
),
"vchan %p: issued
\n
"
,
&
chan
->
vchan
);
ret
=
stm32_dma_start_transfer
(
chan
);
stm32_dma_start_transfer
(
chan
);
if
((
!
ret
)
&&
(
chan
->
desc
->
cyclic
)
)
if
(
chan
->
desc
->
cyclic
)
stm32_dma_configure_next_sg
(
chan
);
stm32_dma_configure_next_sg
(
chan
);
}
}
}
spin_unlock_irqrestore
(
&
chan
->
vchan
.
lock
,
flags
);
spin_unlock_irqrestore
(
&
chan
->
vchan
.
lock
,
flags
);
}
}
...
@@ -848,26 +853,40 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy(
...
@@ -848,26 +853,40 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy(
return
vchan_tx_prep
(
&
chan
->
vchan
,
&
desc
->
vdesc
,
flags
);
return
vchan_tx_prep
(
&
chan
->
vchan
,
&
desc
->
vdesc
,
flags
);
}
}
static
u32
stm32_dma_get_remaining_bytes
(
struct
stm32_dma_chan
*
chan
)
{
u32
dma_scr
,
width
,
ndtr
;
struct
stm32_dma_device
*
dmadev
=
stm32_dma_get_dev
(
chan
);
dma_scr
=
stm32_dma_read
(
dmadev
,
STM32_DMA_SCR
(
chan
->
id
));
width
=
STM32_DMA_SCR_PSIZE_GET
(
dma_scr
);
ndtr
=
stm32_dma_read
(
dmadev
,
STM32_DMA_SNDTR
(
chan
->
id
));
return
ndtr
<<
width
;
}
static
size_t
stm32_dma_desc_residue
(
struct
stm32_dma_chan
*
chan
,
static
size_t
stm32_dma_desc_residue
(
struct
stm32_dma_chan
*
chan
,
struct
stm32_dma_desc
*
desc
,
struct
stm32_dma_desc
*
desc
,
u32
next_sg
)
u32
next_sg
)
{
{
struct
stm32_dma_device
*
dmadev
=
stm32_dma_get_dev
(
chan
);
u32
residue
=
0
;
u32
dma_scr
,
width
,
residue
,
count
;
int
i
;
int
i
;
residue
=
0
;
/*
* In cyclic mode, for the last period, residue = remaining bytes from
* NDTR
*/
if
(
chan
->
desc
->
cyclic
&&
next_sg
==
0
)
return
stm32_dma_get_remaining_bytes
(
chan
);
/*
* For all other periods in cyclic mode, and in sg mode,
* residue = remaining bytes from NDTR + remaining periods/sg to be
* transferred
*/
for
(
i
=
next_sg
;
i
<
desc
->
num_sgs
;
i
++
)
for
(
i
=
next_sg
;
i
<
desc
->
num_sgs
;
i
++
)
residue
+=
desc
->
sg_req
[
i
].
len
;
residue
+=
desc
->
sg_req
[
i
].
len
;
residue
+=
stm32_dma_get_remaining_bytes
(
chan
);
if
(
next_sg
!=
0
)
{
dma_scr
=
stm32_dma_read
(
dmadev
,
STM32_DMA_SCR
(
chan
->
id
));
width
=
STM32_DMA_SCR_PSIZE_GET
(
dma_scr
);
count
=
stm32_dma_read
(
dmadev
,
STM32_DMA_SNDTR
(
chan
->
id
));
residue
+=
count
<<
width
;
}
return
residue
;
return
residue
;
}
}
...
@@ -968,29 +987,35 @@ static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
...
@@ -968,29 +987,35 @@ static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
struct
of_dma
*
ofdma
)
struct
of_dma
*
ofdma
)
{
{
struct
stm32_dma_device
*
dmadev
=
ofdma
->
of_dma_data
;
struct
stm32_dma_device
*
dmadev
=
ofdma
->
of_dma_data
;
struct
device
*
dev
=
dmadev
->
ddev
.
dev
;
struct
stm32_dma_cfg
cfg
;
struct
stm32_dma_cfg
cfg
;
struct
stm32_dma_chan
*
chan
;
struct
stm32_dma_chan
*
chan
;
struct
dma_chan
*
c
;
struct
dma_chan
*
c
;
if
(
dma_spec
->
args_count
<
3
)
if
(
dma_spec
->
args_count
<
4
)
{
dev_err
(
dev
,
"Bad number of cells
\n
"
);
return
NULL
;
return
NULL
;
}
cfg
.
channel_id
=
dma_spec
->
args
[
0
];
cfg
.
channel_id
=
dma_spec
->
args
[
0
];
cfg
.
request_line
=
dma_spec
->
args
[
1
];
cfg
.
request_line
=
dma_spec
->
args
[
1
];
cfg
.
stream_config
=
dma_spec
->
args
[
2
];
cfg
.
stream_config
=
dma_spec
->
args
[
2
];
cfg
.
threshold
=
0
;
cfg
.
threshold
=
dma_spec
->
args
[
3
]
;
if
((
cfg
.
channel_id
>=
STM32_DMA_MAX_CHANNELS
)
||
(
cfg
.
request_line
>=
if
((
cfg
.
channel_id
>=
STM32_DMA_MAX_CHANNELS
)
||
STM32_DMA_MAX_REQUEST_ID
))
(
cfg
.
request_line
>=
STM32_DMA_MAX_REQUEST_ID
))
{
dev_err
(
dev
,
"Bad channel and/or request id
\n
"
);
return
NULL
;
return
NULL
;
}
if
(
dma_spec
->
args_count
>
3
)
cfg
.
threshold
=
dma_spec
->
args
[
3
];
chan
=
&
dmadev
->
chan
[
cfg
.
channel_id
];
chan
=
&
dmadev
->
chan
[
cfg
.
channel_id
];
c
=
dma_get_slave_channel
(
&
chan
->
vchan
.
chan
);
c
=
dma_get_slave_channel
(
&
chan
->
vchan
.
chan
);
if
(
c
)
if
(
!
c
)
{
dev_err
(
dev
,
"No more channel avalaible
\n
"
);
return
NULL
;
}
stm32_dma_set_config
(
chan
,
&
cfg
);
stm32_dma_set_config
(
chan
,
&
cfg
);
return
c
;
return
c
;
...
@@ -1055,6 +1080,7 @@ static int stm32_dma_probe(struct platform_device *pdev)
...
@@ -1055,6 +1080,7 @@ static int stm32_dma_probe(struct platform_device *pdev)
dd
->
device_prep_dma_cyclic
=
stm32_dma_prep_dma_cyclic
;
dd
->
device_prep_dma_cyclic
=
stm32_dma_prep_dma_cyclic
;
dd
->
device_config
=
stm32_dma_slave_config
;
dd
->
device_config
=
stm32_dma_slave_config
;
dd
->
device_terminate_all
=
stm32_dma_terminate_all
;
dd
->
device_terminate_all
=
stm32_dma_terminate_all
;
dd
->
device_synchronize
=
stm32_dma_synchronize
;
dd
->
src_addr_widths
=
BIT
(
DMA_SLAVE_BUSWIDTH_1_BYTE
)
|
dd
->
src_addr_widths
=
BIT
(
DMA_SLAVE_BUSWIDTH_1_BYTE
)
|
BIT
(
DMA_SLAVE_BUSWIDTH_2_BYTES
)
|
BIT
(
DMA_SLAVE_BUSWIDTH_2_BYTES
)
|
BIT
(
DMA_SLAVE_BUSWIDTH_4_BYTES
);
BIT
(
DMA_SLAVE_BUSWIDTH_4_BYTES
);
...
@@ -1063,6 +1089,7 @@ static int stm32_dma_probe(struct platform_device *pdev)
...
@@ -1063,6 +1089,7 @@ static int stm32_dma_probe(struct platform_device *pdev)
BIT
(
DMA_SLAVE_BUSWIDTH_4_BYTES
);
BIT
(
DMA_SLAVE_BUSWIDTH_4_BYTES
);
dd
->
directions
=
BIT
(
DMA_DEV_TO_MEM
)
|
BIT
(
DMA_MEM_TO_DEV
);
dd
->
directions
=
BIT
(
DMA_DEV_TO_MEM
)
|
BIT
(
DMA_MEM_TO_DEV
);
dd
->
residue_granularity
=
DMA_RESIDUE_GRANULARITY_BURST
;
dd
->
residue_granularity
=
DMA_RESIDUE_GRANULARITY_BURST
;
dd
->
max_burst
=
STM32_DMA_MAX_BURST
;
dd
->
dev
=
&
pdev
->
dev
;
dd
->
dev
=
&
pdev
->
dev
;
INIT_LIST_HEAD
(
&
dd
->
channels
);
INIT_LIST_HEAD
(
&
dd
->
channels
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录