diff mbox series

[RFC] net: dsa: mv88e6xxx: correct CC scale factor for 88E6393X

Message ID b940ddf9-745f-4f2a-a29e-d6efe64de9a8@shenghaoyang.info (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series [RFC] net: dsa: mv88e6xxx: correct CC scale factor for 88E6393X | expand

Checks

Context Check Description
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 16 this patch: 16
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 5 maintainers not CCed: pabeni@redhat.com kuba@kernel.org edumazet@google.com richardcochran@gmail.com linux@armlinux.org.uk
netdev/build_clang success Errors and warnings before: 16 this patch: 16
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 16 this patch: 16
netdev/checkpatch warning CHECK: Prefer using the BIT macro
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Shenghao Yang Sept. 15, 2024, 11:57 a.m. UTC
Sending this as an RFC: no datasheet access - this
scaling factor may not be correct for all boards if this
4ns vs 8ns discrepancy is down to physical design.

If the counter is truly spec'd to always count at
250MHz other chips in the same family may need
correction too.

Tested on a MikroTik RB5009.

Fixes: de776d0d316f ("net: dsa: mv88e6xxx: add support for mv88e6393x family")
Signed-off-by: Shenghao Yang <me@shenghaoyang.info>
---
 drivers/net/dsa/mv88e6xxx/chip.c |  2 +-
 drivers/net/dsa/mv88e6xxx/ptp.c  | 43 ++++++++++++++++++++++++++++++--
 drivers/net/dsa/mv88e6xxx/ptp.h  |  2 ++
 3 files changed, 44 insertions(+), 3 deletions(-)

Comments

Andrew Lunn Sept. 15, 2024, 7:14 p.m. UTC | #1
On Sun, Sep 15, 2024 at 07:57:27PM +0800, Shenghao Yang wrote:
> Sending this as an RFC: no datasheet access - this
> scaling factor may not be correct for all boards if this
> 4ns vs 8ns discrepancy is down to physical design.
> 
> If the counter is truly spec'd to always count at
> 250MHz other chips in the same family may need
> correction too.

Hi Shenghao

This sort of text should be placed below the --- marker so it is not
part of the commit message which actually get merged.

What we want above the --- is a description of the problem you see,
and how your patch fixes this problem. It should include an
explanation of what you think the real problem is.

My understanding is that the clock can either be 250MHz or 125MHz like
older generations. If an external clock is used, it should be 125MHz.
The internally generated clock is however 250Mhz.

There is a register MV88E6XXX_TAI_CLOCK_PERIOD which indicates the
period of one clock tick. It probably defaults to 0x0FA0, or 4000
decimal which should be correct for the internal clock. But if an
external clock is being used, it needs to be set to 0x1F40, or 8000
decimal. It would be good if you could read it out and see if it is
correct by default.

This should apply to the 6393X family, so 6191X 6193X 6361 6393X. It
does not appear to apply to older devices.

	Andrew
Shenghao Yang Sept. 22, 2024, 11:15 a.m. UTC | #2
On 16/9/24 03:14, Andrew Lunn wrote:
> On Sun, Sep 15, 2024 at 07:57:27PM +0800, Shenghao Yang wrote:
>> Sending this as an RFC: no datasheet access - this
>> scaling factor may not be correct for all boards if this
>> 4ns vs 8ns discrepancy is down to physical design.
>>
>> If the counter is truly spec'd to always count at
>> 250MHz other chips in the same family may need
>> correction too.
> 
> This sort of text should be placed below the --- marker so it is not
> part of the commit message which actually get merged.

Hi Andrew,

Gotcha - I'll move things around in the future.

> There is a register MV88E6XXX_TAI_CLOCK_PERIOD which indicates the
> period of one clock tick. It probably defaults to 0x0FA0, or 4000
> decimal which should be correct for the internal clock. But if an
> external clock is being used, it needs to be set to 0x1F40, or 8000
> decimal. It would be good if you could read it out and see if it is
> correct by default.

Thanks! The register appears to contain the correct value on this
device - 4000ps using the 250MHz internal clock.

Would you happen to know if that register is valid for all the
families currently supported? 

I'm preparing a few patches to read off that register in 
mv88e6xxx_ptp_setup() and choose a correct set of cycle counter
coefficients to avoid introducing more device-specific handling.

If that sounds reasonable I'll send them for net - would you also be
okay with a Suggested-By?

Shenghao
Andrew Lunn Sept. 22, 2024, 3:20 p.m. UTC | #3
> Would you happen to know if that register is valid for all the
> families currently supported? 

6352 has it, 6320 also has it. So it seems to be common to all
implementations.

> If that sounds reasonable I'll send them for net - would you also be
> okay with a Suggested-By?

Yes, that is fine.

	Andrew
diff mbox series

Patch

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 5b4e2ce5470d..480fd93a336a 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -5617,7 +5617,7 @@  static const struct mv88e6xxx_ops mv88e6393x_ops = {
 	/* TODO: serdes stats */
 	.gpio_ops = &mv88e6352_gpio_ops,
 	.avb_ops = &mv88e6390_avb_ops,
-	.ptp_ops = &mv88e6352_ptp_ops,
+	.ptp_ops = &mv88e6393x_ptp_ops,
 	.phylink_get_caps = mv88e6393x_phylink_get_caps,
 	.pcs_ops = &mv88e6393x_pcs_ops,
 };
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c
index 56391e09b325..02bfff368be2 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.c
+++ b/drivers/net/dsa/mv88e6xxx/ptp.c
@@ -30,6 +30,18 @@ 
 #define MV88E6250_CC_MULT_NUM	(1 << 7)
 #define MV88E6250_CC_MULT_DEM	3125ULL
 
+/* Family MV88E6393X:
+ * Raw timestamps appear to be in units of 4-ns clock periods.
+ *
+ * clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16)
+ * simplifies to
+ * clkadj = scaled_ppm * 2^8 / 5^6
+ */
+#define MV88E6393X_CC_SHIFT	28
+#define MV88E6393X_CC_MULT	(4 << MV88E6393X_CC_SHIFT)
+#define MV88E6393X_CC_MULT_NUM	(1 << 8)
+#define MV88E6393X_CC_MULT_DEM	15625ULL
+
 /* Other families:
  * Raw timestamps are in units of 8-ns clock periods.
  *
@@ -452,6 +464,33 @@  const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
 	.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
 };
 
+const struct mv88e6xxx_ptp_ops mv88e6393x_ptp_ops = {
+	.clock_read = mv88e6352_ptp_clock_read,
+	.ptp_enable = mv88e6352_ptp_enable,
+	.ptp_verify = mv88e6352_ptp_verify,
+	.event_work = mv88e6352_tai_event_work,
+	.port_enable = mv88e6352_hwtstamp_port_enable,
+	.port_disable = mv88e6352_hwtstamp_port_disable,
+	.n_ext_ts = 1,
+	.arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS,
+	.arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS,
+	.dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS,
+	.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
+		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
+	.cc_shift = MV88E6393X_CC_SHIFT,
+	.cc_mult = MV88E6393X_CC_MULT,
+	.cc_mult_num = MV88E6393X_CC_MULT_NUM,
+	.cc_mult_dem = MV88E6393X_CC_MULT_DEM,
+};
+
 static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
 {
 	struct mv88e6xxx_chip *chip = cc_to_chip(cc);
@@ -462,10 +501,10 @@  static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
 	return 0;
 }
 
-/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3
+/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~17.2
  * seconds; this task forces periodic reads so that we don't miss any.
  */
-#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16)
+#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8)
 static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
 {
 	struct delayed_work *dw = to_delayed_work(work);
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.h b/drivers/net/dsa/mv88e6xxx/ptp.h
index 6c4d09adc93c..b236e11c6d78 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.h
+++ b/drivers/net/dsa/mv88e6xxx/ptp.h
@@ -152,6 +152,7 @@  extern const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops;
 extern const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops;
 extern const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops;
 extern const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops;
+extern const struct mv88e6xxx_ptp_ops mv88e6393x_ptp_ops;
 
 #else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
 
@@ -173,6 +174,7 @@  static const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {};
 static const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {};
 static const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {};
 static const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {};
+static const struct mv88e6xxx_ptp_ops mv88e6393x_ptp_ops = {};
 
 #endif /* CONFIG_NET_DSA_MV88E6XXX_PTP */