lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <CO1PR11MB47713D1140834D937435A6CBE2529@CO1PR11MB4771.namprd11.prod.outlook.com> Date: Mon, 26 Sep 2022 04:46:35 +0000 From: <Divya.Koppera@...rochip.com> To: <Divya.Koppera@...rochip.com>, <andrew@...n.ch>, <hkallweit1@...il.com>, <linux@...linux.org.uk>, <davem@...emloft.net>, <edumazet@...gle.com>, <kuba@...nel.org>, <pabeni@...hat.com>, <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>, <richardcochran@...il.com> CC: <UNGLinuxDriver@...rochip.com> Subject: RE: [patch v2 net-next] net: phy: micrel: PEROUT support in lan8814 > -----Original Message----- > From: Divya Koppera <Divya.Koppera@...rochip.com> > Sent: Friday, September 16, 2022 5:48 PM > To: andrew@...n.ch; hkallweit1@...il.com; linux@...linux.org.uk; > davem@...emloft.net; edumazet@...gle.com; kuba@...nel.org; > pabeni@...hat.com; netdev@...r.kernel.org; linux- > kernel@...r.kernel.org; richardcochran@...il.com > Cc: UNGLinuxDriver <UNGLinuxDriver@...rochip.com> > Subject: [patch v2 net-next] net: phy: micrel: PEROUT support in lan8814 > > Support Periodic output from lan8814 gpio > > Signed-off-by: Divya Koppera <Divya.Koppera@...rochip.com> > --- > v1 -> v2 > - Adding PTP maintainer > - Given line space between Macro and function. > --- > drivers/net/phy/micrel.c | 408 > ++++++++++++++++++++++++++++++++++++--- > 1 file changed, 384 insertions(+), 24 deletions(-) > Gentle ping. > diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index > 7b8c5c8d013e..91e5bf04f652 100644 > --- a/drivers/net/phy/micrel.c > +++ b/drivers/net/phy/micrel.c > @@ -243,6 +243,50 @@ > #define PS_TO_REG 200 > #define FIFO_SIZE 8 > > +#define LAN8814_GPIO_EN1 0x20 > +#define LAN8814_GPIO_EN2 0x21 > +#define LAN8814_GPIO_DIR1 0x22 > +#define LAN8814_GPIO_DIR2 0x23 > +#define LAN8814_GPIO_BUF1 0x24 > +#define LAN8814_GPIO_BUF2 0x25 > + > +#define LAN8814_GPIO_EN_ADDR(pin) ((pin) > 15 ? > LAN8814_GPIO_EN1 : LAN8814_GPIO_EN2) > +#define LAN8814_GPIO_EN_BIT_(pin) BIT(pin) > +#define LAN8814_GPIO_DIR_ADDR(pin) ((pin) > 15 ? > LAN8814_GPIO_DIR1 : LAN8814_GPIO_DIR2) > +#define LAN8814_GPIO_DIR_BIT_(pin) BIT(pin) > +#define LAN8814_GPIO_BUF_ADDR(pin) ((pin) > 15 ? > LAN8814_GPIO_BUF1 : LAN8814_GPIO_BUF2) > +#define LAN8814_GPIO_BUF_BIT_(pin) BIT(pin) > + > +#define LAN8814_N_GPIO 24 > + > +/* The number of periodic outputs is limited by number of > + * PTP clock event channels > + */ > +#define LAN8814_PTP_N_PEROUT 2 > + > +/* LAN8814_TARGET_BUFF: Seconds difference between LTC and target > register. > + * Should be more than 1 sec. > + */ > +#define LAN8814_TARGET_BUFF 3 > + > +#define LAN8814_PTP_GENERAL_CONFIG 0x0201 > +#define LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_X_MASK_(channel) > \ > + ((channel) ? GENMASK(11, 8) : GENMASK(7, > 4)) > + > +#define LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_X_SET_(channel, > value) \ > + (((value) & 0xF) << (4 + ((channel) << 2))) > +#define LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X_(channel) > ((channel) ? BIT(2) : BIT(0)) > +#define LAN8814_PTP_GENERAL_CONFIG_POLARITY_X_(channel) > ((channel) ? BIT(3) : BIT(1)) > + > +#define LAN8814_PTP_CLOCK_TARGET_SEC_HI_X(channel) > ((channel) ? 0x21F : 0x215) > +#define LAN8814_PTP_CLOCK_TARGET_SEC_LO_X(channel) > ((channel) ? 0x220 : 0x216) > +#define LAN8814_PTP_CLOCK_TARGET_NS_HI_X(channel) > ((channel) ? 0x221 : 0x217) > +#define LAN8814_PTP_CLOCK_TARGET_NS_LO_X(channel) > ((channel) ? 0x222 : 0x218) > +#define LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_HI_X(channel) > ((channel) ? 0x223 : 0x219) > +#define LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_LO_X(channel) > ((channel) ? 0x224 : 0x21A) > +#define LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_HI_X(channel) > ((channel) ? 0x225 : 0x21B) > +#define LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_LO_X(channel) > ((channel) ? 0x226 : 0x21C) > + > struct kszphy_hw_stat { > const char *string; > u8 reg; > @@ -267,13 +311,10 @@ struct lan8814_shared_priv { > struct phy_device *phydev; > struct ptp_clock *ptp_clock; > struct ptp_clock_info ptp_clock_info; > + struct ptp_pin_desc *pin_config; > + s8 gpio_pin; > > - /* Reference counter to how many ports in the package are enabling > the > - * timestamping > - */ > - u8 ref; > - > - /* Lock for ptp_clock and ref */ > + /* Lock for ptp_clock and gpio_pin */ > struct mutex shared_lock; > }; > > @@ -2091,8 +2132,6 @@ static int lan8814_hwtstamp(struct > mii_timestamper *mii_ts, struct ifreq *ifr) { > struct kszphy_ptp_priv *ptp_priv = > container_of(mii_ts, struct kszphy_ptp_priv, > mii_ts); > - struct phy_device *phydev = ptp_priv->phydev; > - struct lan8814_shared_priv *shared = phydev->shared->priv; > struct lan8814_ptp_rx_ts *rx_ts, *tmp; > struct hwtstamp_config config; > int txcfg = 0, rxcfg = 0; > @@ -2155,20 +2194,6 @@ static int lan8814_hwtstamp(struct > mii_timestamper *mii_ts, struct ifreq *ifr) > else > lan8814_config_ts_intr(ptp_priv->phydev, false); > > - mutex_lock(&shared->shared_lock); > - if (config.rx_filter != HWTSTAMP_FILTER_NONE) > - shared->ref++; > - else > - shared->ref--; > - > - if (shared->ref) > - lanphy_write_page_reg(ptp_priv->phydev, 4, > PTP_CMD_CTL, > - PTP_CMD_CTL_PTP_ENABLE_); > - else > - lanphy_write_page_reg(ptp_priv->phydev, 4, > PTP_CMD_CTL, > - PTP_CMD_CTL_PTP_DISABLE_); > - mutex_unlock(&shared->shared_lock); > - > /* In case of multiple starts and stops, these needs to be cleared */ > list_for_each_entry_safe(rx_ts, tmp, &ptp_priv->rx_ts_list, list) { > list_del(&rx_ts->list); > @@ -2325,6 +2350,293 @@ static int lan8814_ptpci_gettime64(struct > ptp_clock_info *ptpci, > return 0; > } > > +static void lan8814_gpio_release(struct lan8814_shared_priv *shared, s8 > +gpio_pin) { > + struct phy_device *phydev = shared->phydev; > + int val; > + > + /* Disable gpio alternate function, 1: select as gpio, 0: select alt func > */ > + val = lanphy_read_page_reg(phydev, 4, > LAN8814_GPIO_EN_ADDR(gpio_pin)); > + val |= LAN8814_GPIO_EN_BIT_(gpio_pin); > + lanphy_write_page_reg(phydev, 4, > LAN8814_GPIO_EN_ADDR(gpio_pin), val); > + > + val = lanphy_read_page_reg(phydev, 4, > LAN8814_GPIO_DIR_ADDR(gpio_pin)); > + val &= ~LAN8814_GPIO_DIR_BIT_(gpio_pin); > + lanphy_write_page_reg(phydev, 4, > LAN8814_GPIO_DIR_ADDR(gpio_pin), > +val); > + > + val = lanphy_read_page_reg(phydev, 4, > LAN8814_GPIO_BUF_ADDR(gpio_pin)); > + val &= ~LAN8814_GPIO_BUF_BIT_(gpio_pin); > + lanphy_write_page_reg(phydev, 4, > LAN8814_GPIO_BUF_ADDR(gpio_pin), > +val); } > + > +static void lan8814_gpio_init(struct lan8814_shared_priv *shared) { > + struct phy_device *phydev = shared->phydev; > + > + lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR1, 0); > + lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR2, 0); > + lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN1, 0); > + > + /* By default disabling alternate function to GPIO 0 and 1 > + * i.e., 1: select as gpio, 0: select alt func > + */ > + lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN2, 0x3); > + lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_BUF1, 0); > + lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_BUF2, 0); } > + > +static void lan8814_gpio_config_ptp_out(struct lan8814_shared_priv > *shared, > + s8 gpio_pin) > +{ > + struct phy_device *phydev = shared->phydev; > + int val; > + > + /* Set as gpio output */ > + val = lanphy_read_page_reg(phydev, 4, > LAN8814_GPIO_DIR_ADDR(gpio_pin)); > + val |= LAN8814_GPIO_DIR_BIT_(gpio_pin); > + lanphy_write_page_reg(phydev, 4, > LAN8814_GPIO_DIR_ADDR(gpio_pin), > +val); > + > + /* Enable gpio 0:for alternate function, 1:gpio */ > + val = lanphy_read_page_reg(phydev, 4, > LAN8814_GPIO_EN_ADDR(gpio_pin)); > + val &= ~LAN8814_GPIO_EN_BIT_(gpio_pin); > + lanphy_write_page_reg(phydev, 4, > LAN8814_GPIO_EN_ADDR(gpio_pin), val); > + > + /* Set buffer type to push pull */ > + val = lanphy_read_page_reg(phydev, 4, > LAN8814_GPIO_BUF_ADDR(gpio_pin)); > + val |= LAN8814_GPIO_BUF_BIT_(gpio_pin); > + lanphy_write_page_reg(phydev, 4, > LAN8814_GPIO_BUF_ADDR(gpio_pin), > +val); } > + > +static void lan8814_set_clock_target(struct phy_device *phydev, s8 > gpio_pin, > + s64 start_sec, u32 start_nsec) { > + if (gpio_pin < 0) > + return; > + > + /* Set the start time */ > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_CLOCK_TARGET_SEC_LO_X(gpio_pin), > + lower_16_bits(start_sec)); > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_CLOCK_TARGET_SEC_HI_X(gpio_pin), > + upper_16_bits(start_sec)); > + > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_CLOCK_TARGET_NS_LO_X(gpio_pin), > + lower_16_bits(start_nsec)); > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_CLOCK_TARGET_NS_HI_X(gpio_pin), > + upper_16_bits(start_nsec) & 0x3fff); } > + > +static void lan8814_set_clock_reload(struct phy_device *phydev, s8 > gpio_pin, > + s64 period_sec, u32 period_nsec) { > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_LO_X(gpio_pin), > + lower_16_bits(period_sec)); > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_HI_X(gpio_pin), > + upper_16_bits(period_sec)); > + > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_LO_X(gpio_pin), > + lower_16_bits(period_nsec)); > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_HI_X(gpio_pin), > + upper_16_bits(period_nsec) & 0x3fff); } > + > +static void lan8814_general_event_config(struct phy_device *phydev, s8 > +gpio_pin, int pulse_width) { > + u16 general_config; > + > + general_config = lanphy_read_page_reg(phydev, 4, > LAN8814_PTP_GENERAL_CONFIG); > + general_config &= > ~(LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_X_MASK_(gpio_pin)); > + general_config |= > LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_X_SET_(gpio_pin, > + > pulse_width); > + general_config &= > ~(LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X_(gpio_pin)); > + general_config |= > LAN8814_PTP_GENERAL_CONFIG_POLARITY_X_(gpio_pin); > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_GENERAL_CONFIG, > +general_config); } > + > +static void lan8814_ptp_perout_off(struct lan8814_shared_priv *shared, > + s8 gpio_pin) > +{ > + struct phy_device *phydev = shared->phydev; > + u16 general_config; > + > + /* Set target to too far in the future, effectively disabling it */ > + lan8814_set_clock_target(phydev, gpio_pin, 0xFFFFFFFF, 0); > + > + general_config = lanphy_read_page_reg(phydev, 4, > LAN8814_PTP_GENERAL_CONFIG); > + general_config |= > LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X_(gpio_pin); > + lanphy_write_page_reg(phydev, 4, > LAN8814_PTP_GENERAL_CONFIG, > +general_config); > + > + lan8814_gpio_release(shared, gpio_pin); } > + > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_200MS_ 13 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_100MS_ 12 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_50MS_ 11 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_10MS_ 10 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_5MS_ 9 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_1MS_ 8 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_500US_ 7 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_100US_ 6 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_50US_ 5 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_10US_ 4 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_5US_ 3 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_1US_ 2 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_500NS_ 1 > +#define LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_100NS_ 0 > + > +static int lan88xx_get_pulsewidth(struct phy_device *phydev, > + struct ptp_perout_request > *perout_request, > + int *pulse_width) > +{ > + struct timespec64 ts_period; > + s64 ts_on_nsec, period_nsec; > + struct timespec64 ts_on; > + > + ts_period.tv_sec = perout_request->period.sec; > + ts_period.tv_nsec = perout_request->period.nsec; > + > + ts_on.tv_sec = perout_request->on.sec; > + ts_on.tv_nsec = perout_request->on.nsec; > + ts_on_nsec = timespec64_to_ns(&ts_on); > + period_nsec = timespec64_to_ns(&ts_period); > + > + if (period_nsec < 200) { > + phydev_warn(phydev, "perout period too small, minimum is > 200ns\n"); > + return -EOPNOTSUPP; > + } > + > + if (ts_on_nsec >= period_nsec) { > + phydev_warn(phydev, "pulse width must be smaller than > period\n"); > + return -EINVAL; > + } > + > + switch (ts_on_nsec) { > + case 200000000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_200MS_; > + break; > + case 100000000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_100MS_; > + break; > + case 50000000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_50MS_; > + break; > + case 10000000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_10MS_; > + break; > + case 5000000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_5MS_; > + break; > + case 1000000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_1MS_; > + break; > + case 500000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_500US_; > + break; > + case 100000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_100US_; > + break; > + case 50000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_50US_; > + break; > + case 10000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_10US_; > + break; > + case 5000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_5US_; > + break; > + case 1000: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_1US_; > + break; > + case 500: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_500NS_; > + break; > + case 100: > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_100NS_; > + break; > + default: > + phydev_warn(phydev, "Using default pulse width of > 100ns\n"); > + *pulse_width = > LAN88XX_PTP_GENERAL_CONFIG_LTC_EVENT_100NS_; > + break; > + } > + return 0; > +} > + > +static int lan8814_ptp_perout(struct lan8814_shared_priv *shared, int on, > + struct ptp_perout_request *perout_request) { > + unsigned int perout_ch = perout_request->index; > + struct phy_device *phydev = shared->phydev; > + int pulse_width; > + int ret; > + > + /* Reject requests with unsupported flags */ > + if (perout_request->flags & ~PTP_PEROUT_DUTY_CYCLE) > + return -EOPNOTSUPP; > + > + mutex_lock(&shared->shared_lock); > + shared->gpio_pin = ptp_find_pin(shared->ptp_clock, > PTP_PF_PEROUT, > + perout_ch); > + if (shared->gpio_pin < 0) { > + mutex_unlock(&shared->shared_lock); > + return -EBUSY; > + } > + > + if (!on) { > + lan8814_ptp_perout_off(shared, shared->gpio_pin); > + shared->gpio_pin = -1; > + mutex_unlock(&shared->shared_lock); > + return 0; > + } > + > + ret = lan88xx_get_pulsewidth(phydev, perout_request, > &pulse_width); > + if (ret < 0) { > + shared->gpio_pin = -1; > + mutex_unlock(&shared->shared_lock); > + return ret; > + } > + > + /* Configure to pulse every period */ > + lan8814_general_event_config(phydev, shared->gpio_pin, > pulse_width); > + lan8814_set_clock_target(phydev, shared->gpio_pin, > perout_request->start.sec, > + perout_request->start.nsec); > + lan8814_set_clock_reload(phydev, shared->gpio_pin, > perout_request->period.sec, > + perout_request->period.nsec); > + lan8814_gpio_config_ptp_out(shared, shared->gpio_pin); > + mutex_unlock(&shared->shared_lock); > + > + return 0; > +} > + > +static int lan8814_ptpci_verify(struct ptp_clock_info *ptp, unsigned int pin, > + enum ptp_pin_function func, unsigned int > chan) { > + if (chan != 0 || (pin != 0 && pin != 1)) > + return -1; > + > + switch (func) { > + case PTP_PF_NONE: > + case PTP_PF_PEROUT: > + break; > + default: > + return -1; > + } > + > + return 0; > +} > + > +static int lan8814_ptpci_enable(struct ptp_clock_info *ptpci, > + struct ptp_clock_request *request, int on) { > + struct lan8814_shared_priv *shared = container_of(ptpci, struct > lan8814_shared_priv, > + ptp_clock_info); > + > + switch (request->type) { > + case PTP_CLK_REQ_PEROUT: > + return lan8814_ptp_perout(shared, on, &request->perout); > + default: > + return -EINVAL; > + } > +} > + > static int lan8814_ptpci_settime64(struct ptp_clock_info *ptpci, > const struct timespec64 *ts) > { > @@ -2333,6 +2645,8 @@ static int lan8814_ptpci_settime64(struct > ptp_clock_info *ptpci, > struct phy_device *phydev = shared->phydev; > > mutex_lock(&shared->shared_lock); > + lan8814_set_clock_target(phydev, shared->gpio_pin, > + ts->tv_sec + LAN8814_TARGET_BUFF, 0); > lan8814_ptp_clock_set(phydev, ts->tv_sec, ts->tv_nsec); > mutex_unlock(&shared->shared_lock); > > @@ -2342,12 +2656,16 @@ static int lan8814_ptpci_settime64(struct > ptp_clock_info *ptpci, static void lan8814_ptp_clock_step(struct phy_device > *phydev, > s64 time_step_ns) > { > + struct lan8814_shared_priv *shared = phydev->shared->priv; > + int gpio_pin = shared->gpio_pin; > u32 nano_seconds_step; > u64 abs_time_step_ns; > u32 unsigned_seconds; > u32 nano_seconds; > u32 remainder; > s32 seconds; > + u32 tar_sec; > + u32 nsec; > > if (time_step_ns > 15000000000LL) { > /* convert to clock set */ > @@ -2359,6 +2677,8 @@ static void lan8814_ptp_clock_step(struct > phy_device *phydev, > unsigned_seconds++; > nano_seconds -= 1000000000; > } > + lan8814_set_clock_target(phydev, gpio_pin, > + unsigned_seconds + > LAN8814_TARGET_BUFF, 0); > lan8814_ptp_clock_set(phydev, unsigned_seconds, > nano_seconds); > return; > } else if (time_step_ns < -15000000000LL) { @@ -2374,6 +2694,8 @@ > static void lan8814_ptp_clock_step(struct phy_device *phydev, > nano_seconds += 1000000000; > } > nano_seconds -= nano_seconds_step; > + lan8814_set_clock_target(phydev, gpio_pin, > + unsigned_seconds + > LAN8814_TARGET_BUFF, 0); > lan8814_ptp_clock_set(phydev, unsigned_seconds, > nano_seconds); > return; > @@ -2428,6 +2750,11 @@ static void lan8814_ptp_clock_step(struct > phy_device *phydev, > PTP_LTC_STEP_ADJ_DIR_ | > adjustment_value_hi); > seconds -= ((s32)adjustment_value); > + > + lan8814_ptp_clock_get(phydev, > &unsigned_seconds, &nsec); > + tar_sec = unsigned_seconds - adjustment_value; > + lan8814_set_clock_target(phydev, gpio_pin, > + tar_sec + > LAN8814_TARGET_BUFF, 0); > } else { > u32 adjustment_value = (u32)(-seconds); > u16 adjustment_value_lo, adjustment_value_hi; > @@ -2443,6 +2770,11 @@ static void lan8814_ptp_clock_step(struct > phy_device *phydev, > lanphy_write_page_reg(phydev, 4, > PTP_LTC_STEP_ADJ_HI, > adjustment_value_hi); > seconds += ((s32)adjustment_value); > + > + lan8814_ptp_clock_get(phydev, > &unsigned_seconds, &nsec); > + tar_sec = unsigned_seconds + adjustment_value; > + lan8814_set_clock_target(phydev, gpio_pin, > + tar_sec + > LAN8814_TARGET_BUFF, 0); > } > lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, > PTP_CMD_CTL_PTP_LTC_STEP_SEC_); > @@ -2783,11 +3115,16 @@ static void lan8814_ptp_init(struct phy_device > *phydev) > ptp_priv->mii_ts.ts_info = lan8814_ts_info; > > phydev->mii_ts = &ptp_priv->mii_ts; > + > + /* Enable ptp to run LTC clock for ptp and gpio 1PPS operation */ > + lanphy_write_page_reg(ptp_priv->phydev, 4, PTP_CMD_CTL, > + PTP_CMD_CTL_PTP_ENABLE_); > } > > static int lan8814_ptp_probe_once(struct phy_device *phydev) { > struct lan8814_shared_priv *shared = phydev->shared->priv; > + int i; > > if (!IS_ENABLED(CONFIG_PTP_1588_CLOCK) || > !IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING)) > @@ -2796,19 +3133,41 @@ static int lan8814_ptp_probe_once(struct > phy_device *phydev) > /* Initialise shared lock for clock*/ > mutex_init(&shared->shared_lock); > > + shared->pin_config = devm_kmalloc_array(&phydev->mdio.dev, > + LAN8814_N_GPIO, > + sizeof(*shared->pin_config), > + GFP_KERNEL); > + if (!shared->pin_config) > + return -ENOMEM; > + > + for (i = 0; i < LAN8814_N_GPIO; i++) { > + struct ptp_pin_desc *ptp_pin = &shared->pin_config[i]; > + > + memset(ptp_pin, 0, sizeof(*ptp_pin)); > + snprintf(ptp_pin->name, > + sizeof(ptp_pin->name), "lan8814_ptp_pin_%02d", i); > + ptp_pin->index = i; > + ptp_pin->func = PTP_PF_NONE; > + } > + > + shared->gpio_pin = -1; > + > shared->ptp_clock_info.owner = THIS_MODULE; > snprintf(shared->ptp_clock_info.name, 30, "%s", phydev->drv- > >name); > shared->ptp_clock_info.max_adj = 31249999; > shared->ptp_clock_info.n_alarm = 0; > shared->ptp_clock_info.n_ext_ts = 0; > - shared->ptp_clock_info.n_pins = 0; > + shared->ptp_clock_info.n_pins = LAN8814_N_GPIO; > shared->ptp_clock_info.pps = 0; > - shared->ptp_clock_info.pin_config = NULL; > + shared->ptp_clock_info.pin_config = shared->pin_config; > + shared->ptp_clock_info.n_per_out = LAN8814_PTP_N_PEROUT; > shared->ptp_clock_info.adjfine = lan8814_ptpci_adjfine; > shared->ptp_clock_info.adjtime = lan8814_ptpci_adjtime; > shared->ptp_clock_info.gettime64 = lan8814_ptpci_gettime64; > shared->ptp_clock_info.settime64 = lan8814_ptpci_settime64; > shared->ptp_clock_info.getcrosststamp = NULL; > + shared->ptp_clock_info.enable = lan8814_ptpci_enable; > + shared->ptp_clock_info.verify = lan8814_ptpci_verify; > > shared->ptp_clock = ptp_clock_register(&shared->ptp_clock_info, > &phydev->mdio.dev); > @@ -2829,6 +3188,7 @@ static int lan8814_ptp_probe_once(struct > phy_device *phydev) > lanphy_write_page_reg(phydev, 4, PTP_OPERATING_MODE, > PTP_OPERATING_MODE_STANDALONE_); > > + lan8814_gpio_init(shared); > return 0; > } > > -- > 2.17.1
Powered by blists - more mailing lists