aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2014-08-27 04:37:49 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-29 22:54:36 -0400
commit5566401f2f10556776fd199c11d6a02a5e0b7b95 (patch)
treeb9127a13d0c5df4939c72be2fc618e38e9afaf5c
parent2b78d348f1bc3396ca1662c6a6177a7fb1ca62ff (diff)
stmmac: ptp: fix the reference clock
The PTP reference clock, used for setting the addend in the Timestamp Addend Register, was erroneously hard-coded (as reported in the databook just as example). The patch removes the macro named: STMMAC_SYSCLOCK and allows to use a reference clock (clk_ptp_ref_i) that can be passed from the platform. If not passed, the main driver clock will be used as default; note that this can be fine on some platforms. Note that, prior this patch, using the old STMMAC_SYSCLOCK on some platforms, as side effect, the ptp clock can move faster/slower than the system clock. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/stmmac.txt4
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c20
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h2
4 files changed, 22 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt
index 9b03c57563a4..e45ac3f926b1 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -39,6 +39,10 @@ Optional properties:
39 further clocks may be specified in derived bindings. 39 further clocks may be specified in derived bindings.
40- clock-names: One name for each entry in the clocks property, the 40- clock-names: One name for each entry in the clocks property, the
41 first one should be "stmmaceth". 41 first one should be "stmmaceth".
42- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is
43 available this clock is used for programming the Timestamp Addend Register.
44 If not passed then the system clock will be used and this is fine on some
45 platforms.
42 46
43Examples: 47Examples:
44 48
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index ca01035634a7..128a0b723a00 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -105,6 +105,8 @@ struct stmmac_priv {
105 struct ptp_clock *ptp_clock; 105 struct ptp_clock *ptp_clock;
106 struct ptp_clock_info ptp_clock_ops; 106 struct ptp_clock_info ptp_clock_ops;
107 unsigned int default_addend; 107 unsigned int default_addend;
108 struct clk *clk_ptp_ref;
109 unsigned int clk_ptp_rate;
108 u32 adv_ts; 110 u32 adv_ts;
109 int use_riwt; 111 int use_riwt;
110 int irq_wake; 112 int irq_wake;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 51a89d4bb125..03652891fcbf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -603,16 +603,16 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
603 /* calculate default added value: 603 /* calculate default added value:
604 * formula is : 604 * formula is :
605 * addend = (2^32)/freq_div_ratio; 605 * addend = (2^32)/freq_div_ratio;
606 * where, freq_div_ratio = STMMAC_SYSCLOCK/50MHz 606 * where, freq_div_ratio = clk_ptp_ref_i/50MHz
607 * hence, addend = ((2^32) * 50MHz)/STMMAC_SYSCLOCK; 607 * hence, addend = ((2^32) * 50MHz)/clk_ptp_ref_i;
608 * NOTE: STMMAC_SYSCLOCK should be >= 50MHz to 608 * NOTE: clk_ptp_ref_i should be >= 50MHz to
609 * achive 20ns accuracy. 609 * achive 20ns accuracy.
610 * 610 *
611 * 2^x * y == (y << x), hence 611 * 2^x * y == (y << x), hence
612 * 2^32 * 50000000 ==> (50000000 << 32) 612 * 2^32 * 50000000 ==> (50000000 << 32)
613 */ 613 */
614 temp = (u64) (50000000ULL << 32); 614 temp = (u64) (50000000ULL << 32);
615 priv->default_addend = div_u64(temp, STMMAC_SYSCLOCK); 615 priv->default_addend = div_u64(temp, priv->clk_ptp_rate);
616 priv->hw->ptp->config_addend(priv->ioaddr, 616 priv->hw->ptp->config_addend(priv->ioaddr,
617 priv->default_addend); 617 priv->default_addend);
618 618
@@ -638,6 +638,16 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
638 if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) 638 if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
639 return -EOPNOTSUPP; 639 return -EOPNOTSUPP;
640 640
641 /* Fall-back to main clock in case of no PTP ref is passed */
642 priv->clk_ptp_ref = devm_clk_get(priv->device, "clk_ptp_ref");
643 if (IS_ERR(priv->clk_ptp_ref)) {
644 priv->clk_ptp_rate = clk_get_rate(priv->stmmac_clk);
645 priv->clk_ptp_ref = NULL;
646 } else {
647 clk_prepare_enable(priv->clk_ptp_ref);
648 priv->clk_ptp_rate = clk_get_rate(priv->clk_ptp_ref);
649 }
650
641 priv->adv_ts = 0; 651 priv->adv_ts = 0;
642 if (priv->dma_cap.atime_stamp && priv->extend_desc) 652 if (priv->dma_cap.atime_stamp && priv->extend_desc)
643 priv->adv_ts = 1; 653 priv->adv_ts = 1;
@@ -657,6 +667,8 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
657 667
658static void stmmac_release_ptp(struct stmmac_priv *priv) 668static void stmmac_release_ptp(struct stmmac_priv *priv)
659{ 669{
670 if (priv->clk_ptp_ref)
671 clk_disable_unprepare(priv->clk_ptp_ref);
660 stmmac_ptp_unregister(priv); 672 stmmac_ptp_unregister(priv);
661} 673}
662 674
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
index 3dbc047622fa..4535df37c227 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
@@ -25,8 +25,6 @@
25#ifndef __STMMAC_PTP_H__ 25#ifndef __STMMAC_PTP_H__
26#define __STMMAC_PTP_H__ 26#define __STMMAC_PTP_H__
27 27
28#define STMMAC_SYSCLOCK 62500000
29
30/* IEEE 1588 PTP register offsets */ 28/* IEEE 1588 PTP register offsets */
31#define PTP_TCR 0x0700 /* Timestamp Control Reg */ 29#define PTP_TCR 0x0700 /* Timestamp Control Reg */
32#define PTP_SSIR 0x0704 /* Sub-Second Increment Reg */ 30#define PTP_SSIR 0x0704 /* Sub-Second Increment Reg */