diff options
-rw-r--r-- | arch/arm/boot/dts/am33xx.dtsi | 2 | ||||
-rw-r--r-- | arch/arm/boot/dts/am4372.dtsi | 2 | ||||
-rw-r--r-- | drivers/clk/ti/clk-43xx.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.c | 56 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpts.c | 11 |
5 files changed, 66 insertions, 21 deletions
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 9770e35f253..d1e2b363f92 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -665,6 +665,8 @@ mac: ethernet@4a100000 { compatible = "ti,cpsw"; ti,hwmods = "cpgmac0"; + clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>; + clock-names = "fck", "cpts"; cpdma_channels = <8>; ale_entries = <1024>; bd_ram_size = <0x2000>; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 36d523a2683..c2779f65302 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -489,6 +489,8 @@ #address-cells = <1>; #size-cells = <1>; ti,hwmods = "cpgmac0"; + clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>; + clock-names = "fck", "cpts"; status = "disabled"; cpdma_channels = <8>; ale_entries = <1024>; diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c index 67c8de572c5..b4877e0ee91 100644 --- a/drivers/clk/ti/clk-43xx.c +++ b/drivers/clk/ti/clk-43xx.c @@ -110,9 +110,25 @@ static struct ti_dt_clk am43xx_clks[] = { int __init am43xx_dt_clk_init(void) { + struct clk *clk1, *clk2; + ti_dt_clocks_register(am43xx_clks); omap2_clk_disable_autoidle_all(); + /* + * cpsw_cpts_rft_clk has got the choice of 3 clocksources + * dpll_core_m4_ck, dpll_core_m5_ck and dpll_disp_m2_ck. + * By default dpll_core_m4_ck is selected, witn this as clock + * source the CPTS doesnot work properly. It gives clockcheck errors + * while running PTP. + * clockcheck: clock jumped backward or running slower than expected! + * By selecting dpll_core_m5_ck as the clocksource fixes this issue. + * In AM335x dpll_core_m5_ck is the default clocksource. + */ + clk1 = clk_get_sys(NULL, "cpsw_cpts_rft_clk"); + clk2 = clk_get_sys(NULL, "dpll_core_m5_ck"); + clk_set_parent(clk1, clk2); + return 0; } diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 36aa109416c..d14c8da5316 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -248,20 +248,31 @@ struct cpsw_ss_regs { #define TS_131 (1<<11) /* Time Sync Dest IP Addr 131 enable */ #define TS_130 (1<<10) /* Time Sync Dest IP Addr 130 enable */ #define TS_129 (1<<9) /* Time Sync Dest IP Addr 129 enable */ -#define TS_BIT8 (1<<8) /* ts_ttl_nonzero? */ +#define TS_TTL_NONZERO (1<<8) /* Time Sync Time To Live Non-zero enable */ +#define TS_ANNEX_F_EN (1<<6) /* Time Sync Annex F enable */ #define TS_ANNEX_D_EN (1<<4) /* Time Sync Annex D enable */ #define TS_LTYPE2_EN (1<<3) /* Time Sync LTYPE 2 enable */ #define TS_LTYPE1_EN (1<<2) /* Time Sync LTYPE 1 enable */ #define TS_TX_EN (1<<1) /* Time Sync Transmit Enable */ #define TS_RX_EN (1<<0) /* Time Sync Receive Enable */ -#define CTRL_TS_BITS \ - (TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 | TS_BIT8 | \ - TS_ANNEX_D_EN | TS_LTYPE1_EN) +#define CTRL_V2_TS_BITS \ + (TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\ + TS_TTL_NONZERO | TS_ANNEX_D_EN | TS_LTYPE1_EN) -#define CTRL_ALL_TS_MASK (CTRL_TS_BITS | TS_TX_EN | TS_RX_EN) -#define CTRL_TX_TS_BITS (CTRL_TS_BITS | TS_TX_EN) -#define CTRL_RX_TS_BITS (CTRL_TS_BITS | TS_RX_EN) +#define CTRL_V2_ALL_TS_MASK (CTRL_V2_TS_BITS | TS_TX_EN | TS_RX_EN) +#define CTRL_V2_TX_TS_BITS (CTRL_V2_TS_BITS | TS_TX_EN) +#define CTRL_V2_RX_TS_BITS (CTRL_V2_TS_BITS | TS_RX_EN) + + +#define CTRL_V3_TS_BITS \ + (TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\ + TS_TTL_NONZERO | TS_ANNEX_F_EN | TS_ANNEX_D_EN |\ + TS_LTYPE1_EN) + +#define CTRL_V3_ALL_TS_MASK (CTRL_V3_TS_BITS | TS_TX_EN | TS_RX_EN) +#define CTRL_V3_TX_TS_BITS (CTRL_V3_TS_BITS | TS_TX_EN) +#define CTRL_V3_RX_TS_BITS (CTRL_V3_TS_BITS | TS_RX_EN) /* Bit definitions for the CPSW2_TS_SEQ_MTYPE register */ #define TS_SEQ_ID_OFFSET_SHIFT (16) /* Time Sync Sequence ID Offset */ @@ -1376,13 +1387,27 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) slave = &priv->slaves[priv->data.active_slave]; ctrl = slave_read(slave, CPSW2_CONTROL); - ctrl &= ~CTRL_ALL_TS_MASK; + switch (priv->version) { + case CPSW_VERSION_2: + ctrl &= ~CTRL_V2_ALL_TS_MASK; - if (priv->cpts->tx_enable) - ctrl |= CTRL_TX_TS_BITS; + if (priv->cpts->tx_enable) + ctrl |= CTRL_V2_TX_TS_BITS; - if (priv->cpts->rx_enable) - ctrl |= CTRL_RX_TS_BITS; + if (priv->cpts->rx_enable) + ctrl |= CTRL_V2_RX_TS_BITS; + break; + case CPSW_VERSION_3: + default: + ctrl &= ~CTRL_V3_ALL_TS_MASK; + + if (priv->cpts->tx_enable) + ctrl |= CTRL_V3_TX_TS_BITS; + + if (priv->cpts->rx_enable) + ctrl |= CTRL_V3_RX_TS_BITS; + break; + } mtype = (30 << TS_SEQ_ID_OFFSET_SHIFT) | EVENT_MSG_BITS; @@ -1398,7 +1423,8 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) struct hwtstamp_config cfg; if (priv->version != CPSW_VERSION_1 && - priv->version != CPSW_VERSION_2) + priv->version != CPSW_VERSION_2 && + priv->version != CPSW_VERSION_3) return -EOPNOTSUPP; if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) @@ -1443,6 +1469,7 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) cpsw_hwtstamp_v1(priv); break; case CPSW_VERSION_2: + case CPSW_VERSION_3: cpsw_hwtstamp_v2(priv); break; default: @@ -1459,7 +1486,8 @@ static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) struct hwtstamp_config cfg; if (priv->version != CPSW_VERSION_1 && - priv->version != CPSW_VERSION_2) + priv->version != CPSW_VERSION_2 && + priv->version != CPSW_VERSION_3) return -EOPNOTSUPP; cfg.flags = 0; diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index 243513980b5..6b56f85951e 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c @@ -236,13 +236,11 @@ static void cpts_overflow_check(struct work_struct *work) schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD); } -#define CPTS_REF_CLOCK_NAME "cpsw_cpts_rft_clk" - -static void cpts_clk_init(struct cpts *cpts) +static void cpts_clk_init(struct device *dev, struct cpts *cpts) { - cpts->refclk = clk_get(NULL, CPTS_REF_CLOCK_NAME); + cpts->refclk = devm_clk_get(dev, "cpts"); if (IS_ERR(cpts->refclk)) { - pr_err("Failed to clk_get %s\n", CPTS_REF_CLOCK_NAME); + dev_err(dev, "Failed to get cpts refclk\n"); cpts->refclk = NULL; return; } @@ -252,7 +250,6 @@ static void cpts_clk_init(struct cpts *cpts) static void cpts_clk_release(struct cpts *cpts) { clk_disable(cpts->refclk); - clk_put(cpts->refclk); } static int cpts_match(struct sk_buff *skb, unsigned int ptp_class, @@ -390,7 +387,7 @@ int cpts_register(struct device *dev, struct cpts *cpts, for (i = 0; i < CPTS_MAX_EVENTS; i++) list_add(&cpts->pool_data[i].list, &cpts->pool); - cpts_clk_init(cpts); + cpts_clk_init(dev, cpts); cpts_write32(cpts, CPTS_EN, control); cpts_write32(cpts, TS_PEND_EN, int_enable); |