Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1531769 > unrolled thread
| Started by | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| First post | 2016-11-29 00:10 +0100 |
| Last post | 2016-11-29 10:50 +0100 |
| Articles | 20 on this page of 30 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v2 00/13] net: ethernet: ti: cpts: update and fixes Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
[PATCH v2 12/13] net: ethernet: ti: cpts: calc mult and shift from refclk freq Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH v2 12/13] net: ethernet: ti: cpts: calc mult and shift from refclk freq Richard Cochran <richardcochran@gmail.com> - 2016-11-29 11:40 +0100
Re: [PATCH v2 12/13] net: ethernet: ti: cpts: calc mult and shift from refclk freq Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 17:30 +0100
[PATCH v2 03/13] net: ethernet: ti: cpsw: minimize direct access to struct cpts Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
[PATCH v2 10/13] net: ethernet: ti: cpts: drop excessive writes to CTRL and INT_EN regs Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH v2 10/13] net: ethernet: ti: cpts: drop excessive writes to CTRL and INT_EN regs Richard Cochran <richardcochran@gmail.com> - 2016-11-29 11:20 +0100
[PATCH v2 06/13] net: ethernet: ti: cpts: disable cpts when unregistered Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH v2 06/13] net: ethernet: ti: cpts: disable cpts when unregistered Richard Cochran <richardcochran@gmail.com> - 2016-11-29 11:00 +0100
[PATCH v2 07/13] net: ethernet: ti: cpts: rework initialization/deinitialization Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH v2 07/13] net: ethernet: ti: cpts: rework initialization/deinitialization Richard Cochran <richardcochran@gmail.com> - 2016-11-29 11:10 +0100
Re: [PATCH v2 07/13] net: ethernet: ti: cpts: rework initialization/deinitialization Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 17:00 +0100
Re: [PATCH v2 07/13] net: ethernet: ti: cpts: rework initialization/deinitialization Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-30 19:40 +0100
[PATCH v2 02/13] net: ethernet: ti: allow cpts to be built separately Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH v2 02/13] net: ethernet: ti: allow cpts to be built separately Richard Cochran <richardcochran@gmail.com> - 2016-11-29 10:40 +0100
[PATCH v2 01/13] net: ethernet: ti: cpts: switch to readl/writel_relaxed() Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH v2 01/13] net: ethernet: ti: cpts: switch to readl/writel_relaxed() Richard Cochran <richardcochran@gmail.com> - 2016-11-29 10:40 +0100
[PATCH v2 13/13] net: ethernet: ti: cpts: fix overflow check period Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH v2 13/13] net: ethernet: ti: cpts: fix overflow check period Richard Cochran <richardcochran@gmail.com> - 2016-11-30 10:20 +0100
[PATCH v2 11/13] clocksource: export the clocks_calc_mult_shift to use by timestamp code Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:10 +0100
Re: [PATCH v2 11/13] clocksource: export the clocks_calc_mult_shift to use by timestamp code Thomas Gleixner <tglx@linutronix.de> - 2016-11-29 10:20 +0100
[PATCH v2 09/13] net: ethernet: ti: cpts: clean up event list if event pool is empty Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:20 +0100
Re: [PATCH v2 09/13] net: ethernet: ti: cpts: clean up event list if event pool is empty Richard Cochran <richardcochran@gmail.com> - 2016-11-29 11:20 +0100
[PATCH v2 04/13] net: ethernet: ti: cpts: fix unbalanced clk api usage in cpts_register/unregister Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:20 +0100
Re: [PATCH v2 04/13] net: ethernet: ti: cpts: fix unbalanced clk api usage in cpts_register/unregister Richard Cochran <richardcochran@gmail.com> - 2016-11-29 10:50 +0100
[PATCH v2 08/13] net: ethernet: ti: cpts: move dt props parsing to cpts driver Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:20 +0100
Re: [PATCH v2 08/13] net: ethernet: ti: cpts: move dt props parsing to cpts driver Richard Cochran <richardcochran@gmail.com> - 2016-11-29 11:20 +0100
Re: [PATCH v2 08/13] net: ethernet: ti: cpts: move dt props parsing to cpts driver Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 17:00 +0100
[PATCH v2 05/13] net: ethernet: ti: cpts: fix registration order Grygorii Strashko <grygorii.strashko@ti.com> - 2016-11-29 00:20 +0100
Re: [PATCH v2 05/13] net: ethernet: ti: cpts: fix registration order Richard Cochran <richardcochran@gmail.com> - 2016-11-29 10:50 +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 v2 00/13] net: ethernet: ti: cpts: update and fixes |
| Message-ID | <sIDdD-75-3@gated-at.bofh.it> |
It is preparation series intended to clean up and optimize TI CPTS driver to facilitate further integration with other TI's SoCs like Keystone 2. Changes in v2: - patch "net: ethernet: ti: cpts: rework initialization/deinitialization" was split on 4 patches - applied comments from Richard Cochran - dropped patch "net: ethernet: ti: cpts: add return value to tx and rx timestamp funcitons" - new patches added: "net: ethernet: ti: cpts: drop excessive writes to CTRL and INT_EN regs" and "clocksource: export the clocks_calc_mult_shift to use by timestamp code" Link on v1: http://www.spinics.net/lists/linux-omap/msg131925.html Grygorii Strashko (11): net: ethernet: ti: cpts: switch to readl/writel_relaxed() net: ethernet: ti: allow cpts to be built separately net: ethernet: ti: cpsw: minimize direct access to struct cpts net: ethernet: ti: cpts: fix unbalanced clk api usage in cpts_register/unregister net: ethernet: ti: cpts: fix registration order net: ethernet: ti: cpts: disable cpts when unregistered net: ethernet: ti: cpts: rework initialization/deinitialization net: ethernet: ti: cpts: move dt props parsing to cpts driver net: ethernet: ti: cpts: drop excessive writes to CTRL and INT_EN regs net: ethernet: ti: cpts: calc mult and shift from refclk freq net: ethernet: ti: cpts: fix overflow check period Murali Karicheri (1): clocksource: export the clocks_calc_mult_shift to use by timestamp code WingMan Kwok (1): net: ethernet: ti: cpts: clean up event list if event pool is empty Documentation/devicetree/bindings/net/cpsw.txt | 8 +- drivers/net/ethernet/ti/Kconfig | 2 +- drivers/net/ethernet/ti/Makefile | 3 +- drivers/net/ethernet/ti/cpsw.c | 84 ++++----- drivers/net/ethernet/ti/cpsw.h | 2 - drivers/net/ethernet/ti/cpts.c | 232 ++++++++++++++++++------- drivers/net/ethernet/ti/cpts.h | 80 ++++++++- kernel/time/clocksource.c | 1 + 8 files changed, 297 insertions(+), 115 deletions(-) -- 2.10.1
[toc] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 12/13] net: ethernet: ti: cpts: calc mult and shift from refclk freq |
| Message-ID | <sIDdD-75-1@gated-at.bofh.it> |
| In reply to | #1531769 |
The cyclecounter mult and shift values can be calculated based on the
CPTS rfclk frequency and timekeepnig framework provides required algos
and API's.
Hence, calc mult and shift basing on CPTS rfclk frequency if both
cpts_clock_shift and cpts_clock_mult properties are not provided in DT (the
basis of calculation algorithm is borrowed from
__clocksource_update_freq_scale() commit 7d2f944a2b83 ("clocksource:
Provide a generic mult/shift factor calculation")). After this change
cpts_clock_shift and cpts_clock_mult DT properties will become optional.
Cc: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/cpsw.txt | 8 +++--
drivers/net/ethernet/ti/cpts.c | 50 ++++++++++++++++++++++----
2 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt
index 5ad439f..ebda7c9 100644
--- a/Documentation/devicetree/bindings/net/cpsw.txt
+++ b/Documentation/devicetree/bindings/net/cpsw.txt
@@ -20,8 +20,6 @@ Required properties:
- slaves : Specifies number for slaves
- active_slave : Specifies the slave to use for time stamping,
ethtool and SIOCGMIIPHY
-- cpts_clock_mult : Numerator to convert input clock ticks into nanoseconds
-- cpts_clock_shift : Denominator to convert input clock ticks into nanoseconds
Optional properties:
- ti,hwmods : Must be "cpgmac0"
@@ -35,7 +33,11 @@ Optional properties:
For example in dra72x-evm, pcf gpio has to be
driven low so that cpsw slave 0 and phy data
lines are connected via mux.
-
+- cpts_clock_mult : Numerator to convert input clock ticks into nanoseconds
+- cpts_clock_shift : Denominator to convert input clock ticks into nanoseconds
+ Mult and shift will be calculated basing on CPTS
+ rftclk frequency if both cpts_clock_shift and
+ cpts_clock_mult properties are not provided.
Slave Properties:
Required properties:
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index da3339b..4761d8c 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -406,18 +406,54 @@ void cpts_unregister(struct cpts *cpts)
}
EXPORT_SYMBOL_GPL(cpts_unregister);
+static void cpts_calc_mult_shift(struct cpts *cpts)
+{
+ u64 frac, maxsec, ns;
+ u32 freq, mult, shift;
+
+ freq = clk_get_rate(cpts->refclk);
+
+ /* Calc the maximum number of seconds which we can run before
+ * wrapping around.
+ */
+ maxsec = cpts->cc.mask;
+ do_div(maxsec, freq);
+ if (maxsec > 600 && cpts->cc.mask > UINT_MAX)
+ maxsec = 600;
+
+ if (cpts->cc_mult || cpts->cc.shift)
+ return;
+
+ clocks_calc_mult_shift(&mult, &shift, freq, NSEC_PER_SEC, maxsec);
+
+ cpts->cc_mult = mult;
+ cpts->cc.mult = mult;
+ cpts->cc.shift = shift;
+
+ frac = 0;
+ ns = cyclecounter_cyc2ns(&cpts->cc, freq, cpts->cc.mask, &frac);
+
+ dev_info(cpts->dev,
+ "CPTS: ref_clk_freq:%u calc_mult:%u calc_shift:%u error:%lld nsec/sec\n",
+ freq, cpts->cc_mult, cpts->cc.shift, (ns - NSEC_PER_SEC));
+}
+
static int cpts_of_parse(struct cpts *cpts, struct device_node *node)
{
int ret = -EINVAL;
u32 prop;
- if (of_property_read_u32(node, "cpts_clock_mult", &prop))
- goto of_error;
- cpts->cc_mult = prop;
+ cpts->cc_mult = 0;
+ if (!of_property_read_u32(node, "cpts_clock_mult", &prop))
+ cpts->cc_mult = prop;
+
+ cpts->cc.shift = 0;
+ if (!of_property_read_u32(node, "cpts_clock_shift", &prop))
+ cpts->cc.shift = prop;
- if (of_property_read_u32(node, "cpts_clock_shift", &prop))
- goto of_error;
- cpts->cc.shift = prop;
+ if ((cpts->cc_mult && !cpts->cc.shift) ||
+ (!cpts->cc_mult && cpts->cc.shift))
+ goto of_error;
return 0;
@@ -460,6 +496,8 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
cpts->cc.mask = CLOCKSOURCE_MASK(32);
cpts->info = cpts_info;
+ cpts_calc_mult_shift(cpts);
+
return cpts;
}
EXPORT_SYMBOL_GPL(cpts_create);
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-29 11:40 +0100 |
| Subject | Re: [PATCH v2 12/13] net: ethernet: ti: cpts: calc mult and shift from refclk freq |
| Message-ID | <sINZo-7hY-3@gated-at.bofh.it> |
| In reply to | #1531771 |
On Mon, Nov 28, 2016 at 05:03:36PM -0600, Grygorii Strashko wrote:
> +static void cpts_calc_mult_shift(struct cpts *cpts)
> +{
> + u64 frac, maxsec, ns;
> + u32 freq, mult, shift;
> +
> + freq = clk_get_rate(cpts->refclk);
> +
> + /* Calc the maximum number of seconds which we can run before
> + * wrapping around.
> + */
> + maxsec = cpts->cc.mask;
> + do_div(maxsec, freq);
> + if (maxsec > 600 && cpts->cc.mask > UINT_MAX)
> + maxsec = 600;
The reason for this test is not obvious. Why check cc.mask against
UINT_MAX? Please use the comment to explain it.
Thanks,
Richard
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 17:30 +0100 |
| Subject | Re: [PATCH v2 12/13] net: ethernet: ti: cpts: calc mult and shift from refclk freq |
| Message-ID | <sITs5-2o0-17@gated-at.bofh.it> |
| In reply to | #1532111 |
On 11/29/2016 04:34 AM, Richard Cochran wrote:
> On Mon, Nov 28, 2016 at 05:03:36PM -0600, Grygorii Strashko wrote:
>> +static void cpts_calc_mult_shift(struct cpts *cpts)
>> +{
>> + u64 frac, maxsec, ns;
>> + u32 freq, mult, shift;
>> +
>> + freq = clk_get_rate(cpts->refclk);
>> +
>> + /* Calc the maximum number of seconds which we can run before
>> + * wrapping around.
>> + */
>> + maxsec = cpts->cc.mask;
>> + do_div(maxsec, freq);
>> + if (maxsec > 600 && cpts->cc.mask > UINT_MAX)
>> + maxsec = 600;
>
> The reason for this test is not obvious. Why check cc.mask against
> UINT_MAX? Please use the comment to explain it.
>
Yeah. This is copy paste from __clocksource_update_freq_scale(), but
I'm going to limit it to 10 sec for now, because otherwise it will result in too small
mult in case of 64bit counter.
if (maxsec > 10)
maxsec = 10;
--
regards,
-grygorii
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 03/13] net: ethernet: ti: cpsw: minimize direct access to struct cpts |
| Message-ID | <sIDdD-75-5@gated-at.bofh.it> |
| In reply to | #1531769 |
This will provide more flexibility in changing CPTS internals and also
required for further changes.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpsw.c | 28 +++++++++++++++-------------
drivers/net/ethernet/ti/cpts.h | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index f65a4e8..a6a93ad 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1481,7 +1481,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
}
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
- cpsw->cpts->tx_enable)
+ cpts_is_tx_enabled(cpsw->cpts))
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
skb_tx_timestamp(skb);
@@ -1520,7 +1520,8 @@ static void cpsw_hwtstamp_v1(struct cpsw_common *cpsw)
struct cpsw_slave *slave = &cpsw->slaves[cpsw->data.active_slave];
u32 ts_en, seq_id;
- if (!cpsw->cpts->tx_enable && !cpsw->cpts->rx_enable) {
+ if (!cpts_is_tx_enabled(cpsw->cpts) &&
+ !cpts_is_rx_enabled(cpsw->cpts)) {
slave_write(slave, 0, CPSW1_TS_CTL);
return;
}
@@ -1528,10 +1529,10 @@ static void cpsw_hwtstamp_v1(struct cpsw_common *cpsw)
seq_id = (30 << CPSW_V1_SEQ_ID_OFS_SHIFT) | ETH_P_1588;
ts_en = EVENT_MSG_BITS << CPSW_V1_MSG_TYPE_OFS;
- if (cpsw->cpts->tx_enable)
+ if (cpts_is_tx_enabled(cpsw->cpts))
ts_en |= CPSW_V1_TS_TX_EN;
- if (cpsw->cpts->rx_enable)
+ if (cpts_is_rx_enabled(cpsw->cpts))
ts_en |= CPSW_V1_TS_RX_EN;
slave_write(slave, ts_en, CPSW1_TS_CTL);
@@ -1554,20 +1555,20 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv)
case CPSW_VERSION_2:
ctrl &= ~CTRL_V2_ALL_TS_MASK;
- if (cpsw->cpts->tx_enable)
+ if (cpts_is_tx_enabled(cpsw->cpts))
ctrl |= CTRL_V2_TX_TS_BITS;
- if (cpsw->cpts->rx_enable)
+ if (cpts_is_rx_enabled(cpsw->cpts))
ctrl |= CTRL_V2_RX_TS_BITS;
break;
case CPSW_VERSION_3:
default:
ctrl &= ~CTRL_V3_ALL_TS_MASK;
- if (cpsw->cpts->tx_enable)
+ if (cpts_is_tx_enabled(cpsw->cpts))
ctrl |= CTRL_V3_TX_TS_BITS;
- if (cpsw->cpts->rx_enable)
+ if (cpts_is_rx_enabled(cpsw->cpts))
ctrl |= CTRL_V3_RX_TS_BITS;
break;
}
@@ -1603,7 +1604,7 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
switch (cfg.rx_filter) {
case HWTSTAMP_FILTER_NONE:
- cpts->rx_enable = 0;
+ cpts_rx_enable(cpts, 0);
break;
case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
@@ -1619,14 +1620,14 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
- cpts->rx_enable = 1;
+ cpts_rx_enable(cpts, 1);
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
break;
default:
return -ERANGE;
}
- cpts->tx_enable = cfg.tx_type == HWTSTAMP_TX_ON;
+ cpts_tx_enable(cpts, cfg.tx_type == HWTSTAMP_TX_ON);
switch (cpsw->version) {
case CPSW_VERSION_1:
@@ -1655,8 +1656,9 @@ static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
return -EOPNOTSUPP;
cfg.flags = 0;
- cfg.tx_type = cpts->tx_enable ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
- cfg.rx_filter = (cpts->rx_enable ?
+ cfg.tx_type = cpts_is_tx_enabled(cpts) ?
+ HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+ cfg.rx_filter = (cpts_is_rx_enabled(cpts) ?
HWTSTAMP_FILTER_PTP_V2_EVENT : HWTSTAMP_FILTER_NONE);
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index 416ba2c..29a1e80c 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -132,6 +132,27 @@ void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb);
int cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift);
void cpts_unregister(struct cpts *cpts);
+
+static inline void cpts_rx_enable(struct cpts *cpts, int enable)
+{
+ cpts->rx_enable = enable;
+}
+
+static inline bool cpts_is_rx_enabled(struct cpts *cpts)
+{
+ return !!cpts->rx_enable;
+}
+
+static inline void cpts_tx_enable(struct cpts *cpts, int enable)
+{
+ cpts->tx_enable = enable;
+}
+
+static inline bool cpts_is_tx_enabled(struct cpts *cpts)
+{
+ return !!cpts->tx_enable;
+}
+
#else
static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
{
@@ -149,6 +170,24 @@ cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift)
static inline void cpts_unregister(struct cpts *cpts)
{
}
+
+static inline void cpts_rx_enable(struct cpts *cpts, int enable)
+{
+}
+
+static inline bool cpts_is_rx_enabled(struct cpts *cpts)
+{
+ return false;
+}
+
+static inline void cpts_tx_enable(struct cpts *cpts, int enable)
+{
+}
+
+static inline bool cpts_is_tx_enabled(struct cpts *cpts)
+{
+ return false;
+}
#endif
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 10/13] net: ethernet: ti: cpts: drop excessive writes to CTRL and INT_EN regs |
| Message-ID | <sIDdD-75-13@gated-at.bofh.it> |
| In reply to | #1531769 |
CPTS module and IRQs are always enabled when CPTS is registered,
before starting overflow check work, and disabled during
deregistration, when overflow check work has been canceled already.
So, It doesn't require to (re)enable CPTS module and IRQs in
cpts_overflow_check().
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpts.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 1b766eb..da3339b 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -243,8 +243,6 @@ static void cpts_overflow_check(struct work_struct *work)
struct timespec64 ts;
struct cpts *cpts = container_of(work, struct cpts, overflow_work.work);
- cpts_write32(cpts, CPTS_EN, control);
- cpts_write32(cpts, TS_PEND_EN, int_enable);
cpts_ptp_gettime(&cpts->info, &ts);
pr_debug("cpts overflow check at %lld.%09lu\n", ts.tv_sec, ts.tv_nsec);
schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD);
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-29 11:20 +0100 |
| Subject | Re: [PATCH v2 10/13] net: ethernet: ti: cpts: drop excessive writes to CTRL and INT_EN regs |
| Message-ID | <sING1-7bs-5@gated-at.bofh.it> |
| In reply to | #1531776 |
On Mon, Nov 28, 2016 at 05:03:34PM -0600, Grygorii Strashko wrote: > CPTS module and IRQs are always enabled when CPTS is registered, > before starting overflow check work, and disabled during > deregistration, when overflow check work has been canceled already. > So, It doesn't require to (re)enable CPTS module and IRQs in > cpts_overflow_check(). > > Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Acked-by: Richard Cochran <richardcochran@gmail.com>
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 06/13] net: ethernet: ti: cpts: disable cpts when unregistered |
| Message-ID | <sIDdD-75-7@gated-at.bofh.it> |
| In reply to | #1531769 |
The cpts now is left enabled after unregistration. Hence, disable it in cpts_unregister(). Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> --- drivers/net/ethernet/ti/cpts.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index cb851a7..9ad0998 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c @@ -404,6 +404,10 @@ void cpts_unregister(struct cpts *cpts) ptp_clock_unregister(cpts->clock); cancel_delayed_work_sync(&cpts->overflow_work); } + + cpts_write32(cpts, 0, int_enable); + cpts_write32(cpts, 0, control); + if (cpts->refclk) cpts_clk_release(cpts); } -- 2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-29 11:00 +0100 |
| Subject | Re: [PATCH v2 06/13] net: ethernet: ti: cpts: disable cpts when unregistered |
| Message-ID | <sINmF-6Mq-3@gated-at.bofh.it> |
| In reply to | #1531777 |
On Mon, Nov 28, 2016 at 05:03:30PM -0600, Grygorii Strashko wrote: > The cpts now is left enabled after unregistration. > Hence, disable it in cpts_unregister(). > > Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Acked-by: Richard Cochran <richardcochran@gmail.com>
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 07/13] net: ethernet: ti: cpts: rework initialization/deinitialization |
| Message-ID | <sIDdD-75-27@gated-at.bofh.it> |
| In reply to | #1531769 |
The current implementation CPTS initialization and deinitialization
(represented by cpts_register/unregister()) does too many static
initialization from .ndo_open(), which is reasonable to do once at probe
time instead, and also require caller to allocate memory for struct cpts,
which is internal for CPTS driver in general.
This patch splits CPTS initialization and deinitialization on two parts:
- static initializtion cpts_create()/cpts_release() which expected to be
executed when parent driver is probed/removed;
- dynamic part cpts_register/unregister() which expected to be executed
when network device is opened/closed.
As result, current code of CPTS parent driver - CPSW - will be simplified
(and it also will allow simplify adding support for Keystone 2 devices in
the future), plus more initialization errors will be catched earlier. In
addition, this change allows to clean up cpts.h for the case when CPTS is
disabled.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpsw.c | 24 +++++-----
drivers/net/ethernet/ti/cpts.c | 102 ++++++++++++++++++++++++-----------------
drivers/net/ethernet/ti/cpts.h | 26 +++++++++--
3 files changed, 95 insertions(+), 57 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index a6a93ad..6c28ef1 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1406,9 +1406,7 @@ static int cpsw_ndo_open(struct net_device *ndev)
if (ret < 0)
goto err_cleanup;
- if (cpts_register(cpsw->dev, cpsw->cpts,
- cpsw->data.cpts_clock_mult,
- cpsw->data.cpts_clock_shift))
+ if (cpts_register(cpsw->cpts))
dev_err(priv->dev, "error registering cpts device\n");
}
@@ -2596,6 +2594,7 @@ static int cpsw_probe(struct platform_device *pdev)
struct cpdma_params dma_params;
struct cpsw_ale_params ale_params;
void __iomem *ss_regs;
+ void __iomem *cpts_regs;
struct resource *res, *ss_res;
const struct of_device_id *of_id;
struct gpio_descs *mode;
@@ -2623,12 +2622,6 @@ static int cpsw_probe(struct platform_device *pdev)
priv->dev = &ndev->dev;
priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
cpsw->rx_packet_max = max(rx_packet_max, 128);
- cpsw->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL);
- if (!cpsw->cpts) {
- dev_err(&pdev->dev, "error allocating cpts\n");
- ret = -ENOMEM;
- goto clean_ndev_ret;
- }
mode = devm_gpiod_get_array_optional(&pdev->dev, "mode", GPIOD_OUT_LOW);
if (IS_ERR(mode)) {
@@ -2716,7 +2709,7 @@ static int cpsw_probe(struct platform_device *pdev)
switch (cpsw->version) {
case CPSW_VERSION_1:
cpsw->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET;
- cpsw->cpts->reg = ss_regs + CPSW1_CPTS_OFFSET;
+ cpts_regs = ss_regs + CPSW1_CPTS_OFFSET;
cpsw->hw_stats = ss_regs + CPSW1_HW_STATS;
dma_params.dmaregs = ss_regs + CPSW1_CPDMA_OFFSET;
dma_params.txhdp = ss_regs + CPSW1_STATERAM_OFFSET;
@@ -2730,7 +2723,7 @@ static int cpsw_probe(struct platform_device *pdev)
case CPSW_VERSION_3:
case CPSW_VERSION_4:
cpsw->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET;
- cpsw->cpts->reg = ss_regs + CPSW2_CPTS_OFFSET;
+ cpts_regs = ss_regs + CPSW2_CPTS_OFFSET;
cpsw->hw_stats = ss_regs + CPSW2_HW_STATS;
dma_params.dmaregs = ss_regs + CPSW2_CPDMA_OFFSET;
dma_params.txhdp = ss_regs + CPSW2_STATERAM_OFFSET;
@@ -2796,6 +2789,14 @@ static int cpsw_probe(struct platform_device *pdev)
goto clean_dma_ret;
}
+ cpsw->cpts = cpts_create(cpsw->dev, cpts_regs,
+ cpsw->data.cpts_clock_mult,
+ cpsw->data.cpts_clock_shift);
+ if (IS_ERR(cpsw->cpts)) {
+ ret = PTR_ERR(cpsw->cpts);
+ goto clean_ale_ret;
+ }
+
ndev->irq = platform_get_irq(pdev, 1);
if (ndev->irq < 0) {
dev_err(priv->dev, "error getting irq resource\n");
@@ -2911,6 +2912,7 @@ static int cpsw_remove(struct platform_device *pdev)
unregister_netdev(cpsw->slaves[1].ndev);
unregister_netdev(ndev);
+ cpts_release(cpsw->cpts);
cpsw_ale_destroy(cpsw->ale);
cpdma_ctlr_destroy(cpsw->dma);
cpsw_remove_dt(pdev);
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 9ad0998..ec3f702 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -228,24 +228,6 @@ static void cpts_overflow_check(struct work_struct *work)
schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD);
}
-static void cpts_clk_init(struct device *dev, struct cpts *cpts)
-{
- if (!cpts->refclk) {
- cpts->refclk = devm_clk_get(dev, "cpts");
- if (IS_ERR(cpts->refclk)) {
- dev_err(dev, "Failed to get cpts refclk\n");
- cpts->refclk = NULL;
- return;
- }
- }
- clk_prepare_enable(cpts->refclk);
-}
-
-static void cpts_clk_release(struct cpts *cpts)
-{
- clk_disable_unprepare(cpts->refclk);
-}
-
static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
u16 ts_seqid, u8 ts_msgtype)
{
@@ -352,34 +334,24 @@ void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(cpts_tx_timestamp);
-int cpts_register(struct device *dev, struct cpts *cpts,
- u32 mult, u32 shift)
+int cpts_register(struct cpts *cpts)
{
int err, i;
- cpts->info = cpts_info;
- spin_lock_init(&cpts->lock);
-
- cpts->cc.read = cpts_systim_read;
- cpts->cc.mask = CLOCKSOURCE_MASK(32);
- cpts->cc_mult = mult;
- cpts->cc.mult = mult;
- cpts->cc.shift = shift;
-
INIT_LIST_HEAD(&cpts->events);
INIT_LIST_HEAD(&cpts->pool);
for (i = 0; i < CPTS_MAX_EVENTS; i++)
list_add(&cpts->pool_data[i].list, &cpts->pool);
- cpts_clk_init(dev, cpts);
+ clk_enable(cpts->refclk);
+
cpts_write32(cpts, CPTS_EN, control);
cpts_write32(cpts, TS_PEND_EN, int_enable);
+ cpts->cc.mult = cpts->cc_mult;
timecounter_init(&cpts->tc, &cpts->cc, ktime_to_ns(ktime_get_real()));
- INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check);
-
- cpts->clock = ptp_clock_register(&cpts->info, dev);
+ cpts->clock = ptp_clock_register(&cpts->info, cpts->dev);
if (IS_ERR(cpts->clock)) {
err = PTR_ERR(cpts->clock);
cpts->clock = NULL;
@@ -392,26 +364,74 @@ int cpts_register(struct device *dev, struct cpts *cpts,
return 0;
err_ptp:
- if (cpts->refclk)
- cpts_clk_release(cpts);
+ clk_disable(cpts->refclk);
return err;
}
EXPORT_SYMBOL_GPL(cpts_register);
void cpts_unregister(struct cpts *cpts)
{
- if (cpts->clock) {
- ptp_clock_unregister(cpts->clock);
- cancel_delayed_work_sync(&cpts->overflow_work);
- }
+ if (WARN_ON(!cpts->clock))
+ return;
+
+ cancel_delayed_work_sync(&cpts->overflow_work);
+
+ ptp_clock_unregister(cpts->clock);
+ cpts->clock = NULL;
cpts_write32(cpts, 0, int_enable);
cpts_write32(cpts, 0, control);
- if (cpts->refclk)
- cpts_clk_release(cpts);
+ clk_disable(cpts->refclk);
}
EXPORT_SYMBOL_GPL(cpts_unregister);
+struct cpts *cpts_create(struct device *dev, void __iomem *regs,
+ u32 mult, u32 shift)
+{
+ struct cpts *cpts;
+
+ if (!regs || !dev)
+ return ERR_PTR(-EINVAL);
+
+ cpts = devm_kzalloc(dev, sizeof(*cpts), GFP_KERNEL);
+ if (!cpts)
+ return ERR_PTR(-ENOMEM);
+
+ cpts->dev = dev;
+ cpts->reg = (struct cpsw_cpts __iomem *)regs;
+ spin_lock_init(&cpts->lock);
+ INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check);
+
+ cpts->refclk = devm_clk_get(dev, "cpts");
+ if (IS_ERR(cpts->refclk)) {
+ dev_err(dev, "Failed to get cpts refclk\n");
+ return ERR_PTR(PTR_ERR(cpts->refclk));
+ }
+
+ clk_prepare(cpts->refclk);
+
+ cpts->cc.read = cpts_systim_read;
+ cpts->cc.mask = CLOCKSOURCE_MASK(32);
+ cpts->cc.shift = shift;
+ cpts->cc_mult = mult;
+ cpts->info = cpts_info;
+
+ return cpts;
+}
+EXPORT_SYMBOL_GPL(cpts_create);
+
+void cpts_release(struct cpts *cpts)
+{
+ if (!cpts)
+ return;
+
+ if (WARN_ON(!cpts->clock))
+ return;
+
+ clk_unprepare(cpts->refclk);
+}
+EXPORT_SYMBOL_GPL(cpts_release);
+
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("TI CPTS ALE driver");
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index 29a1e80c..e7d857c 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -20,6 +20,8 @@
#ifndef _TI_CPTS_H_
#define _TI_CPTS_H_
+#if IS_ENABLED(CONFIG_TI_CPTS)
+
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clocksource.h>
@@ -108,10 +110,10 @@ struct cpts_event {
};
struct cpts {
+ struct device *dev;
struct cpsw_cpts __iomem *reg;
int tx_enable;
int rx_enable;
-#if IS_ENABLED(CONFIG_TI_CPTS)
struct ptp_clock_info info;
struct ptp_clock *clock;
spinlock_t lock; /* protects time registers */
@@ -124,14 +126,15 @@ struct cpts {
struct list_head events;
struct list_head pool;
struct cpts_event pool_data[CPTS_MAX_EVENTS];
-#endif
};
-#if IS_ENABLED(CONFIG_TI_CPTS)
void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb);
-int cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift);
+int cpts_register(struct cpts *cpts);
void cpts_unregister(struct cpts *cpts);
+struct cpts *cpts_create(struct device *dev, void __iomem *regs,
+ u32 mult, u32 shift);
+void cpts_release(struct cpts *cpts);
static inline void cpts_rx_enable(struct cpts *cpts, int enable)
{
@@ -154,6 +157,8 @@ static inline bool cpts_is_tx_enabled(struct cpts *cpts)
}
#else
+struct cpts;
+
static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
{
}
@@ -161,8 +166,19 @@ static inline void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
{
}
+static inline
+struct cpts *cpts_create(struct device *dev, void __iomem *regs,
+ u32 mult, u32 shift)
+{
+ return NULL;
+}
+
+static inline void cpts_release(struct cpts *cpts)
+{
+}
+
static inline int
-cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift)
+cpts_register(struct cpts *cpts)
{
return 0;
}
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-29 11:10 +0100 |
| Subject | Re: [PATCH v2 07/13] net: ethernet: ti: cpts: rework initialization/deinitialization |
| Message-ID | <sINwl-75C-1@gated-at.bofh.it> |
| In reply to | #1531779 |
On Mon, Nov 28, 2016 at 05:03:31PM -0600, Grygorii Strashko wrote:
> +int cpts_register(struct cpts *cpts)
> {
> int err, i;
>
> - cpts->info = cpts_info;
> - spin_lock_init(&cpts->lock);
> -
> - cpts->cc.read = cpts_systim_read;
> - cpts->cc.mask = CLOCKSOURCE_MASK(32);
> - cpts->cc_mult = mult;
> - cpts->cc.mult = mult;
> - cpts->cc.shift = shift;
> -
> INIT_LIST_HEAD(&cpts->events);
> INIT_LIST_HEAD(&cpts->pool);
> for (i = 0; i < CPTS_MAX_EVENTS; i++)
> list_add(&cpts->pool_data[i].list, &cpts->pool);
>
> - cpts_clk_init(dev, cpts);
> + clk_enable(cpts->refclk);
> +
> cpts_write32(cpts, CPTS_EN, control);
> cpts_write32(cpts, TS_PEND_EN, int_enable);
>
> + cpts->cc.mult = cpts->cc_mult;
It is not clear why you set cc.mult in a different place than
cc.shift. That isn't logical, but maybe later patches make it
clear...
> timecounter_init(&cpts->tc, &cpts->cc, ktime_to_ns(ktime_get_real()));
>
> - INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check);
> -
> - cpts->clock = ptp_clock_register(&cpts->info, dev);
> + cpts->clock = ptp_clock_register(&cpts->info, cpts->dev);
> if (IS_ERR(cpts->clock)) {
> err = PTR_ERR(cpts->clock);
> cpts->clock = NULL;
> @@ -392,26 +364,74 @@ int cpts_register(struct device *dev, struct cpts *cpts,
> return 0;
>
> err_ptp:
> - if (cpts->refclk)
> - cpts_clk_release(cpts);
> + clk_disable(cpts->refclk);
> return err;
> }
> EXPORT_SYMBOL_GPL(cpts_register);
>
> void cpts_unregister(struct cpts *cpts)
> {
> - if (cpts->clock) {
> - ptp_clock_unregister(cpts->clock);
> - cancel_delayed_work_sync(&cpts->overflow_work);
> - }
> + if (WARN_ON(!cpts->clock))
> + return;
> +
> + cancel_delayed_work_sync(&cpts->overflow_work);
> +
> + ptp_clock_unregister(cpts->clock);
> + cpts->clock = NULL;
>
> cpts_write32(cpts, 0, int_enable);
> cpts_write32(cpts, 0, control);
>
> - if (cpts->refclk)
> - cpts_clk_release(cpts);
> + clk_disable(cpts->refclk);
> }
> EXPORT_SYMBOL_GPL(cpts_unregister);
>
> +struct cpts *cpts_create(struct device *dev, void __iomem *regs,
> + u32 mult, u32 shift)
> +{
> + struct cpts *cpts;
> +
> + if (!regs || !dev)
> + return ERR_PTR(-EINVAL);
There is no need for this test, as the caller will always pass valid
pointers. (This isn't a user space library!)
Thanks,
Richard
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 17:00 +0100 |
| Subject | Re: [PATCH v2 07/13] net: ethernet: ti: cpts: rework initialization/deinitialization |
| Message-ID | <sISZ4-1UF-25@gated-at.bofh.it> |
| In reply to | #1532074 |
Hi Richard,
On 11/29/2016 04:07 AM, Richard Cochran wrote:
> On Mon, Nov 28, 2016 at 05:03:31PM -0600, Grygorii Strashko wrote:
>> +int cpts_register(struct cpts *cpts)
>> {
>> int err, i;
>>
>> - cpts->info = cpts_info;
>> - spin_lock_init(&cpts->lock);
>> -
>> - cpts->cc.read = cpts_systim_read;
>> - cpts->cc.mask = CLOCKSOURCE_MASK(32);
>> - cpts->cc_mult = mult;
>> - cpts->cc.mult = mult;
>> - cpts->cc.shift = shift;
>> -
>> INIT_LIST_HEAD(&cpts->events);
>> INIT_LIST_HEAD(&cpts->pool);
>> for (i = 0; i < CPTS_MAX_EVENTS; i++)
>> list_add(&cpts->pool_data[i].list, &cpts->pool);
>>
>> - cpts_clk_init(dev, cpts);
>> + clk_enable(cpts->refclk);
>> +
>> cpts_write32(cpts, CPTS_EN, control);
>> cpts_write32(cpts, TS_PEND_EN, int_enable);
>>
>> + cpts->cc.mult = cpts->cc_mult;
>
> It is not clear why you set cc.mult in a different place than
> cc.shift. That isn't logical, but maybe later patches make it
> clear...
cc.mult has to be reloaded to original value each time CPTS is registered(restarted)
as it can be modified by cpts_ptp_adjfreq().
While cc.shift is static.
>
>> timecounter_init(&cpts->tc, &cpts->cc, ktime_to_ns(ktime_get_real()));
>>
[...]
>> }
>> EXPORT_SYMBOL_GPL(cpts_unregister);
>>
>> +struct cpts *cpts_create(struct device *dev, void __iomem *regs,
>> + u32 mult, u32 shift)
>> +{
>> + struct cpts *cpts;
>> +
>> + if (!regs || !dev)
>> + return ERR_PTR(-EINVAL);
>
> There is no need for this test, as the caller will always pass valid
> pointers. (This isn't a user space library!)
>
ok
--
regards,
-grygorii
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-30 19:40 +0100 |
| Subject | Re: [PATCH v2 07/13] net: ethernet: ti: cpts: rework initialization/deinitialization |
| Message-ID | <sJhXs-1dw-17@gated-at.bofh.it> |
| In reply to | #1532451 |
Hi Richard,
On 11/29/2016 09:50 AM, Grygorii Strashko wrote:
> On 11/29/2016 04:07 AM, Richard Cochran wrote:
>> On Mon, Nov 28, 2016 at 05:03:31PM -0600, Grygorii Strashko wrote:
>>> +int cpts_register(struct cpts *cpts)
>>> {
>>> int err, i;
>>>
>>> - cpts->info = cpts_info;
>>> - spin_lock_init(&cpts->lock);
>>> -
>>> - cpts->cc.read = cpts_systim_read;
>>> - cpts->cc.mask = CLOCKSOURCE_MASK(32);
>>> - cpts->cc_mult = mult;
>>> - cpts->cc.mult = mult;
>>> - cpts->cc.shift = shift;
>>> -
>>> INIT_LIST_HEAD(&cpts->events);
>>> INIT_LIST_HEAD(&cpts->pool);
>>> for (i = 0; i < CPTS_MAX_EVENTS; i++)
>>> list_add(&cpts->pool_data[i].list, &cpts->pool);
>>>
>>> - cpts_clk_init(dev, cpts);
>>> + clk_enable(cpts->refclk);
>>> +
>>> cpts_write32(cpts, CPTS_EN, control);
>>> cpts_write32(cpts, TS_PEND_EN, int_enable);
>>>
>>> + cpts->cc.mult = cpts->cc_mult;
>>
>> It is not clear why you set cc.mult in a different place than
>> cc.shift. That isn't logical, but maybe later patches make it
>> clear...
>
> cc.mult has to be reloaded to original value each time CPTS is registered(restarted)
> as it can be modified by cpts_ptp_adjfreq().
>
> While cc.shift is static.
>
>
Will it ok if i will add comment here and re-send series?
--
regards,
-grygorii
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 02/13] net: ethernet: ti: allow cpts to be built separately |
| Message-ID | <sIDdE-75-41@gated-at.bofh.it> |
| In reply to | #1531769 |
TI CPTS IP is used as part of TI OMAP CPSW driver, but it's also
present as part of NETCP on TI Keystone 2 SoCs. So, It's required
to enable build of CPTS for both this drivers and this can be
achieved by allowing CPTS to be built separately.
Hence, allow cpts to be built separately and convert it to be
a module as both CPSW and NETCP drives can be built as modules.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/Kconfig | 2 +-
drivers/net/ethernet/ti/Makefile | 3 ++-
drivers/net/ethernet/ti/cpsw.c | 22 +++++++++++++++++-----
drivers/net/ethernet/ti/cpts.c | 15 +++++++--------
drivers/net/ethernet/ti/cpts.h | 18 ++++++++++++++----
5 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index 9904d74..ff7f518 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -74,7 +74,7 @@ config TI_CPSW
will be called cpsw.
config TI_CPTS
- bool "TI Common Platform Time Sync (CPTS) Support"
+ tristate "TI Common Platform Time Sync (CPTS) Support"
depends on TI_CPSW
select PTP_1588_CLOCK
---help---
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
index d420d94..1e7c10b 100644
--- a/drivers/net/ethernet/ti/Makefile
+++ b/drivers/net/ethernet/ti/Makefile
@@ -12,8 +12,9 @@ obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o
obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
obj-$(CONFIG_TI_CPSW_PHY_SEL) += cpsw-phy-sel.o
obj-$(CONFIG_TI_CPSW_ALE) += cpsw_ale.o
+obj-$(CONFIG_TI_CPTS) += cpts.o
obj-$(CONFIG_TI_CPSW) += ti_cpsw.o
-ti_cpsw-y := cpsw.o cpts.o
+ti_cpsw-y := cpsw.o
obj-$(CONFIG_TI_KEYSTONE_NETCP) += keystone_netcp.o
keystone_netcp-y := netcp_core.o
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 58947aa..f65a4e8 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1513,7 +1513,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
-#ifdef CONFIG_TI_CPTS
+#if IS_ENABLED(CONFIG_TI_CPTS)
static void cpsw_hwtstamp_v1(struct cpsw_common *cpsw)
{
@@ -1661,7 +1661,16 @@ static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
}
+#else
+static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
+{
+ return -EOPNOTSUPP;
+}
+static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
+{
+ return -EOPNOTSUPP;
+}
#endif /*CONFIG_TI_CPTS*/
static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
@@ -1674,12 +1683,10 @@ static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
return -EINVAL;
switch (cmd) {
-#ifdef CONFIG_TI_CPTS
case SIOCSHWTSTAMP:
return cpsw_hwtstamp_set(dev, req);
case SIOCGHWTSTAMP:
return cpsw_hwtstamp_get(dev, req);
-#endif
}
if (!cpsw->slaves[slave_no].phy)
@@ -1935,10 +1942,10 @@ static void cpsw_set_msglevel(struct net_device *ndev, u32 value)
priv->msg_enable = value;
}
+#if IS_ENABLED(CONFIG_TI_CPTS)
static int cpsw_get_ts_info(struct net_device *ndev,
struct ethtool_ts_info *info)
{
-#ifdef CONFIG_TI_CPTS
struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
info->so_timestamping =
@@ -1955,7 +1962,12 @@ static int cpsw_get_ts_info(struct net_device *ndev,
info->rx_filters =
(1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
+ return 0;
+}
#else
+static int cpsw_get_ts_info(struct net_device *ndev,
+ struct ethtool_ts_info *info)
+{
info->so_timestamping =
SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_RX_SOFTWARE |
@@ -1963,9 +1975,9 @@ static int cpsw_get_ts_info(struct net_device *ndev,
info->phc_index = -1;
info->tx_types = 0;
info->rx_filters = 0;
-#endif
return 0;
}
+#endif
static int cpsw_get_settings(struct net_device *ndev,
struct ethtool_cmd *ecmd)
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index a42c449..b26d6fe 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -31,8 +31,6 @@
#include "cpts.h"
-#ifdef CONFIG_TI_CPTS
-
#define cpts_read32(c, r) readl_relaxed(&c->reg->r)
#define cpts_write32(c, v, r) writel_relaxed(v, &c->reg->r)
@@ -334,6 +332,7 @@ void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
memset(ssh, 0, sizeof(*ssh));
ssh->hwtstamp = ns_to_ktime(ns);
}
+EXPORT_SYMBOL_GPL(cpts_rx_timestamp);
void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
{
@@ -349,13 +348,11 @@ void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
ssh.hwtstamp = ns_to_ktime(ns);
skb_tstamp_tx(skb, &ssh);
}
-
-#endif /*CONFIG_TI_CPTS*/
+EXPORT_SYMBOL_GPL(cpts_tx_timestamp);
int cpts_register(struct device *dev, struct cpts *cpts,
u32 mult, u32 shift)
{
-#ifdef CONFIG_TI_CPTS
int err, i;
unsigned long flags;
@@ -391,18 +388,20 @@ int cpts_register(struct device *dev, struct cpts *cpts,
schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD);
cpts->phc_index = ptp_clock_index(cpts->clock);
-#endif
return 0;
}
+EXPORT_SYMBOL_GPL(cpts_register);
void cpts_unregister(struct cpts *cpts)
{
-#ifdef CONFIG_TI_CPTS
if (cpts->clock) {
ptp_clock_unregister(cpts->clock);
cancel_delayed_work_sync(&cpts->overflow_work);
}
if (cpts->refclk)
cpts_clk_release(cpts);
-#endif
}
+EXPORT_SYMBOL_GPL(cpts_unregister);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI CPTS ALE driver");
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index 69a46b9..416ba2c 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -111,7 +111,7 @@ struct cpts {
struct cpsw_cpts __iomem *reg;
int tx_enable;
int rx_enable;
-#ifdef CONFIG_TI_CPTS
+#if IS_ENABLED(CONFIG_TI_CPTS)
struct ptp_clock_info info;
struct ptp_clock *clock;
spinlock_t lock; /* protects time registers */
@@ -127,9 +127,11 @@ struct cpts {
#endif
};
-#ifdef CONFIG_TI_CPTS
+#if IS_ENABLED(CONFIG_TI_CPTS)
void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb);
+int cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift);
+void cpts_unregister(struct cpts *cpts);
#else
static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
{
@@ -137,9 +139,17 @@ static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
static inline void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
{
}
+
+static inline int
+cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift)
+{
+ return 0;
+}
+
+static inline void cpts_unregister(struct cpts *cpts)
+{
+}
#endif
-int cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift);
-void cpts_unregister(struct cpts *cpts);
#endif
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-29 10:40 +0100 |
| Subject | Re: [PATCH v2 02/13] net: ethernet: ti: allow cpts to be built separately |
| Message-ID | <sIN3k-6FC-33@gated-at.bofh.it> |
| In reply to | #1531780 |
On Mon, Nov 28, 2016 at 05:03:26PM -0600, Grygorii Strashko wrote:
> diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
> +EXPORT_SYMBOL_GPL(cpts_unregister);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("TI CPTS ALE driver");
ALE?
Also, MODULE_AUTHOR (that's me) is missing.
Thanks,
Richard
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 01/13] net: ethernet: ti: cpts: switch to readl/writel_relaxed() |
| Message-ID | <sIDdD-75-17@gated-at.bofh.it> |
| In reply to | #1531769 |
Switch to readl/writel_relaxed() APIs, because this is recommended
API and the CPTS IP is reused on Keystone 2 SoCs
where LE/BE modes are supported.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpts.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 85a55b4..a42c449 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -33,8 +33,8 @@
#ifdef CONFIG_TI_CPTS
-#define cpts_read32(c, r) __raw_readl(&c->reg->r)
-#define cpts_write32(c, v, r) __raw_writel(v, &c->reg->r)
+#define cpts_read32(c, r) readl_relaxed(&c->reg->r)
+#define cpts_write32(c, v, r) writel_relaxed(v, &c->reg->r)
static int event_expired(struct cpts_event *event)
{
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Richard Cochran <richardcochran@gmail.com> |
|---|---|
| Date | 2016-11-29 10:40 +0100 |
| Subject | Re: [PATCH v2 01/13] net: ethernet: ti: cpts: switch to readl/writel_relaxed() |
| Message-ID | <sIN3l-6FC-61@gated-at.bofh.it> |
| In reply to | #1531782 |
On Mon, Nov 28, 2016 at 05:03:25PM -0600, Grygorii Strashko wrote: > Switch to readl/writel_relaxed() APIs, because this is recommended > API and the CPTS IP is reused on Keystone 2 SoCs > where LE/BE modes are supported. > > Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Acked-by: Richard Cochran <richardcochran@gmail.com>
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 13/13] net: ethernet: ti: cpts: fix overflow check period |
| Message-ID | <sIDdE-75-39@gated-at.bofh.it> |
| In reply to | #1531769 |
The CPTS drivers uses 8sec period for overflow checking with
assumption that CPTS retclk will not exceed 500MHz. But that's not
true on some TI platforms (Kesytone 2). As result, it is possible that
CPTS counter will overflow more than once between two readings.
Hence, fix it by selecting overflow check period dynamically as
max_sec_before_overflow/2, where
max_sec_before_overflow = max_counter_val / rftclk_freq.
Cc: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpts.c | 10 +++++++---
drivers/net/ethernet/ti/cpts.h | 4 +---
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 4761d8c..c96a94a 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -245,7 +245,7 @@ static void cpts_overflow_check(struct work_struct *work)
cpts_ptp_gettime(&cpts->info, &ts);
pr_debug("cpts overflow check at %lld.%09lu\n", ts.tv_sec, ts.tv_nsec);
- schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD);
+ schedule_delayed_work(&cpts->overflow_work, cpts->ov_check_period);
}
static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
@@ -379,8 +379,7 @@ int cpts_register(struct cpts *cpts)
}
cpts->phc_index = ptp_clock_index(cpts->clock);
- schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD);
-
+ schedule_delayed_work(&cpts->overflow_work, cpts->ov_check_period);
return 0;
err_ptp:
@@ -421,6 +420,11 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
if (maxsec > 600 && cpts->cc.mask > UINT_MAX)
maxsec = 600;
+ /* Calc overflow check period (maxsec / 2) */
+ cpts->ov_check_period = (HZ * maxsec) / 2;
+ dev_info(cpts->dev, "cpts: overflow check period %lu (jiffies)\n",
+ cpts->ov_check_period);
+
if (cpts->cc_mult || cpts->cc.shift)
return;
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index 5da23af..c96eca2 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -97,9 +97,6 @@ enum {
CPTS_EV_TX, /* Ethernet Transmit Event */
};
-/* This covers any input clock up to about 500 MHz. */
-#define CPTS_OVERFLOW_PERIOD (HZ * 8)
-
#define CPTS_FIFO_DEPTH 16
#define CPTS_MAX_EVENTS 32
@@ -127,6 +124,7 @@ struct cpts {
struct list_head events;
struct list_head pool;
struct cpts_event pool_data[CPTS_MAX_EVENTS];
+ unsigned long ov_check_period;
};
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 10:20 +0100 |
| Subject | Re: [PATCH v2 13/13] net: ethernet: ti: cpts: fix overflow check period |
| Message-ID | <sJ9dv-4cm-15@gated-at.bofh.it> |
| In reply to | #1531784 |
On Mon, Nov 28, 2016 at 05:03:37PM -0600, Grygorii Strashko wrote: > The CPTS drivers uses 8sec period for overflow checking with > assumption that CPTS retclk will not exceed 500MHz. But that's not > true on some TI platforms (Kesytone 2). As result, it is possible that > CPTS counter will overflow more than once between two readings. > > Hence, fix it by selecting overflow check period dynamically as > max_sec_before_overflow/2, where > max_sec_before_overflow = max_counter_val / rftclk_freq. > > Cc: John Stultz <john.stultz@linaro.org> > Cc: Thomas Gleixner <tglx@linutronix.de> > Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Acked-by: Richard Cochran <richardcochran@gmail.com>
[toc] | [prev] | [next] | [standalone]
| From | Grygorii Strashko <grygorii.strashko@ti.com> |
|---|---|
| Date | 2016-11-29 00:10 +0100 |
| Subject | [PATCH v2 11/13] clocksource: export the clocks_calc_mult_shift to use by timestamp code |
| Message-ID | <sIDdE-75-43@gated-at.bofh.it> |
| In reply to | #1531769 |
From: Murali Karicheri <m-karicheri2@ti.com> The CPSW CPTS driver is capable of doing timestamping on tx/rx packets and requires to know mult and shift factors for timestamp conversion from raw value to nanoseconds (ptp clock). Now these mult and shift factors are calculated manually and provided through DT, which makes very hard to support of a lot number of platforms, especially if CPTS refclk is not the same for some kind of boards and depends on efuse settings (Keystone 2 platforms). Hence, export clocks_calc_mult_shift() to allow drivers like CPSW CPTS (and other ptp drivesr) to benefit from automaitc calculation of mult and shift factors. Cc: John Stultz <john.stultz@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> --- kernel/time/clocksource.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 7e4fad7..150242c 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -89,6 +89,7 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 maxsec) *mult = tmp; *shift = sft; } +EXPORT_SYMBOL_GPL(clocks_calc_mult_shift); /*[Clocksource internal variables]--------- * curr_clocksource: -- 2.10.1
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web