All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Cochran <richardcochran@gmail.com>
To: Kurt Kanzenbach <kurt@linutronix.de>
Cc: Andrew Lunn <andrew@lunn.ch>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	netdev@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
	devicetree@vger.kernel.org,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Kamil Alkhouri <kamil.alkhouri@hs-offenburg.de>,
	ilias.apalodimas@linaro.org
Subject: Re: [RFC PATCH 3/9] net: dsa: hellcreek: Add PTP clock support
Date: Wed, 24 Jun 2020 06:03:18 -0700	[thread overview]
Message-ID: <20200624130318.GD7247@localhost> (raw)
In-Reply-To: <20200618064029.32168-4-kurt@linutronix.de>

On Thu, Jun 18, 2020 at 08:40:23AM +0200, Kurt Kanzenbach wrote:

> diff --git a/drivers/net/dsa/hirschmann/hellcreek.h b/drivers/net/dsa/hirschmann/hellcreek.h
> index a08a10cb5ab7..2d4422fd2567 100644
> --- a/drivers/net/dsa/hirschmann/hellcreek.h
> +++ b/drivers/net/dsa/hirschmann/hellcreek.h
> @@ -234,10 +234,17 @@ struct hellcreek_fdb_entry {
>  struct hellcreek {
>  	struct device *dev;
>  	struct dsa_switch *ds;
> +	struct ptp_clock *ptp_clock;
> +	struct ptp_clock_info ptp_clock_info;
>  	struct hellcreek_port ports[4];
> +	struct delayed_work overflow_work;
>  	spinlock_t reg_lock;	/* Switch IP register lock */
> +	spinlock_t ptp_lock;	/* PTP IP register lock */

Why use a spin lock and not a mutex?

>  	void __iomem *base;
> +	void __iomem *ptp_base;
>  	u8 *vidmbrcfg;		/* vidmbrcfg shadow */
> +	u64 seconds;		/* PTP seconds */
> +	u64 last_ts;		/* Used for overflow detection */
>  	size_t fdb_entries;
>  };

> +static int hellcreek_ptp_gettime(struct ptp_clock_info *ptp,
> +				 struct timespec64 *ts)
> +{
> +	struct hellcreek *hellcreek = ptp_to_hellcreek(ptp);
> +	u64 ns;
> +
> +	spin_lock(&hellcreek->ptp_lock);

Won't a mutex do here instead?

> +	ns = __hellcreek_ptp_gettime(hellcreek);
> +	spin_unlock(&hellcreek->ptp_lock);
> +
> +	*ts = ns_to_timespec64(ns);
> +
> +	return 0;
> +}

> +static int hellcreek_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
> +{
> +	struct hellcreek *hellcreek = ptp_to_hellcreek(ptp);
> +	u16 negative = 0, counth, countl;
> +	u32 count_val;
> +
> +	/* If the offset is larger than IP-Core slow offset resources. Don't
> +	 * concider slow adjustment. Rather, add the offset directly to the

consider

> +	 * current time
> +	 */
> +	if (abs(delta) > MAX_SLOW_OFFSET_ADJ) {
> +		struct timespec64 now, then = ns_to_timespec64(delta);
> +
> +		hellcreek_ptp_gettime(ptp, &now);
> +		now = timespec64_add(now, then);
> +		hellcreek_ptp_settime(ptp, &now);
> +
> +		return 0;
> +	}
> +
> +	if (delta < 0) {
> +		negative = 1;
> +		delta = -delta;
> +	}
> +
> +	/* 'count_val' does not exceed the maximum register size (2^30) */
> +	count_val = div_s64(delta, MAX_NS_PER_STEP);
> +
> +	counth = (count_val & 0xffff0000) >> 16;
> +	countl = count_val & 0xffff;
> +
> +	negative = (negative << 15) & 0x8000;
> +
> +	spin_lock(&hellcreek->ptp_lock);
> +
> +	/* Set offset write register */
> +	hellcreek_ptp_write(hellcreek, negative, PR_CLOCK_OFFSET_C);
> +	hellcreek_ptp_write(hellcreek, MAX_NS_PER_STEP, PR_CLOCK_OFFSET_C);
> +	hellcreek_ptp_write(hellcreek, MIN_CLK_CYCLES_BETWEEN_STEPS,
> +			    PR_CLOCK_OFFSET_C);
> +	hellcreek_ptp_write(hellcreek, countl,  PR_CLOCK_OFFSET_C);
> +	hellcreek_ptp_write(hellcreek, counth,  PR_CLOCK_OFFSET_C);
> +
> +	spin_unlock(&hellcreek->ptp_lock);
> +
> +	return 0;
> +}

> +int hellcreek_ptp_setup(struct hellcreek *hellcreek)
> +{
> +	u16 status;
> +
> +	/* Set up the overflow work */
> +	INIT_DELAYED_WORK(&hellcreek->overflow_work,
> +			  hellcreek_ptp_overflow_check);
> +
> +	/* Setup PTP clock */
> +	hellcreek->ptp_clock_info.owner = THIS_MODULE;
> +	snprintf(hellcreek->ptp_clock_info.name,
> +		 sizeof(hellcreek->ptp_clock_info.name),
> +		 dev_name(hellcreek->dev));
> +
> +	/* IP-Core can add up to 0.5 ns per 8 ns cycle, which means
> +	 * accumulator_overflow_rate shall not exceed 62.5 MHz (which adjusts
> +	 * the nominal frequency by 6.25%)
> +	 */
> +	hellcreek->ptp_clock_info.max_adj   = 62500000;
> +	hellcreek->ptp_clock_info.n_alarm   = 0;
> +	hellcreek->ptp_clock_info.n_pins    = 0;
> +	hellcreek->ptp_clock_info.n_ext_ts  = 0;
> +	hellcreek->ptp_clock_info.n_per_out = 0;
> +	hellcreek->ptp_clock_info.pps	    = 0;
> +	hellcreek->ptp_clock_info.adjfine   = hellcreek_ptp_adjfine;
> +	hellcreek->ptp_clock_info.adjtime   = hellcreek_ptp_adjtime;
> +	hellcreek->ptp_clock_info.gettime64 = hellcreek_ptp_gettime;
> +	hellcreek->ptp_clock_info.settime64 = hellcreek_ptp_settime;
> +	hellcreek->ptp_clock_info.enable    = hellcreek_ptp_enable;
> +
> +	hellcreek->ptp_clock = ptp_clock_register(&hellcreek->ptp_clock_info,
> +						  hellcreek->dev);
> +	if (IS_ERR(hellcreek->ptp_clock))
> +		return PTR_ERR(hellcreek->ptp_clock);

The ptp_clock_register() can also return NULL:

 * Returns a valid pointer on success or PTR_ERR on failure.  If PHC
 * support is missing at the configuration level, this function
 * returns NULL, and drivers are expected to gracefully handle that
 * case separately.

> +
> +	/* Enable the offset correction process, if no offset correction is
> +	 * already taking place
> +	 */
> +	status = hellcreek_ptp_read(hellcreek, PR_CLOCK_STATUS_C);
> +	if (!(status & PR_CLOCK_STATUS_C_OFS_ACT))
> +		hellcreek_ptp_write(hellcreek,
> +				    status | PR_CLOCK_STATUS_C_ENA_OFS,
> +				    PR_CLOCK_STATUS_C);
> +
> +	/* Enable the drift correction process */
> +	hellcreek_ptp_write(hellcreek, status | PR_CLOCK_STATUS_C_ENA_DRIFT,
> +			    PR_CLOCK_STATUS_C);
> +
> +	schedule_delayed_work(&hellcreek->overflow_work,
> +			      HELLCREEK_OVERFLOW_PERIOD);
> +
> +	return 0;
> +}

Thanks,
Richard

  parent reply	other threads:[~2020-06-24 13:03 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-18  6:40 [RFC PATCH 0/9] Hirschmann Hellcreek DSA driver Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 1/9] net: dsa: Add tag handling for Hirschmann Hellcreek switches Kurt Kanzenbach
2020-06-18 13:42   ` Andrew Lunn
2020-06-18  6:40 ` [RFC PATCH 2/9] net: dsa: Add DSA driver " Kurt Kanzenbach
2020-06-18 15:22   ` Andrew Lunn
2020-06-19  8:12     ` Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 3/9] net: dsa: hellcreek: Add PTP clock support Kurt Kanzenbach
2020-06-18 15:46   ` Jakub Kicinski
2020-06-19  8:13     ` Kurt Kanzenbach
2020-06-18 17:23   ` Andrew Lunn
2020-06-19  8:26     ` Kurt Kanzenbach
2020-06-19 13:40       ` Andrew Lunn
2020-06-22 11:52         ` Kurt Kanzenbach
2020-06-24 13:03   ` Richard Cochran [this message]
2020-06-25  7:08     ` Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 4/9] net: dsa: hellcreek: Add support for hardware timestamping Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 5/9] net: dsa: hellcreek: Add TAPRIO offloading support Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 6/9] net: dsa: hellcreek: Add debugging mechanisms Kurt Kanzenbach
2020-06-18 17:34   ` Andrew Lunn
2020-06-19  8:36     ` Kurt Kanzenbach
2020-06-19 13:42       ` Andrew Lunn
2020-06-22 12:32         ` Kurt Kanzenbach
2020-06-22 13:55           ` Andrew Lunn
2020-06-23  6:07             ` Kurt Kanzenbach
2020-06-22 14:14           ` Vladimir Oltean
2020-06-23  6:04             ` Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 7/9] net: dsa: hellcreek: Add PTP status LEDs Kurt Kanzenbach
2020-06-18 17:46   ` Andrew Lunn
2020-06-19  8:45     ` Kurt Kanzenbach
2020-06-19 13:52       ` Andrew Lunn
2020-06-18  6:40 ` [RFC PATCH 8/9] dt-bindings: Add vendor prefix for Hirschmann Kurt Kanzenbach
2020-06-18  6:40 ` [RFC PATCH 9/9] dt-bindings: net: dsa: Add documentation for Hellcreek switches Kurt Kanzenbach
2020-06-18 13:47   ` Andrew Lunn
2020-06-19  8:47     ` Kurt Kanzenbach
2020-06-19 13:56       ` Andrew Lunn
2020-06-22 12:02         ` Kurt Kanzenbach
2020-06-22 13:49           ` Andrew Lunn
2020-06-23  6:09             ` Kurt Kanzenbach
2020-06-18 17:40   ` Florian Fainelli
2020-06-19  8:48     ` Kurt Kanzenbach
2020-06-22 12:05       ` Kurt Kanzenbach
2020-06-26 17:11         ` Florian Fainelli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200624130318.GD7247@localhost \
    --to=richardcochran@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=bigeasy@linutronix.de \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=kamil.alkhouri@hs-offenburg.de \
    --cc=kuba@kernel.org \
    --cc=kurt@linutronix.de \
    --cc=netdev@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=vivien.didelot@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.