mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-21 15:00:42 +07:00
net: dsa: mv88e6xxx: Abstract PTP operations
The mv88e6165 family supports PTP, but its registers use a different layout to the currently supported devices. Abstract accessing the PTP registers into a set of ops, so making space for a second implementation. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Acked-by: Richard Cochran <richardcochran@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0725345e5f
commit
6d2ac8ee67
@ -3134,6 +3134,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
||||
.vtu_getnext = mv88e6390_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
||||
.serdes_power = mv88e6390_serdes_power,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
@ -3176,6 +3178,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
.serdes_power = mv88e6352_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6290_ops = {
|
||||
@ -3215,6 +3218,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
||||
.serdes_power = mv88e6390_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
@ -3253,6 +3257,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
@ -3289,6 +3294,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6341_ops = {
|
||||
@ -3329,6 +3335,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6350_ops = {
|
||||
@ -3402,6 +3409,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
||||
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
@ -3444,6 +3452,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
.serdes_power = mv88e6352_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
|
||||
.serdes_get_strings = mv88e6352_serdes_get_strings,
|
||||
.serdes_get_stats = mv88e6352_serdes_get_stats,
|
||||
@ -3488,6 +3497,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
||||
.serdes_power = mv88e6390_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
||||
@ -3529,6 +3539,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
||||
.serdes_power = mv88e6390_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
|
@ -155,6 +155,7 @@ struct mv88e6xxx_bus_ops;
|
||||
struct mv88e6xxx_irq_ops;
|
||||
struct mv88e6xxx_gpio_ops;
|
||||
struct mv88e6xxx_avb_ops;
|
||||
struct mv88e6xxx_ptp_ops;
|
||||
|
||||
struct mv88e6xxx_irq {
|
||||
u16 masked;
|
||||
@ -439,6 +440,9 @@ struct mv88e6xxx_ops {
|
||||
|
||||
/* Remote Management Unit operations */
|
||||
int (*rmu_disable)(struct mv88e6xxx_chip *chip);
|
||||
|
||||
/* Precision Time Protocol operations */
|
||||
const struct mv88e6xxx_ptp_ops *ptp_ops;
|
||||
};
|
||||
|
||||
struct mv88e6xxx_irq_ops {
|
||||
@ -486,6 +490,16 @@ struct mv88e6xxx_avb_ops {
|
||||
int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
|
||||
};
|
||||
|
||||
struct mv88e6xxx_ptp_ops {
|
||||
u64 (*clock_read)(const struct cyclecounter *cc);
|
||||
int (*ptp_enable)(struct ptp_clock_info *ptp,
|
||||
struct ptp_clock_request *rq, int on);
|
||||
int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin,
|
||||
enum ptp_pin_function func, unsigned int chan);
|
||||
void (*event_work)(struct work_struct *ugly);
|
||||
int n_ext_ts;
|
||||
};
|
||||
|
||||
#define STATS_TYPE_PORT BIT(0)
|
||||
#define STATS_TYPE_BANK0 BIT(1)
|
||||
#define STATS_TYPE_BANK1 BIT(2)
|
||||
|
@ -50,7 +50,7 @@ static int mv88e6xxx_tai_write(struct mv88e6xxx_chip *chip, int addr, u16 data)
|
||||
}
|
||||
|
||||
/* TODO: places where this are called should be using pinctrl */
|
||||
static int mv88e6xxx_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
|
||||
static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
|
||||
int func, int input)
|
||||
{
|
||||
int err;
|
||||
@ -65,7 +65,7 @@ static int mv88e6xxx_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
|
||||
return chip->info->ops->gpio_ops->set_pctl(chip, pin, func);
|
||||
}
|
||||
|
||||
static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
|
||||
static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = cc_to_chip(cc);
|
||||
u16 phc_time[2];
|
||||
@ -79,13 +79,13 @@ static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
|
||||
return ((u32)phc_time[1] << 16) | phc_time[0];
|
||||
}
|
||||
|
||||
/* mv88e6xxx_config_eventcap - configure TAI event capture
|
||||
/* mv88e6352_config_eventcap - configure TAI event capture
|
||||
* @event: PTP_CLOCK_PPS (internal) or PTP_CLOCK_EXTTS (external)
|
||||
* @rising: zero for falling-edge trigger, else rising-edge trigger
|
||||
*
|
||||
* This will also reset the capture sequence counter.
|
||||
*/
|
||||
static int mv88e6xxx_config_eventcap(struct mv88e6xxx_chip *chip, int event,
|
||||
static int mv88e6352_config_eventcap(struct mv88e6xxx_chip *chip, int event,
|
||||
int rising)
|
||||
{
|
||||
u16 global_config;
|
||||
@ -118,7 +118,7 @@ static int mv88e6xxx_config_eventcap(struct mv88e6xxx_chip *chip, int event,
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mv88e6xxx_tai_event_work(struct work_struct *ugly)
|
||||
static void mv88e6352_tai_event_work(struct work_struct *ugly)
|
||||
{
|
||||
struct delayed_work *dw = to_delayed_work(ugly);
|
||||
struct mv88e6xxx_chip *chip = dw_tai_event_to_chip(dw);
|
||||
@ -232,7 +232,7 @@ static int mv88e6xxx_ptp_settime(struct ptp_clock_info *ptp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mv88e6xxx_ptp_enable_extts(struct mv88e6xxx_chip *chip,
|
||||
static int mv88e6352_ptp_enable_extts(struct mv88e6xxx_chip *chip,
|
||||
struct ptp_clock_request *rq, int on)
|
||||
{
|
||||
int rising = (rq->extts.flags & PTP_RISING_EDGE);
|
||||
@ -250,18 +250,18 @@ static int mv88e6xxx_ptp_enable_extts(struct mv88e6xxx_chip *chip,
|
||||
if (on) {
|
||||
func = MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ;
|
||||
|
||||
err = mv88e6xxx_set_gpio_func(chip, pin, func, true);
|
||||
err = mv88e6352_set_gpio_func(chip, pin, func, true);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
schedule_delayed_work(&chip->tai_event_work,
|
||||
TAI_EVENT_WORK_INTERVAL);
|
||||
|
||||
err = mv88e6xxx_config_eventcap(chip, PTP_CLOCK_EXTTS, rising);
|
||||
err = mv88e6352_config_eventcap(chip, PTP_CLOCK_EXTTS, rising);
|
||||
} else {
|
||||
func = MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO;
|
||||
|
||||
err = mv88e6xxx_set_gpio_func(chip, pin, func, true);
|
||||
err = mv88e6352_set_gpio_func(chip, pin, func, true);
|
||||
|
||||
cancel_delayed_work_sync(&chip->tai_event_work);
|
||||
}
|
||||
@ -272,20 +272,20 @@ static int mv88e6xxx_ptp_enable_extts(struct mv88e6xxx_chip *chip,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mv88e6xxx_ptp_enable(struct ptp_clock_info *ptp,
|
||||
static int mv88e6352_ptp_enable(struct ptp_clock_info *ptp,
|
||||
struct ptp_clock_request *rq, int on)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
|
||||
|
||||
switch (rq->type) {
|
||||
case PTP_CLK_REQ_EXTTS:
|
||||
return mv88e6xxx_ptp_enable_extts(chip, rq, on);
|
||||
return mv88e6352_ptp_enable_extts(chip, rq, on);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static int mv88e6xxx_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
|
||||
static int mv88e6352_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
|
||||
enum ptp_pin_function func, unsigned int chan)
|
||||
{
|
||||
switch (func) {
|
||||
@ -299,6 +299,24 @@ static int mv88e6xxx_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
|
||||
.clock_read = mv88e6352_ptp_clock_read,
|
||||
.ptp_enable = mv88e6352_ptp_enable,
|
||||
.ptp_verify = mv88e6352_ptp_verify,
|
||||
.event_work = mv88e6352_tai_event_work,
|
||||
.n_ext_ts = 1,
|
||||
};
|
||||
|
||||
static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = cc_to_chip(cc);
|
||||
|
||||
if (chip->info->ops->ptp_ops->clock_read)
|
||||
return chip->info->ops->ptp_ops->clock_read(cc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3
|
||||
* seconds; this task forces periodic reads so that we don't miss any.
|
||||
*/
|
||||
@ -317,6 +335,7 @@ static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
|
||||
|
||||
int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
|
||||
int i;
|
||||
|
||||
/* Set up the cycle counter */
|
||||
@ -330,14 +349,15 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
|
||||
ktime_to_ns(ktime_get_real()));
|
||||
|
||||
INIT_DELAYED_WORK(&chip->overflow_work, mv88e6xxx_ptp_overflow_check);
|
||||
INIT_DELAYED_WORK(&chip->tai_event_work, mv88e6xxx_tai_event_work);
|
||||
if (ptp_ops->event_work)
|
||||
INIT_DELAYED_WORK(&chip->tai_event_work, ptp_ops->event_work);
|
||||
|
||||
chip->ptp_clock_info.owner = THIS_MODULE;
|
||||
snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
|
||||
dev_name(chip->dev));
|
||||
chip->ptp_clock_info.max_adj = 1000000;
|
||||
|
||||
chip->ptp_clock_info.n_ext_ts = 1;
|
||||
chip->ptp_clock_info.n_ext_ts = ptp_ops->n_ext_ts;
|
||||
chip->ptp_clock_info.n_per_out = 0;
|
||||
chip->ptp_clock_info.n_pins = mv88e6xxx_num_gpio(chip);
|
||||
chip->ptp_clock_info.pps = 0;
|
||||
@ -355,8 +375,8 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
|
||||
chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime;
|
||||
chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime;
|
||||
chip->ptp_clock_info.settime64 = mv88e6xxx_ptp_settime;
|
||||
chip->ptp_clock_info.enable = mv88e6xxx_ptp_enable;
|
||||
chip->ptp_clock_info.verify = mv88e6xxx_ptp_verify;
|
||||
chip->ptp_clock_info.enable = ptp_ops->ptp_enable;
|
||||
chip->ptp_clock_info.verify = ptp_ops->ptp_verify;
|
||||
chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work;
|
||||
|
||||
chip->ptp_clock = ptp_clock_register(&chip->ptp_clock_info, chip->dev);
|
||||
@ -373,7 +393,8 @@ void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
if (chip->ptp_clock) {
|
||||
cancel_delayed_work_sync(&chip->overflow_work);
|
||||
cancel_delayed_work_sync(&chip->tai_event_work);
|
||||
if (chip->info->ops->ptp_ops->event_work)
|
||||
cancel_delayed_work_sync(&chip->tai_event_work);
|
||||
|
||||
ptp_clock_unregister(chip->ptp_clock);
|
||||
chip->ptp_clock = NULL;
|
||||
|
@ -87,6 +87,8 @@ void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip);
|
||||
#define ptp_to_chip(ptp) container_of(ptp, struct mv88e6xxx_chip, \
|
||||
ptp_clock_info)
|
||||
|
||||
extern const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops;
|
||||
|
||||
#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
|
||||
|
||||
static inline long mv88e6xxx_hwtstamp_work(struct ptp_clock_info *ptp)
|
||||
@ -103,6 +105,8 @@ static inline void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {};
|
||||
|
||||
#endif /* CONFIG_NET_DSA_MV88E6XXX_PTP */
|
||||
|
||||
#endif /* _MV88E6XXX_PTP_H */
|
||||
|
Loading…
Reference in New Issue
Block a user