From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94275C3A5A7 for ; Mon, 2 Sep 2019 16:26:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 658F921744 for ; Mon, 2 Sep 2019 16:26:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l29m6h9C" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726515AbfIBQ0N (ORCPT ); Mon, 2 Sep 2019 12:26:13 -0400 Received: from mail-wr1-f66.google.com ([209.85.221.66]:34190 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726475AbfIBQ0M (ORCPT ); Mon, 2 Sep 2019 12:26:12 -0400 Received: by mail-wr1-f66.google.com with SMTP id s18so14645232wrn.1 for ; Mon, 02 Sep 2019 09:26:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7dkAt6nuhj8rdhBzSeXxS2KBJwsYrPojk+ZV4XMS+RI=; b=l29m6h9CP2rpwcXaTVUEPHhGJfxpvpdNiTjIdD8VcmK73B8W1TjTf1kCYp3QdWzh15 ust3SzuVidJOdlSatrCj9kH0g6KNICWWVqtkgx8DGbcA/bon6mpLtJZPvn9gZCXcUMMX 0dVKxf+I49qwqbntQKUK8ZUwO2YkE+wmqEshTl/Nbdo4UJgRf8wS5avzMYsbuuPPXzrf Z14cZosa75Z99LDJ6c1c92n7xoxsJO/tTCJCGQkDBoTMDScc9CabqVoJ3MfTqKxLne6N HacU2UuPZ+BDmCsKycgxWfIv8N3VxPPedUejnV5Az/C6U5+h+6CHcjwRmGw8aE5FNHRi ldTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7dkAt6nuhj8rdhBzSeXxS2KBJwsYrPojk+ZV4XMS+RI=; b=PqafrCwp2J8eJtfVUJDtq5D4mAoZLbPXqKO6KUSIfz1XwXjXEaZalVM4BI/XX/eG+0 A60/v23agPbNILRNgcOO5W0RJfdgz8SAM5O4Sg4+983NM/94orW6WAyy0WXUlAhu2M63 oFlPkDCql/08rhgq/9rL5uqNdUvc+gtc+C5jQIvBzaa3X2KJzwEzpQT5KNERHaj2cp9y wC+KSvM7j6WZZjkymChJuoIa7Jf0LdPrfi4LVym1UW9KBUTGtPyWh3uFWwdBk0hBQsN1 dU6e4iNVEzqqgsjy3ZXS8czJLgrUqACsxrSouw12QuOXY4INYHdjYQRX8B11/Ny4cb9S IGuw== X-Gm-Message-State: APjAAAWQ/zjMDkZFR6ArScKOzGYI+vpHBaM48tF0oBvNfTpjk1LYWJaO /O9Vg9fzsx+DcgPjj8qTC+w= X-Google-Smtp-Source: APXvYqwIiiyMGfBiTo5iwx+XPTcDhA83xZGUW3pdXkcm1tD41+1Mp06yvIkxXiTYbq/2r6ByqU5uXA== X-Received: by 2002:a5d:4ac7:: with SMTP id y7mr12540827wrs.271.1567441570532; Mon, 02 Sep 2019 09:26:10 -0700 (PDT) Received: from localhost.localdomain ([86.126.25.232]) by smtp.gmail.com with ESMTPSA id z187sm2879994wmb.0.2019.09.02.09.26.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Sep 2019 09:26:09 -0700 (PDT) From: Vladimir Oltean To: f.fainelli@gmail.com, vivien.didelot@gmail.com, andrew@lunn.ch, davem@davemloft.net, vinicius.gomes@intel.com, vedang.patel@intel.com, richardcochran@gmail.com Cc: weifeng.voon@intel.com, jiri@mellanox.com, m-karicheri2@ti.com, Jose.Abreu@synopsys.com, ilias.apalodimas@linaro.org, jhs@mojatatu.com, xiyou.wangcong@gmail.com, kurt.kanzenbach@linutronix.de, netdev@vger.kernel.org, Vladimir Oltean Subject: [PATCH v1 net-next 05/15] net: dsa: sja1105: Restore PTP time after switch reset Date: Mon, 2 Sep 2019 19:25:34 +0300 Message-Id: <20190902162544.24613-6-olteanv@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190902162544.24613-1-olteanv@gmail.com> References: <20190902162544.24613-1-olteanv@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The PTP time of the switch is not preserved when uploading a new static configuration. Work around this hardware oddity by reading its PTP time before a static config upload, and restoring it afterwards. Static config changes are expected to occur at runtime even in scenarios directly related to PTP, i.e. the Time-Aware Scheduler of the switch is programmed in this way. Signed-off-by: Vladimir Oltean --- Changes since RFC: - None. drivers/net/dsa/sja1105/sja1105_main.c | 32 ++++++++++++- drivers/net/dsa/sja1105/sja1105_ptp.c | 66 ++++++++++++++++++-------- drivers/net/dsa/sja1105/sja1105_ptp.h | 25 ++++++++++ drivers/net/dsa/sja1105/sja1105_spi.c | 4 -- 4 files changed, 101 insertions(+), 26 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index f7f03d486499..abb22f0a9884 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -1382,8 +1382,13 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port, */ static int sja1105_static_config_reload(struct sja1105_private *priv) { + struct ptp_system_timestamp ptp_sts_before; + struct ptp_system_timestamp ptp_sts_after; struct sja1105_mac_config_entry *mac; int speed_mbps[SJA1105_NUM_PORTS]; + s64 t1, t2, t3, t4; + s64 ptpclkval; + s64 t12, t34; int rc, i; mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; @@ -1398,10 +1403,35 @@ static int sja1105_static_config_reload(struct sja1105_private *priv) mac[i].speed = SJA1105_SPEED_AUTO; } + /* No PTP operations can run right now */ + mutex_lock(&priv->ptp_lock); + + ptpclkval = __sja1105_ptp_gettimex(priv, &ptp_sts_before); + /* Reset switch and send updated static configuration */ rc = sja1105_static_config_upload(priv); if (rc < 0) - goto out; + goto out_unlock_ptp; + + rc = __sja1105_ptp_settime(priv, 0, &ptp_sts_after); + if (rc < 0) + goto out_unlock_ptp; + + t1 = timespec64_to_ns(&ptp_sts_before.pre_ts); + t2 = timespec64_to_ns(&ptp_sts_before.post_ts); + t3 = timespec64_to_ns(&ptp_sts_after.pre_ts); + t4 = timespec64_to_ns(&ptp_sts_after.post_ts); + /* Mid point, corresponds to pre-reset PTPCLKVAL */ + t12 = t1 + (t2 - t1) / 2; + /* Mid point, corresponds to post-reset PTPCLKVAL, aka 0 */ + t34 = t3 + (t4 - t3) / 2; + /* Advance PTPCLKVAL by the time it took since its readout */ + ptpclkval += (t34 - t12); + + __sja1105_ptp_adjtime(priv, ptpclkval); + +out_unlock_ptp: + mutex_unlock(&priv->ptp_lock); /* Configure the CGU (PLLs) for MII and RMII PHYs. * For these interfaces there is no dynamic configuration diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c index 04693c702b09..a7722c0944fb 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.c +++ b/drivers/net/dsa/sja1105/sja1105_ptp.c @@ -215,17 +215,26 @@ int sja1105_ptp_reset(struct sja1105_private *priv) return rc; } +/* Caller must hold priv->ptp_lock */ +u64 __sja1105_ptp_gettimex(struct sja1105_private *priv, + struct ptp_system_timestamp *sts) +{ + u64 ticks; + + ticks = sja1105_ptpclkval_read(priv, sts); + + return sja1105_ticks_to_ns(ticks); +} + static int sja1105_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts, struct ptp_system_timestamp *sts) { struct sja1105_private *priv = ptp_to_sja1105(ptp); - u64 ticks; mutex_lock(&priv->ptp_lock); - ticks = sja1105_ptpclkval_read(priv, sts); - *ts = ns_to_timespec64(sja1105_ticks_to_ns(ticks)); + *ts = ns_to_timespec64(__sja1105_ptp_gettimex(priv, sts)); mutex_unlock(&priv->ptp_lock); @@ -245,33 +254,42 @@ static int sja1105_ptp_mode_set(struct sja1105_private *priv, } /* Caller must hold priv->ptp_lock */ -static int sja1105_ptpclkval_write(struct sja1105_private *priv, u64 val) +static int sja1105_ptpclkval_write(struct sja1105_private *priv, u64 val, + struct ptp_system_timestamp *ptp_sts) { const struct sja1105_regs *regs = priv->info->regs; return sja1105_spi_send_int(priv, SPI_WRITE, regs->ptpclk, &val, 8, - NULL); + ptp_sts); } /* Write to PTPCLKVAL while PTPCLKADD is 0 */ -static int sja1105_ptp_settime(struct ptp_clock_info *ptp, - const struct timespec64 *ts) +int __sja1105_ptp_settime(struct sja1105_private *priv, u64 ns, + struct ptp_system_timestamp *ptp_sts) { - u64 ticks = ns_to_sja1105_ticks(timespec64_to_ns(ts)); - struct sja1105_private *priv = ptp_to_sja1105(ptp); + u64 ticks = ns_to_sja1105_ticks(ns); int rc; - mutex_lock(&priv->ptp_lock); - rc = sja1105_ptp_mode_set(priv, PTP_SET_MODE); if (rc < 0) { dev_err(priv->ds->dev, "Failed to put PTPCLK in set mode\n"); - goto out; + return rc; } - rc = sja1105_ptpclkval_write(priv, ticks); + return sja1105_ptpclkval_write(priv, ticks, ptp_sts); +} + +static int sja1105_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + struct sja1105_private *priv = ptp_to_sja1105(ptp); + u64 ns = timespec64_to_ns(ts); + int rc; + + mutex_lock(&priv->ptp_lock); + + rc = __sja1105_ptp_settime(priv, ns, NULL); -out: mutex_unlock(&priv->ptp_lock); return rc; @@ -320,23 +338,29 @@ u64 sja1105_ptpclkval_read(struct sja1105_private *priv, } /* Write to PTPCLKVAL while PTPCLKADD is 1 */ -static int sja1105_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +int __sja1105_ptp_adjtime(struct sja1105_private *priv, s64 delta) { - struct sja1105_private *priv = ptp_to_sja1105(ptp); s64 ticks = ns_to_sja1105_ticks(delta); int rc; - mutex_lock(&priv->ptp_lock); - rc = sja1105_ptp_mode_set(priv, PTP_ADD_MODE); if (rc < 0) { dev_err(priv->ds->dev, "Failed to put PTPCLK in add mode\n"); - goto out; + return rc; } - rc = sja1105_ptpclkval_write(priv, ticks); + return sja1105_ptpclkval_write(priv, ticks, NULL); +} + +static int sja1105_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct sja1105_private *priv = ptp_to_sja1105(ptp); + int rc; + + mutex_lock(&priv->ptp_lock); + + rc = __sja1105_ptp_adjtime(priv, delta); -out: mutex_unlock(&priv->ptp_lock); return rc; diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.h b/drivers/net/dsa/sja1105/sja1105_ptp.h index 80c33e5e4503..c699611e585d 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.h +++ b/drivers/net/dsa/sja1105/sja1105_ptp.h @@ -42,6 +42,14 @@ int sja1105_ptp_reset(struct sja1105_private *priv); u64 sja1105_ptpclkval_read(struct sja1105_private *priv, struct ptp_system_timestamp *sts); +u64 __sja1105_ptp_gettimex(struct sja1105_private *priv, + struct ptp_system_timestamp *sts); + +int __sja1105_ptp_settime(struct sja1105_private *priv, u64 ns, + struct ptp_system_timestamp *ptp_sts); + +int __sja1105_ptp_adjtime(struct sja1105_private *priv, s64 delta); + #else static inline int sja1105_ptp_clock_register(struct sja1105_private *priv) @@ -77,6 +85,23 @@ static inline u64 sja1105_ptpclkval_read(struct sja1105_private *priv, return 0; } +static inline u64 __sja1105_ptp_gettimex(struct sja1105_private *priv, + struct ptp_system_timestamp *sts) +{ + return 0; +} + +static inline int __sja1105_ptp_settime(struct sja1105_private *priv, u64 ns, + struct ptp_system_timestamp *ptp_sts) +{ + return 0; +} + +static inline int __sja1105_ptp_adjtime(struct sja1105_private *priv, s64 delta) +{ + return 0; +} + #define sja1105et_ptp_cmd NULL #define sja1105pqrs_ptp_cmd NULL diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 26985f1209ad..eae9c9baa189 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -496,10 +496,6 @@ int sja1105_static_config_upload(struct sja1105_private *priv) dev_info(dev, "Succeeded after %d tried\n", RETRIES - retries); } - rc = sja1105_ptp_reset(priv); - if (rc < 0) - dev_err(dev, "Failed to reset PTP clock: %d\n", rc); - dev_info(dev, "Reset switch and programmed static config\n"); out: -- 2.17.1