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
2cb2cad0
Commit
2cb2cad0
authored
Apr 24, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
time: function to get and set hw time (not working)
parent
650c907b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
133 additions
and
1 deletion
+133
-1
fd-core.c
fd-core.c
+16
-1
fine-delay.h
fine-delay.h
+20
-0
time.c
time.c
+97
-0
No files found.
fd-core.c
View file @
2cb2cad0
...
...
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/list.h>
...
...
@@ -114,7 +115,7 @@ static struct modlist mods[] = {
{
"gpio-default"
,
fd_gpio_defaults
},
{
"reset-again"
,
fd_reset_again
},
SUBSYS
(
acam
),
//
SUBSYS(time),
SUBSYS
(
time
),
//SUBSYS(i2c),
//SUBSYS(zio),
};
...
...
@@ -132,6 +133,7 @@ int fd_probe(struct spec_dev *dev)
pr_err
(
"%s: can't allocate device
\n
"
,
__func__
);
return
-
ENOMEM
;
}
spin_lock_init
(
&
fd
->
lock
);
dev
->
sub_priv
=
fd
;
fd
->
spec
=
dev
;
fd
->
base
=
dev
->
remap
[
0
];
...
...
@@ -165,6 +167,19 @@ int fd_probe(struct spec_dev *dev)
/* Finally, enable the input */
fd_writel
(
fd
,
FD_GCR_INPUT_EN
,
FD_REG_GCR
);
if
(
1
)
{
struct
timespec
ts1
,
ts2
,
ts3
;
/* Temporarily, test the time stuff */
fd_time_set
(
fd
,
NULL
,
NULL
);
fd_time_get
(
fd
,
NULL
,
&
ts1
);
msleep
(
100
);
fd_time_get
(
fd
,
NULL
,
&
ts2
);
getnstimeofday
(
&
ts3
);
printk
(
"%li.%li
\n
%li.%li
\n
%li.%li
\n
"
,
ts1
.
tv_sec
,
ts1
.
tv_nsec
,
ts2
.
tv_sec
,
ts2
.
tv_nsec
,
ts3
.
tv_sec
,
ts3
.
tv_nsec
);
}
return
0
;
err:
...
...
fine-delay.h
View file @
2cb2cad0
...
...
@@ -42,6 +42,16 @@ struct spec_fd {
int
temp
;
/* scaled by 4 bits */
};
/* Internal time: the first three fields are just converted to zio time */
struct
fd_time
{
int64_t
utc
;
int32_t
coarse
;
int32_t
frac
;
int
channel
;
uint16_t
seq_id
;
};
static
inline
uint32_t
fd_readl
(
struct
spec_fd
*
fd
,
unsigned
long
reg
)
{
return
readl
(
fd
->
regs
+
reg
);
...
...
@@ -134,6 +144,16 @@ extern void fd_gpio_set_clr(struct spec_fd *fd, int pin, int set);
#define fd_gpio_set(fd, pin) fd_gpio_set_clr((fd), (pin), 1)
#define fd_gpio_clr(fd, pin) fd_gpio_set_clr((fd), (pin), 0)
/* Functions exported by time.c */
extern
int
fd_time_init
(
struct
spec_fd
*
fd
);
extern
void
fd_time_exit
(
struct
spec_fd
*
fd
);
extern
int
fd_time_set
(
struct
spec_fd
*
fd
,
struct
fd_time
*
t
,
struct
timespec
*
ts
);
extern
int
fd_time_get
(
struct
spec_fd
*
fd
,
struct
fd_time
*
t
,
struct
timespec
*
ts
);
/* Functions exported by fd-zio.c */
extern
int
fd_zio_register
(
void
);
extern
void
fd_zio_unregister
(
void
);
...
...
time.c
View file @
2cb2cad0
/*
* SPI access to fine-delay internals
*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include <linux/io.h>
#include <linux/time.h>
#include <linux/spinlock.h>
#include "fine-delay.h"
#include "hw/fd_main_regs.h"
/* If fd_time is not null, use it. if ts is not null, use it, else current */
int
fd_time_set
(
struct
spec_fd
*
fd
,
struct
fd_time
*
t
,
struct
timespec
*
ts
)
{
uint32_t
tcr
;
unsigned
long
flags
;
struct
timespec
localts
;
spin_lock_irqsave
(
&
fd
->
lock
,
flags
);
fd_writel
(
fd
,
0
,
FD_REG_GCR
);
if
(
t
)
{
fd_writel
(
fd
,
t
->
utc
>>
32
,
FD_REG_TM_SECH
);
fd_writel
(
fd
,
t
->
utc
&
0xffffffff
,
FD_REG_TM_SECL
);
fd_writel
(
fd
,
t
->
coarse
,
FD_REG_TM_CYCLES
);
}
else
{
if
(
!
ts
)
{
/* no caller-provided time: use Linux timer */
ts
=
&
localts
;
getnstimeofday
(
ts
);
}
if
(
BITS_PER_LONG
>
32
)
fd_writel
(
fd
,
ts
->
tv_sec
>>
32
,
FD_REG_TM_SECH
);
else
fd_writel
(
fd
,
0
,
FD_REG_TM_SECH
);
fd_writel
(
fd
,
(
int32_t
)
ts
->
tv_sec
,
FD_REG_TM_SECL
);
fd_writel
(
fd
,
ts
->
tv_nsec
>>
3
,
FD_REG_TM_CYCLES
);
}
tcr
=
fd_readl
(
fd
,
FD_REG_TCR
);
fd_writel
(
fd
,
tcr
|
FD_TCR_SET_TIME
,
FD_REG_TCR
);
spin_unlock_irqrestore
(
&
fd
->
lock
,
flags
);
return
0
;
}
/* If fd_time is not null, use it. Otherwise use ts */
int
fd_time_get
(
struct
spec_fd
*
fd
,
struct
fd_time
*
t
,
struct
timespec
*
ts
)
{
uint32_t
h1
,
l1
,
h2
,
l2
,
c
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
fd
->
lock
,
flags
);
/* get the tuple. If inconsistent re-read the high part */
h1
=
fd_readl
(
fd
,
FD_REG_TM_SECH
);
l1
=
fd_readl
(
fd
,
FD_REG_TM_SECL
);
c
=
fd_readl
(
fd
,
FD_REG_TM_CYCLES
);
h2
=
fd_readl
(
fd
,
FD_REG_TM_SECH
);
l2
=
fd_readl
(
fd
,
FD_REG_TM_SECL
);
if
(
h2
!=
h1
||
l2
!=
l1
)
{
c
=
fd_readl
(
fd
,
FD_REG_TM_CYCLES
);
h1
=
h2
;
l1
=
l2
;
}
spin_unlock_irqrestore
(
&
fd
->
lock
,
flags
);
printk
(
"got %i %i %i
\n
"
,
h1
,
l1
,
c
);
if
(
t
)
{
t
->
utc
=
((
uint64_t
)
h1
<<
32
)
|
l1
;
t
->
coarse
=
c
;
}
if
(
ts
)
{
ts
->
tv_sec
=
((
uint64_t
)
h1
<<
32
)
|
l1
;
ts
->
tv_nsec
=
c
*
8
;
}
return
0
;
}
int
fd_time_init
(
struct
spec_fd
*
fd
)
{
/* nothing to do */
return
0
;
}
void
fd_time_exit
(
struct
spec_fd
*
fd
)
{
/* nothing to do */
}
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