]> www.infradead.org Git - linux.git/commitdiff
net: dsa: mv88e6xxx: read cycle counter period from hardware
authorShenghao Yang <me@shenghaoyang.info>
Sun, 20 Oct 2024 06:38:29 +0000 (14:38 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 24 Oct 2024 10:57:46 +0000 (12:57 +0200)
Instead of relying on a fixed mapping of hardware family to cycle
counter frequency, pull this information from the
MV88E6XXX_TAI_CLOCK_PERIOD register.

This lets us support switches whose cycle counter frequencies depend on
board design.

Fixes: de776d0d316f ("net: dsa: mv88e6xxx: add support for mv88e6393x family")
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Shenghao Yang <me@shenghaoyang.info>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/dsa/mv88e6xxx/chip.h
drivers/net/dsa/mv88e6xxx/ptp.c

index 1d003a9deafa733c742b65e59ecf6bc066471efc..a54682240839627979007a597df376054f6c26a3 100644 (file)
@@ -409,6 +409,7 @@ struct mv88e6xxx_chip {
        struct cyclecounter     tstamp_cc;
        struct timecounter      tstamp_tc;
        struct delayed_work     overflow_work;
+       const struct mv88e6xxx_cc_coeffs *cc_coeffs;
 
        struct ptp_clock        *ptp_clock;
        struct ptp_clock_info   ptp_clock_info;
@@ -732,7 +733,6 @@ struct mv88e6xxx_ptp_ops {
        int arr1_sts_reg;
        int dep_sts_reg;
        u32 rx_filters;
-       const struct mv88e6xxx_cc_coeffs *cc_coeffs;
 };
 
 struct mv88e6xxx_pcs_ops {
index 641af44e00af9cf8817ab1fd96e05300022bfbdf..a409b8661fadd509e5e45ade8d0866ae05cc41ed 100644 (file)
@@ -32,10 +32,10 @@ struct mv88e6xxx_cc_coeffs {
  * simplifies to
  * clkadj = scaled_ppm * 2^7 / 5^5
  */
-#define MV88E6250_CC_SHIFT 28
-static const struct mv88e6xxx_cc_coeffs mv88e6250_cc_coeffs = {
-       .cc_shift = MV88E6250_CC_SHIFT,
-       .cc_mult = 10 << MV88E6250_CC_SHIFT,
+#define MV88E6XXX_CC_10NS_SHIFT 28
+static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = {
+       .cc_shift = MV88E6XXX_CC_10NS_SHIFT,
+       .cc_mult = 10 << MV88E6XXX_CC_10NS_SHIFT,
        .cc_mult_num = 1 << 7,
        .cc_mult_dem = 3125ULL,
 };
@@ -47,10 +47,10 @@ static const struct mv88e6xxx_cc_coeffs mv88e6250_cc_coeffs = {
  * simplifies to
  * clkadj = scaled_ppm * 2^9 / 5^6
  */
-#define MV88E6XXX_CC_SHIFT 28
-static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_coeffs = {
-       .cc_shift = MV88E6XXX_CC_SHIFT,
-       .cc_mult = 8 << MV88E6XXX_CC_SHIFT,
+#define MV88E6XXX_CC_8NS_SHIFT 28
+static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = {
+       .cc_shift = MV88E6XXX_CC_8NS_SHIFT,
+       .cc_mult = 8 << MV88E6XXX_CC_8NS_SHIFT,
        .cc_mult_num = 1 << 9,
        .cc_mult_dem = 15625ULL
 };
@@ -96,6 +96,31 @@ static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
        return chip->info->ops->gpio_ops->set_pctl(chip, pin, func);
 }
 
+static const struct mv88e6xxx_cc_coeffs *
+mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip *chip)
+{
+       u16 period_ps;
+       int err;
+
+       err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_CLOCK_PERIOD, &period_ps, 1);
+       if (err) {
+               dev_err(chip->dev, "failed to read cycle counter period: %d\n",
+                       err);
+               return ERR_PTR(err);
+       }
+
+       switch (period_ps) {
+       case 8000:
+               return &mv88e6xxx_cc_8ns_coeffs;
+       case 10000:
+               return &mv88e6xxx_cc_10ns_coeffs;
+       default:
+               dev_err(chip->dev, "unexpected cycle counter period of %u ps\n",
+                       period_ps);
+               return ERR_PTR(-ENODEV);
+       }
+}
+
 static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc)
 {
        struct mv88e6xxx_chip *chip = cc_to_chip(cc);
@@ -217,7 +242,6 @@ out:
 static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 {
        struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
-       const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
        int neg_adj = 0;
        u32 diff, mult;
        u64 adj;
@@ -227,10 +251,10 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
                scaled_ppm = -scaled_ppm;
        }
 
-       mult = ptp_ops->cc_coeffs->cc_mult;
-       adj = ptp_ops->cc_coeffs->cc_mult_num;
+       mult = chip->cc_coeffs->cc_mult;
+       adj = chip->cc_coeffs->cc_mult_num;
        adj *= scaled_ppm;
-       diff = div_u64(adj, ptp_ops->cc_coeffs->cc_mult_dem);
+       diff = div_u64(adj, chip->cc_coeffs->cc_mult_dem);
 
        mv88e6xxx_reg_lock(chip);
 
@@ -377,7 +401,6 @@ const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
                (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-       .cc_coeffs = &mv88e6xxx_cc_coeffs
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
@@ -401,7 +424,6 @@ const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
                (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-       .cc_coeffs = &mv88e6250_cc_coeffs,
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
@@ -425,7 +447,6 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
                (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-       .cc_coeffs = &mv88e6xxx_cc_coeffs,
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
@@ -450,7 +471,6 @@ const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
                (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-       .cc_coeffs = &mv88e6xxx_cc_coeffs,
 };
 
 static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
@@ -485,11 +505,15 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
        int i;
 
        /* Set up the cycle counter */
+       chip->cc_coeffs = mv88e6xxx_cc_coeff_get(chip);
+       if (IS_ERR(chip->cc_coeffs))
+               return PTR_ERR(chip->cc_coeffs);
+
        memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
        chip->tstamp_cc.read    = mv88e6xxx_ptp_clock_read;
        chip->tstamp_cc.mask    = CYCLECOUNTER_MASK(32);
-       chip->tstamp_cc.mult    = ptp_ops->cc_coeffs->cc_mult;
-       chip->tstamp_cc.shift   = ptp_ops->cc_coeffs->cc_shift;
+       chip->tstamp_cc.mult    = chip->cc_coeffs->cc_mult;
+       chip->tstamp_cc.shift   = chip->cc_coeffs->cc_shift;
 
        timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
                         ktime_to_ns(ktime_get_real()));