Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
2e76eba5
Commit
2e76eba5
authored
Jul 04, 2017
by
Vinod Koul
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/pl330' into for-linus
parents
98cd085e
d43674ec
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
66 additions
and
76 deletions
+66
-76
drivers/dma/pl330.c
drivers/dma/pl330.c
+66
-76
No files found.
drivers/dma/pl330.c
View file @
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment