Skip to content

Commit 9efc44f

Browse files
author
Paolo Abeni
committed
Merge branch 'net-dsa-mv88e6xxx-fix-mv88e6393x-phc-frequency-on-internal-clock'
Shenghao Yang says: ==================== net: dsa: mv88e6xxx: fix MV88E6393X PHC frequency on internal clock The MV88E6393X family of switches can additionally run their cycle counters using a 250MHz internal clock instead of the usual 125MHz external clock [1]. The driver currently assumes all designs utilize that external clock, but MikroTik's RB5009 uses the internal source - causing the PHC to be seen running at 2x real time in userspace, making synchronization with ptp4l impossible. This series adds support for reading off the cycle counter frequency known to the hardware in the TAI_CLOCK_PERIOD register and picking an appropriate set of scaling coefficients instead of using a fixed set for each switch family. Patch 1 groups those cycle counter coefficients into a new structure to make it easier to pass them around. Patch 2 modifies PTP initialization to probe TAI_CLOCK_PERIOD and use an appropriate set of coefficients. Patch 3 adds support for 4000ps cycle counter periods. Changes since v2 [2]: - Patch 1: "net: dsa: mv88e6xxx: group cycle counter coefficients" - Moved declaration of mv88e6xxx_cc_coeffs to avoid moving that in Patch 2. - Patch 2: "net: dsa: mv88e6xxx: read cycle counter period from hardware" - Removed move of mv88e6xxx_cc_coeffs declaration. - Patch 3: "net: dsa: mv88e6xxx: support 4000ps cycle counter periods" - No change. [1] https://lore.kernel.org/netdev/[email protected]/ [2] https://lore.kernel.org/netdev/[email protected]/ ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 64761c9 + 3e65ede commit 9efc44f

File tree

2 files changed

+77
-37
lines changed

2 files changed

+77
-37
lines changed

drivers/net/dsa/mv88e6xxx/chip.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ struct mv88e6xxx_gpio_ops;
206206
struct mv88e6xxx_avb_ops;
207207
struct mv88e6xxx_ptp_ops;
208208
struct mv88e6xxx_pcs_ops;
209+
struct mv88e6xxx_cc_coeffs;
209210

210211
struct mv88e6xxx_irq {
211212
u16 masked;
@@ -408,6 +409,7 @@ struct mv88e6xxx_chip {
408409
struct cyclecounter tstamp_cc;
409410
struct timecounter tstamp_tc;
410411
struct delayed_work overflow_work;
412+
const struct mv88e6xxx_cc_coeffs *cc_coeffs;
411413

412414
struct ptp_clock *ptp_clock;
413415
struct ptp_clock_info ptp_clock_info;
@@ -731,10 +733,6 @@ struct mv88e6xxx_ptp_ops {
731733
int arr1_sts_reg;
732734
int dep_sts_reg;
733735
u32 rx_filters;
734-
u32 cc_shift;
735-
u32 cc_mult;
736-
u32 cc_mult_num;
737-
u32 cc_mult_dem;
738736
};
739737

740738
struct mv88e6xxx_pcs_ops {

drivers/net/dsa/mv88e6xxx/ptp.c

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,57 @@
1818

1919
#define MV88E6XXX_MAX_ADJ_PPB 1000000
2020

21+
struct mv88e6xxx_cc_coeffs {
22+
u32 cc_shift;
23+
u32 cc_mult;
24+
u32 cc_mult_num;
25+
u32 cc_mult_dem;
26+
};
27+
2128
/* Family MV88E6250:
2229
* Raw timestamps are in units of 10-ns clock periods.
2330
*
2431
* clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16)
2532
* simplifies to
2633
* clkadj = scaled_ppm * 2^7 / 5^5
2734
*/
28-
#define MV88E6250_CC_SHIFT 28
29-
#define MV88E6250_CC_MULT (10 << MV88E6250_CC_SHIFT)
30-
#define MV88E6250_CC_MULT_NUM (1 << 7)
31-
#define MV88E6250_CC_MULT_DEM 3125ULL
35+
#define MV88E6XXX_CC_10NS_SHIFT 28
36+
static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = {
37+
.cc_shift = MV88E6XXX_CC_10NS_SHIFT,
38+
.cc_mult = 10 << MV88E6XXX_CC_10NS_SHIFT,
39+
.cc_mult_num = 1 << 7,
40+
.cc_mult_dem = 3125ULL,
41+
};
3242

33-
/* Other families:
43+
/* Other families except MV88E6393X in internal clock mode:
3444
* Raw timestamps are in units of 8-ns clock periods.
3545
*
3646
* clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
3747
* simplifies to
3848
* clkadj = scaled_ppm * 2^9 / 5^6
3949
*/
40-
#define MV88E6XXX_CC_SHIFT 28
41-
#define MV88E6XXX_CC_MULT (8 << MV88E6XXX_CC_SHIFT)
42-
#define MV88E6XXX_CC_MULT_NUM (1 << 9)
43-
#define MV88E6XXX_CC_MULT_DEM 15625ULL
50+
#define MV88E6XXX_CC_8NS_SHIFT 28
51+
static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = {
52+
.cc_shift = MV88E6XXX_CC_8NS_SHIFT,
53+
.cc_mult = 8 << MV88E6XXX_CC_8NS_SHIFT,
54+
.cc_mult_num = 1 << 9,
55+
.cc_mult_dem = 15625ULL
56+
};
57+
58+
/* Family MV88E6393X using internal clock:
59+
* Raw timestamps are in units of 4-ns clock periods.
60+
*
61+
* clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16)
62+
* simplifies to
63+
* clkadj = scaled_ppm * 2^8 / 5^6
64+
*/
65+
#define MV88E6XXX_CC_4NS_SHIFT 28
66+
static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_4ns_coeffs = {
67+
.cc_shift = MV88E6XXX_CC_4NS_SHIFT,
68+
.cc_mult = 4 << MV88E6XXX_CC_4NS_SHIFT,
69+
.cc_mult_num = 1 << 8,
70+
.cc_mult_dem = 15625ULL
71+
};
4472

4573
#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
4674

@@ -83,6 +111,33 @@ static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
83111
return chip->info->ops->gpio_ops->set_pctl(chip, pin, func);
84112
}
85113

114+
static const struct mv88e6xxx_cc_coeffs *
115+
mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip *chip)
116+
{
117+
u16 period_ps;
118+
int err;
119+
120+
err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_CLOCK_PERIOD, &period_ps, 1);
121+
if (err) {
122+
dev_err(chip->dev, "failed to read cycle counter period: %d\n",
123+
err);
124+
return ERR_PTR(err);
125+
}
126+
127+
switch (period_ps) {
128+
case 4000:
129+
return &mv88e6xxx_cc_4ns_coeffs;
130+
case 8000:
131+
return &mv88e6xxx_cc_8ns_coeffs;
132+
case 10000:
133+
return &mv88e6xxx_cc_10ns_coeffs;
134+
default:
135+
dev_err(chip->dev, "unexpected cycle counter period of %u ps\n",
136+
period_ps);
137+
return ERR_PTR(-ENODEV);
138+
}
139+
}
140+
86141
static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc)
87142
{
88143
struct mv88e6xxx_chip *chip = cc_to_chip(cc);
@@ -204,7 +259,6 @@ static void mv88e6352_tai_event_work(struct work_struct *ugly)
204259
static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
205260
{
206261
struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
207-
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
208262
int neg_adj = 0;
209263
u32 diff, mult;
210264
u64 adj;
@@ -214,10 +268,10 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
214268
scaled_ppm = -scaled_ppm;
215269
}
216270

217-
mult = ptp_ops->cc_mult;
218-
adj = ptp_ops->cc_mult_num;
271+
mult = chip->cc_coeffs->cc_mult;
272+
adj = chip->cc_coeffs->cc_mult_num;
219273
adj *= scaled_ppm;
220-
diff = div_u64(adj, ptp_ops->cc_mult_dem);
274+
diff = div_u64(adj, chip->cc_coeffs->cc_mult_dem);
221275

222276
mv88e6xxx_reg_lock(chip);
223277

@@ -364,10 +418,6 @@ const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
364418
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
365419
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
366420
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
367-
.cc_shift = MV88E6XXX_CC_SHIFT,
368-
.cc_mult = MV88E6XXX_CC_MULT,
369-
.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
370-
.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
371421
};
372422

373423
const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
@@ -391,10 +441,6 @@ const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
391441
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
392442
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
393443
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
394-
.cc_shift = MV88E6250_CC_SHIFT,
395-
.cc_mult = MV88E6250_CC_MULT,
396-
.cc_mult_num = MV88E6250_CC_MULT_NUM,
397-
.cc_mult_dem = MV88E6250_CC_MULT_DEM,
398444
};
399445

400446
const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
@@ -418,10 +464,6 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
418464
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
419465
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
420466
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
421-
.cc_shift = MV88E6XXX_CC_SHIFT,
422-
.cc_mult = MV88E6XXX_CC_MULT,
423-
.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
424-
.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
425467
};
426468

427469
const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
@@ -446,10 +488,6 @@ const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
446488
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
447489
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
448490
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
449-
.cc_shift = MV88E6XXX_CC_SHIFT,
450-
.cc_mult = MV88E6XXX_CC_MULT,
451-
.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
452-
.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
453491
};
454492

455493
static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
@@ -462,10 +500,10 @@ static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
462500
return 0;
463501
}
464502

465-
/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3
503+
/* With a 250MHz input clock, the 32-bit timestamp counter overflows in ~17.2
466504
* seconds; this task forces periodic reads so that we don't miss any.
467505
*/
468-
#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16)
506+
#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8)
469507
static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
470508
{
471509
struct delayed_work *dw = to_delayed_work(work);
@@ -484,11 +522,15 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
484522
int i;
485523

486524
/* Set up the cycle counter */
525+
chip->cc_coeffs = mv88e6xxx_cc_coeff_get(chip);
526+
if (IS_ERR(chip->cc_coeffs))
527+
return PTR_ERR(chip->cc_coeffs);
528+
487529
memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
488530
chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read;
489531
chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32);
490-
chip->tstamp_cc.mult = ptp_ops->cc_mult;
491-
chip->tstamp_cc.shift = ptp_ops->cc_shift;
532+
chip->tstamp_cc.mult = chip->cc_coeffs->cc_mult;
533+
chip->tstamp_cc.shift = chip->cc_coeffs->cc_shift;
492534

493535
timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
494536
ktime_to_ns(ktime_get_real()));

0 commit comments

Comments
 (0)