Commit 7e3c1809 authored by Shenghao Yang's avatar Shenghao Yang Committed by Paolo Abeni
Browse files

net: dsa: mv88e6xxx: read cycle counter period from hardware



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: de776d0d ("net: dsa: mv88e6xxx: add support for mv88e6393x family")
Suggested-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarShenghao Yang <me@shenghaoyang.info>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 67af86af
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 {
+42 −18
Original line number Diff line number Diff line
@@ -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 @@ static void mv88e6352_tai_event_work(struct work_struct *ugly)
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()));