mediatek: use backported Ethernet PHY driver also for 5.15
Backport in-SoC Gigabit Ethernet PHY driver instead of carrying the driver in files-5.15. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,82 +0,0 @@ | ||||
| From 60ed9eb9605656c19ca402b7bd3f47552e901601 Mon Sep 17 00:00:00 2001 | ||||
| From: Daniel Golle <daniel@makrotopia.org> | ||||
| Date: Mon, 13 Feb 2023 02:33:14 +0000 | ||||
| Subject: [PATCH] net: phy: add driver for MediaTek SoC built-in GE PHYs | ||||
|  | ||||
| Some of MediaTek's Filogic SoCs come with built-in gigabit Ethernet | ||||
| PHYs which require calibration data from the SoC's efuse. | ||||
| Despite the similar design the driver doesn't share any code with the | ||||
| existing mediatek-ge.c, so add support for these PHYs by introducing a | ||||
| new driver for only MediaTek's ARM64 SoCs. | ||||
|  | ||||
| Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||
| --- | ||||
|  MAINTAINERS                       |    9 + | ||||
|  drivers/net/phy/Kconfig           |   12 + | ||||
|  drivers/net/phy/Makefile          |    1 + | ||||
|  drivers/net/phy/mediatek-ge-soc.c | 1263 +++++++++++++++++++++++++++++ | ||||
|  drivers/net/phy/mediatek-ge.c     |    3 +- | ||||
|  5 files changed, 1287 insertions(+), 1 deletion(-) | ||||
|  create mode 100644 drivers/net/phy/mediatek-ge-soc.c | ||||
|  | ||||
| --- a/MAINTAINERS | ||||
| +++ b/MAINTAINERS | ||||
| @@ -11790,6 +11790,15 @@ S:	Maintained | ||||
|  F:	drivers/net/pcs/pcs-mtk-lynxi.c | ||||
|  F:	include/linux/pcs/pcs-mtk-lynxi.h | ||||
|   | ||||
| +MEDIATEK ETHERNET PHY DRIVERS | ||||
| +M:	Daniel Golle <daniel@makrotopia.org> | ||||
| +M:	Qingfang Deng <dqfext@gmail.com> | ||||
| +M:	SkyLake Huang <SkyLake.Huang@mediatek.com> | ||||
| +L:	netdev@vger.kernel.org | ||||
| +S:	Maintained | ||||
| +F:	drivers/net/phy/mediatek-ge-soc.c | ||||
| +F:	drivers/net/phy/mediatek-ge.c | ||||
| + | ||||
|  MEDIATEK I2C CONTROLLER DRIVER | ||||
|  M:	Qii Wang <qii.wang@mediatek.com> | ||||
|  L:	linux-i2c@vger.kernel.org | ||||
| --- a/drivers/net/phy/Kconfig | ||||
| +++ b/drivers/net/phy/Kconfig | ||||
| @@ -293,6 +293,18 @@ config MEDIATEK_GE_PHY | ||||
|  	help | ||||
|  	  Supports the MediaTek Gigabit Ethernet PHYs. | ||||
|   | ||||
| +config MEDIATEK_GE_SOC_PHY | ||||
| +	tristate "MediaTek SoC Ethernet PHYs" | ||||
| +	depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST | ||||
| +	select NVMEM_MTK_EFUSE | ||||
| +	help | ||||
| +	  Supports MediaTek SoC built-in Gigabit Ethernet PHYs. | ||||
| + | ||||
| +	  Include support for built-in Ethernet PHYs which are present in | ||||
| +	  the MT7981 and MT7988 SoCs. These PHYs need calibration data | ||||
| +	  present in the SoCs efuse and will dynamically calibrate VCM | ||||
| +	  (common-mode voltage) during startup. | ||||
| + | ||||
|  config MICREL_PHY | ||||
|  	tristate "Micrel PHYs" | ||||
|  	help | ||||
| --- a/drivers/net/phy/Makefile | ||||
| +++ b/drivers/net/phy/Makefile | ||||
| @@ -81,6 +81,7 @@ obj-$(CONFIG_MARVELL_PHY)	+= marvell.o | ||||
|  obj-$(CONFIG_MARVELL_88X2222_PHY)	+= marvell-88x2222.o | ||||
|  obj-$(CONFIG_MAXLINEAR_GPHY)	+= mxl-gpy.o | ||||
|  obj-$(CONFIG_MEDIATEK_GE_PHY)	+= mediatek-ge.o | ||||
| +obj-$(CONFIG_MEDIATEK_GE_SOC_PHY)	+= mediatek-ge-soc.o | ||||
|  obj-$(CONFIG_MESON_GXL_PHY)	+= meson-gxl.o | ||||
|  obj-$(CONFIG_MICREL_KS8995MA)	+= spi_ks8995.o | ||||
|  obj-$(CONFIG_MICREL_PHY)	+= micrel.o | ||||
| --- a/drivers/net/phy/mediatek-ge.c | ||||
| +++ b/drivers/net/phy/mediatek-ge.c | ||||
| @@ -136,7 +136,8 @@ static struct phy_driver mtk_gephy_drive | ||||
|  module_phy_driver(mtk_gephy_driver); | ||||
|   | ||||
|  static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = { | ||||
| -	{ PHY_ID_MATCH_VENDOR(0x03a29400) }, | ||||
| +	{ PHY_ID_MATCH_EXACT(0x03a29441) }, | ||||
| +	{ PHY_ID_MATCH_EXACT(0x03a29412) }, | ||||
|  	{ } | ||||
|  }; | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,213 @@ | ||||
| From 5d2d78860f98eb5c03bc404eb024606878901ac8 Mon Sep 17 00:00:00 2001 | ||||
| From: Daniel Golle <daniel@makrotopia.org> | ||||
| Date: Tue, 13 Jun 2023 03:27:14 +0100 | ||||
| Subject: [PATCH] net: phy: mediatek-ge-soc: initialize MT7988 PHY LEDs default | ||||
|  state | ||||
|  | ||||
| Initialize LEDs and set sane default values. | ||||
| Read boottrap register and apply LED polarities accordingly to get | ||||
| uniform behavior from all LEDs on MT7988. | ||||
| Requires syscon phandle 'mediatek,pio' present in parenting MDIO bus | ||||
| which should point to the syscon holding the boottrap register. | ||||
|  | ||||
| Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||
| --- | ||||
|  drivers/net/phy/mediatek-ge-soc.c | 144 ++++++++++++++++++++++++++++-- | ||||
|  1 file changed, 136 insertions(+), 8 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/phy/mediatek-ge-soc.c | ||||
| +++ b/drivers/net/phy/mediatek-ge-soc.c | ||||
| @@ -1,11 +1,13 @@ | ||||
|  // SPDX-License-Identifier: GPL-2.0+ | ||||
|  #include <linux/bitfield.h> | ||||
| +#include <linux/mfd/syscon.h> | ||||
|  #include <linux/module.h> | ||||
|  #include <linux/nvmem-consumer.h> | ||||
|  #include <linux/of_address.h> | ||||
|  #include <linux/of_platform.h> | ||||
|  #include <linux/pinctrl/consumer.h> | ||||
|  #include <linux/phy.h> | ||||
| +#include <linux/regmap.h> | ||||
|   | ||||
|  #define MTK_GPHY_ID_MT7981			0x03a29461 | ||||
|  #define MTK_GPHY_ID_MT7988			0x03a29481 | ||||
| @@ -208,9 +210,40 @@ | ||||
|  #define MTK_PHY_DA_TX_R50_PAIR_C		0x53f | ||||
|  #define MTK_PHY_DA_TX_R50_PAIR_D		0x540 | ||||
|   | ||||
| +/* Registers on MDIO_MMD_VEND2 */ | ||||
| +#define MTK_PHY_LED0_ON_CTRL			0x24 | ||||
| +#define MTK_PHY_LED1_ON_CTRL			0x26 | ||||
| +#define   MTK_PHY_LED_ON_MASK			GENMASK(6, 0) | ||||
| +#define   MTK_PHY_LED_ON_LINK1000		BIT(0) | ||||
| +#define   MTK_PHY_LED_ON_LINK100		BIT(1) | ||||
| +#define   MTK_PHY_LED_ON_LINK10			BIT(2) | ||||
| +#define   MTK_PHY_LED_ON_LINKDOWN		BIT(3) | ||||
| +#define   MTK_PHY_LED_ON_FDX			BIT(4) /* Full duplex */ | ||||
| +#define   MTK_PHY_LED_ON_HDX			BIT(5) /* Half duplex */ | ||||
| +#define   MTK_PHY_LED_FORCE_ON			BIT(6) | ||||
| +#define   MTK_PHY_LED_POLARITY			BIT(14) | ||||
| +#define   MTK_PHY_LED_ENABLE			BIT(15) | ||||
| + | ||||
| +#define MTK_PHY_LED0_BLINK_CTRL			0x25 | ||||
| +#define MTK_PHY_LED1_BLINK_CTRL			0x27 | ||||
| +#define   MTK_PHY_LED_1000TX			BIT(0) | ||||
| +#define   MTK_PHY_LED_1000RX			BIT(1) | ||||
| +#define   MTK_PHY_LED_100TX			BIT(2) | ||||
| +#define   MTK_PHY_LED_100RX			BIT(3) | ||||
| +#define   MTK_PHY_LED_10TX			BIT(4) | ||||
| +#define   MTK_PHY_LED_10RX			BIT(5) | ||||
| +#define   MTK_PHY_LED_COLLISION			BIT(6) | ||||
| +#define   MTK_PHY_LED_RX_CRC_ERR		BIT(7) | ||||
| +#define   MTK_PHY_LED_RX_IDLE_ERR		BIT(8) | ||||
| +#define   MTK_PHY_LED_FORCE_BLINK		BIT(9) | ||||
| + | ||||
|  #define MTK_PHY_RG_BG_RASEL			0x115 | ||||
|  #define   MTK_PHY_RG_BG_RASEL_MASK		GENMASK(2, 0) | ||||
|   | ||||
| +/* Register in boottrap syscon defining the initial state of the 4 PHY LEDs */ | ||||
| +#define RG_GPIO_MISC_TPBANK0			0x6f0 | ||||
| +#define   RG_GPIO_MISC_TPBANK0_BOOTMODE		GENMASK(11, 8) | ||||
| + | ||||
|  /* These macro privides efuse parsing for internal phy. */ | ||||
|  #define EFS_DA_TX_I2MPB_A(x)			(((x) >> 0) & GENMASK(5, 0)) | ||||
|  #define EFS_DA_TX_I2MPB_B(x)			(((x) >> 6) & GENMASK(5, 0)) | ||||
| @@ -238,13 +271,6 @@ enum { | ||||
|  	PAIR_D, | ||||
|  }; | ||||
|   | ||||
| -enum { | ||||
| -	GPHY_PORT0, | ||||
| -	GPHY_PORT1, | ||||
| -	GPHY_PORT2, | ||||
| -	GPHY_PORT3, | ||||
| -}; | ||||
| - | ||||
|  enum calibration_mode { | ||||
|  	EFUSE_K, | ||||
|  	SW_K | ||||
| @@ -263,6 +289,10 @@ enum CAL_MODE { | ||||
|  	SW_M | ||||
|  }; | ||||
|   | ||||
| +struct mtk_socphy_shared { | ||||
| +	u32			boottrap; | ||||
| +}; | ||||
| + | ||||
|  static int mtk_socphy_read_page(struct phy_device *phydev) | ||||
|  { | ||||
|  	return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); | ||||
| @@ -1073,6 +1103,104 @@ static int mt798x_phy_config_init(struct | ||||
|  	return mt798x_phy_calibration(phydev); | ||||
|  } | ||||
|   | ||||
| +static int mt798x_phy_setup_led(struct phy_device *phydev, bool inverted) | ||||
| +{ | ||||
| +	struct pinctrl *pinctrl; | ||||
| +	const u16 led_on_ctrl_defaults = MTK_PHY_LED_ENABLE      | | ||||
| +					 MTK_PHY_LED_ON_LINK1000 | | ||||
| +					 MTK_PHY_LED_ON_LINK100  | | ||||
| +					 MTK_PHY_LED_ON_LINK10; | ||||
| +	const u16 led_blink_defaults = MTK_PHY_LED_1000TX | | ||||
| +				       MTK_PHY_LED_1000RX | | ||||
| +				       MTK_PHY_LED_100TX  | | ||||
| +				       MTK_PHY_LED_100RX  | | ||||
| +				       MTK_PHY_LED_10TX   | | ||||
| +				       MTK_PHY_LED_10RX; | ||||
| + | ||||
| +	phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL, | ||||
| +		      led_on_ctrl_defaults ^ | ||||
| +		      (inverted ? MTK_PHY_LED_POLARITY : 0)); | ||||
| + | ||||
| +	phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL, | ||||
| +		      led_on_ctrl_defaults); | ||||
| + | ||||
| +	phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL, | ||||
| +		      led_blink_defaults); | ||||
| + | ||||
| +	phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_BLINK_CTRL, | ||||
| +		      led_blink_defaults); | ||||
| + | ||||
| +	pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); | ||||
| +	if (IS_ERR(pinctrl)) | ||||
| +		dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED\n"); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int mt7988_phy_probe_shared(struct phy_device *phydev) | ||||
| +{ | ||||
| +	struct device_node *np = dev_of_node(&phydev->mdio.bus->dev); | ||||
| +	struct mtk_socphy_shared *priv = phydev->shared->priv; | ||||
| +	struct regmap *regmap; | ||||
| +	u32 reg; | ||||
| +	int ret; | ||||
| + | ||||
| +	/* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B, | ||||
| +	 * LED_C and LED_D respectively. At the same time those pins are used to | ||||
| +	 * bootstrap configuration of the reference clock source (LED_A), | ||||
| +	 * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D). | ||||
| +	 * In practise this is done using a LED and a resistor pulling the pin | ||||
| +	 * either to GND or to VIO. | ||||
| +	 * The detected value at boot time is accessible at run-time using the | ||||
| +	 * TPBANK0 register located in the gpio base of the pinctrl, in order | ||||
| +	 * to read it here it needs to be referenced by a phandle called | ||||
| +	 * 'mediatek,pio' in the MDIO bus hosting the PHY. | ||||
| +	 * The 4 bits in TPBANK0 are kept as package shared data and are used to | ||||
| +	 * set LED polarity for each of the LED0. | ||||
| +	 */ | ||||
| +	regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio"); | ||||
| +	if (IS_ERR(regmap)) | ||||
| +		return PTR_ERR(regmap); | ||||
| + | ||||
| +	ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, ®); | ||||
| +	if (ret) | ||||
| +		return ret; | ||||
| + | ||||
| +	priv->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static bool mt7988_phy_get_boottrap_polarity(struct phy_device *phydev) | ||||
| +{ | ||||
| +	struct mtk_socphy_shared *priv = phydev->shared->priv; | ||||
| + | ||||
| +	if (priv->boottrap & BIT(phydev->mdio.addr)) | ||||
| +		return false; | ||||
| + | ||||
| +	return true; | ||||
| +} | ||||
| + | ||||
| +static int mt7988_phy_probe(struct phy_device *phydev) | ||||
| +{ | ||||
| +	int err; | ||||
| + | ||||
| +	err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0, | ||||
| +				    sizeof(struct mtk_socphy_shared)); | ||||
| +	if (err) | ||||
| +		return err; | ||||
| + | ||||
| +	if (phy_package_probe_once(phydev)) { | ||||
| +		err = mt7988_phy_probe_shared(phydev); | ||||
| +		if (err) | ||||
| +			return err; | ||||
| +	} | ||||
| + | ||||
| +	mt798x_phy_setup_led(phydev, mt7988_phy_get_boottrap_polarity(phydev)); | ||||
| + | ||||
| +	return mt798x_phy_calibration(phydev); | ||||
| +} | ||||
| + | ||||
|  static struct phy_driver mtk_socphy_driver[] = { | ||||
|  	{ | ||||
|  		PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), | ||||
| @@ -1092,7 +1220,7 @@ static struct phy_driver mtk_socphy_driv | ||||
|  		.config_init	= mt798x_phy_config_init, | ||||
|  		.config_intr	= genphy_no_config_intr, | ||||
|  		.handle_interrupt = genphy_handle_interrupt_no_ack, | ||||
| -		.probe		= mt798x_phy_calibration, | ||||
| +		.probe		= mt7988_phy_probe, | ||||
|  		.suspend	= genphy_suspend, | ||||
|  		.resume		= genphy_resume, | ||||
|  		.read_page	= mtk_socphy_read_page, | ||||
		Reference in New Issue
	
	Block a user
	 Daniel Golle
					Daniel Golle