Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC ADC 100M 14b 4cha - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
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 - Software
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
Hide 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,19 +311,70 @@ static int zfad_dma_block_to_pages(struct page **pages, unsigned int nr_pages,
}
static
void
zfad_dma_context_exit_svec
(
struct
zio_cset
*
cset
,
struct
zfad_block
*
zfad_block
)
{
__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
;
if
(
fa_is_flag_set
(
fa
,
FMC_ADC_SVEC
))
{
__endianness
(
zfad_block
->
block
->
datalen
,
zfad_block
->
block
->
data
);
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
;
struct
vme_dma
*
desc
;
int
err
;
dev_dbg
(
&
fa
->
pdev
->
dev
,
"SVEC build DMA context
\n
"
);
kfree
(
zfad_block
->
dma_ctx
);
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
* address has been computed after ACQ_END by looking to the
* trigger position see fa-irq.c::irq_acq_end.
* Be careful: the SVEC HW version expects an address of 32bits word
* therefore mem-offset in byte is translated into 32bit word
*/
fa_iowrite
(
fa
,
zfad_block
->
sconfig
.
src_addr
/
4
,
addr
);
}
}
zfad_block
->
dma_ctx
=
desc
;
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
...
...
@@ -293,40 +382,10 @@ static void zfad_dma_context_exit(struct zio_cset *cset,
static
int
zfad_dma_context_init
(
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
;
desc
=
kmalloc
(
sizeof
(
struct
vme_dma
),
GFP_ATOMIC
);
if
(
!
desc
)
return
-
ENOMEM
;
if
(
zfad_block
==
cset
->
interleave
->
priv_d
)
{
/*
* Only for the first block:
* write the data address in the ddr_addr register: this
* address has been computed after ACQ_END by looking to the
* trigger position see fa-irq.c::irq_acq_end.
* 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
);
}
zfad_block
->
dma_ctx
=
desc
;
vme_addr
=
svec_data
->
vme_base
+
svec_data
->
fa_dma_ddr_data
;
build_dma_desc
(
desc
,
vme_addr
,
zfad_block
->
block
->
data
,
zfad_block
->
block
->
datalen
);
}
#endif
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