Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
2e76eba5
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看板
提交
2e76eba5
编写于
7月 04, 2017
作者:
V
Vinod Koul
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/pl330' into for-linus
上级
98cd085e
d43674ec
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
66 addition
and
76 deletion
+66
-76
drivers/dma/pl330.c
drivers/dma/pl330.c
+66
-76
未找到文件。
drivers/dma/pl330.c
浏览文件 @
2e76eba5
...
...
@@ -443,7 +443,10 @@ struct dma_pl330_chan {
/* For D-to-M and M-to-D channels */
int
burst_sz
;
/* the peripheral fifo width */
int
burst_len
;
/* the number of burst */
dma_addr_t
fifo_addr
;
phys_addr_t
fifo_addr
;
/* DMA-mapped view of the FIFO; may differ if an IOMMU is present */
dma_addr_t
fifo_dma
;
enum
dma_data_direction
dir
;
/* for cyclic capability */
bool
cyclic
;
...
...
@@ -538,11 +541,6 @@ struct _xfer_spec {
struct
dma_pl330_desc
*
desc
;
};
static
inline
bool
_queue_empty
(
struct
pl330_thread
*
thrd
)
{
return
thrd
->
req
[
0
].
desc
==
NULL
&&
thrd
->
req
[
1
].
desc
==
NULL
;
}
static
inline
bool
_queue_full
(
struct
pl330_thread
*
thrd
)
{
return
thrd
->
req
[
0
].
desc
!=
NULL
&&
thrd
->
req
[
1
].
desc
!=
NULL
;
...
...
@@ -564,23 +562,6 @@ static inline u32 get_revision(u32 periph_id)
return
(
periph_id
>>
PERIPH_REV_SHIFT
)
&
PERIPH_REV_MASK
;
}
static
inline
u32
_emit_ADDH
(
unsigned
dry_run
,
u8
buf
[],
enum
pl330_dst
da
,
u16
val
)
{
if
(
dry_run
)
return
SZ_DMAADDH
;
buf
[
0
]
=
CMD_DMAADDH
;
buf
[
0
]
|=
(
da
<<
1
);
buf
[
1
]
=
val
;
buf
[
2
]
=
val
>>
8
;
PL330_DBGCMD_DUMP
(
SZ_DMAADDH
,
"
\t
DMAADDH %s %u
\n
"
,
da
==
1
?
"DA"
:
"SA"
,
val
);
return
SZ_DMAADDH
;
}
static
inline
u32
_emit_END
(
unsigned
dry_run
,
u8
buf
[])
{
if
(
dry_run
)
...
...
@@ -738,18 +719,6 @@ static inline u32 _emit_MOV(unsigned dry_run, u8 buf[],
return
SZ_DMAMOV
;
}
static
inline
u32
_emit_NOP
(
unsigned
dry_run
,
u8
buf
[])
{
if
(
dry_run
)
return
SZ_DMANOP
;
buf
[
0
]
=
CMD_DMANOP
;
PL330_DBGCMD_DUMP
(
SZ_DMANOP
,
"
\t
DMANOP
\n
"
);
return
SZ_DMANOP
;
}
static
inline
u32
_emit_RMB
(
unsigned
dry_run
,
u8
buf
[])
{
if
(
dry_run
)
...
...
@@ -817,39 +786,6 @@ static inline u32 _emit_STP(unsigned dry_run, u8 buf[],
return
SZ_DMASTP
;
}
static
inline
u32
_emit_STZ
(
unsigned
dry_run
,
u8
buf
[])
{
if
(
dry_run
)
return
SZ_DMASTZ
;
buf
[
0
]
=
CMD_DMASTZ
;
PL330_DBGCMD_DUMP
(
SZ_DMASTZ
,
"
\t
DMASTZ
\n
"
);
return
SZ_DMASTZ
;
}
static
inline
u32
_emit_WFE
(
unsigned
dry_run
,
u8
buf
[],
u8
ev
,
unsigned
invalidate
)
{
if
(
dry_run
)
return
SZ_DMAWFE
;
buf
[
0
]
=
CMD_DMAWFE
;
ev
&=
0x1f
;
ev
<<=
3
;
buf
[
1
]
=
ev
;
if
(
invalidate
)
buf
[
1
]
|=
(
1
<<
1
);
PL330_DBGCMD_DUMP
(
SZ_DMAWFE
,
"
\t
DMAWFE %u%s
\n
"
,
ev
>>
3
,
invalidate
?
", I"
:
""
);
return
SZ_DMAWFE
;
}
static
inline
u32
_emit_WFP
(
unsigned
dry_run
,
u8
buf
[],
enum
pl330_cond
cond
,
u8
peri
)
{
...
...
@@ -2120,11 +2056,60 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
return
1
;
}
/*
* We need the data direction between the DMAC (the dma-mapping "device") and
* the FIFO (the dmaengine "dev"), from the FIFO's point of view. Confusing!
*/
static
enum
dma_data_direction
pl330_dma_slave_map_dir
(
enum
dma_transfer_direction
dir
)
{
switch
(
dir
)
{
case
DMA_MEM_TO_DEV
:
return
DMA_FROM_DEVICE
;
case
DMA_DEV_TO_MEM
:
return
DMA_TO_DEVICE
;
case
DMA_DEV_TO_DEV
:
return
DMA_BIDIRECTIONAL
;
default:
return
DMA_NONE
;
}
}
static
void
pl330_unprep_slave_fifo
(
struct
dma_pl330_chan
*
pch
)
{
if
(
pch
->
dir
!=
DMA_NONE
)
dma_unmap_resource
(
pch
->
chan
.
device
->
dev
,
pch
->
fifo_dma
,
1
<<
pch
->
burst_sz
,
pch
->
dir
,
0
);
pch
->
dir
=
DMA_NONE
;
}
static
bool
pl330_prep_slave_fifo
(
struct
dma_pl330_chan
*
pch
,
enum
dma_transfer_direction
dir
)
{
struct
device
*
dev
=
pch
->
chan
.
device
->
dev
;
enum
dma_data_direction
dma_dir
=
pl330_dma_slave_map_dir
(
dir
);
/* Already mapped for this config? */
if
(
pch
->
dir
==
dma_dir
)
return
true
;
pl330_unprep_slave_fifo
(
pch
);
pch
->
fifo_dma
=
dma_map_resource
(
dev
,
pch
->
fifo_addr
,
1
<<
pch
->
burst_sz
,
dma_dir
,
0
);
if
(
dma_mapping_error
(
dev
,
pch
->
fifo_dma
))
return
false
;
pch
->
dir
=
dma_dir
;
return
true
;
}
static
int
pl330_config
(
struct
dma_chan
*
chan
,
struct
dma_slave_config
*
slave_config
)
{
struct
dma_pl330_chan
*
pch
=
to_pchan
(
chan
);
pl330_unprep_slave_fifo
(
pch
);
if
(
slave_config
->
direction
==
DMA_MEM_TO_DEV
)
{
if
(
slave_config
->
dst_addr
)
pch
->
fifo_addr
=
slave_config
->
dst_addr
;
...
...
@@ -2235,6 +2220,7 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
spin_unlock_irqrestore
(
&
pl330
->
lock
,
flags
);
pm_runtime_mark_last_busy
(
pch
->
dmac
->
ddma
.
dev
);
pm_runtime_put_autosuspend
(
pch
->
dmac
->
ddma
.
dev
);
pl330_unprep_slave_fifo
(
pch
);
}
static
int
pl330_get_current_xferred_count
(
struct
dma_pl330_chan
*
pch
,
...
...
@@ -2564,6 +2550,9 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
return
NULL
;
}
if
(
!
pl330_prep_slave_fifo
(
pch
,
direction
))
return
NULL
;
for
(
i
=
0
;
i
<
len
/
period_len
;
i
++
)
{
desc
=
pl330_get_desc
(
pch
);
if
(
!
desc
)
{
...
...
@@ -2593,12 +2582,12 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
desc
->
rqcfg
.
src_inc
=
1
;
desc
->
rqcfg
.
dst_inc
=
0
;
src
=
dma_addr
;
dst
=
pch
->
fifo_
addr
;
dst
=
pch
->
fifo_
dma
;
break
;
case
DMA_DEV_TO_MEM
:
desc
->
rqcfg
.
src_inc
=
0
;
desc
->
rqcfg
.
dst_inc
=
1
;
src
=
pch
->
fifo_
addr
;
src
=
pch
->
fifo_
dma
;
dst
=
dma_addr
;
break
;
default:
...
...
@@ -2711,12 +2700,12 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
struct
dma_pl330_chan
*
pch
=
to_pchan
(
chan
);
struct
scatterlist
*
sg
;
int
i
;
dma_addr_t
addr
;
if
(
unlikely
(
!
pch
||
!
sgl
||
!
sg_len
))
return
NULL
;
addr
=
pch
->
fifo_addr
;
if
(
!
pl330_prep_slave_fifo
(
pch
,
direction
))
return
NULL
;
first
=
NULL
;
...
...
@@ -2742,13 +2731,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
if
(
direction
==
DMA_MEM_TO_DEV
)
{
desc
->
rqcfg
.
src_inc
=
1
;
desc
->
rqcfg
.
dst_inc
=
0
;
fill_px
(
&
desc
->
px
,
addr
,
sg_dma_address
(
sg
),
sg_dma_len
(
sg
));
fill_px
(
&
desc
->
px
,
pch
->
fifo_dma
,
sg_dma_address
(
sg
),
sg_dma_len
(
sg
));
}
else
{
desc
->
rqcfg
.
src_inc
=
0
;
desc
->
rqcfg
.
dst_inc
=
1
;
fill_px
(
&
desc
->
px
,
sg_dma_
address
(
sg
),
addr
,
sg_dma_
len
(
sg
));
fill_px
(
&
desc
->
px
,
sg_dma_address
(
sg
),
pch
->
fifo_dma
,
sg_dma_len
(
sg
));
}
desc
->
rqcfg
.
brst_size
=
pch
->
burst_sz
;
...
...
@@ -2906,6 +2895,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
pch
->
thread
=
NULL
;
pch
->
chan
.
device
=
pd
;
pch
->
dmac
=
pl330
;
pch
->
dir
=
DMA_NONE
;
/* Add the channel to the DMAC list */
list_add_tail
(
&
pch
->
chan
.
device_node
,
&
pd
->
channels
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录