diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 6a999e6814a073a2a4bf33ee944d3c32c4a085eb..293ad064905d6058bb72d5e4b68f832c9053451a 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -40,6 +40,7 @@ #define LAYER2 0x01 #define MAX_RXTS 64 #define N_EXT_TS 6 +#define N_PER_OUT 7 #define PSF_PTPVER 2 #define PSF_EVNT 0x4000 #define PSF_RX 0x2000 @@ -47,7 +48,6 @@ #define EXT_EVENT 1 #define CAL_EVENT 7 #define CAL_TRIGGER 7 -#define PER_TRIGGER 6 #define DP83640_N_PINS 12 #define MII_DP83640_MICR 0x11 @@ -300,23 +300,23 @@ static u64 phy2txts(struct phy_txts *p) } static int periodic_output(struct dp83640_clock *clock, - struct ptp_clock_request *clkreq, bool on) + struct ptp_clock_request *clkreq, bool on, + int trigger) { struct dp83640_private *dp83640 = clock->chosen; struct phy_device *phydev = dp83640->phydev; u32 sec, nsec, pwidth; - u16 gpio, ptp_trig, trigger, val; + u16 gpio, ptp_trig, val; if (on) { - gpio = 1 + ptp_find_pin(clock->ptp_clock, PTP_PF_PEROUT, 0); + gpio = 1 + ptp_find_pin(clock->ptp_clock, PTP_PF_PEROUT, + trigger); if (gpio < 1) return -EINVAL; } else { gpio = 0; } - trigger = PER_TRIGGER; - ptp_trig = TRIG_WR | (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT | (gpio & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT | @@ -353,6 +353,11 @@ static int periodic_output(struct dp83640_clock *clock, ext_write(0, phydev, PAGE4, PTP_TDR, sec >> 16); /* sec[31:16] */ ext_write(0, phydev, PAGE4, PTP_TDR, pwidth & 0xffff); /* ns[15:0] */ ext_write(0, phydev, PAGE4, PTP_TDR, pwidth >> 16); /* ns[31:16] */ + /* Triggers 0 and 1 has programmable pulsewidth2 */ + if (trigger < 2) { + ext_write(0, phydev, PAGE4, PTP_TDR, pwidth & 0xffff); + ext_write(0, phydev, PAGE4, PTP_TDR, pwidth >> 16); + } /*enable trigger*/ val &= ~TRIG_LOAD; @@ -491,9 +496,9 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp, return 0; case PTP_CLK_REQ_PEROUT: - if (rq->perout.index != 0) + if (rq->perout.index >= N_PER_OUT) return -EINVAL; - return periodic_output(clock, rq, on); + return periodic_output(clock, rq, on, rq->perout.index); default: break; @@ -505,6 +510,16 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp, static int ptp_dp83640_verify(struct ptp_clock_info *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan) { + struct dp83640_clock *clock = + container_of(ptp, struct dp83640_clock, caps); + + if (clock->caps.pin_config[pin].func == PTP_PF_PHYSYNC && + !list_empty(&clock->phylist)) + return 1; + + if (func == PTP_PF_PHYSYNC) + return 1; + return 0; } @@ -594,7 +609,11 @@ static void recalibrate(struct dp83640_clock *clock) u16 cal_gpio, cfg0, evnt, ptp_trig, trigger, val; trigger = CAL_TRIGGER; - cal_gpio = gpio_tab[CALIBRATE_GPIO]; + cal_gpio = 1 + ptp_find_pin(clock->ptp_clock, PTP_PF_PHYSYNC, 0); + if (cal_gpio < 1) { + pr_err("PHY calibration pin not avaible - PHY is not calibrated."); + return; + } mutex_lock(&clock->extreg_lock); @@ -944,7 +963,7 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus) clock->caps.max_adj = 1953124; clock->caps.n_alarm = 0; clock->caps.n_ext_ts = N_EXT_TS; - clock->caps.n_per_out = 1; + clock->caps.n_per_out = N_PER_OUT; clock->caps.n_pins = DP83640_N_PINS; clock->caps.pps = 0; clock->caps.adjfreq = ptp_dp83640_adjfreq; diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 419056d7887ec9f516e46699bdc0f46dfe85eeb7..f8a76090cbca1e8bbf694a4fbc16a54ef60490d5 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -86,17 +86,12 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, return -EINVAL; break; case PTP_PF_PHYSYNC: - pr_err("sorry, cannot reassign the calibration pin\n"); - return -EINVAL; + if (chan != 0) + return -EINVAL; default: return -EINVAL; } - if (pin2->func == PTP_PF_PHYSYNC) { - pr_err("sorry, cannot reprogram the calibration pin\n"); - return -EINVAL; - } - if (info->verify(info, pin, func, chan)) { pr_err("driver cannot use function %u on pin %u\n", func, chan); return -EOPNOTSUPP;