Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC ADC 100M 14b 4cha
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
FMC ADC 100M 14b 4cha
Commits
abfec267
Commit
abfec267
authored
Sep 15, 2020
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drv: fix SVEC DMA
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
1581e43e
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
109 additions
and
39 deletions
+109
-39
fa-dma.c
kernel/fa-dma.c
+96
-37
fmc-adc-100m14b4ch-svec-core.c
kernel/fmc-adc-100m14b4ch-svec-core.c
+13
-2
No files found.
kernel/fa-dma.c
View file @
abfec267
...
...
@@ -216,6 +216,44 @@ static unsigned int zfad_block_n_pages(struct zio_block *block)
#ifdef CONFIG_FMC_ADC_SVEC
#define ADC_VME_DDR_ADDR 0x00
#define ADC_VME_DDR_DATA 0x04
#define SVEC_FUNC_NR 1
/* HARD coded in SVEC */
static
unsigned
long
fa_ddr_data_vme_addr
(
struct
fa_dev
*
fa
)
{
struct
fmc_adc_platform_data
*
data
=
fa
->
pdev
->
dev
.
platform_data
;
struct
vme_dev
*
vdev
;
unsigned
long
addr
;
vdev
=
to_vme_dev
(
fa
->
pdev
->
dev
.
parent
->
parent
->
parent
->
parent
);
if
(
WARN
(
vdev
->
map
[
SVEC_FUNC_NR
].
kernel_va
==
NULL
,
"Invalid VME function
\n
"
))
return
~
0
;
/* invalid address, we will see VME errors */
WARN
(
data
->
vme_ddr_offset
==
0
,
"Invalid DDR DATA offset"
);
addr
=
vdev
->
map
[
SVEC_FUNC_NR
].
vme_addrl
;
addr
+=
data
->
vme_ddr_offset
+
ADC_VME_DDR_DATA
;
return
addr
;
}
static
void
*
fa_ddr_addr_reg_off
(
struct
fa_dev
*
fa
)
{
struct
fmc_adc_platform_data
*
data
=
fa
->
pdev
->
dev
.
platform_data
;
struct
vme_dev
*
vdev
;
void
*
addr
;
vdev
=
to_vme_dev
(
fa
->
pdev
->
dev
.
parent
->
parent
->
parent
->
parent
);
if
(
WARN
(
vdev
->
map
[
SVEC_FUNC_NR
].
kernel_va
==
NULL
,
"Invalid VME function
\n
"
))
return
NULL
;
/* invalid address, we will see VME errors */
addr
=
vdev
->
map
[
SVEC_FUNC_NR
].
kernel_va
;
addr
+=
data
->
vme_ddr_offset
+
ADC_VME_DDR_ADDR
;
return
addr
;
}
#define VME_NO_ADDR_INCREMENT 1
/* FIXME: move to include again */
...
...
@@ -273,39 +311,46 @@ static int zfad_dma_block_to_pages(struct page **pages, unsigned int nr_pages,
}
static
void
zfad_dma_context_exit
(
struct
zio_cset
*
cset
,
static
void
zfad_dma_context_exit
_svec
(
struct
zio_cset
*
cset
,
struct
zfad_block
*
zfad_block
)
{
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
{
__endianness
(
zfad_block
->
block
->
datalen
,
zfad_block
->
block
->
data
);
kfree
(
zfad_block
->
dma_ctx
);
}
}
static
void
zfad_dma_context_exit
(
struct
zio_cset
*
cset
,
struct
zfad_block
*
zfad_block
)
{
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
/**
* It initialize the DMA context for the given block transfer
*/
static
int
zfad_dma_context_init
(
struct
zio_cset
*
cset
,
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
zfad_dma_context_exit_svec
(
cset
,
zfad_block
);
}
static
int
zfad_dma_context_init_svec
(
struct
zio_cset
*
cset
,
struct
zfad_block
*
zfad_block
)
{
#ifdef CONFIG_FMC_ADC_SVEC
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
)))
{
struct
fa_svec_data
*
svec_data
=
fa
->
carrier_data
;
unsigned
long
vme_addr
;
struct
vme_dma
*
desc
;
int
err
;
dev_dbg
(
&
fa
->
pdev
->
dev
,
"SVEC build DMA context
\n
"
);
desc
=
kmalloc
(
sizeof
(
struct
vme_dma
),
GFP_ATOMIC
);
if
(
!
desc
)
return
-
ENOMEM
;
if
(
zfad_block
==
cset
->
interleave
->
priv_d
)
{
void
*
addr
=
fa_ddr_addr_reg_off
(
fa
);
if
(
!
addr
)
{
err
=
-
ENODEV
;
goto
err_reg_addr
;
}
/*
* Only for the first block:
* write the data address in the ddr_addr register: this
...
...
@@ -314,19 +359,33 @@ static int zfad_dma_context_init(struct zio_cset *cset,
* Be careful: the SVEC HW version expects an address of 32bits word
* therefore mem-offset in byte is translated into 32bit word
*/
fa_writel
(
fa
,
svec_data
->
fa_dma_ddr_addr
,
&
fa_svec_regfield
[
FA_DMA_DDR_ADDR
],
zfad_block
->
dev_mem_off
/
4
);
fa_iowrite
(
fa
,
zfad_block
->
sconfig
.
src_addr
/
4
,
addr
);
}
zfad_block
->
dma_ctx
=
desc
;
vme_addr
=
svec_data
->
vme_base
+
svec_data
->
fa_dma_ddr_data
;
build_dma_desc
(
desc
,
vme_addr
,
build_dma_desc
(
desc
,
fa_ddr_data_vme_addr
(
fa
),
zfad_block
->
block
->
data
,
zfad_block
->
block
->
datalen
);
}
return
0
;
err_reg_addr:
kfree
(
desc
);
return
err
;
#else
return
0
;
#endif
}
/**
* It initialize the DMA context for the given block transfer
*/
static
int
zfad_dma_context_init
(
struct
zio_cset
*
cset
,
struct
zfad_block
*
zfad_block
)
{
struct
fa_dev
*
fa
=
cset
->
zdev
->
priv_d
;
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
return
zfad_dma_context_init_svec
(
cset
,
zfad_block
);
return
0
;
}
...
...
kernel/fmc-adc-100m14b4ch-svec-core.c
View file @
abfec267
...
...
@@ -12,6 +12,17 @@
#include "platform_data/fmc-adc-100m14b4cha.h"
/*
* From SVEC but we do not want to add a dependency for these 4 registers
* which should never change by design. If they do, and you end up here:
* sorry! It shouldn't have happened.
*/
#define SVEC_BASE_REGS_CSR 0x40UL
#define SVEC_FPGA_CSR_DDR4_ADDR (SVEC_BASE_REGS_CSR + 0x18)
#define SVEC_FPGA_CSR_DDR4_DATA (SVEC_BASE_REGS_CSR + 0x1C)
#define SVEC_FPGA_CSR_DDR5_ADDR (SVEC_BASE_REGS_CSR + 0x20)
#define SVEC_FPGA_CSR_DDR5_DATA (SVEC_BASE_REGS_CSR + 0x24)
enum
fa_svec_dev_offsets
{
FA_SVEC_ADC1_MEM_START
=
0x000002000
,
FA_SVEC_ADC1_MEM_END
=
0x00003FFF
,
...
...
@@ -21,7 +32,7 @@ enum fa_svec_dev_offsets {
static
struct
fmc_adc_platform_data
fmc_adc_pdata1
=
{
.
flags
=
FMC_ADC_BIG_ENDIAN
|
FMC_ADC_SVEC
,
.
vme_ddr_offset
=
0x1000
,
.
vme_ddr_offset
=
SVEC_FPGA_CSR_DDR4_ADDR
,
.
calib_trig_time
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_internal
=
0
,
...
...
@@ -30,7 +41,7 @@ static struct fmc_adc_platform_data fmc_adc_pdata1 = {
static
struct
fmc_adc_platform_data
fmc_adc_pdata2
=
{
.
flags
=
FMC_ADC_BIG_ENDIAN
|
FMC_ADC_SVEC
,
.
vme_ddr_offset
=
0x2000
,
.
vme_ddr_offset
=
SVEC_FPGA_CSR_DDR5_ADDR
,
.
calib_trig_time
=
0
,
.
calib_trig_threshold
=
0
,
.
calib_trig_internal
=
0
,
...
...
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