Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1531783 > unrolled thread
| Started by | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| First post | 2016-11-29 00:10 +0100 |
| Last post | 2016-12-05 20:40 +0100 |
| Articles | 20 on this page of 28 — 5 participants |
Back to article view | Back to linux.kernel
[PATCH 0/6] net: ethernet: ti: cpts: update and enable support on keystone 2 socs Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
[PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Richard Cochran <richardcochran@gmail.com> - 2016-11-30 11:00 +0100
Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-30 18:40 +0100
Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Grygorii Strashko <grygorii.strashko@ti.com> - 2016-12-06 20:50 +0100
Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Richard Cochran <richardcochran@gmail.com> - 2016-12-06 21:30 +0100
Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Grygorii Strashko <grygorii.strashko@ti.com> - 2016-12-06 21:50 +0100
Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Stephen Boyd <sboyd@codeaurora.org> - 2016-12-09 01:50 +0100
Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Grygorii Strashko <grygorii.strashko@ti.com> - 2016-12-10 00:40 +0100
Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection Rob Herring <robh@kernel.org> - 2016-12-05 16:00 +0100
[PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Richard Cochran <richardcochran@gmail.com> - 2016-11-30 11:10 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Richard Cochran <richardcochran@gmail.com> - 2016-12-06 19:10 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Grygorii Strashko <grygorii.strashko@ti.com> - 2016-12-06 23:40 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Jan Lübbe <jlu@pengutronix.de> - 2016-11-30 12:10 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Richard Cochran <richardcochran@gmail.com> - 2016-11-30 19:50 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-30 21:50 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Richard Cochran <richardcochran@gmail.com> - 2016-11-30 23:20 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Richard Cochran <richardcochran@gmail.com> - 2016-12-02 11:00 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Grygorii Strashko <grygorii.strashko@ti.com> - 2016-12-02 19:00 +0100
Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support Richard Cochran <richardcochran@gmail.com> - 2016-12-02 20:30 +0100
[PATCH 1/6] net: ethernet: ti: netcp: add support of cpts Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH 1/6] net: ethernet: ti: netcp: add support of cpts Richard Cochran <richardcochran@gmail.com> - 2016-11-30 10:50 +0100
Re: [PATCH 1/6] net: ethernet: ti: netcp: add support of cpts Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-30 18:40 +0100
Re: [PATCH 1/6] net: ethernet: ti: netcp: add support of cpts Richard Cochran <richardcochran@gmail.com> - 2016-11-30 19:30 +0100
Re: [PATCH 1/6] net: ethernet: ti: netcp: add support of cpts Rob Herring <robh@kernel.org> - 2016-12-05 15:50 +0100
Re: [PATCH 1/6] net: ethernet: ti: netcp: add support of cpts Grygorii Strashko <grygorii.strashko@ti.com> - 2016-12-05 19:30 +0100
Re: [PATCH 1/6] net: ethernet: ti: netcp: add support of cpts Richard Cochran <richardcochran@gmail.com> - 2016-12-05 20:40 +0100
Page 1 of 2 [1] 2 Next page →
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH 0/6] net: ethernet: ti: cpts: update and enable support on keystone 2 socs |
| Message-ID | <sIDdD-75-21@gated-at.bofh.it> |
Time Synchronization (CPTS) submodule which is present on KeyStone 66AK2HK/E/L/Gx
1G Switch Subsystem provides the same basic functionality as OMAP CPSW CPTS, but
with few additional features:
- CPTS rftclk selection (reg CPTS_RFTCLK_SEL). This feature is declared
to be supported on am437x SoCs also.
- CPTS HW_TS_PUSH events which can be generated by external low frequency
time stamp channels (66AK2E/L/Gx, am437x)
- one Time Stamp Compare (TS_COMP) output which is reused for PTP PPS feature
implementation (66AK2E/L/Gx).
Hence, This series enables basic CPTS support on Keystone 2 SoCs by resuing
current CPSW CPTS driver.
Links on docs:
66AK2H/kx http://www.ti.com/lit/pdf/sprugv9
66AK2E/Lx http://www.ti.com/lit/pdf/spruhz3
66AK2Gx http://www.ti.com/lit/pdf/spruhy8
Note. This series based on top of preparation series
"[PATCH v2 00/13] net: ethernet: ti: cpts: update and fixes"
Tested on am437x-idk, am57xx-evm, 66AK2HK, 66AK2E, 66AK2G
Tests:
server: ptp4l -E -2 -H -i eth0 -l 6 -m -q -p /dev/ptp0
client: ptp4l -E -2 -H -i eth0 -l 6 -m -q -p /dev/ptp0 -s
testptp -g && sleep X && testptp -g
testptp -c
testptp -g
testptp -s
testptp -k 25
testptp -e 3
testptp -P 1 && .ppstest /dev/pps0
Grygorii Strashko (4):
net: ethernet: ti: cpts: add support for ext rftclk selection
net: ethernet: ti: cpts: add support of cpts HW_TS_PUSH
net: ethernet: ti: cpts: add ptp pps support
ARM: dts: keystone: enable time synchronization (cpts) submodule
Murali Karicheri (1):
ARM: keystone: dts: fix netcp clocks and add names
WingMan Kwok (1):
net: ethernet: ti: netcp: add support of cpts
Documentation/devicetree/bindings/net/cpsw.txt | 4 +
.../devicetree/bindings/net/keystone-netcp.txt | 25 ++
arch/arm/boot/dts/keystone-k2e-netcp.dtsi | 6 +-
arch/arm/boot/dts/keystone-k2hk-netcp.dtsi | 4 +-
arch/arm/boot/dts/keystone-k2l-netcp.dtsi | 6 +-
drivers/net/ethernet/ti/Kconfig | 7 +-
drivers/net/ethernet/ti/cpts.c | 343 +++++++++++++++-
drivers/net/ethernet/ti/cpts.h | 28 +-
drivers/net/ethernet/ti/netcp.h | 2 +-
drivers/net/ethernet/ti/netcp_core.c | 18 +-
drivers/net/ethernet/ti/netcp_ethss.c | 437 ++++++++++++++++++++-
11 files changed, 853 insertions(+), 27 deletions(-)
--
2.10.1
[toc] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sIDdE-75-53@gated-at.bofh.it> |
| In reply to | #1531783 |
Some CPTS instances, which can be found on KeyStone 2 1/10G Ethernet
Switch Subsystems, can control an external multiplexer that selects
one of up to 32 clocks for time sync reference (RFTCLK). This feature
can be configured through CPTS_RFTCLK_SEL register (offset: x08).
Hence, introduce optional DT cpts_rftclk_sel poperty wich, if present,
will specify CPTS reference clock. The cpts_rftclk_sel should be
omitted in DT if HW doesn't support this feature. The external fixed
rate clocks can be defined in board files as "fixed-clock".
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/keystone-netcp.txt | 2 ++
drivers/net/ethernet/ti/cpts.c | 12 ++++++++++++
drivers/net/ethernet/ti/cpts.h | 8 +++++++-
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/keystone-netcp.txt b/Documentation/devicetree/bindings/net/keystone-netcp.txt
index c37b54e..ec4a241 100644
--- a/Documentation/devicetree/bindings/net/keystone-netcp.txt
+++ b/Documentation/devicetree/bindings/net/keystone-netcp.txt
@@ -114,6 +114,8 @@ Optional properties:
driver to them if needed.
Properties related to cpts configurations.
+ - cpts-rftclk-sel: selects one of up to 32 clocks for time sync
+ reference. Default = 0.
- cpts_clock_mult/cpts_clock_shift:
used for converting time counter cycles to ns as in
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index c96a94a..9c5b835 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -459,6 +459,15 @@ static int cpts_of_parse(struct cpts *cpts, struct device_node *node)
(!cpts->cc_mult && cpts->cc.shift))
goto of_error;
+ if (!of_property_read_u32(node, "cpts-rftclk-sel", &prop)) {
+ if (prop & ~CPTS_RFTCLK_SEL_MASK) {
+ dev_err(cpts->dev, "cpts: invalid cpts_rftclk_sel.\n");
+ goto of_error;
+ }
+ cpts->caps |= CPTS_CAP_RFTCLK_SEL;
+ cpts->rftclk_sel = prop & CPTS_RFTCLK_SEL_MASK;
+ }
+
return 0;
of_error:
@@ -496,6 +505,9 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
clk_prepare(cpts->refclk);
+ if (cpts->caps & CPTS_CAP_RFTCLK_SEL)
+ cpts_write32(cpts, cpts->rftclk_sel, rftclk_sel);
+
cpts->cc.read = cpts_systim_read;
cpts->cc.mask = CLOCKSOURCE_MASK(32);
cpts->info = cpts_info;
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index c96eca2..c934b61 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -35,7 +35,7 @@
struct cpsw_cpts {
u32 idver; /* Identification and version */
u32 control; /* Time sync control */
- u32 res1;
+ u32 rftclk_sel; /* Reference Clock Select Register */
u32 ts_push; /* Time stamp event push */
u32 ts_load_val; /* Time stamp load value */
u32 ts_load_en; /* Time stamp load enable */
@@ -67,6 +67,8 @@ struct cpsw_cpts {
#define INT_TEST (1<<1) /* Interrupt Test */
#define CPTS_EN (1<<0) /* Time Sync Enable */
+#define CPTS_RFTCLK_SEL_MASK 0x1f
+
/*
* Definitions for the single bit resisters:
* TS_PUSH TS_LOAD_EN INTSTAT_RAW INTSTAT_MASKED INT_ENABLE EVENT_POP
@@ -107,6 +109,8 @@ struct cpts_event {
u32 low;
};
+#define CPTS_CAP_RFTCLK_SEL BIT(0)
+
struct cpts {
struct device *dev;
struct cpsw_cpts __iomem *reg;
@@ -125,6 +129,8 @@ struct cpts {
struct list_head pool;
struct cpts_event pool_data[CPTS_MAX_EVENTS];
unsigned long ov_check_period;
+ u32 rftclk_sel;
+ u32 caps;
};
void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-30 11:00 +0100 |
| Subject | Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sJ9Qf-4q9-57@gated-at.bofh.it> |
| In reply to | #1531787 |
On Mon, Nov 28, 2016 at 05:04:24PM -0600, Grygorii Strashko wrote: > Some CPTS instances, which can be found on KeyStone 2 1/10G Ethernet > Switch Subsystems, can control an external multiplexer that selects > one of up to 32 clocks for time sync reference (RFTCLK). This feature > can be configured through CPTS_RFTCLK_SEL register (offset: x08). > > Hence, introduce optional DT cpts_rftclk_sel poperty wich, if present, > will specify CPTS reference clock. The cpts_rftclk_sel should be > omitted in DT if HW doesn't support this feature. The external fixed > rate clocks can be defined in board files as "fixed-clock". Can't you implement this using the clock tree, rather than an ad-hoc DT property? Thanks, Richard
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-30 18:40 +0100 |
| Subject | Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sJh1n-BB-11@gated-at.bofh.it> |
| In reply to | #1533167 |
On 11/30/2016 03:56 AM, Richard Cochran wrote: > On Mon, Nov 28, 2016 at 05:04:24PM -0600, Grygorii Strashko wrote: >> Some CPTS instances, which can be found on KeyStone 2 1/10G Ethernet >> Switch Subsystems, can control an external multiplexer that selects >> one of up to 32 clocks for time sync reference (RFTCLK). This feature >> can be configured through CPTS_RFTCLK_SEL register (offset: x08). >> >> Hence, introduce optional DT cpts_rftclk_sel poperty wich, if present, >> will specify CPTS reference clock. The cpts_rftclk_sel should be >> omitted in DT if HW doesn't support this feature. The external fixed >> rate clocks can be defined in board files as "fixed-clock". > > Can't you implement this using the clock tree, rather than an ad-hoc > DT property? > I've thought about this, but decided to move forward with this impl which is pretty simple. I will try. -- regards, -grygorii
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-12-06 20:50 +0100 |
| Subject | Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sLtUu-6ii-21@gated-at.bofh.it> |
| In reply to | #1533467 |
On 11/30/2016 11:35 AM, Grygorii Strashko wrote:
>
>
> On 11/30/2016 03:56 AM, Richard Cochran wrote:
>> On Mon, Nov 28, 2016 at 05:04:24PM -0600, Grygorii Strashko wrote:
>>> Some CPTS instances, which can be found on KeyStone 2 1/10G Ethernet
>>> Switch Subsystems, can control an external multiplexer that selects
>>> one of up to 32 clocks for time sync reference (RFTCLK). This feature
>>> can be configured through CPTS_RFTCLK_SEL register (offset: x08).
>>>
>>> Hence, introduce optional DT cpts_rftclk_sel poperty wich, if present,
>>> will specify CPTS reference clock. The cpts_rftclk_sel should be
>>> omitted in DT if HW doesn't support this feature. The external fixed
>>> rate clocks can be defined in board files as "fixed-clock".
>>
>> Can't you implement this using the clock tree, rather than an ad-hoc
>> DT property?
>>
>
> I've thought about this, but decided to move forward with this impl
> which is pretty simple. I will try.
>
>
I come with below RFC patch. if no objection I'll move forward with it.
According to Keystone 2 66AK2e DM there are 7 possible ref clocks:
0000 = SYSCLK2
0001 = SYSCLK3
0010 = TIMI0
0011 = TIMI1
0100 = TSIPCLKA
1000 = TSREFCLK
1100 = TSIPCLKB
Others = Reserved
2 from above clocks are internal SYSCLK2 and SYSCLK3 - other external
(board specific). So default definition of cpts_mux will have only two parents.
If ext clock is going to be use as cpts rftclk then it should be
defined in board file and cpts_refclk_mux definition updated to support
this ext clock:
timi1clk: timi1clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <xxxxxxxxxx>;
clock-output-names = "timi1";
};
&cpts_mux {
clocks = <&chipclk12>, <&chipclk13>, <timi1clk>;
cpts-mux-tbl = <0>, <1>, <3>;
assigned-clocks = <&cpts_mux>;
assigned-clock-parents = <&timi1clk>;
};
From ec5c7bed0e021c2ca7e9392173bf67bb9a45d0f4 Mon Sep 17 00:00:00 2001
From: Grygorii Strashko <grygorii.strashko@ti.com>
Date: Mon, 5 Dec 2016 12:34:45 -0600
Subject: [PATCH] cpts refclk sel
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
arch/arm/boot/dts/keystone-k2e-netcp.dtsi | 10 +++++-
drivers/net/ethernet/ti/cpts.c | 52 ++++++++++++++++++++++++++++++-
2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
index 919e655..b27aa22 100644
--- a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
+++ b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
@@ -138,7 +138,7 @@ netcp: netcp@24000000 {
/* NetCP address range */
ranges = <0 0x24000000 0x1000000>;
- clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>;
+ clocks = <&clkpa>, <&clkcpgmac>, <&cpts_mux>;
clock-names = "pa_clk", "ethss_clk", "cpts";
dma-coherent;
@@ -162,6 +162,14 @@ netcp: netcp@24000000 {
cpts-ext-ts-inputs = <6>;
cpts-ts-comp-length;
+ cpts_mux: cpts_refclk_mux {
+ #clock-cells = <0>;
+ clocks = <&chipclk12>, <&chipclk13>;
+ cpts-mux-tbl = <0>, <1>;
+ assigned-clocks = <&cpts_mux>;
+ assigned-clock-parents = <&chipclk12>;
+ };
+
interfaces {
gbe0: interface-0 {
slave-port = <0>;
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 938de22..ef94316 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/if.h>
#include <linux/hrtimer.h>
@@ -672,6 +673,7 @@ int cpts_register(struct cpts *cpts)
cpts->phc_index = ptp_clock_index(cpts->clock);
schedule_delayed_work(&cpts->overflow_work, cpts->ov_check_period);
+
return 0;
err_ptp:
@@ -741,6 +743,54 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
freq, cpts->cc_mult, cpts->cc.shift, (ns - NSEC_PER_SEC));
}
+static int cpts_of_mux_clk_setup(struct cpts *cpts, struct device_node *node)
+{
+ unsigned int num_parents;
+ const char **parent_names;
+ struct device_node *refclk_np;
+ void __iomem *reg;
+ struct clk *clk;
+ u32 *mux_table;
+ int ret;
+
+ refclk_np = of_get_child_by_name(node, "cpts_refclk_mux");
+ if (!refclk_np)
+ return -EINVAL;
+
+ num_parents = of_clk_get_parent_count(refclk_np);
+ if (num_parents < 1) {
+ dev_err(cpts->dev, "mux-clock %s must have parents\n",
+ refclk_np->name);
+ return -EINVAL;
+ }
+ parent_names = devm_kzalloc(cpts->dev, (sizeof(char *) * num_parents),
+ GFP_KERNEL);
+ if (!parent_names)
+ return -ENOMEM;
+
+ of_clk_parent_fill(refclk_np, parent_names, num_parents);
+
+ mux_table = devm_kzalloc(cpts->dev, sizeof(*mux_table) * (32 + 1),
+ GFP_KERNEL);
+ if (!mux_table)
+ return -ENOMEM;
+
+ ret = of_property_read_variable_u32_array(refclk_np, "cpts-mux-tbl",
+ mux_table, 1, 32);
+ if (ret < 0)
+ return ret;
+
+ reg = &cpts->reg->rftclk_sel;
+
+ clk = clk_register_mux_table(cpts->dev, refclk_np->name,
+ parent_names, num_parents,
+ 0, reg, 0, 0x1F, 0, mux_table, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return of_clk_add_provider(refclk_np, of_clk_src_simple_get, clk);
+}
+
static int cpts_of_parse(struct cpts *cpts, struct device_node *node)
{
int ret = -EINVAL;
@@ -787,7 +837,7 @@ static int cpts_of_parse(struct cpts *cpts, struct device_node *node)
if (!of_property_read_u32(node, "cpts-ext-ts-inputs", &prop))
cpts->ext_ts_inputs = prop;
- return 0;
+ return cpts_of_mux_clk_setup(cpts, node);
of_error:
dev_err(cpts->dev, "CPTS: Missing property in the DT.\n");
--
2.10.1
--
regards,
-grygorii
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-12-06 21:30 +0100 |
| Subject | Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sLuxb-6Pb-13@gated-at.bofh.it> |
| In reply to | #1537245 |
On Tue, Dec 06, 2016 at 01:39:40PM -0600, Grygorii Strashko wrote: > I come with below RFC patch. if no objection I'll move forward with it. Thanks for following through with this! The am335x will also need the MUX in its clock tree, won't it? Thanks, Richard
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-12-06 21:50 +0100 |
| Subject | Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sLuQy-6Vs-21@gated-at.bofh.it> |
| In reply to | #1537261 |
On 12/06/2016 02:25 PM, Richard Cochran wrote:
> On Tue, Dec 06, 2016 at 01:39:40PM -0600, Grygorii Strashko wrote:
>> I come with below RFC patch. if no objection I'll move forward with it.
>
> Thanks for following through with this!
>
> The am335x will also need the MUX in its clock tree, won't it?
>
Not exactly. I do not see CPTS_RFTCLK_SEL register in trm, but looks like
it's already implemented in am335 clock tree:
cpsw_cpts_rft_clk: cpsw_cpts_rft_clk@520 {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&dpll_core_m5_ck>, <&dpll_core_m4_ck>;
reg = <0x0520>;
};
and ssigned-clock-xx can be used to change parent in board file:
&cpsw_cpts_rft_clk {
assigned-clocks = <&cpsw_cpts_rft_clk>;
assigned-clock-parents = <&dpll_core_m4_ck>;
};
--
regards,
-grygorii
[toc] | [prev] | [next] | [standalone]
| From | Stephen Boyd <sboyd@codeaurora.org> |
|---|---|
| Date | 2016-12-09 01:50 +0100 |
| Subject | Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sMhxU-4EV-9@gated-at.bofh.it> |
| In reply to | #1537245 |
On 12/06, Grygorii Strashko wrote:
> Subject: [PATCH] cpts refclk sel
>
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
> ---
> arch/arm/boot/dts/keystone-k2e-netcp.dtsi | 10 +++++-
> drivers/net/ethernet/ti/cpts.c | 52 ++++++++++++++++++++++++++++++-
> 2 files changed, 60 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
> index 919e655..b27aa22 100644
> --- a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
> +++ b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
> @@ -138,7 +138,7 @@ netcp: netcp@24000000 {
> /* NetCP address range */
> ranges = <0 0x24000000 0x1000000>;
>
> - clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>;
> + clocks = <&clkpa>, <&clkcpgmac>, <&cpts_mux>;
> clock-names = "pa_clk", "ethss_clk", "cpts";
> dma-coherent;
>
> @@ -162,6 +162,14 @@ netcp: netcp@24000000 {
> cpts-ext-ts-inputs = <6>;
> cpts-ts-comp-length;
>
> + cpts_mux: cpts_refclk_mux {
> + #clock-cells = <0>;
> + clocks = <&chipclk12>, <&chipclk13>;
> + cpts-mux-tbl = <0>, <1>;
> + assigned-clocks = <&cpts_mux>;
> + assigned-clock-parents = <&chipclk12>;
Is there a binding update? Why the subnode? Why not have it as
part of the netcp node? Does the cpts-mux-tbl property change?
> + };
> +
> interfaces {
> gbe0: interface-0 {
> slave-port = <0>;
> diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
> index 938de22..ef94316 100644
> --- a/drivers/net/ethernet/ti/cpts.c
> +++ b/drivers/net/ethernet/ti/cpts.c
> @@ -17,6 +17,7 @@
> * along with this program; if not, write to the Free Software
> * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> */
> +#include <linux/clk-provider.h>
> #include <linux/err.h>
> #include <linux/if.h>
> #include <linux/hrtimer.h>
> @@ -672,6 +673,7 @@ int cpts_register(struct cpts *cpts)
> cpts->phc_index = ptp_clock_index(cpts->clock);
>
> schedule_delayed_work(&cpts->overflow_work, cpts->ov_check_period);
> +
Maybe in another patch.
> return 0;
>
> err_ptp:
> @@ -741,6 +743,54 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
> freq, cpts->cc_mult, cpts->cc.shift, (ns - NSEC_PER_SEC));
> }
>
> +static int cpts_of_mux_clk_setup(struct cpts *cpts, struct device_node *node)
> +{
> + unsigned int num_parents;
> + const char **parent_names;
> + struct device_node *refclk_np;
> + void __iomem *reg;
> + struct clk *clk;
> + u32 *mux_table;
> + int ret;
> +
> + refclk_np = of_get_child_by_name(node, "cpts_refclk_mux");
> + if (!refclk_np)
> + return -EINVAL;
> +
> + num_parents = of_clk_get_parent_count(refclk_np);
> + if (num_parents < 1) {
> + dev_err(cpts->dev, "mux-clock %s must have parents\n",
> + refclk_np->name);
> + return -EINVAL;
> + }
> + parent_names = devm_kzalloc(cpts->dev, (sizeof(char *) * num_parents),
> + GFP_KERNEL);
> + if (!parent_names)
> + return -ENOMEM;
> +
> + of_clk_parent_fill(refclk_np, parent_names, num_parents);
> +
> + mux_table = devm_kzalloc(cpts->dev, sizeof(*mux_table) * (32 + 1),
> + GFP_KERNEL);
> + if (!mux_table)
> + return -ENOMEM;
> +
> + ret = of_property_read_variable_u32_array(refclk_np, "cpts-mux-tbl",
> + mux_table, 1, 32);
> + if (ret < 0)
> + return ret;
> +
> + reg = &cpts->reg->rftclk_sel;
> +
> + clk = clk_register_mux_table(cpts->dev, refclk_np->name,
> + parent_names, num_parents,
> + 0, reg, 0, 0x1F, 0, mux_table, NULL);
> + if (IS_ERR(clk))
> + return PTR_ERR(clk);
> +
> + return of_clk_add_provider(refclk_np, of_clk_src_simple_get, clk);
Can you please use the clk_hw APIs instead?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-12-10 00:40 +0100 |
| Subject | Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sMCVI-140-9@gated-at.bofh.it> |
| In reply to | #1538988 |
On 12/08/2016 06:47 PM, Stephen Boyd wrote:
> On 12/06, Grygorii Strashko wrote:
>> Subject: [PATCH] cpts refclk sel
>>
>> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
>> ---
>> arch/arm/boot/dts/keystone-k2e-netcp.dtsi | 10 +++++-
>> drivers/net/ethernet/ti/cpts.c | 52 ++++++++++++++++++++++++++++++-
>> 2 files changed, 60 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
>> index 919e655..b27aa22 100644
>> --- a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
>> +++ b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
>> @@ -138,7 +138,7 @@ netcp: netcp@24000000 {
>> /* NetCP address range */
>> ranges = <0 0x24000000 0x1000000>;
>>
>> - clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>;
>> + clocks = <&clkpa>, <&clkcpgmac>, <&cpts_mux>;
^^ mux clock used here
>> clock-names = "pa_clk", "ethss_clk", "cpts";
>> dma-coherent;
>>
>> @@ -162,6 +162,14 @@ netcp: netcp@24000000 {
>> cpts-ext-ts-inputs = <6>;
>> cpts-ts-comp-length;
>>
>> + cpts_mux: cpts_refclk_mux {
>> + #clock-cells = <0>;
>> + clocks = <&chipclk12>, <&chipclk13>;
>> + cpts-mux-tbl = <0>, <1>;
>> + assigned-clocks = <&cpts_mux>;
>> + assigned-clock-parents = <&chipclk12>;
>
> Is there a binding update?
this was pure RFC-DEV patch just to check the possibility of modeling
CPTS_RFTCLK_SEL register as mux clock.
Original patch:
https://lkml.org/lkml/2016/11/28/780
I've plan to resend it using clk framework.
Why the subnode?
Sry, I did not get this question - is there another way to pas phandle on clock
in clocks list property? Am I missing smth.?
Sry, this is my first clock :)
> Why not have it as part of the netcp node?
cpts is part of gbe ethss, which is part of netcp.
Only netcp is modeled as DD - cpts and gbe ethss implemented without using DD model,
so generic resources acquired by netcp and then passed to cpts and gbe ethss.
CPTS has register to control an external multiplexer that selects
one of up to 32 clocks for time sync reference (RFTCLK)
> Does the cpts-mux-tbl property change?
On Keystone 2 66AK2e (as example) the following list of clocks can be selected
as ref clocks (list is different for other SoCs):
0000 = SYSCLK2
0001 = SYSCLK3
0010 = TIMI0
0011 = TIMI1
0100 = TSIPCLKA
1000 = TSREFCLK
1100 = TSIPCLKB
Others = Reserved
and only 0 and 1 are internal, other external and board specific
(parameters unknown and corresponding inputs can be used for other purposes),
so I can't define all parent clocks, only internal:
clocks = <&chipclk12>, <&chipclk13>;
cpts-mux-tbl = <0>, <1>;
to use another, external, clock - it should be explicitly defined in board file the board file
timi1clk: timi1clk {
#clock-cells = <0>;
compatible = "fixed-clock";
...
&cpts_mux {
clocks = <&chipclk12>, <&chipclk13>, <timi1clk>;
^^^ i can't predict value here
cpts-mux-tbl = <0>, <1>, <3>;
^^i can't predict value here
assigned-clocks = <&cpts_mux>;
assigned-clock-parents = <&timi1clk>;
};
or I understood your question wrongly?
>
>> + };
>> +
>> interfaces {
>> gbe0: interface-0 {
>> slave-port = <0>;
>> diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
>> index 938de22..ef94316 100644
>> --- a/drivers/net/ethernet/ti/cpts.c
>> +++ b/drivers/net/ethernet/ti/cpts.c
>> @@ -17,6 +17,7 @@
>> * along with this program; if not, write to the Free Software
>> * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>> */
>> +#include <linux/clk-provider.h>
>> #include <linux/err.h>
>> #include <linux/if.h>
>> #include <linux/hrtimer.h>
>> @@ -672,6 +673,7 @@ int cpts_register(struct cpts *cpts)
>> cpts->phc_index = ptp_clock_index(cpts->clock);
>>
>> schedule_delayed_work(&cpts->overflow_work, cpts->ov_check_period);
>> +
>
> Maybe in another patch.
>
sure
>> return 0;
>>
>> err_ptp:
>> @@ -741,6 +743,54 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
>> freq, cpts->cc_mult, cpts->cc.shift, (ns - NSEC_PER_SEC));
>> }
>>
...
>> +
>> + reg = &cpts->reg->rftclk_sel;
>> +
>> + clk = clk_register_mux_table(cpts->dev, refclk_np->name,
>> + parent_names, num_parents,
>> + 0, reg, 0, 0x1F, 0, mux_table, NULL);
>> + if (IS_ERR(clk))
>> + return PTR_ERR(clk);
>> +
>> + return of_clk_add_provider(refclk_np, of_clk_src_simple_get, clk);
>
> Can you please use the clk_hw APIs instead?
>
ok
--
regards,
-grygorii
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2016-12-05 16:00 +0100 |
| Subject | Re: [PATCH 2/6] net: ethernet: ti: cpts: add support for ext rftclk selection |
| Message-ID | <sL2Uh-5Q1-7@gated-at.bofh.it> |
| In reply to | #1531787 |
On Mon, Nov 28, 2016 at 05:04:24PM -0600, Grygorii Strashko wrote: > Some CPTS instances, which can be found on KeyStone 2 1/10G Ethernet > Switch Subsystems, can control an external multiplexer that selects > one of up to 32 clocks for time sync reference (RFTCLK). This feature > can be configured through CPTS_RFTCLK_SEL register (offset: x08). > > Hence, introduce optional DT cpts_rftclk_sel poperty wich, if present, > will specify CPTS reference clock. The cpts_rftclk_sel should be > omitted in DT if HW doesn't support this feature. The external fixed > rate clocks can be defined in board files as "fixed-clock". > > Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> > --- > Documentation/devicetree/bindings/net/keystone-netcp.txt | 2 ++ Please group binding changes into a single patch. > drivers/net/ethernet/ti/cpts.c | 12 ++++++++++++ > drivers/net/ethernet/ti/cpts.h | 8 +++++++- > 3 files changed, 21 insertions(+), 1 deletion(-) > > diff --git a/Documentation/devicetree/bindings/net/keystone-netcp.txt b/Documentation/devicetree/bindings/net/keystone-netcp.txt > index c37b54e..ec4a241 100644 > --- a/Documentation/devicetree/bindings/net/keystone-netcp.txt > +++ b/Documentation/devicetree/bindings/net/keystone-netcp.txt > @@ -114,6 +114,8 @@ Optional properties: > driver to them if needed. > > Properties related to cpts configurations. > + - cpts-rftclk-sel: selects one of up to 32 clocks for time sync > + reference. Default = 0. Vendor prefix. > - cpts_clock_mult/cpts_clock_shift: > used for converting time counter cycles to ns as in >
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sIDdE-75-47@gated-at.bofh.it> |
| In reply to | #1531783 |
The TS_COMP output in the CPSW CPTS module is asserted for
ts_comp_length[15:0] RCLK periods when the time_stamp value compares
with the ts_comp_val[31:0] and the length value is non-zero. The
TS_COMP pulse edge occurs three RCLK periods after the values
compare. A timestamp compare event is pushed into the event FIFO when
TS_COMP is asserted.
This patch adds support of Pulse-Per-Second (PPS) by using the
timestamp compare output. The CPTS driver adds one second of counter
value to the ts_comp_val register after each assertion of the TS_COMP
output. The TS_COMP pulse polarity and width are configurable in DT.
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
.../devicetree/bindings/net/keystone-netcp.txt | 10 +
drivers/net/ethernet/ti/cpts.c | 237 ++++++++++++++++++++-
drivers/net/ethernet/ti/cpts.h | 14 +-
3 files changed, 251 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/keystone-netcp.txt b/Documentation/devicetree/bindings/net/keystone-netcp.txt
index 1c805319..060af96 100644
--- a/Documentation/devicetree/bindings/net/keystone-netcp.txt
+++ b/Documentation/devicetree/bindings/net/keystone-netcp.txt
@@ -127,6 +127,16 @@ Optional properties:
The number of external time stamp channels.
The different CPTS versions might support up 8
external time stamp channels. if absent - unsupported.
+ - cpts-ts-comp-length:
+ Enable time stamp comparison event and TS_COMP signal output
+ generation when CPTS counter reaches a value written to
+ the TS_COMP_VAL register.
+ The generated pulse width is 3 refclk cycles if this property
+ has no value (empty) or, otherwise, it should specify desired
+ pulse width in number of refclk periods - max value 2^16.
+ TS_COMP functionality will be disabled if not present.
+ - cpts-ts-comp-polarity-low:
+ Set polarity of TS_COMP signal to low. Default is hight.
NetCP interface properties: Interface specification for NetCP sub-modules.
Required properties:
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 2f7641a..8ff70cc 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -31,9 +31,13 @@
#include "cpts.h"
+#define CPTS_TS_COMP_PULSE_LENGTH_DEF 3
+
#define cpts_read32(c, r) readl_relaxed(&c->reg->r)
#define cpts_write32(c, v, r) writel_relaxed(v, &c->reg->r)
+static int cpts_report_ts_events(struct cpts *cpts, bool pps_reload);
+
static int cpts_event_port(struct cpts_event *event)
{
return (event->high >> PORT_NUMBER_SHIFT) & PORT_NUMBER_MASK;
@@ -108,6 +112,7 @@ static int cpts_fifo_read(struct cpts *cpts, int match)
type = event_type(event);
switch (type) {
case CPTS_EV_HW:
+ case CPTS_EV_COMP:
event->tmo +=
msecs_to_jiffies(CPTS_EVENT_HWSTAMP_TIMEOUT);
case CPTS_EV_PUSH:
@@ -153,6 +158,60 @@ static cycle_t cpts_systim_read(const struct cyclecounter *cc)
return val;
}
+static cycle_t cpts_cc_ns2cyc(struct cpts *cpts, u64 nsecs)
+{
+ cycle_t cyc = (nsecs << cpts->cc.shift) + nsecs;
+
+ do_div(cyc, cpts->cc.mult);
+
+ return cyc;
+}
+
+static void cpts_ts_comp_disable(struct cpts *cpts)
+{
+ cpts_write32(cpts, 0, ts_comp_length);
+}
+
+static void cpts_ts_comp_enable(struct cpts *cpts)
+{
+ /* TS_COMP_LENGTH should be 0 while the TS_COMP_VAL value is
+ * being written
+ */
+ cpts_write32(cpts, 0, ts_comp_length);
+ cpts_write32(cpts, cpts->ts_comp_next, ts_comp_val);
+ cpts_write32(cpts, cpts->ts_comp_length, ts_comp_length);
+}
+
+static void cpts_ts_comp_add_ns(struct cpts *cpts, s64 add_ns)
+{
+ cycle_t cyc_next;
+
+ if (add_ns == NSEC_PER_SEC)
+ /* avoid calculation */
+ cyc_next = cpts->ts_comp_one_sec_cycs;
+ else
+ cyc_next = cpts_cc_ns2cyc(cpts, add_ns);
+
+ cyc_next += cpts->ts_comp_next;
+ cpts->ts_comp_next = cyc_next & cpts->cc.mask;
+ pr_debug("cpts comp ts_comp_next: %u\n", cpts->ts_comp_next);
+}
+
+static void cpts_ts_comp_settime(struct cpts *cpts, s64 now_ns)
+{
+ struct timespec64 ts;
+
+ if (cpts->ts_comp_enabled) {
+ ts = ns_to_timespec64(now_ns);
+
+ /* align pulse to next sec boundary and add one sec */
+ cpts_ts_comp_add_ns(cpts, NSEC_PER_SEC - ts.tv_nsec);
+
+ /* enable ts_comp pulse */
+ cpts_ts_comp_enable(cpts);
+ }
+}
+
/* PTP clock operations */
static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
@@ -162,6 +221,7 @@ static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
int neg_adj = 0;
unsigned long flags;
struct cpts *cpts = container_of(ptp, struct cpts, info);
+ u64 ns;
if (ppb < 0) {
neg_adj = 1;
@@ -172,14 +232,31 @@ static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
adj *= ppb;
diff = div_u64(adj, 1000000000ULL);
+ mutex_lock(&cpts->ptp_clk_mutex);
+
spin_lock_irqsave(&cpts->lock, flags);
+ if (cpts->ts_comp_enabled) {
+ cpts_ts_comp_disable(cpts);
+ /* if any, report existing pulse before adj */
+ cpts_fifo_read(cpts, CPTS_EV_COMP);
+ /* if any, report existing pulse before adj */
+ cpts_report_ts_events(cpts, false);
+ }
timecounter_read(&cpts->tc);
cpts->cc.mult = neg_adj ? mult - diff : mult + diff;
-
+ /* get updated time with adj */
+ ns = timecounter_read(&cpts->tc);
+ cpts->ts_comp_next = cpts->tc.cycle_last;
spin_unlock_irqrestore(&cpts->lock, flags);
+ if (cpts->ts_comp_enabled)
+ cpts->ts_comp_one_sec_cycs = cpts_cc_ns2cyc(cpts, NSEC_PER_SEC);
+ cpts_ts_comp_settime(cpts, ns);
+
+ mutex_unlock(&cpts->ptp_clk_mutex);
+
return 0;
}
@@ -187,11 +264,28 @@ static int cpts_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
unsigned long flags;
struct cpts *cpts = container_of(ptp, struct cpts, info);
+ u64 ns;
+
+ mutex_lock(&cpts->ptp_clk_mutex);
spin_lock_irqsave(&cpts->lock, flags);
+ if (cpts->ts_comp_enabled) {
+ cpts_ts_comp_disable(cpts);
+ /* if any, report existing pulse before adj */
+ cpts_fifo_read(cpts, CPTS_EV_COMP);
+ /* if any, report existing pulse before adj */
+ cpts_report_ts_events(cpts, false);
+ }
+
timecounter_adjtime(&cpts->tc, delta);
+ ns = timecounter_read(&cpts->tc);
+ cpts->ts_comp_next = cpts->tc.cycle_last;
spin_unlock_irqrestore(&cpts->lock, flags);
+ cpts_ts_comp_settime(cpts, ns);
+
+ mutex_unlock(&cpts->ptp_clk_mutex);
+
return 0;
}
@@ -213,25 +307,90 @@ static int cpts_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
static int cpts_ptp_settime(struct ptp_clock_info *ptp,
const struct timespec64 *ts)
{
- u64 ns;
- unsigned long flags;
struct cpts *cpts = container_of(ptp, struct cpts, info);
+ unsigned long flags;
+ u64 ns;
ns = timespec64_to_ns(ts);
+ mutex_lock(&cpts->ptp_clk_mutex);
+
spin_lock_irqsave(&cpts->lock, flags);
+ if (cpts->ts_comp_enabled) {
+ cpts_ts_comp_disable(cpts);
+ /* if any, get existing pulse event before adj */
+ cpts_fifo_read(cpts, CPTS_EV_COMP);
+ /* if any, report existing pulse before adj */
+ cpts_report_ts_events(cpts, false);
+ }
+
timecounter_init(&cpts->tc, &cpts->cc, ns);
+ cpts->ts_comp_next = cpts->tc.cycle_last;
spin_unlock_irqrestore(&cpts->lock, flags);
+ cpts_ts_comp_settime(cpts, ns);
+
+ mutex_unlock(&cpts->ptp_clk_mutex);
+
return 0;
}
-static int cpts_report_ts_events(struct cpts *cpts)
+static int cpts_pps_enable(struct cpts *cpts, int on)
+{
+ struct timespec64 ts;
+ unsigned long flags;
+ u64 ns;
+
+ if (cpts->ts_comp_enabled == on)
+ return 0;
+
+ mutex_lock(&cpts->ptp_clk_mutex);
+ cpts->ts_comp_enabled = on;
+
+ if (!on) {
+ cpts_ts_comp_disable(cpts);
+ if (!cpts->hw_ts_enable)
+ cpts->ov_check_period = cpts->ov_check_period_slow;
+ mutex_unlock(&cpts->ptp_clk_mutex);
+ return 0;
+ }
+
+ /* get current counter value */
+ spin_lock_irqsave(&cpts->lock, flags);
+ ns = timecounter_read(&cpts->tc);
+ cpts->ts_comp_next = cpts->tc.cycle_last;
+ spin_unlock_irqrestore(&cpts->lock, flags);
+
+ ts = ns_to_timespec64(ns);
+ cpts->ts_comp_one_sec_cycs = cpts_cc_ns2cyc(cpts, NSEC_PER_SEC);
+ /* align to next sec boundary and add one sec to avoid the situation
+ * when the current time is very close to the next second point and
+ * it might be possible that ts_comp_val will be configured to
+ * the time in the past.
+ */
+ cpts_ts_comp_add_ns(cpts, 2 * NSEC_PER_SEC - ts.tv_nsec);
+
+ /* enable ts_comp pulse */
+ cpts_ts_comp_enable(cpts);
+
+ /* poll for events faster - evry 200 ms */
+ cpts->ov_check_period = msecs_to_jiffies(CPTS_EVENT_HWSTAMP_TIMEOUT);
+
+ mod_delayed_work(system_wq, &cpts->overflow_work,
+ cpts->ov_check_period);
+
+ mutex_unlock(&cpts->ptp_clk_mutex);
+
+ return 0;
+}
+
+static int cpts_report_ts_events(struct cpts *cpts, bool pps_reload)
{
struct list_head *this, *next;
struct ptp_clock_event pevent;
struct cpts_event *event;
int reported = 0, ev;
+ u64 ns;
list_for_each_safe(this, next, &cpts->events) {
event = list_entry(this, struct cpts_event, list);
@@ -248,6 +407,33 @@ static int cpts_report_ts_events(struct cpts *cpts)
++reported;
continue;
}
+
+ if (event_type(event) == CPTS_EV_COMP) {
+ list_del_init(&event->list);
+ list_add(&event->list, &cpts->pool);
+ if (cpts->ts_comp_next != event->low) {
+ pr_err("cpts ts_comp mismatch: %08x %08x\n",
+ cpts->ts_comp_next, event->low);
+ continue;
+ } else
+ pr_debug("cpts comp ev tstamp: %u\n",
+ event->low);
+
+ /* report the event */
+ ns = timecounter_cyc2time(&cpts->tc, event->low);
+ pevent.type = PTP_CLOCK_PPSUSR;
+ pevent.pps_times.ts_real = ns_to_timespec64(ns);
+ ptp_clock_event(cpts->clock, &pevent);
+
+ if (pps_reload) {
+ /* reload: add ns to ts_comp */
+ cpts_ts_comp_add_ns(cpts, NSEC_PER_SEC);
+ /* enable ts_comp pulse with new val */
+ cpts_ts_comp_enable(cpts);
+ }
+ ++reported;
+ continue;
+ }
}
return reported;
}
@@ -264,6 +450,8 @@ static int cpts_extts_enable(struct cpts *cpts, u32 index, int on)
if (((cpts->hw_ts_enable & BIT(index)) >> index) == on)
return 0;
+ mutex_lock(&cpts->ptp_clk_mutex);
+
spin_lock_irqsave(&cpts->lock, flags);
v = cpts_read32(cpts, control);
@@ -282,12 +470,12 @@ static int cpts_extts_enable(struct cpts *cpts, u32 index, int on)
/* poll for events faster - evry 200 ms */
cpts->ov_check_period =
msecs_to_jiffies(CPTS_EVENT_HWSTAMP_TIMEOUT);
- else
+ else if (!cpts->ts_comp_enabled)
cpts->ov_check_period = cpts->ov_check_period_slow;
mod_delayed_work(system_wq, &cpts->overflow_work,
cpts->ov_check_period);
-
+ mutex_unlock(&cpts->ptp_clk_mutex);
return 0;
}
@@ -299,6 +487,8 @@ static int cpts_ptp_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
return cpts_extts_enable(cpts, rq->extts.index, on);
+ case PTP_CLK_REQ_PPS:
+ return cpts_pps_enable(cpts, on);
default:
break;
}
@@ -326,12 +516,15 @@ static void cpts_overflow_check(struct work_struct *work)
struct timespec64 ts;
unsigned long flags;
+ mutex_lock(&cpts->ptp_clk_mutex);
spin_lock_irqsave(&cpts->lock, flags);
ts = ns_to_timespec64(timecounter_read(&cpts->tc));
spin_unlock_irqrestore(&cpts->lock, flags);
- if (cpts->hw_ts_enable)
- cpts_report_ts_events(cpts);
+ if (cpts->hw_ts_enable || cpts->ts_comp_enabled)
+ cpts_report_ts_events(cpts, true);
+ mutex_unlock(&cpts->ptp_clk_mutex);
+
pr_debug("cpts overflow check at %lld.%09lu\n", ts.tv_sec, ts.tv_nsec);
schedule_delayed_work(&cpts->overflow_work, cpts->ov_check_period);
}
@@ -445,6 +638,7 @@ EXPORT_SYMBOL_GPL(cpts_tx_timestamp);
int cpts_register(struct cpts *cpts)
{
int err, i;
+ u32 control;
INIT_LIST_HEAD(&cpts->events);
INIT_LIST_HEAD(&cpts->pool);
@@ -453,7 +647,14 @@ int cpts_register(struct cpts *cpts)
clk_enable(cpts->refclk);
- cpts_write32(cpts, CPTS_EN, control);
+ control = CPTS_EN;
+ if (cpts->caps & CPTS_CAP_TS_COMP_EN) {
+ if (cpts->caps & CPTS_CAP_TS_COMP_POL_LOW_SEL)
+ control &= ~TS_COMP_POL;
+ else
+ control |= TS_COMP_POL;
+ }
+ cpts_write32(cpts, control, control);
cpts_write32(cpts, TS_PEND_EN, int_enable);
cpts->cc.mult = cpts->cc_mult;
@@ -558,6 +759,20 @@ static int cpts_of_parse(struct cpts *cpts, struct device_node *node)
cpts->rftclk_sel = prop & CPTS_RFTCLK_SEL_MASK;
}
+ if (of_property_read_bool(node, "cpts-ts-comp-length")) {
+ cpts->caps |= CPTS_CAP_TS_COMP_EN;
+ cpts->ts_comp_length = CPTS_TS_COMP_PULSE_LENGTH_DEF;
+ }
+
+ if (cpts->caps & CPTS_CAP_TS_COMP_EN) {
+ ret = of_property_read_u32(node, "cpts-ts-comp-length", &prop);
+ if (!ret)
+ cpts->ts_comp_length = prop;
+
+ if (of_property_read_bool(node, "cpts-ts-comp-polarity-low"))
+ cpts->caps |= CPTS_CAP_TS_COMP_POL_LOW_SEL;
+ }
+
if (!of_property_read_u32(node, "cpts-ext-ts-inputs", &prop))
cpts->ext_ts_inputs = prop;
@@ -584,6 +799,7 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
cpts->dev = dev;
cpts->reg = (struct cpsw_cpts __iomem *)regs;
spin_lock_init(&cpts->lock);
+ mutex_init(&cpts->ptp_clk_mutex);
INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check);
ret = cpts_of_parse(cpts, node);
@@ -608,6 +824,9 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
if (cpts->ext_ts_inputs)
cpts->info.n_ext_ts = cpts->ext_ts_inputs;
+ if (cpts->caps & CPTS_CAP_TS_COMP_EN)
+ cpts->info.pps = 1;
+
cpts_calc_mult_shift(cpts);
return cpts;
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index ad80c95..a82520d 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -39,7 +39,8 @@ struct cpsw_cpts {
u32 ts_push; /* Time stamp event push */
u32 ts_load_val; /* Time stamp load value */
u32 ts_load_en; /* Time stamp load enable */
- u32 res2[2];
+ u32 ts_comp_val; /* Time stamp comparison value, v1.5 & up */
+ u32 ts_comp_length; /* Time stamp comp assert len, v1.5 & up */
u32 intstat_raw; /* Time sync interrupt status raw */
u32 intstat_masked; /* Time sync interrupt status masked */
u32 int_enable; /* Time sync interrupt enable */
@@ -64,11 +65,14 @@ struct cpsw_cpts {
#define HW3_TS_PUSH_EN (1<<10) /* Hardware push 3 enable */
#define HW2_TS_PUSH_EN (1<<9) /* Hardware push 2 enable */
#define HW1_TS_PUSH_EN (1<<8) /* Hardware push 1 enable */
+#define TS_COMP_POL BIT(2) /* TS_COMP Polarity */
#define INT_TEST (1<<1) /* Interrupt Test */
#define CPTS_EN (1<<0) /* Time Sync Enable */
#define CPTS_RFTCLK_SEL_MASK 0x1f
+#define CPTS_TS_COMP_LENGTH_MASK 0xffff
+
/*
* Definitions for the single bit resisters:
* TS_PUSH TS_LOAD_EN INTSTAT_RAW INTSTAT_MASKED INT_ENABLE EVENT_POP
@@ -97,6 +101,7 @@ enum {
CPTS_EV_HW, /* Hardware Time Stamp Push Event */
CPTS_EV_RX, /* Ethernet Receive Event */
CPTS_EV_TX, /* Ethernet Transmit Event */
+ CPTS_EV_COMP, /* Time Stamp Compare Event */
};
#define CPTS_FIFO_DEPTH 16
@@ -113,6 +118,8 @@ struct cpts_event {
};
#define CPTS_CAP_RFTCLK_SEL BIT(0)
+#define CPTS_CAP_TS_COMP_EN BIT(1)
+#define CPTS_CAP_TS_COMP_POL_LOW_SEL BIT(2)
struct cpts {
struct device *dev;
@@ -137,6 +144,11 @@ struct cpts {
u32 ext_ts_inputs;
u32 hw_ts_enable;
u32 caps;
+ u32 ts_comp_next; /* next time_stamp value to compare with */
+ u32 ts_comp_length; /* TS_COMP Output pulse width */
+ u32 ts_comp_one_sec_cycs; /* number of counter cycles in one sec */
+ int ts_comp_enabled;
+ struct mutex ptp_clk_mutex; /* sync PTP interface with overflow_work */
};
void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-30 11:10 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sJ9ZU-4JS-21@gated-at.bofh.it> |
| In reply to | #1531788 |
On Mon, Nov 28, 2016 at 05:04:26PM -0600, Grygorii Strashko wrote: > The TS_COMP output in the CPSW CPTS module is asserted for > ts_comp_length[15:0] RCLK periods when the time_stamp value compares > with the ts_comp_val[31:0] and the length value is non-zero. The > TS_COMP pulse edge occurs three RCLK periods after the values > compare. A timestamp compare event is pushed into the event FIFO when > TS_COMP is asserted. > > This patch adds support of Pulse-Per-Second (PPS) by using the > timestamp compare output. The CPTS driver adds one second of counter > value to the ts_comp_val register after each assertion of the TS_COMP > output. The TS_COMP pulse polarity and width are configurable in DT. I really dislike this patch. You go through contortions to get from the timecounter back to the raw HW counter. That is rather ugly. Can you adjust the frequency of the keystone devices in hardware? If so, then please implement it, and just disable PPS for the CPSW. The only reason I used the timecounter for frequency adjustment was because the am335x HW is broken. But this shouldn't hold back other newer HW without the same silicon flaws. Thanks, Richard
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-12-06 19:10 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sLslI-5to-21@gated-at.bofh.it> |
| In reply to | #1533177 |
On Wed, Nov 30, 2016 at 11:05:19AM +0100, Richard Cochran wrote: > Can you adjust the frequency of the keystone devices in hardware? If > so, then please implement it, and just disable PPS for the CPSW. > > The only reason I used the timecounter for frequency adjustment was > because the am335x HW is broken. But this shouldn't hold back other > newer HW without the same silicon flaws. I am talking here about the ADPLLLJ units. Are they usable on the keystone? If so, please implement the frequency adjustment with them. Thanks, Richard
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-12-06 23:40 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sLwyZ-854-3@gated-at.bofh.it> |
| In reply to | #1537179 |
On 12/06/2016 12:08 PM, Richard Cochran wrote: > On Wed, Nov 30, 2016 at 11:05:19AM +0100, Richard Cochran wrote: >> Can you adjust the frequency of the keystone devices in hardware? If >> so, then please implement it, and just disable PPS for the CPSW. >> >> The only reason I used the timecounter for frequency adjustment was >> because the am335x HW is broken. But this shouldn't hold back other >> newer HW without the same silicon flaws. > > I am talking here about the ADPLLLJ units. Are they usable on the > keystone? > > If so, please implement the frequency adjustment with them. > No, I think it's not impossible (at least as I know now). i'll drop this patch for now. By the way, I've tested am335 (BBB)+ HW_TS_PUSH + PWM. Seems works. -- regards, -grygorii
[toc] | [prev] | [next] | [standalone]
| From | Jan Lübbe <jlu@pengutronix.de> |
|---|---|
| Date | 2016-11-30 12:10 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sJaVY-5lj-13@gated-at.bofh.it> |
| In reply to | #1531788 |
On Mo, 2016-11-28 at 17:04 -0600, Grygorii Strashko wrote: > --- a/Documentation/devicetree/bindings/net/keystone-netcp.txt > +++ b/Documentation/devicetree/bindings/net/keystone-netcp.txt > @@ -127,6 +127,16 @@ Optional properties: > The number of external time stamp channels. > The different CPTS versions might support up 8 > external time stamp channels. if absent - unsupported. > + - cpts-ts-comp-length: > + Enable time stamp comparison event and TS_COMP signal output > + generation when CPTS counter reaches a value written to > + the TS_COMP_VAL register. > + The generated pulse width is 3 refclk cycles if this property > + has no value (empty) or, otherwise, it should specify desired > + pulse width in number of refclk periods - max value 2^16. > + TS_COMP functionality will be disabled if not present. > + - cpts-ts-comp-polarity-low: > + Set polarity of TS_COMP signal to low. Default is hight. Why is this configured via DT? Are the values fixed for a given board, depending on external components? Couldn't this be configured somewhere else? Regards, Jan -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-30 19:50 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sJi78-1gR-15@gated-at.bofh.it> |
| In reply to | #1531788 |
On Mon, Nov 28, 2016 at 05:04:26PM -0600, Grygorii Strashko wrote:
> +static cycle_t cpts_cc_ns2cyc(struct cpts *cpts, u64 nsecs)
> +{
> + cycle_t cyc = (nsecs << cpts->cc.shift) + nsecs;
> +
> + do_div(cyc, cpts->cc.mult);
> +
> + return cyc;
> +}
So you set the comparison value once per second, based on cc.mult.
But when the clock is being actively synchronized, user space calls to
clock_adjtimex() will change cc.mult. This can happen several times
per second, depending on the PTP Sync rate.
In order to produce the PPS edge correctly, you would have to adjust
the comparison value whenever cc.mult changes, but of course this is
unworkable.
So I'll have to say NAK for this patch.
Thanks,
Richard
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-30 21:50 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sJjZf-2rP-19@gated-at.bofh.it> |
| In reply to | #1533505 |
On 11/30/2016 12:45 PM, Richard Cochran wrote:
> On Mon, Nov 28, 2016 at 05:04:26PM -0600, Grygorii Strashko wrote:
>> +static cycle_t cpts_cc_ns2cyc(struct cpts *cpts, u64 nsecs)
>> +{
>> + cycle_t cyc = (nsecs << cpts->cc.shift) + nsecs;
>> +
>> + do_div(cyc, cpts->cc.mult);
>> +
>> + return cyc;
>> +}
>
> So you set the comparison value once per second, based on cc.mult.
> But when the clock is being actively synchronized, user space calls to
> clock_adjtimex() will change cc.mult. This can happen several times
> per second, depending on the PTP Sync rate.
>
Right.
> In order to produce the PPS edge correctly, you would have to adjust
> the comparison value whenever cc.mult changes,
yes. And that is done in cpts_ptp_adjfreq()
if (cpts->ts_comp_enabled)
cpts->ts_comp_one_sec_cycs = cpts_cc_ns2cyc(cpts, NSEC_PER_SEC);
^^^ re-calculate reload value for
cpts_ts_comp_settime(cpts, ns);
^^^ adjust the ts_comp
> but of course this is unworkable.
>
Sry, but this is questionable - code for pps comes from TI internal
branches (SDK releases) where it survived for a pretty long time.
I'm, of course, agree that without HW support for freq adjustment
this PPS feature is not super precise and has some limitation,
but that is what we agree to live with.
Murali, do you have any comments regarding usability of SW
freq freq adjustment approach?
> So I'll have to say NAK for this patch.
>
:)
--
regards,
-grygorii
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-30 23:20 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sJlol-3uZ-7@gated-at.bofh.it> |
| In reply to | #1533561 |
On Wed, Nov 30, 2016 at 02:43:57PM -0600, Grygorii Strashko wrote:
> > In order to produce the PPS edge correctly, you would have to adjust
> > the comparison value whenever cc.mult changes,
>
> yes. And that is done in cpts_ptp_adjfreq()
> if (cpts->ts_comp_enabled)
> cpts->ts_comp_one_sec_cycs = cpts_cc_ns2cyc(cpts, NSEC_PER_SEC);
> ^^^ re-calculate reload value for
>
> cpts_ts_comp_settime(cpts, ns);
> ^^^ adjust the ts_comp
And it races with the pulse itself. You forgot about this part:
> @@ -172,14 +232,31 @@ static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
> adj *= ppb;
> diff = div_u64(adj, 1000000000ULL);
>
> + mutex_lock(&cpts->ptp_clk_mutex);
> +
> spin_lock_irqsave(&cpts->lock, flags);
> + if (cpts->ts_comp_enabled) {
> + cpts_ts_comp_disable(cpts);
Sorry, but this is a train wreck.
> > but of course this is unworkable.
> >
>
> Sry, but this is questionable - code for pps comes from TI internal
> branches (SDK releases) where it survived for a pretty long time.
That doesn't mean the code is any good. If you adjust at the right
moment, then no pulse occurs at all!
> I'm, of course, agree that without HW support for freq adjustment
> this PPS feature is not super precise and has some limitation,
> but that is what we agree to live with.
I do NOT agree to live with this. I am one who is going to have to
explain to the world why their beagle bone PPS sucks.
Thanks,
Richard
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-12-02 11:00 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sJSNj-29y-5@gated-at.bofh.it> |
| In reply to | #1533631 |
On Wed, Nov 30, 2016 at 11:17:38PM +0100, Richard Cochran wrote: > On Wed, Nov 30, 2016 at 02:43:57PM -0600, Grygorii Strashko wrote: > > Sry, but this is questionable - code for pps comes from TI internal > > branches (SDK releases) where it survived for a pretty long time. Actually, there is a way to get an accurate PPS from the am335x. See this recent thread: https://www.mail-archive.com/linuxptp-devel@lists.sourceforge.net/msg01726.html That is the way to go, and so, please drop this present patch. Thanks, Richard
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-12-02 19:00 +0100 |
| Subject | Re: [PATCH 4/6] net: ethernet: ti: cpts: add ptp pps support |
| Message-ID | <sK0hQ-6VB-9@gated-at.bofh.it> |
| In reply to | #1534777 |
Hi Richard, On 12/02/2016 03:58 AM, Richard Cochran wrote: > On Wed, Nov 30, 2016 at 11:17:38PM +0100, Richard Cochran wrote: >> On Wed, Nov 30, 2016 at 02:43:57PM -0600, Grygorii Strashko wrote: >>> Sry, but this is questionable - code for pps comes from TI internal >>> branches (SDK releases) where it survived for a pretty long time. > > Actually, there is a way to get an accurate PPS from the am335x. See > this recent thread: > > https://www.mail-archive.com/linuxptp-devel@lists.sourceforge.net/msg01726.html > > That is the way to go, and so, please drop this present patch. > thanks for the links - it sounds very interesting. As I understood, people trying to enable PPS on am335 device with the goal to have PPS signal generated on some SoC pin and therefore they use DMtimer. Also, as i understood, the Timer Load Register (TLDR) is corrected once a second at each HW_TS_PUSH - as result, if freq was corrected during current sec there will be some HW_TS_PUSH generation jitter any way. Above solution is a bit complex for keystone 2 SoCs, as CPTS itself on these SoCs has output pin (ts_comp) which can be used for PPS signal generation. So, I think, similar results can be achieved by removing PPS correction code from cpts_ptp_adjfreq() and updating CPTS_TS_LOAD_VAL once a sec in cpts_overflow_check(). or I missed smth? -- regards, -grygorii
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web