Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
dma_ip_drivers
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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
dma_ip_drivers
Commits
b3e6af5e
Unverified
Commit
b3e6af5e
authored
Oct 07, 2020
by
Karen Xie
Committed by
GitHub
Oct 07, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #77 from jberaud/pr/adjacent-desc
libxdma: fix next adjacent descriptors
parents
cf2efd16
f1e834be
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
56 additions
and
35 deletions
+56
-35
XDMA/linux-kernel/libxdma/libxdma.c
XDMA/linux-kernel/libxdma/libxdma.c
+54
-34
XDMA/linux-kernel/libxdma/libxdma.h
XDMA/linux-kernel/libxdma/libxdma.h
+2
-1
No files found.
XDMA/linux-kernel/libxdma/libxdma.c
View file @
b3e6af5e
...
@@ -602,6 +602,35 @@ static int engine_start_mode_config(struct xdma_engine *engine)
...
@@ -602,6 +602,35 @@ static int engine_start_mode_config(struct xdma_engine *engine)
return
0
;
return
0
;
}
}
/**
* xdma_get_next_adj()
*
* Get the number for adjacent descriptors to set in a descriptor, based on the
* remaining number of descriptors and the lower bits of the address of the
* next descriptor.
* Since the number of descriptors in a page (XDMA_PAGE_SIZE) is 128 and the
* maximum size of a block of adjacent descriptors is 64 (63 max adjacent
* descriptors for any descriptor), align the blocks of adjacent descriptors
* to the block size.
*/
static
u32
xdma_get_next_adj
(
unsigned
int
remaining
,
u32
next_lo
)
{
unsigned
int
next_index
;
dbg_desc
(
"%s: remaining_desc %u, next_lo 0x%x
\n
"
,
__func__
,
remaining
,
next_lo
);
if
(
remaining
<=
1
)
return
0
;
/* shift right 5 times corresponds to a division by
* sizeof(xdma_desc) = 32
*/
next_index
=
((
next_lo
&
(
XDMA_PAGE_SIZE
-
1
))
>>
5
)
%
XDMA_MAX_ADJ_BLOCK_SIZE
;
return
min
(
XDMA_MAX_ADJ_BLOCK_SIZE
-
next_index
-
1
,
remaining
-
1
);
}
/**
/**
* engine_start() - start an idle engine with its first transfer on queue
* engine_start() - start an idle engine with its first transfer on queue
*
*
...
@@ -621,8 +650,7 @@ static int engine_start_mode_config(struct xdma_engine *engine)
...
@@ -621,8 +650,7 @@ static int engine_start_mode_config(struct xdma_engine *engine)
static
struct
xdma_transfer
*
engine_start
(
struct
xdma_engine
*
engine
)
static
struct
xdma_transfer
*
engine_start
(
struct
xdma_engine
*
engine
)
{
{
struct
xdma_transfer
*
transfer
;
struct
xdma_transfer
*
transfer
;
u32
w
;
u32
w
,
next_adj
;
int
extra_adj
=
0
;
int
rv
;
int
rv
;
if
(
!
engine
)
{
if
(
!
engine
)
{
...
@@ -682,15 +710,14 @@ static struct xdma_transfer *engine_start(struct xdma_engine *engine)
...
@@ -682,15 +710,14 @@ static struct xdma_transfer *engine_start(struct xdma_engine *engine)
(
unsigned
long
)(
&
engine
->
sgdma_regs
->
first_desc_hi
)
-
(
unsigned
long
)(
&
engine
->
sgdma_regs
->
first_desc_hi
)
-
(
unsigned
long
)(
&
engine
->
sgdma_regs
));
(
unsigned
long
)(
&
engine
->
sgdma_regs
));
if
(
transfer
->
desc_adjacent
>
0
)
{
next_adj
=
xdma_get_next_adj
(
transfer
->
desc_adjacent
,
extra_adj
=
transfer
->
desc_adjacent
-
1
;
cpu_to_le32
(
PCI_DMA_L
(
transfer
->
desc_bus
)));
if
(
extra_adj
>
MAX_EXTRA_ADJ
)
extra_adj
=
MAX_EXTRA_ADJ
;
dbg_tfr
(
"iowrite32(0x%08x to 0x%p) (first_desc_adjacent)
\n
"
,
next_adj
,
}
dbg_tfr
(
"iowrite32(0x%08x to 0x%p) (first_desc_adjacent)
\n
"
,
extra_adj
,
(
void
*
)
&
engine
->
sgdma_regs
->
first_desc_adjacent
);
(
void
*
)
&
engine
->
sgdma_regs
->
first_desc_adjacent
);
write_register
(
write_register
(
extra
_adj
,
&
engine
->
sgdma_regs
->
first_desc_adjacent
,
next
_adj
,
&
engine
->
sgdma_regs
->
first_desc_adjacent
,
(
unsigned
long
)(
&
engine
->
sgdma_regs
->
first_desc_adjacent
)
-
(
unsigned
long
)(
&
engine
->
sgdma_regs
->
first_desc_adjacent
)
-
(
unsigned
long
)(
&
engine
->
sgdma_regs
));
(
unsigned
long
)(
&
engine
->
sgdma_regs
));
...
@@ -2439,6 +2466,7 @@ static int transfer_desc_init(struct xdma_transfer *transfer, int count)
...
@@ -2439,6 +2466,7 @@ static int transfer_desc_init(struct xdma_transfer *transfer, int count)
desc_virt
[
i
].
next_lo
=
cpu_to_le32
(
PCI_DMA_L
(
desc_bus
));
desc_virt
[
i
].
next_lo
=
cpu_to_le32
(
PCI_DMA_L
(
desc_bus
));
desc_virt
[
i
].
next_hi
=
cpu_to_le32
(
PCI_DMA_H
(
desc_bus
));
desc_virt
[
i
].
next_hi
=
cpu_to_le32
(
PCI_DMA_H
(
desc_bus
));
desc_virt
[
i
].
bytes
=
cpu_to_le32
(
0
);
desc_virt
[
i
].
bytes
=
cpu_to_le32
(
0
);
desc_virt
[
i
].
control
=
cpu_to_le32
(
DESC_MAGIC
);
desc_virt
[
i
].
control
=
cpu_to_le32
(
DESC_MAGIC
);
}
}
/* { i = number - 1 } */
/* { i = number - 1 } */
...
@@ -2490,16 +2518,12 @@ static void xdma_desc_link(struct xdma_desc *first, struct xdma_desc *second,
...
@@ -2490,16 +2518,12 @@ static void xdma_desc_link(struct xdma_desc *first, struct xdma_desc *second,
}
}
/* xdma_desc_adjacent -- Set how many descriptors are adjacent to this one */
/* xdma_desc_adjacent -- Set how many descriptors are adjacent to this one */
static
void
xdma_desc_adjacent
(
struct
xdma_desc
*
desc
,
int
next_adjacent
)
static
void
xdma_desc_adjacent
(
struct
xdma_desc
*
desc
,
u32
next_adjacent
)
{
{
/* remember reserved and control bits */
/* remember reserved and control bits */
u32
control
=
le32_to_cpu
(
desc
->
control
)
&
0xffffc0ffUL
;
u32
control
=
le32_to_cpu
(
desc
->
control
)
&
0x0000f0ffUL
;
/* merge adjacent and control field */
if
(
next_adjacent
)
control
|=
0xAD4B0000UL
|
(
next_adjacent
<<
8
);
next_adjacent
=
next_adjacent
-
1
;
if
(
next_adjacent
>
MAX_EXTRA_ADJ
)
next_adjacent
=
MAX_EXTRA_ADJ
;
control
|=
(
next_adjacent
<<
8
);
/* write control and next_adjacent */
/* write control and next_adjacent */
desc
->
control
=
cpu_to_le32
(
control
);
desc
->
control
=
cpu_to_le32
(
control
);
}
}
...
@@ -3142,7 +3166,6 @@ static int transfer_init(struct xdma_engine *engine,
...
@@ -3142,7 +3166,6 @@ static int transfer_init(struct xdma_engine *engine,
unsigned
int
desc_max
=
min_t
(
unsigned
int
,
unsigned
int
desc_max
=
min_t
(
unsigned
int
,
req
->
sw_desc_cnt
-
req
->
sw_desc_idx
,
req
->
sw_desc_cnt
-
req
->
sw_desc_idx
,
XDMA_TRANSFER_MAX_DESC
);
XDMA_TRANSFER_MAX_DESC
);
unsigned
int
desc_align
=
0
;
int
i
=
0
;
int
i
=
0
;
int
last
=
0
;
int
last
=
0
;
u32
control
;
u32
control
;
...
@@ -3180,16 +3203,7 @@ static int transfer_init(struct xdma_engine *engine,
...
@@ -3180,16 +3203,7 @@ static int transfer_init(struct xdma_engine *engine,
xfer
,
(
u64
)
xfer
->
desc_bus
);
xfer
,
(
u64
)
xfer
->
desc_bus
);
transfer_build
(
engine
,
req
,
xfer
,
desc_max
);
transfer_build
(
engine
,
req
,
xfer
,
desc_max
);
/*
xfer
->
desc_adjacent
=
desc_max
;
* Contiguous descriptors cannot cross PAGE boundary
* The 1st descriptor may start in the middle of the page,
* calculate the 1st block of adj desc accordingly
*/
desc_align
=
128
-
(
engine
->
desc_idx
%
128
)
-
1
;
if
(
desc_align
>
(
desc_max
-
1
))
desc_align
=
desc_max
-
1
;
xfer
->
desc_adjacent
=
desc_align
;
/* terminate last descriptor */
/* terminate last descriptor */
last
=
desc_max
-
1
;
last
=
desc_max
-
1
;
...
@@ -3205,11 +3219,13 @@ static int transfer_init(struct xdma_engine *engine,
...
@@ -3205,11 +3219,13 @@ static int transfer_init(struct xdma_engine *engine,
engine
->
desc_used
+=
desc_max
;
engine
->
desc_used
+=
desc_max
;
/* fill in adjacent numbers */
/* fill in adjacent numbers */
for
(
i
=
0
;
i
<
xfer
->
desc_num
&&
desc_align
;
i
++
,
desc_align
--
)
for
(
i
=
0
;
i
<
xfer
->
desc_num
;
i
++
)
{
xdma_desc_adjacent
(
xfer
->
desc_virt
+
i
,
desc_align
);
u32
next_adj
=
xdma_get_next_adj
(
xfer
->
desc_num
-
i
-
1
,
(
xfer
->
desc_virt
+
i
)
->
next_lo
);
for
(;
i
<
xfer
->
desc_num
;
i
++
)
dbg_desc
(
"set next adj at index %d to %u
\n
"
,
i
,
next_adj
);
xdma_desc_adjacent
(
xfer
->
desc_virt
+
i
,
xfer
->
desc_num
-
i
-
1
);
xdma_desc_adjacent
(
xfer
->
desc_virt
+
i
,
next_adj
);
}
spin_unlock_irqrestore
(
&
engine
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
engine
->
lock
,
flags
);
return
0
;
return
0
;
...
@@ -3267,8 +3283,12 @@ static int transfer_init_cyclic(struct xdma_engine *engine,
...
@@ -3267,8 +3283,12 @@ static int transfer_init_cyclic(struct xdma_engine *engine,
dbg_sg
(
"transfer 0x%p has %d descriptors
\n
"
,
xfer
,
xfer
->
desc_num
);
dbg_sg
(
"transfer 0x%p has %d descriptors
\n
"
,
xfer
,
xfer
->
desc_num
);
/* fill in adjacent numbers */
/* fill in adjacent numbers */
for
(
i
=
0
;
i
<
xfer
->
desc_num
;
i
++
)
for
(
i
=
0
;
i
<
xfer
->
desc_num
;
i
++
)
{
xdma_desc_adjacent
(
xfer
->
desc_virt
+
i
,
xfer
->
desc_num
-
i
-
1
);
u32
next_adj
=
xdma_get_next_adj
(
xfer
->
desc_num
-
i
-
1
,
(
xfer
->
desc_virt
+
i
)
->
next_lo
);
dbg_desc
(
"set next adj at index %d to %u
\n
"
,
i
,
next_adj
);
xdma_desc_adjacent
(
xfer
->
desc_virt
+
i
,
next_adj
);
}
return
0
;
return
0
;
}
}
...
...
XDMA/linux-kernel/libxdma/libxdma.h
View file @
b3e6af5e
...
@@ -58,7 +58,8 @@
...
@@ -58,7 +58,8 @@
* .REG_IRQ_OUT (reg_irq_from_ch[(channel*2) +: 2]),
* .REG_IRQ_OUT (reg_irq_from_ch[(channel*2) +: 2]),
*/
*/
#define XDMA_ENG_IRQ_NUM (1)
#define XDMA_ENG_IRQ_NUM (1)
#define MAX_EXTRA_ADJ (0x3F)
#define XDMA_MAX_ADJ_BLOCK_SIZE 0x40
#define XDMA_PAGE_SIZE 0x1000
#define RX_STATUS_EOP (1)
#define RX_STATUS_EOP (1)
/* Target internal components on XDMA control BAR */
/* Target internal components on XDMA control BAR */
...
...
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