Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC DEL 1ns 4cha - Software
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 DEL 1ns 4cha - Software
Commits
8924b43d
Commit
8924b43d
authored
Jul 16, 2014
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel: add comments to explain driver behavior
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
ebdd9e63
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
42 additions
and
5 deletions
+42
-5
calibrate.c
kernel/calibrate.c
+12
-1
fd-core.c
kernel/fd-core.c
+10
-1
fd-zio.c
kernel/fd-zio.c
+20
-3
No files found.
kernel/calibrate.c
View file @
8924b43d
...
@@ -152,6 +152,7 @@ static int fd_find_8ns_tap(struct fd_dev *fd, int ch)
...
@@ -152,6 +152,7 @@ static int fd_find_8ns_tap(struct fd_dev *fd, int ch)
* Measure the delay at zero setting, so it can be further
* Measure the delay at zero setting, so it can be further
* subtracted to get only the delay part introduced by the
* subtracted to get only the delay part introduced by the
* delay line (ingoring the TDC, FPGA and routing delays).
* delay line (ingoring the TDC, FPGA and routing delays).
* Use a binary search of the delay value.
*/
*/
bias
=
output_delay_ps
(
fd
,
ch
,
0
,
FD_CAL_STEPS
,
NULL
);
bias
=
output_delay_ps
(
fd
,
ch
,
0
,
FD_CAL_STEPS
,
NULL
);
while
(
r
-
l
>
1
)
{
while
(
r
-
l
>
1
)
{
...
@@ -174,6 +175,12 @@ static int fd_find_8ns_tap(struct fd_dev *fd, int ch)
...
@@ -174,6 +175,12 @@ static int fd_find_8ns_tap(struct fd_dev *fd, int ch)
}
}
/**
* fd_calibrate_outputs
* It calibrates the delay line by finding the correct 8ns-tap value
* for each channel. This is done during ACAM initialization, so on driver
* probe.
*/
int
fd_calibrate_outputs
(
struct
fd_dev
*
fd
)
int
fd_calibrate_outputs
(
struct
fd_dev
*
fd
)
{
{
int
ret
,
ch
;
int
ret
,
ch
;
...
@@ -206,7 +213,11 @@ int fd_calibrate_outputs(struct fd_dev *fd)
...
@@ -206,7 +213,11 @@ int fd_calibrate_outputs(struct fd_dev *fd)
return
0
;
return
0
;
}
}
/* Called from a timer any few seconds */
/**
* fd_update_calibration
* Called from a timer any few seconds. It updates the Delay line tap
* according to the measured temperature
*/
void
fd_update_calibration
(
unsigned
long
arg
)
void
fd_update_calibration
(
unsigned
long
arg
)
{
{
struct
fd_dev
*
fd
=
(
void
*
)
arg
;
struct
fd_dev
*
fd
=
(
void
*
)
arg
;
...
...
kernel/fd-core.c
View file @
8924b43d
...
@@ -41,10 +41,18 @@ module_param_named(show_sdb, fd_show_sdb, int, 0444);
...
@@ -41,10 +41,18 @@ module_param_named(show_sdb, fd_show_sdb, int, 0444);
/* FIXME: add parameters "file=" and "wrc=" like wr-nic-core does */
/* FIXME: add parameters "file=" and "wrc=" like wr-nic-core does */
/* The reset function (by Tomasz) */
/**
* fd_do_reset
* The reset function (by Tomasz)
*
* This function can reset the entire mezzanine (FMC) or just
* the fine-delay core (CORE).
* In the reset register 0 means reset, 1 means normal operation.
*/
static
void
fd_do_reset
(
struct
fd_dev
*
fd
,
int
hw_reset
)
static
void
fd_do_reset
(
struct
fd_dev
*
fd
,
int
hw_reset
)
{
{
if
(
hw_reset
)
{
if
(
hw_reset
)
{
/* clear RSTS_RST_FMC bit, set RSTS_RST_CORE bit*/
fd_writel
(
fd
,
FD_RSTR_LOCK_W
(
0xdead
)
|
FD_RSTR_RST_CORE_MASK
,
fd_writel
(
fd
,
FD_RSTR_LOCK_W
(
0xdead
)
|
FD_RSTR_RST_CORE_MASK
,
FD_REG_RSTR
);
FD_REG_RSTR
);
udelay
(
10000
);
udelay
(
10000
);
...
@@ -55,6 +63,7 @@ static void fd_do_reset(struct fd_dev *fd, int hw_reset)
...
@@ -55,6 +63,7 @@ static void fd_do_reset(struct fd_dev *fd, int hw_reset)
return
;
return
;
}
}
/* clear RSTS_RST_CORE bit, set RSTS_RST_FMC bit */
fd_writel
(
fd
,
FD_RSTR_LOCK_W
(
0xdead
)
|
FD_RSTR_RST_FMC_MASK
,
fd_writel
(
fd
,
FD_RSTR_LOCK_W
(
0xdead
)
|
FD_RSTR_RST_FMC_MASK
,
FD_REG_RSTR
);
FD_REG_RSTR
);
udelay
(
1000
);
udelay
(
1000
);
...
...
kernel/fd-zio.c
View file @
8924b43d
...
@@ -540,40 +540,54 @@ static int __fd_zio_output(struct fd_dev *fd, int index1_4, uint32_t *attrs)
...
@@ -540,40 +540,54 @@ static int __fd_zio_output(struct fd_dev *fd, int index1_4, uint32_t *attrs)
fd
->
calib
.
tdc_zero_offset
);
fd
->
calib
.
tdc_zero_offset
);
}
}
/* Apply offset to START timestamp */
fd_apply_offset
(
attrs
+
FD_ATTR_OUT_START_H
,
fd_apply_offset
(
attrs
+
FD_ATTR_OUT_START_H
,
fd
->
calib
.
zero_offset
[
ch
]);
fd
->
calib
.
zero_offset
[
ch
]);
fd_apply_offset
(
attrs
+
FD_ATTR_OUT_START_H
,
fd_apply_offset
(
attrs
+
FD_ATTR_OUT_START_H
,
fd
->
ch_user_offset
[
ch
]);
fd
->
ch_user_offset
[
ch
]);
/* Apply offset to END timestamp */
fd_apply_offset
(
attrs
+
FD_ATTR_OUT_END_H
,
fd_apply_offset
(
attrs
+
FD_ATTR_OUT_END_H
,
fd
->
calib
.
zero_offset
[
ch
]);
fd
->
calib
.
zero_offset
[
ch
]);
fd_apply_offset
(
attrs
+
FD_ATTR_OUT_END_H
,
fd_apply_offset
(
attrs
+
FD_ATTR_OUT_END_H
,
fd
->
ch_user_offset
[
ch
]);
fd
->
ch_user_offset
[
ch
]);
/* Update Fine Register with calibrated value */
fd_ch_writel
(
fd
,
ch
,
fd
->
ch
[
ch
].
frr_cur
,
FD_REG_FRR
);
fd_ch_writel
(
fd
,
ch
,
fd
->
ch
[
ch
].
frr_cur
,
FD_REG_FRR
);
/* Write Pulse Start Absolute Time */
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_H
],
FD_REG_U_STARTH
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_H
],
FD_REG_U_STARTH
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_L
],
FD_REG_U_STARTL
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_L
],
FD_REG_U_STARTL
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_COARSE
],
FD_REG_C_START
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_COARSE
],
FD_REG_C_START
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_FINE
],
FD_REG_F_START
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_START_FINE
],
FD_REG_F_START
);
/* Write Pulse End Absolute Time */
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_H
],
FD_REG_U_ENDH
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_H
],
FD_REG_U_ENDH
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_L
],
FD_REG_U_ENDL
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_L
],
FD_REG_U_ENDL
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_COARSE
],
FD_REG_C_END
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_COARSE
],
FD_REG_C_END
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_FINE
],
FD_REG_F_END
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_END_FINE
],
FD_REG_F_END
);
/* Write clock cycles between rasing edges of output pulses */
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_L
],
FD_REG_U_DELTA
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_L
],
FD_REG_U_DELTA
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_COARSE
],
FD_REG_C_DELTA
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_COARSE
],
FD_REG_C_DELTA
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_FINE
],
FD_REG_F_DELTA
);
fd_ch_writel
(
fd
,
ch
,
attrs
[
FD_ATTR_OUT_DELTA_FINE
],
FD_REG_F_DELTA
);
/*
* Configure the number of repetitions and the operational mode.
* The Fine delay always add an extra pulse to the repetition
* counter, so remove it on our side in order to produce exactly
* the number of pulses requested
*/
if
(
mode
==
FD_OUT_MODE_DELAY
||
mode
==
FD_OUT_MODE_DISABLED
)
{
if
(
mode
==
FD_OUT_MODE_DELAY
||
mode
==
FD_OUT_MODE_DISABLED
)
{
/* Delay Mode */
dcr
=
0
;
dcr
=
0
;
fd_ch_writel
(
fd
,
ch
,
FD_RCR_REP_CNT_W
(
rep
-
1
)
fd_ch_writel
(
fd
,
ch
,
FD_RCR_REP_CNT_W
(
rep
-
1
)
|
(
rep
<
0
?
FD_RCR_CONT
:
0
),
FD_REG_RCR
);
|
(
rep
<
0
?
FD_RCR_CONT
:
0
),
FD_REG_RCR
);
}
else
{
}
else
{
dcr
=
FD_DCR_MODE
;
/* Pulse Mode */
dcr
=
FD_DCR_MODE
;
/* Set pulse mode */
fd_ch_writel
(
fd
,
ch
,
FD_RCR_REP_CNT_W
(
rep
<
0
?
0
:
rep
-
1
)
fd_ch_writel
(
fd
,
ch
,
FD_RCR_REP_CNT_W
(
rep
<
0
?
0
:
rep
-
1
)
|
(
rep
<
0
?
FD_RCR_CONT
:
0
),
FD_REG_RCR
);
|
(
rep
<
0
?
FD_RCR_CONT
:
0
),
FD_REG_RCR
);
}
}
...
@@ -620,13 +634,16 @@ static int __fd_zio_output(struct fd_dev *fd, int index1_4, uint32_t *attrs)
...
@@ -620,13 +634,16 @@ static int __fd_zio_output(struct fd_dev *fd, int index1_4, uint32_t *attrs)
if
(
delta
.
tv_sec
==
0
&&
delta
.
tv_nsec
<
200
)
if
(
delta
.
tv_sec
==
0
&&
delta
.
tv_nsec
<
200
)
dcr
|=
FD_DCR_NO_FINE
;
dcr
|=
FD_DCR_NO_FINE
;
/* Configure Fine Delay output */
fd_ch_writel
(
fd
,
ch
,
dcr
,
FD_REG_DCR
);
fd_ch_writel
(
fd
,
ch
,
dcr
,
FD_REG_DCR
);
/* Update the time stamps according to start/end registers */
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_UPDATE
,
FD_REG_DCR
);
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_UPDATE
,
FD_REG_DCR
);
/* Enable channel output */
if
(
mode
==
FD_OUT_MODE_DELAY
)
{
if
(
mode
==
FD_OUT_MODE_DELAY
)
{
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_ENABLE
,
FD_REG_DCR
);
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_ENABLE
,
FD_REG_DCR
);
}
else
if
(
mode
==
FD_OUT_MODE_PULSE
)
{
}
else
if
(
mode
==
FD_OUT_MODE_PULSE
)
{
/* ... and arm the pulse generator */
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_ENABLE
|
FD_DCR_PG_ARM
,
FD_REG_DCR
);
fd_ch_writel
(
fd
,
ch
,
dcr
|
FD_DCR_ENABLE
|
FD_DCR_PG_ARM
,
FD_REG_DCR
);
}
}
return
0
;
return
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