2019-12-23 04:51:43 +08:00
|
|
|
/**
|
|
|
|
* @file ts2phc_phc_master.c
|
|
|
|
* @note Copyright (C) 2019 Richard Cochran <richardcochran@gmail.com>
|
|
|
|
* @note SPDX-License-Identifier: GPL-2.0+
|
|
|
|
*/
|
|
|
|
#include <linux/ptp_clock.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "phc.h"
|
|
|
|
#include "print.h"
|
|
|
|
#include "missing.h"
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
#include "ts2phc.h"
|
2019-12-23 04:51:43 +08:00
|
|
|
#include "ts2phc_master_private.h"
|
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
struct ts2phc_phc_master {
|
|
|
|
struct ts2phc_master master;
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
struct clock *clock;
|
2019-12-23 04:51:43 +08:00
|
|
|
int channel;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int ts2phc_phc_master_activate(struct config *cfg, const char *dev,
|
|
|
|
struct ts2phc_phc_master *master)
|
|
|
|
{
|
|
|
|
struct ptp_perout_request perout_request;
|
|
|
|
struct ptp_pin_desc desc;
|
ts2phc_phc_master: make use of new kernel API for perout waveform
This API was introduced for 2 reasons:
1. Some hardware can emit PPS signals but not starting from arbitrary
absolute times, but rather phase-aligned to the beginning of a
second. We _could_ patch ts2phc to always specify a start time of
0.000000000 to PTP_PEROUT_REQUEST, but in practice, we would never
know whether that would actually work with all in-tree PHC drivers.
So there was a need for a new flag that only specifies the phase of
the periodic signal, and not the absolute start time.
2. Some hardware can, rather unfortunately, not distinguish between a
rising and a falling extts edge. And, since whatever rises also has
to fall before rising again, the strategy in ts2phc is to set a
'large' pulse width (half the period) and ignore the extts event
corresponding to the mid-way between one second and another. This is
all fine, but currently, ts2phc.pulsewidth is a read-only property in
the config file. The kernel is not instructed in any way to use this
value, it is simply that must be configured based on prior knowledge
of the PHC's implementation. This API changes that.
The introduction of a phase adjustment for the master PHC means we have
to adjust our approximation of the precise perout timestamp. We put that
code into a common function and convert all call sites to call that. We
also need to do the same thing for the edge ignoring logic.
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-05-25 15:57:44 +08:00
|
|
|
int32_t perout_phase;
|
|
|
|
int32_t pulsewidth;
|
2019-12-23 04:51:43 +08:00
|
|
|
struct timespec ts;
|
|
|
|
|
|
|
|
memset(&desc, 0, sizeof(desc));
|
|
|
|
|
|
|
|
master->channel = config_get_int(cfg, dev, "ts2phc.channel");
|
|
|
|
|
|
|
|
desc.index = config_get_int(cfg, dev, "ts2phc.pin_index");
|
|
|
|
desc.func = PTP_PF_PEROUT;
|
|
|
|
desc.chan = master->channel;
|
|
|
|
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
if (phc_pin_setfunc(master->clock->clkid, &desc)) {
|
2019-12-23 04:51:43 +08:00
|
|
|
pr_warning("Failed to set the pin. Continuing bravely on...");
|
|
|
|
}
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
if (clock_gettime(master->clock->clkid, &ts)) {
|
2019-12-23 04:51:43 +08:00
|
|
|
perror("clock_gettime");
|
|
|
|
return -1;
|
|
|
|
}
|
ts2phc_phc_master: make use of new kernel API for perout waveform
This API was introduced for 2 reasons:
1. Some hardware can emit PPS signals but not starting from arbitrary
absolute times, but rather phase-aligned to the beginning of a
second. We _could_ patch ts2phc to always specify a start time of
0.000000000 to PTP_PEROUT_REQUEST, but in practice, we would never
know whether that would actually work with all in-tree PHC drivers.
So there was a need for a new flag that only specifies the phase of
the periodic signal, and not the absolute start time.
2. Some hardware can, rather unfortunately, not distinguish between a
rising and a falling extts edge. And, since whatever rises also has
to fall before rising again, the strategy in ts2phc is to set a
'large' pulse width (half the period) and ignore the extts event
corresponding to the mid-way between one second and another. This is
all fine, but currently, ts2phc.pulsewidth is a read-only property in
the config file. The kernel is not instructed in any way to use this
value, it is simply that must be configured based on prior knowledge
of the PHC's implementation. This API changes that.
The introduction of a phase adjustment for the master PHC means we have
to adjust our approximation of the precise perout timestamp. We put that
code into a common function and convert all call sites to call that. We
also need to do the same thing for the edge ignoring logic.
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-05-25 15:57:44 +08:00
|
|
|
perout_phase = config_get_int(cfg, dev, "ts2phc.perout_phase");
|
2019-12-23 04:51:43 +08:00
|
|
|
memset(&perout_request, 0, sizeof(perout_request));
|
|
|
|
perout_request.index = master->channel;
|
|
|
|
perout_request.period.sec = 1;
|
|
|
|
perout_request.period.nsec = 0;
|
ts2phc_phc_master: make use of new kernel API for perout waveform
This API was introduced for 2 reasons:
1. Some hardware can emit PPS signals but not starting from arbitrary
absolute times, but rather phase-aligned to the beginning of a
second. We _could_ patch ts2phc to always specify a start time of
0.000000000 to PTP_PEROUT_REQUEST, but in practice, we would never
know whether that would actually work with all in-tree PHC drivers.
So there was a need for a new flag that only specifies the phase of
the periodic signal, and not the absolute start time.
2. Some hardware can, rather unfortunately, not distinguish between a
rising and a falling extts edge. And, since whatever rises also has
to fall before rising again, the strategy in ts2phc is to set a
'large' pulse width (half the period) and ignore the extts event
corresponding to the mid-way between one second and another. This is
all fine, but currently, ts2phc.pulsewidth is a read-only property in
the config file. The kernel is not instructed in any way to use this
value, it is simply that must be configured based on prior knowledge
of the PHC's implementation. This API changes that.
The introduction of a phase adjustment for the master PHC means we have
to adjust our approximation of the precise perout timestamp. We put that
code into a common function and convert all call sites to call that. We
also need to do the same thing for the edge ignoring logic.
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-05-25 15:57:44 +08:00
|
|
|
perout_request.flags = 0;
|
|
|
|
pulsewidth = config_get_int(cfg, dev, "ts2phc.pulsewidth");
|
|
|
|
if (pulsewidth) {
|
|
|
|
perout_request.flags |= PTP_PEROUT_DUTY_CYCLE;
|
|
|
|
perout_request.on.sec = pulsewidth / NS_PER_SEC;
|
|
|
|
perout_request.on.nsec = pulsewidth % NS_PER_SEC;
|
|
|
|
}
|
|
|
|
if (perout_phase != -1) {
|
|
|
|
perout_request.flags |= PTP_PEROUT_PHASE;
|
|
|
|
perout_request.phase.sec = perout_phase / NS_PER_SEC;
|
|
|
|
perout_request.phase.nsec = perout_phase % NS_PER_SEC;
|
|
|
|
} else {
|
|
|
|
perout_request.start.sec = ts.tv_sec + 2;
|
|
|
|
perout_request.start.nsec = 0;
|
|
|
|
}
|
2019-12-23 04:51:43 +08:00
|
|
|
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
if (ioctl(CLOCKID_TO_FD(master->clock->clkid), PTP_PEROUT_REQUEST2,
|
|
|
|
&perout_request)) {
|
2019-12-23 04:51:43 +08:00
|
|
|
pr_err(PTP_PEROUT_REQUEST_FAILED);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ts2phc_phc_master_destroy(struct ts2phc_master *master)
|
|
|
|
{
|
|
|
|
struct ts2phc_phc_master *m =
|
|
|
|
container_of(master, struct ts2phc_phc_master, master);
|
|
|
|
struct ptp_perout_request perout_request;
|
|
|
|
|
|
|
|
memset(&perout_request, 0, sizeof(perout_request));
|
|
|
|
perout_request.index = m->channel;
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
if (ioctl(CLOCKID_TO_FD(m->clock->clkid), PTP_PEROUT_REQUEST2,
|
|
|
|
&perout_request)) {
|
2019-12-23 04:51:43 +08:00
|
|
|
pr_err(PTP_PEROUT_REQUEST_FAILED);
|
|
|
|
}
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
clock_destroy(m->clock);
|
2019-12-23 04:51:43 +08:00
|
|
|
free(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ts2phc_phc_master_getppstime(struct ts2phc_master *m,
|
|
|
|
struct timespec *ts)
|
|
|
|
{
|
|
|
|
struct ts2phc_phc_master *master =
|
|
|
|
container_of(m, struct ts2phc_phc_master, master);
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
return clock_gettime(master->clock->clkid, ts);
|
2019-12-23 04:51:43 +08:00
|
|
|
}
|
|
|
|
|
2020-08-01 19:28:50 +08:00
|
|
|
struct clock *ts2phc_phc_master_get_clock(struct ts2phc_master *m)
|
|
|
|
{
|
|
|
|
struct ts2phc_phc_master *master =
|
|
|
|
container_of(m, struct ts2phc_phc_master, master);
|
|
|
|
|
|
|
|
return master->clock;
|
|
|
|
}
|
|
|
|
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
struct ts2phc_master *ts2phc_phc_master_create(struct ts2phc_private *priv,
|
2019-12-23 04:51:43 +08:00
|
|
|
const char *dev)
|
|
|
|
{
|
|
|
|
struct ts2phc_phc_master *master;
|
|
|
|
|
|
|
|
master = calloc(1, sizeof(*master));
|
|
|
|
if (!master) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
master->master.destroy = ts2phc_phc_master_destroy;
|
|
|
|
master->master.getppstime = ts2phc_phc_master_getppstime;
|
2020-08-01 19:28:50 +08:00
|
|
|
master->master.get_clock = ts2phc_phc_master_get_clock;
|
2019-12-23 04:51:43 +08:00
|
|
|
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
master->clock = clock_add(priv, dev);
|
|
|
|
if (!master->clock) {
|
2019-12-23 04:51:43 +08:00
|
|
|
free(master);
|
|
|
|
return NULL;
|
|
|
|
}
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
master->clock->is_destination = 0;
|
2019-12-23 04:51:43 +08:00
|
|
|
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
pr_debug("PHC master %s has ptp index %d", dev,
|
|
|
|
master->clock->phc_index);
|
2019-12-23 04:51:43 +08:00
|
|
|
|
ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.
When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).
This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.
This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-07-28 07:52:16 +08:00
|
|
|
if (ts2phc_phc_master_activate(priv->cfg, dev, master)) {
|
2019-12-23 04:51:43 +08:00
|
|
|
ts2phc_phc_master_destroy(&master->master);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return &master->master;
|
|
|
|
}
|