Messages in this thread | | | Subject | Re: [RFC PATCH 2/4] net: phy: Add support for AC200 EPHY | From | Florian Fainelli <> | Date | Thu, 16 Apr 2020 12:18:29 -0700 |
| |
On 4/16/2020 11:57 AM, Jernej Skrabec wrote: > AC200 MFD IC supports Fast Ethernet PHY. Add a driver for it. > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> > --- > drivers/net/phy/Kconfig | 7 ++ > drivers/net/phy/Makefile | 1 + > drivers/net/phy/ac200.c | 206 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 214 insertions(+) > create mode 100644 drivers/net/phy/ac200.c > > diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig > index 3fa33d27eeba..16af69f69eaf 100644 > --- a/drivers/net/phy/Kconfig > +++ b/drivers/net/phy/Kconfig > @@ -288,6 +288,13 @@ config ADIN_PHY > - ADIN1300 - Robust,Industrial, Low Latency 10/100/1000 Gigabit > Ethernet PHY > > +config AC200_PHY > + tristate "AC200 EPHY" > + depends on NVMEM > + depends on OF > + help > + Fast ethernet PHY as found in X-Powers AC200 multi-function device. > + > config AMD_PHY > tristate "AMD PHYs" > ---help--- > diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile > index 2f5c7093a65b..b0c5b91900fa 100644 > --- a/drivers/net/phy/Makefile > +++ b/drivers/net/phy/Makefile > @@ -53,6 +53,7 @@ obj-$(CONFIG_SFP) += sfp.o > sfp-obj-$(CONFIG_SFP) += sfp-bus.o > obj-y += $(sfp-obj-y) $(sfp-obj-m) > > +obj-$(CONFIG_AC200_PHY) += ac200.o > obj-$(CONFIG_ADIN_PHY) += adin.o > obj-$(CONFIG_AMD_PHY) += amd.o > aquantia-objs += aquantia_main.o > diff --git a/drivers/net/phy/ac200.c b/drivers/net/phy/ac200.c > new file mode 100644 > index 000000000000..3d7856ff8f91 > --- /dev/null > +++ b/drivers/net/phy/ac200.c > @@ -0,0 +1,206 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/** > + * Driver for AC200 Ethernet PHY > + * > + * Copyright (c) 2020 Jernej Skrabec <jernej.skrabec@siol.net> > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/mfd/ac200.h> > +#include <linux/nvmem-consumer.h> > +#include <linux/of.h> > +#include <linux/phy.h> > +#include <linux/platform_device.h> > + > +#define AC200_EPHY_ID 0x00441400 > +#define AC200_EPHY_ID_MASK 0x0ffffff0 > + > +/* macros for system ephy control 0 register */ > +#define AC200_EPHY_RESET_INVALID BIT(0) > +#define AC200_EPHY_SYSCLK_GATING BIT(1) > + > +/* macros for system ephy control 1 register */ > +#define AC200_EPHY_E_EPHY_MII_IO_EN BIT(0) > +#define AC200_EPHY_E_LNK_LED_IO_EN BIT(1) > +#define AC200_EPHY_E_SPD_LED_IO_EN BIT(2) > +#define AC200_EPHY_E_DPX_LED_IO_EN BIT(3) > + > +/* macros for ephy control register */ > +#define AC200_EPHY_SHUTDOWN BIT(0) > +#define AC200_EPHY_LED_POL BIT(1) > +#define AC200_EPHY_CLK_SEL BIT(2) > +#define AC200_EPHY_ADDR(x) (((x) & 0x1F) << 4) > +#define AC200_EPHY_XMII_SEL BIT(11) > +#define AC200_EPHY_CALIB(x) (((x) & 0xF) << 12) > + > +struct ac200_ephy_dev { > + struct phy_driver *ephy; > + struct regmap *regmap; > +}; > + > +static char *ac200_phy_name = "AC200 EPHY"; > + > +static int ac200_ephy_config_init(struct phy_device *phydev) > +{ > + const struct ac200_ephy_dev *priv = phydev->drv->driver_data; > + unsigned int value; > + int ret; > + > + phy_write(phydev, 0x1f, 0x0100); /* Switch to Page 1 */
You could define a macro for accessing the page and you may consider implementing .read_page and .write_page and use the phy_read_paged()/phy_write_paged() helper functions.
> + phy_write(phydev, 0x12, 0x4824); /* Disable APS */ > + > + phy_write(phydev, 0x1f, 0x0200); /* Switch to Page 2 */ > + phy_write(phydev, 0x18, 0x0000); /* PHYAFE TRX optimization */ > + > + phy_write(phydev, 0x1f, 0x0600); /* Switch to Page 6 */ > + phy_write(phydev, 0x14, 0x708f); /* PHYAFE TX optimization */ > + phy_write(phydev, 0x13, 0xF000); /* PHYAFE RX optimization */ > + phy_write(phydev, 0x15, 0x1530); > + > + phy_write(phydev, 0x1f, 0x0800); /* Switch to Page 6 */
Seems like the comment does not match the code, that should be Page 8, no?
> + phy_write(phydev, 0x18, 0x00bc); /* PHYAFE TRX optimization */ > + > + phy_write(phydev, 0x1f, 0x0100); /* switch to page 1 */ > + phy_clear_bits(phydev, 0x17, BIT(3)); /* disable intelligent IEEE */
Intelligent EEE maybe? -- Florian
| |