Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC TDC 1ns 5cha
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
1
Merge Requests
1
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 TDC 1ns 5cha
Commits
2a19a588
Commit
2a19a588
authored
Sep 19, 2019
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sw:drv: review calibration
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
a7ab2109
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
161 additions
and
89 deletions
+161
-89
Kbuild
kernel/Kbuild
+8
-5
Makefile
kernel/Makefile
+9
-1
calibration.c
kernel/calibration.c
+54
-80
fmc-tdc.h
kernel/fmc-tdc.h
+4
-1
ft-core.c
kernel/ft-core.c
+86
-2
No files found.
kernel/Kbuild
View file @
2a19a588
# ZIO comes from the Makefile
KBUILD_EXTRA_SYMBOLS := \
$(ZIO_ABS)/Module.symvers \
KBUILD_EXTRA_SYMBOLS += $(ZIO_EXTRA_SYMBOLS-y)
KBUILD_EXTRA_SYMBOLS += $(FMC_EXTRA_SYMBOLS-y)
ccflags-y = -DGIT_VERSION=\"$(GIT_VERSION)\"
ccflags-y += -I$(src)
ccflags-y += -I$(ZIO_ABS)/include
ccflags-y += -I$(FMC_ABS)/include
ccflags-y = -DGIT_VERSION=\"$(GIT_VERSION)\" \
-I$(src) \
-I$(ZIO_ABS)/include \
ccflags-$(CONFIG_FMC_TDC_DEBUG) += -DDEBUG
ccflags-$(CONFIG_FMC_TDC_VERBOSE_DEBUG) += -DVERBOSE_DEBUG
...
...
kernel/Makefile
View file @
2a19a588
...
...
@@ -11,6 +11,10 @@ ZIO ?= ../zio
# ZIO_ABS has to be absolut path, due to beeing
# passed to the Kbuild
ZIO_ABS
?=
$
(
abspath
$(ZIO)
)
ZIO_EXTRA_SYMBOLS-y
=
$(ZIO_ABS)
/Module.symvers
FMC_ABS
?=
$
(
abspath
$(FMC)
)
FMC_EXTRA_SYMBOLS-y
=
$(FMC_ABS)
/drivers/fmc/Module.symvers
GIT_VERSION
=
$(
shell
git describe
--always
--dirty
--long
--tags
)
export
GIT_VERSION
...
...
@@ -24,7 +28,11 @@ CPPCHECK ?= cppcheck
all
:
modules
modules_install modules
:
$(MAKE)
-C
$(LINUX)
M
=
$(
shell
/bin/pwd
)
ZIO_ABS
=
$(ZIO_ABS)
SPEC_SW_ABS
=
$(SPEC_SW_ABS)
$@
$(MAKE)
-C
$(LINUX)
M
=
$(
shell
/bin/pwd
)
\
ZIO_ABS
=
$(ZIO_ABS)
FMC_ABS
=
$(FMC_ABS)
\
ZIO_EXTRA_SYMBOLS-y
=
$
(
ZIO_EXTRA_SYMBOLS-y
)
\
FMC_EXTRA_SYMBOLS-y
=
$
(
FMC_EXTRA_SYMBOLS-y
)
\
SPEC_SW_ABS
=
$(SPEC_SW_ABS)
$@
clean
:
$(MAKE)
-C
$(LINUX)
M
=
$(
shell
/bin/pwd
)
$@
...
...
kernel/calibration.c
View file @
2a19a588
...
...
@@ -13,10 +13,10 @@
#include <linux/firmware.h>
#include <linux/jhash.h>
#include <linux/slab.h>
#include <linux/fmc.h>
#include <linux/ipmi-fru.h>
#include <linux/zio.h>
#include "libsdbfs.h"
#include "fmc-tdc.h"
#define WR_CALIB_OFFSET 229460
...
...
@@ -40,36 +40,7 @@ static struct ft_calibration default_calibration = {
};
#define WR_OFFSET_FIX_YEAR (2018)
/* sdbfs-related function */
static
int
ft_read_calibration_eeprom
(
struct
fmc_device
*
fmc
,
void
*
buf
,
int
length
)
{
int
i
,
ret
=
0
;
static
struct
sdbfs
fs
;
fs
.
data
=
fmc
->
eeprom
;
fs
.
datalen
=
fmc
->
eeprom_len
;
/* Look for sdb entry point */
for
(
i
=
0x40
;
i
<
fmc
->
eeprom_len
-
0x40
;
i
+=
0x40
)
{
fs
.
entrypoint
=
i
;
ret
=
sdbfs_dev_create
(
&
fs
,
0
);
if
(
ret
==
0
)
break
;
}
if
(
ret
)
return
ret
;
/* Open "cali" as a device id, vendor is "FileData" -- big endian */
ret
=
sdbfs_open_name
(
&
fs
,
"calib"
);
if
(
ret
)
return
ret
;
ret
=
sdbfs_fread
(
&
fs
,
0
,
buf
,
length
);
sdbfs_dev_destroy
(
&
fs
);
return
ret
;
}
#define IPMI_FRU_SIZE 256
/**
* HACK area to get the calibration year
...
...
@@ -79,31 +50,37 @@ static u32 __get_ipmi_fru_id_year(struct fmctdc_dev *ft)
struct
fru_board_info_area
*
bia
;
struct
fru_type_length
*
tmp
;
unsigned
long
year
=
0
;
char
*
buf
=
NULL
;
char
year_ascii
[
5
];
void
*
fru
=
NULL
;
int
err
,
i
;
bia
=
fru_get_board_area
((
const
struct
fru_common_header
*
)
ft
->
fmc
->
eeprom
);
fru
=
kmalloc
(
IPMI_FRU_SIZE
,
GFP_KERNEL
);
if
(
!
fru
)
goto
out_mem
;
err
=
fmc_slot_eeprom_read
(
ft
->
slot
,
fru
,
0x0
,
IPMI_FRU_SIZE
);
if
(
err
)
goto
out_read
;
bia
=
fru_get_board_area
((
const
struct
fru_common_header
*
)
fru
);
tmp
=
bia
->
tl
;
for
(
i
=
0
;
i
<
4
;
++
i
)
{
tmp
=
fru_next_tl
(
tmp
);
if
(
!
tmp
)
goto
out
;
goto
out
_fru
;
}
if
(
!
fru_length
(
tmp
))
goto
out
;
goto
out
_fru
;
if
(
fru_type
(
tmp
)
!=
FRU_TYPE_ASCII
)
goto
out
;
buf
=
kmalloc
(
fru_length
(
tmp
),
GFP_ATOMIC
);
if
(
!
buf
)
goto
out
;
buf
=
fru_strcpy
(
buf
,
tmp
);
buf
[
4
]
=
'\0'
;
err
=
kstrtoul
(
buf
,
10
,
&
year
);
goto
out_fru
;
memcpy
(
year_ascii
,
tmp
->
data
,
4
);
year_ascii
[
4
]
=
'\0'
;
err
=
kstrtoul
(
year_ascii
,
10
,
&
year
);
if
(
err
)
goto
out
;
year
=
0
;
out:
kfree
(
buf
);
out_fru:
out_read:
kfree
(
fru
);
out_mem:
return
year
;
}
...
...
@@ -164,41 +141,6 @@ static void ft_calib_cpy_to_raw(struct ft_calibration_raw *calib_raw,
ft_calib_cpu_to_le32s
(
calib_raw
);
}
/* This is the only thing called by outside */
int
ft_handle_eeprom_calibration
(
struct
fmctdc_dev
*
ft
)
{
struct
ft_calibration
*
calib
;
struct
ft_calibration_raw
calib_raw
;
struct
device
*
d
=
&
ft
->
fmc
->
dev
;
int
i
;
/* Retrieve and validate the calibration */
calib
=
&
ft
->
calib
;
i
=
ft_read_calibration_eeprom
(
ft
->
fmc
,
&
calib_raw
,
sizeof
(
calib_raw
));
if
(
i
>=
0
)
{
u32
year
;
ft_calib_cpy_from_raw
(
calib
,
&
calib_raw
);
year
=
__get_ipmi_fru_id_year
(
ft
);
if
(
year
<
WR_OFFSET_FIX_YEAR
)
{
calib
->
wr_offset
=
wr_calibration_offset
;
calib
->
wr_offset
+=
wr_calibration_offset_carrier
;
dev_warn
(
d
,
"Apply default calibration correction to White-Rabbit offset if done before 2018 (%d)
\n
"
,
year
);
}
}
else
{
dev_err
(
d
,
"Failed to read calibration EEPROM. Using default.
\n
"
);
memcpy
(
calib
,
&
default_calibration
,
sizeof
(
*
calib
));
calib
->
wr_offset
+=
wr_calibration_offset_carrier
;
}
return
0
;
}
static
ssize_t
ft_write_eeprom
(
struct
file
*
file
,
struct
kobject
*
kobj
,
struct
bin_attribute
*
attr
,
char
*
buf
,
loff_t
off
,
size_t
count
)
...
...
@@ -240,3 +182,35 @@ struct bin_attribute dev_attr_calibration = {
.
write
=
ft_write_eeprom
,
.
read
=
ft_read_eeprom
,
};
#define FT_EEPROM_CALIB_OFFSET 0x100
int
ft_calib_init
(
struct
fmctdc_dev
*
ft
)
{
struct
ft_calibration_raw
calib
;
int
ret
;
ret
=
fmc_slot_eeprom_read
(
ft
->
slot
,
&
calib
,
FT_EEPROM_CALIB_OFFSET
,
sizeof
(
calib
));
if
(
ret
<
0
)
{
dev_warn
(
&
ft
->
pdev
->
dev
,
"Failed to read calibration from EEPROM: using identity calibration %d
\n
"
,
ret
);
memcpy
(
&
calib
,
&
default_calibration
,
sizeof
(
calib
));
goto
out
;
}
ft_calib_cpy_from_raw
(
&
ft
->
calib
,
&
calib
);
/* FIX wrong calibration on old FMC-TDC mezzanine */
if
(
__get_ipmi_fru_id_year
(
ft
)
<
WR_OFFSET_FIX_YEAR
)
ft
->
calib
.
wr_offset
=
wr_calibration_offset
;
out:
ft
->
calib
.
wr_offset
+=
wr_calibration_offset_carrier
;
return
0
;
}
void
ft_calib_exit
(
struct
fmctdc_dev
*
ft
)
{
}
kernel/fmc-tdc.h
View file @
2a19a588
...
...
@@ -126,6 +126,7 @@ struct ft_calibration_raw {
#include <linux/timer.h>
#include <linux/version.h>
#include <linux/platform_device.h>
#include <linux/fmc.h>
struct
ft_memory_ops
{
u32
(
*
read
)(
void
*
addr
);
...
...
@@ -247,6 +248,7 @@ struct fmctdc_dev {
void
*
ft_dma_eic_base
;
struct
ft_memory_ops
memops
;
/* IRQ base index (for SVEC) */
struct
fmc_slot
*
slot
;
struct
platform_device
*
pdev
;
struct
zio_device
*
zdev
,
*
hwzdev
;
/* carrier private data */
...
...
@@ -307,6 +309,8 @@ static inline void dma_writel(struct fmctdc_dev *ft, uint32_t data, uint32_t reg
}
int
ft_calib_init
(
struct
fmctdc_dev
*
ft
);
void
ft_calib_exit
(
struct
fmctdc_dev
*
ft
);
void
ft_enable_acquisition
(
struct
fmctdc_dev
*
ft
,
int
enable
);
...
...
@@ -327,7 +331,6 @@ void ft_set_host_time(struct fmctdc_dev *ft);
int
ft_wr_mode
(
struct
fmctdc_dev
*
ft
,
int
on
);
int
ft_wr_query
(
struct
fmctdc_dev
*
ft
);
int
ft_handle_eeprom_calibration
(
struct
fmctdc_dev
*
ft
);
extern
struct
bin_attribute
dev_attr_calibration
;
int
ft_fifo_init
(
struct
fmctdc_dev
*
ft
);
...
...
kernel/ft-core.c
View file @
2a19a588
...
...
@@ -20,6 +20,8 @@
#include <linux/list.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/ipmi-fru.h>
#include <linux/fmc.h>
#include <linux/zio.h>
#include <linux/zio-trigger.h>
...
...
@@ -40,6 +42,7 @@ static int ft_verbose;
module_param_named
(
verbose
,
ft_verbose
,
int
,
0444
);
MODULE_PARM_DESC
(
verbose
,
"Print a lot of debugging messages."
);
#define FT_EEPROM_TYPE "at24c64"
/**
* It sets the coalescing timeout for the DMA buffers
...
...
@@ -639,6 +642,49 @@ static int ft_resource_validation(struct platform_device *pdev)
return
0
;
}
#define FT_FMC_NAME "FmcTdc1ns4cha"
static
bool
ft_fmc_slot_is_valid
(
struct
fmctdc_dev
*
ft
)
{
int
ret
;
void
*
fru
=
NULL
;
char
*
fmc_name
=
NULL
;
if
(
!
fmc_slot_fru_valid
(
ft
->
slot
))
{
dev_err
(
&
ft
->
pdev
->
dev
,
"Can't identify FMC card: invalid FRU
\n
"
);
return
-
EINVAL
;
}
fru
=
kmalloc
(
FRU_SIZE_MAX
,
GFP_KERNEL
);
if
(
!
fru
)
return
-
ENOMEM
;
ret
=
fmc_slot_eeprom_read
(
ft
->
slot
,
fru
,
0x0
,
FRU_SIZE_MAX
);
if
(
ret
!=
FRU_SIZE_MAX
)
{
dev_err
(
&
ft
->
pdev
->
dev
,
"Failed to read FRU header
\n
"
);
goto
err
;
}
fmc_name
=
fru_get_product_name
(
fru
);
ret
=
strcmp
(
fmc_name
,
FT_FMC_NAME
);
if
(
ret
)
{
dev_err
(
&
ft
->
pdev
->
dev
,
"Invalid FMC card: expectd '%s', found '%s'
\n
"
,
FT_FMC_NAME
,
fmc_name
);
goto
err
;
}
kfree
(
fmc_name
);
kfree
(
fru
);
return
true
;
err:
kfree
(
fmc_name
);
kfree
(
fru
);
return
false
;
}
static
int
ft_endianess
(
struct
fmctdc_dev
*
ft
)
{
switch
(
ft
->
pdev
->
id_entry
->
driver_data
)
{
...
...
@@ -682,6 +728,7 @@ int ft_probe(struct platform_device *pdev)
struct
resource
*
r
;
int
i
,
ret
,
err
;
uint32_t
stat
;
uint32_t
slot_nr
;
err
=
ft_resource_validation
(
pdev
);
if
(
err
)
...
...
@@ -744,9 +791,38 @@ int ft_probe(struct platform_device *pdev)
ret
=
ft_reset_core
(
ft
);
if
(
ret
<
0
)
return
ret
;
slot_nr
=
ft_readl
(
ft
,
FT_REG_FMC_SLOT_ID
)
+
1
;
ft
->
slot
=
fmc_slot_get
(
pdev
->
dev
.
parent
->
parent
,
slot_nr
);
if
(
IS_ERR
(
ft
->
slot
))
{
dev_err
(
&
ft
->
pdev
->
dev
,
"Can't find FMC slot %d err: %ld
\n
"
,
slot_nr
,
PTR_ERR
(
ft
->
slot
));
goto
out_fmc
;
}
if
(
!
fmc_slot_present
(
ft
->
slot
))
{
dev_err
(
&
ft
->
pdev
->
dev
,
"Can't identify FMC card: missing card
\n
"
);
goto
out_fmc_pre
;
}
if
(
strcmp
(
fmc_slot_eeprom_type_get
(
ft
->
slot
),
FT_EEPROM_TYPE
))
{
dev_warn
(
&
ft
->
pdev
->
dev
,
"use non standard EERPOM type
\"
%s
\"\n
"
,
FT_EEPROM_TYPE
);
ret
=
fmc_slot_eeprom_type_set
(
ft
->
slot
,
FT_EEPROM_TYPE
);
if
(
ret
<
0
)
{
dev_err
(
&
ft
->
pdev
->
dev
,
"Failed to change EEPROM type to
\"
%s
\"
"
,
FT_EEPROM_TYPE
);
goto
out_fmc_eeprom
;
}
}
if
(
!
ft_fmc_slot_is_valid
(
ft
))
goto
out_fmc_err
;
/* Retrieve calibration from the eeprom, and validate */
ret
=
ft_handle_eeprom_calibration
(
ft
);
ret
=
ft_calib_init
(
ft
);
if
(
ret
<
0
)
goto
err_calib
;
...
...
@@ -782,7 +858,13 @@ err:
while
(
--
m
,
--
i
>=
0
)
if
(
m
->
exit
)
m
->
exit
(
ft
);
ft_calib_exit
(
ft
);
err_calib:
out_fmc_err:
out_fmc_eeprom:
out_fmc_pre:
fmc_slot_put
(
ft
->
slot
);
out_fmc:
err_mode_selection:
err_memops:
iounmap
(
ft
->
ft_base
);
...
...
@@ -817,6 +899,8 @@ int ft_remove(struct platform_device *pdev)
if
(
m
->
exit
)
m
->
exit
(
ft
);
}
ft_calib_exit
(
ft
);
fmc_slot_put
(
ft
->
slot
);
iounmap
(
ft
->
ft_base
);
iounmap
(
ft
->
ft_carrier_base
);
kfree
(
ft
);
...
...
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