From e6c4287246ee43e2375055304ca468e51c1b83ce Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Mon, 28 Jun 2021 13:04:53 +0800 Subject: [PATCH] Pine A64 LTS v2 support (#2919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove obsolete and broken patch for pine64so u-boot This prevents the image from being built. Signed-off-by: Icenowy Zheng * sunxi: fix pine64so phy-mode and add yt8511 support Pine A64-LTS board should have RGMII-TXID mode instead of RGMII-ID (the Realtek PHY chip's RXID is sometimes broken). In addition, new Pine A64-LTS v2 board will use YT8511 instead of RTL8211E, which still works under RGMII-TXID mode. Backport YT8511 driver and phy-mode change from linux-next. Signed-off-by: Icenowy Zheng Co-authored-by: Igor Pečovnik --- config/kernel/linux-sunxi64-current.config | 1 + config/kernel/linux-sunxi64-edge.config | 1 + config/kernel/linux-sunxi64-legacy.config | 3 +- .../board-pine64so-rgmii-txid.patch | 39 ++ .../sunxi-5.10/yt8511-phy-support.patch | 319 ++++++++++++++++ .../board-pine64so-rgmii-txid.patch | 39 ++ .../sunxi-5.12/yt8511-phy-support.patch | 319 ++++++++++++++++ .../board-pine-a64-lts-apply-rgmii-txid.patch | 44 +++ .../sunxi-5.4/yt8511-phy-support.patch | 321 ++++++++++++++++ .../fix-sopine-spi-clusterboad.patch | 343 ------------------ 10 files changed, 1085 insertions(+), 344 deletions(-) create mode 100644 patch/kernel/archive/sunxi-5.10/board-pine64so-rgmii-txid.patch create mode 100644 patch/kernel/archive/sunxi-5.10/yt8511-phy-support.patch create mode 100644 patch/kernel/archive/sunxi-5.12/board-pine64so-rgmii-txid.patch create mode 100644 patch/kernel/archive/sunxi-5.12/yt8511-phy-support.patch create mode 100644 patch/kernel/archive/sunxi-5.4/board-pine-a64-lts-apply-rgmii-txid.patch create mode 100644 patch/kernel/archive/sunxi-5.4/yt8511-phy-support.patch delete mode 100644 patch/u-boot/u-boot-sunxi/board_pine64so/fix-sopine-spi-clusterboad.patch diff --git a/config/kernel/linux-sunxi64-current.config b/config/kernel/linux-sunxi64-current.config index 53b9112a6d..ddb89af076 100644 --- a/config/kernel/linux-sunxi64-current.config +++ b/config/kernel/linux-sunxi64-current.config @@ -2392,6 +2392,7 @@ CONFIG_MICREL_PHY=m CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m # CONFIG_MICROSEMI_PHY is not set +CONFIG_MOTORCOMM_PHY=m CONFIG_NATIONAL_PHY=m # CONFIG_NXP_TJA11XX_PHY is not set CONFIG_AT803X_PHY=m diff --git a/config/kernel/linux-sunxi64-edge.config b/config/kernel/linux-sunxi64-edge.config index 7ab8e156ef..cfa4932052 100644 --- a/config/kernel/linux-sunxi64-edge.config +++ b/config/kernel/linux-sunxi64-edge.config @@ -2422,6 +2422,7 @@ CONFIG_MICREL_PHY=m CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m # CONFIG_MICROSEMI_PHY is not set +CONFIG_MOTORCOMM_PHY=m CONFIG_NATIONAL_PHY=m # CONFIG_NXP_TJA11XX_PHY is not set CONFIG_AT803X_PHY=m diff --git a/config/kernel/linux-sunxi64-legacy.config b/config/kernel/linux-sunxi64-legacy.config index fa28a0a9ff..ec7994da66 100644 --- a/config/kernel/linux-sunxi64-legacy.config +++ b/config/kernel/linux-sunxi64-legacy.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.4.85 Kernel Configuration +# Linux/arm64 5.4.88 Kernel Configuration # # @@ -2463,6 +2463,7 @@ CONFIG_MICREL_PHY=y CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m # CONFIG_MICROSEMI_PHY is not set +CONFIG_MOTORCOMM_PHY=m CONFIG_NATIONAL_PHY=m # CONFIG_NXP_TJA11XX_PHY is not set CONFIG_QSEMI_PHY=m diff --git a/patch/kernel/archive/sunxi-5.10/board-pine64so-rgmii-txid.patch b/patch/kernel/archive/sunxi-5.10/board-pine64so-rgmii-txid.patch new file mode 100644 index 0000000000..2a30e2b8a1 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/board-pine64so-rgmii-txid.patch @@ -0,0 +1,39 @@ +From 0745b77825cdc10eb5381f75056d1a37fbb533ba Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Wed, 9 Jun 2021 12:45:25 +0800 +Subject: [PATCH 4/4] arm64: dts: allwinner: a64-sopine-baseboard: change RGMII + mode to TXID + +Although the schematics of Pine A64-LTS and SoPine Baseboard shows both +the RX and TX internal delay are enabled, they're using the same broken +RTL8211E chip batch with Pine A64+, so they should use TXID instead, not +ID. + +In addition, by checking the real components soldered on both a SoPine +Baseboard and a Pine A64-LTS, RX delay is not enabled (GR69 soldered and +GR70 NC) despite the schematics says it's enabled. + +So the RGMII delay mode should be TXID on these boards. + +Fixes: c2b111e59a7b ("arm64: dts: allwinner: A64 Sopine: phy-mode rgmii-id") +Signed-off-by: Icenowy Zheng +--- + arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +index d4069749d721..068cbd955bfc 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +@@ -79,7 +79,7 @@ &ehci1 { + &emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; +- phy-mode = "rgmii-id"; ++ phy-mode = "rgmii-txid"; + phy-handle = <&ext_rgmii_phy>; + phy-supply = <®_dc1sw>; + status = "okay"; +-- +2.30.2 + diff --git a/patch/kernel/archive/sunxi-5.10/yt8511-phy-support.patch b/patch/kernel/archive/sunxi-5.10/yt8511-phy-support.patch new file mode 100644 index 0000000000..4175ef541b --- /dev/null +++ b/patch/kernel/archive/sunxi-5.10/yt8511-phy-support.patch @@ -0,0 +1,319 @@ +From 2c931ae9788444a8994928366c18d540c9a760eb Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Thu, 20 May 2021 12:32:30 -0400 +Subject: [PATCH 1/4] net: phy: add driver for Motorcomm yt8511 phy + +Add a driver for the Motorcomm yt8511 phy that will be used in the +production Pine64 rk3566-quartz64 development board. +It supports gigabit transfer speeds, rgmii, and 125mhz clk output. + +Signed-off-by: Peter Geis +Signed-off-by: David S. Miller +--- + MAINTAINERS | 6 ++ + drivers/net/phy/Kconfig | 6 ++ + drivers/net/phy/Makefile | 1 + + drivers/net/phy/motorcomm.c | 136 ++++++++++++++++++++++++++++++++++++ + 4 files changed, 149 insertions(+) + create mode 100644 drivers/net/phy/motorcomm.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 4fef10dd2975..0d1d0845da3b 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -11812,6 +11812,12 @@ F: Documentation/userspace-api/media/drivers/meye* + F: drivers/media/pci/meye/ + F: include/uapi/linux/meye.h + ++MOTORCOMM PHY DRIVER ++M: Peter Geis ++L: netdev@vger.kernel.org ++S: Maintained ++F: drivers/net/phy/motorcomm.c ++ + MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD + M: Jiri Slaby + S: Maintained +diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig +index 698bea312adc..940f2d701f86 100644 +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -223,6 +223,12 @@ config MICROSEMI_PHY + help + Currently supports VSC8514, VSC8530, VSC8531, VSC8540 and VSC8541 PHYs + ++config MOTORCOMM_PHY ++ tristate "Motorcomm PHYs" ++ help ++ Enables support for Motorcomm network PHYs. ++ Currently supports the YT8511 gigabit PHY. ++ + config NATIONAL_PHY + tristate "National Semiconductor PHYs" + help +diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile +index a13e402074cf..5b9b714b8dbd 100644 +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -69,6 +69,7 @@ obj-$(CONFIG_MICREL_PHY) += micrel.o + obj-$(CONFIG_MICROCHIP_PHY) += microchip.o + obj-$(CONFIG_MICROCHIP_T1_PHY) += microchip_t1.o + obj-$(CONFIG_MICROSEMI_PHY) += mscc/ ++obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm.o + obj-$(CONFIG_NATIONAL_PHY) += national.o + obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o + obj-$(CONFIG_QSEMI_PHY) += qsemi.o +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +new file mode 100644 +index 000000000000..796b68f4b499 +--- /dev/null ++++ b/drivers/net/phy/motorcomm.c +@@ -0,0 +1,136 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for Motorcomm PHYs ++ * ++ * Author: Peter Geis ++ */ ++ ++#include ++#include ++#include ++ ++#define PHY_ID_YT8511 0x0000010a ++ ++#define YT8511_PAGE_SELECT 0x1e ++#define YT8511_PAGE 0x1f ++#define YT8511_EXT_CLK_GATE 0x0c ++#define YT8511_EXT_DELAY_DRIVE 0x0d ++#define YT8511_EXT_SLEEP_CTRL 0x27 ++ ++/* 2b00 25m from pll ++ * 2b01 25m from xtl *default* ++ * 2b10 62.m from pll ++ * 2b11 125m from pll ++ */ ++#define YT8511_CLK_125M (BIT(2) | BIT(1)) ++#define YT8511_PLLON_SLP BIT(14) ++ ++/* RX Delay enabled = 1.8ns 1000T, 8ns 10/100T */ ++#define YT8511_DELAY_RX BIT(0) ++ ++/* TX Gig-E Delay is bits 7:4, default 0x5 ++ * TX Fast-E Delay is bits 15:12, default 0xf ++ * Delay = 150ps * N - 250ps ++ * On = 2000ps, off = 50ps ++ */ ++#define YT8511_DELAY_GE_TX_EN (0xf << 4) ++#define YT8511_DELAY_GE_TX_DIS (0x2 << 4) ++#define YT8511_DELAY_FE_TX_EN (0xf << 12) ++#define YT8511_DELAY_FE_TX_DIS (0x2 << 12) ++ ++static int yt8511_read_page(struct phy_device *phydev) ++{ ++ return __phy_read(phydev, YT8511_PAGE_SELECT); ++}; ++ ++static int yt8511_write_page(struct phy_device *phydev, int page) ++{ ++ return __phy_write(phydev, YT8511_PAGE_SELECT, page); ++}; ++ ++static int yt8511_config_init(struct phy_device *phydev) ++{ ++ unsigned int ge, fe; ++ int ret, oldpage; ++ ++ /* set clock mode to 125mhz */ ++ oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); ++ if (oldpage < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* set rgmii delay mode */ ++ switch (phydev->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ ge = YT8511_DELAY_GE_TX_DIS; ++ fe = YT8511_DELAY_FE_TX_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_DIS; ++ fe = YT8511_DELAY_FE_TX_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ ge = YT8511_DELAY_GE_TX_EN; ++ fe = YT8511_DELAY_FE_TX_EN; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN; ++ fe = YT8511_DELAY_FE_TX_EN; ++ break; ++ default: /* leave everything alone in other modes */ ++ break; ++ } ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* fast ethernet delay is in a separate page */ ++ ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_DELAY_DRIVE); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, YT8511_DELAY_FE_TX_EN, fe); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* leave pll enabled in sleep */ ++ ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_SLEEP_CTRL); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_PLLON_SLP); ++ if (ret < 0) ++ goto err_restore_page; ++ ++err_restore_page: ++ return phy_restore_page(phydev, oldpage, ret); ++} ++ ++static struct phy_driver motorcomm_phy_drvs[] = { ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8511), ++ .name = "YT8511 Gigabit Ethernet", ++ .config_init = yt8511_config_init, ++ .suspend = genphy_suspend, ++ .resume = genphy_resume, ++ .read_page = yt8511_read_page, ++ .write_page = yt8511_write_page, ++ }, ++}; ++ ++module_phy_driver(motorcomm_phy_drvs); ++ ++MODULE_DESCRIPTION("Motorcomm PHY driver"); ++MODULE_AUTHOR("Peter Geis"); ++MODULE_LICENSE("GPL"); ++ ++static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { ++ { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, ++ { /* sentinal */ } ++}; ++ ++MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); +-- +2.30.2 + +From 5e464ac4cd49603515a053b7292597bfd0e9672c Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 29 May 2021 07:05:55 -0400 +Subject: [PATCH 2/4] net: phy: fix yt8511 clang uninitialized variable warning + +clang doesn't preinitialize variables. If phy_select_page failed and +returned an error, phy_restore_page would be called with `ret` being +uninitialized. +Even though phy_restore_page won't use `ret` in this scenario, +initialize `ret` to silence the warning. + +Fixes: 48e8c6f1612b ("net: phy: add driver for Motorcomm yt8511 phy") +Reported-by: kernel test robot +Reviewed-by: Andrew Lunn +Signed-off-by: Peter Geis +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/motorcomm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +index 796b68f4b499..68cd19540c67 100644 +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -50,8 +50,8 @@ static int yt8511_write_page(struct phy_device *phydev, int page) + + static int yt8511_config_init(struct phy_device *phydev) + { ++ int oldpage, ret = 0; + unsigned int ge, fe; +- int ret, oldpage; + + /* set clock mode to 125mhz */ + oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); +-- +2.30.2 + +From a085ebd8f84bb556116ab41961c4fa671dc84fba Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 29 May 2021 07:05:56 -0400 +Subject: [PATCH 3/4] net: phy: abort loading yt8511 driver in unsupported + modes + +While investigating the clang `ge` uninitialized variable report, it was +discovered the default switch would have unintended consequences. Due to +the switch to __phy_modify, the driver would modify the ID values in the +default scenario. + +Fix this by promoting the interface mode switch and aborting when the +mode is not a supported RGMII mode. + +This prevents the `ge` and `fe` variables from ever being used +uninitialized. + +Fixes: 48e8c6f1612b ("net: phy: add driver for Motorcomm yt8511 phy") +Reported-by: kernel test robot +Reviewed-by: Andrew Lunn +Signed-off-by: Peter Geis +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/motorcomm.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +index 68cd19540c67..7e6ac2c5e27e 100644 +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -53,15 +53,10 @@ static int yt8511_config_init(struct phy_device *phydev) + int oldpage, ret = 0; + unsigned int ge, fe; + +- /* set clock mode to 125mhz */ + oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); + if (oldpage < 0) + goto err_restore_page; + +- ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); +- if (ret < 0) +- goto err_restore_page; +- + /* set rgmii delay mode */ + switch (phydev->interface) { + case PHY_INTERFACE_MODE_RGMII: +@@ -80,14 +75,20 @@ static int yt8511_config_init(struct phy_device *phydev) + ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN; + fe = YT8511_DELAY_FE_TX_EN; + break; +- default: /* leave everything alone in other modes */ +- break; ++ default: /* do not support other modes */ ++ ret = -EOPNOTSUPP; ++ goto err_restore_page; + } + + ret = __phy_modify(phydev, YT8511_PAGE, (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge); + if (ret < 0) + goto err_restore_page; + ++ /* set clock mode to 125mhz */ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); ++ if (ret < 0) ++ goto err_restore_page; ++ + /* fast ethernet delay is in a separate page */ + ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_DELAY_DRIVE); + if (ret < 0) +-- +2.30.2 + diff --git a/patch/kernel/archive/sunxi-5.12/board-pine64so-rgmii-txid.patch b/patch/kernel/archive/sunxi-5.12/board-pine64so-rgmii-txid.patch new file mode 100644 index 0000000000..1d17f4a207 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.12/board-pine64so-rgmii-txid.patch @@ -0,0 +1,39 @@ +From 354d29be4a37055df567f1eb933e19a11e0ef88b Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Wed, 9 Jun 2021 12:45:25 +0800 +Subject: [PATCH 4/4] arm64: dts: allwinner: a64-sopine-baseboard: change RGMII + mode to TXID + +Although the schematics of Pine A64-LTS and SoPine Baseboard shows both +the RX and TX internal delay are enabled, they're using the same broken +RTL8211E chip batch with Pine A64+, so they should use TXID instead, not +ID. + +In addition, by checking the real components soldered on both a SoPine +Baseboard and a Pine A64-LTS, RX delay is not enabled (GR69 soldered and +GR70 NC) despite the schematics says it's enabled. + +So the RGMII delay mode should be TXID on these boards. + +Fixes: c2b111e59a7b ("arm64: dts: allwinner: A64 Sopine: phy-mode rgmii-id") +Signed-off-by: Icenowy Zheng +--- + arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +index e22b94c83647..5e66ce1a334f 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +@@ -79,7 +79,7 @@ &ehci1 { + &emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; +- phy-mode = "rgmii-id"; ++ phy-mode = "rgmii-txid"; + phy-handle = <&ext_rgmii_phy>; + phy-supply = <®_dc1sw>; + status = "okay"; +-- +2.30.2 + diff --git a/patch/kernel/archive/sunxi-5.12/yt8511-phy-support.patch b/patch/kernel/archive/sunxi-5.12/yt8511-phy-support.patch new file mode 100644 index 0000000000..87266927f8 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.12/yt8511-phy-support.patch @@ -0,0 +1,319 @@ +From 4ed95d5b19ded99909ce63d1c2740da60f7abd04 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Thu, 20 May 2021 12:32:30 -0400 +Subject: [PATCH 1/4] net: phy: add driver for Motorcomm yt8511 phy + +Add a driver for the Motorcomm yt8511 phy that will be used in the +production Pine64 rk3566-quartz64 development board. +It supports gigabit transfer speeds, rgmii, and 125mhz clk output. + +Signed-off-by: Peter Geis +Signed-off-by: David S. Miller +--- + MAINTAINERS | 6 ++ + drivers/net/phy/Kconfig | 6 ++ + drivers/net/phy/Makefile | 1 + + drivers/net/phy/motorcomm.c | 136 ++++++++++++++++++++++++++++++++++++ + 4 files changed, 149 insertions(+) + create mode 100644 drivers/net/phy/motorcomm.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 9450e052f1b1..0f71a9983263 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -12094,6 +12094,12 @@ F: Documentation/userspace-api/media/drivers/meye* + F: drivers/media/pci/meye/ + F: include/uapi/linux/meye.h + ++MOTORCOMM PHY DRIVER ++M: Peter Geis ++L: netdev@vger.kernel.org ++S: Maintained ++F: drivers/net/phy/motorcomm.c ++ + MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD + M: Jiri Slaby + S: Maintained +diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig +index 698bea312adc..940f2d701f86 100644 +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -223,6 +223,12 @@ config MICROSEMI_PHY + help + Currently supports VSC8514, VSC8530, VSC8531, VSC8540 and VSC8541 PHYs + ++config MOTORCOMM_PHY ++ tristate "Motorcomm PHYs" ++ help ++ Enables support for Motorcomm network PHYs. ++ Currently supports the YT8511 gigabit PHY. ++ + config NATIONAL_PHY + tristate "National Semiconductor PHYs" + help +diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile +index a13e402074cf..5b9b714b8dbd 100644 +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -69,6 +69,7 @@ obj-$(CONFIG_MICREL_PHY) += micrel.o + obj-$(CONFIG_MICROCHIP_PHY) += microchip.o + obj-$(CONFIG_MICROCHIP_T1_PHY) += microchip_t1.o + obj-$(CONFIG_MICROSEMI_PHY) += mscc/ ++obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm.o + obj-$(CONFIG_NATIONAL_PHY) += national.o + obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o + obj-$(CONFIG_QSEMI_PHY) += qsemi.o +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +new file mode 100644 +index 000000000000..796b68f4b499 +--- /dev/null ++++ b/drivers/net/phy/motorcomm.c +@@ -0,0 +1,136 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for Motorcomm PHYs ++ * ++ * Author: Peter Geis ++ */ ++ ++#include ++#include ++#include ++ ++#define PHY_ID_YT8511 0x0000010a ++ ++#define YT8511_PAGE_SELECT 0x1e ++#define YT8511_PAGE 0x1f ++#define YT8511_EXT_CLK_GATE 0x0c ++#define YT8511_EXT_DELAY_DRIVE 0x0d ++#define YT8511_EXT_SLEEP_CTRL 0x27 ++ ++/* 2b00 25m from pll ++ * 2b01 25m from xtl *default* ++ * 2b10 62.m from pll ++ * 2b11 125m from pll ++ */ ++#define YT8511_CLK_125M (BIT(2) | BIT(1)) ++#define YT8511_PLLON_SLP BIT(14) ++ ++/* RX Delay enabled = 1.8ns 1000T, 8ns 10/100T */ ++#define YT8511_DELAY_RX BIT(0) ++ ++/* TX Gig-E Delay is bits 7:4, default 0x5 ++ * TX Fast-E Delay is bits 15:12, default 0xf ++ * Delay = 150ps * N - 250ps ++ * On = 2000ps, off = 50ps ++ */ ++#define YT8511_DELAY_GE_TX_EN (0xf << 4) ++#define YT8511_DELAY_GE_TX_DIS (0x2 << 4) ++#define YT8511_DELAY_FE_TX_EN (0xf << 12) ++#define YT8511_DELAY_FE_TX_DIS (0x2 << 12) ++ ++static int yt8511_read_page(struct phy_device *phydev) ++{ ++ return __phy_read(phydev, YT8511_PAGE_SELECT); ++}; ++ ++static int yt8511_write_page(struct phy_device *phydev, int page) ++{ ++ return __phy_write(phydev, YT8511_PAGE_SELECT, page); ++}; ++ ++static int yt8511_config_init(struct phy_device *phydev) ++{ ++ unsigned int ge, fe; ++ int ret, oldpage; ++ ++ /* set clock mode to 125mhz */ ++ oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); ++ if (oldpage < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* set rgmii delay mode */ ++ switch (phydev->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ ge = YT8511_DELAY_GE_TX_DIS; ++ fe = YT8511_DELAY_FE_TX_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_DIS; ++ fe = YT8511_DELAY_FE_TX_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ ge = YT8511_DELAY_GE_TX_EN; ++ fe = YT8511_DELAY_FE_TX_EN; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN; ++ fe = YT8511_DELAY_FE_TX_EN; ++ break; ++ default: /* leave everything alone in other modes */ ++ break; ++ } ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* fast ethernet delay is in a separate page */ ++ ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_DELAY_DRIVE); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, YT8511_DELAY_FE_TX_EN, fe); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* leave pll enabled in sleep */ ++ ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_SLEEP_CTRL); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_PLLON_SLP); ++ if (ret < 0) ++ goto err_restore_page; ++ ++err_restore_page: ++ return phy_restore_page(phydev, oldpage, ret); ++} ++ ++static struct phy_driver motorcomm_phy_drvs[] = { ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8511), ++ .name = "YT8511 Gigabit Ethernet", ++ .config_init = yt8511_config_init, ++ .suspend = genphy_suspend, ++ .resume = genphy_resume, ++ .read_page = yt8511_read_page, ++ .write_page = yt8511_write_page, ++ }, ++}; ++ ++module_phy_driver(motorcomm_phy_drvs); ++ ++MODULE_DESCRIPTION("Motorcomm PHY driver"); ++MODULE_AUTHOR("Peter Geis"); ++MODULE_LICENSE("GPL"); ++ ++static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { ++ { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, ++ { /* sentinal */ } ++}; ++ ++MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); +-- +2.30.2 + +From 7828b6d9f8764ea28ea9c4326add1565299bb2e5 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 29 May 2021 07:05:55 -0400 +Subject: [PATCH 2/4] net: phy: fix yt8511 clang uninitialized variable warning + +clang doesn't preinitialize variables. If phy_select_page failed and +returned an error, phy_restore_page would be called with `ret` being +uninitialized. +Even though phy_restore_page won't use `ret` in this scenario, +initialize `ret` to silence the warning. + +Fixes: 48e8c6f1612b ("net: phy: add driver for Motorcomm yt8511 phy") +Reported-by: kernel test robot +Reviewed-by: Andrew Lunn +Signed-off-by: Peter Geis +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/motorcomm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +index 796b68f4b499..68cd19540c67 100644 +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -50,8 +50,8 @@ static int yt8511_write_page(struct phy_device *phydev, int page) + + static int yt8511_config_init(struct phy_device *phydev) + { ++ int oldpage, ret = 0; + unsigned int ge, fe; +- int ret, oldpage; + + /* set clock mode to 125mhz */ + oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); +-- +2.30.2 + +From a33cfaee53ac7e671632f2511192ec6bb2b60b4c Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 29 May 2021 07:05:56 -0400 +Subject: [PATCH 3/4] net: phy: abort loading yt8511 driver in unsupported + modes + +While investigating the clang `ge` uninitialized variable report, it was +discovered the default switch would have unintended consequences. Due to +the switch to __phy_modify, the driver would modify the ID values in the +default scenario. + +Fix this by promoting the interface mode switch and aborting when the +mode is not a supported RGMII mode. + +This prevents the `ge` and `fe` variables from ever being used +uninitialized. + +Fixes: 48e8c6f1612b ("net: phy: add driver for Motorcomm yt8511 phy") +Reported-by: kernel test robot +Reviewed-by: Andrew Lunn +Signed-off-by: Peter Geis +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/motorcomm.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +index 68cd19540c67..7e6ac2c5e27e 100644 +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -53,15 +53,10 @@ static int yt8511_config_init(struct phy_device *phydev) + int oldpage, ret = 0; + unsigned int ge, fe; + +- /* set clock mode to 125mhz */ + oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); + if (oldpage < 0) + goto err_restore_page; + +- ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); +- if (ret < 0) +- goto err_restore_page; +- + /* set rgmii delay mode */ + switch (phydev->interface) { + case PHY_INTERFACE_MODE_RGMII: +@@ -80,14 +75,20 @@ static int yt8511_config_init(struct phy_device *phydev) + ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN; + fe = YT8511_DELAY_FE_TX_EN; + break; +- default: /* leave everything alone in other modes */ +- break; ++ default: /* do not support other modes */ ++ ret = -EOPNOTSUPP; ++ goto err_restore_page; + } + + ret = __phy_modify(phydev, YT8511_PAGE, (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge); + if (ret < 0) + goto err_restore_page; + ++ /* set clock mode to 125mhz */ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); ++ if (ret < 0) ++ goto err_restore_page; ++ + /* fast ethernet delay is in a separate page */ + ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_DELAY_DRIVE); + if (ret < 0) +-- +2.30.2 + diff --git a/patch/kernel/archive/sunxi-5.4/board-pine-a64-lts-apply-rgmii-txid.patch b/patch/kernel/archive/sunxi-5.4/board-pine-a64-lts-apply-rgmii-txid.patch new file mode 100644 index 0000000000..f87f7ee459 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.4/board-pine-a64-lts-apply-rgmii-txid.patch @@ -0,0 +1,44 @@ +From 5aa33a6b5581ad1227b8093b18e2c5bf531e11ed Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Wed, 9 Jun 2021 16:38:43 +0800 +Subject: [PATCH 4/4] arm64: dts: allwinner: a64-sopine-baseboard: change RGMII + mode to TXID + +Although the schematics of Pine A64-LTS and SoPine Baseboard shows both +the RX and TX internal delay are enabled, they're using the same broken +RTL8211E chip batch with Pine A64+, so they should use TXID instead, not +ID. + +In addition, by checking the real components soldered on both a SoPine +Baseboard and a Pine A64-LTS, RX delay is not enabled (GR69 soldered and +GR70 NC) despite the schematics says it's enabled. It's a common +situation for Pine64 boards that the NC information on schematics is not +the same with the board. + +So the RGMII delay mode should be TXID on these boards. + +Fixes: c2b111e59a7b ("arm64: dts: allwinner: A64 Sopine: phy-mode rgmii-id") +Signed-off-by: Icenowy Zheng +Signed-off-by: Maxime Ripard +Link: https://lore.kernel.org/r/20210609083843.463750-1-icenowy@aosc.io +Signed-off-by: Icenowy Zheng +--- + arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +index 25099202c52c..170bb19d894e 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +@@ -115,7 +115,7 @@ + &emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; +- phy-mode = "rgmii"; ++ phy-mode = "rgmii-txid"; + phy-handle = <&ext_rgmii_phy>; + phy-supply = <®_dc1sw>; + status = "okay"; +-- +2.30.2 + diff --git a/patch/kernel/archive/sunxi-5.4/yt8511-phy-support.patch b/patch/kernel/archive/sunxi-5.4/yt8511-phy-support.patch new file mode 100644 index 0000000000..c93a4c3594 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.4/yt8511-phy-support.patch @@ -0,0 +1,321 @@ +From ec565edb5e9216aee89412be327d59f038582df4 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Thu, 20 May 2021 12:32:30 -0400 +Subject: [PATCH 1/4] net: phy: add driver for Motorcomm yt8511 phy + +Add a driver for the Motorcomm yt8511 phy that will be used in the +production Pine64 rk3566-quartz64 development board. +It supports gigabit transfer speeds, rgmii, and 125mhz clk output. + +Signed-off-by: Peter Geis +Signed-off-by: David S. Miller +[Icenowy: backport to 5.4] +Signed-off-by: Icenowy Zheng +--- + MAINTAINERS | 6 ++ + drivers/net/phy/Kconfig | 6 ++ + drivers/net/phy/Makefile | 1 + + drivers/net/phy/motorcomm.c | 136 ++++++++++++++++++++++++++++++++++++ + 4 files changed, 149 insertions(+) + create mode 100644 drivers/net/phy/motorcomm.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 1407008df749..fd8518bc5ba8 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -10966,6 +10966,12 @@ F: Documentation/media/v4l-drivers/meye* + F: drivers/media/pci/meye/ + F: include/uapi/linux/meye.h + ++MOTORCOMM PHY DRIVER ++M: Peter Geis ++L: netdev@vger.kernel.org ++S: Maintained ++F: drivers/net/phy/motorcomm.c ++ + MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD + M: Jiri Slaby + S: Maintained +diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig +index dcf2051ef2c0..a9c66f28c0ce 100644 +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -434,6 +434,12 @@ config MICROSEMI_PHY + ---help--- + Currently supports VSC8514, VSC8530, VSC8531, VSC8540 and VSC8541 PHYs + ++config MOTORCOMM_PHY ++ tristate "Motorcomm PHYs" ++ help ++ Enables support for Motorcomm network PHYs. ++ Currently supports the YT8511 gigabit PHY. ++ + config NATIONAL_PHY + tristate "National Semiconductor PHYs" + ---help--- +diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile +index a03437e091f3..a3933c83fbdc 100644 +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -83,6 +83,7 @@ obj-$(CONFIG_MICREL_PHY) += micrel.o + obj-$(CONFIG_MICROCHIP_PHY) += microchip.o + obj-$(CONFIG_MICROCHIP_T1_PHY) += microchip_t1.o + obj-$(CONFIG_MICROSEMI_PHY) += mscc.o ++obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm.o + obj-$(CONFIG_NATIONAL_PHY) += national.o + obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o + obj-$(CONFIG_QSEMI_PHY) += qsemi.o +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +new file mode 100644 +index 000000000000..796b68f4b499 +--- /dev/null ++++ b/drivers/net/phy/motorcomm.c +@@ -0,0 +1,136 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Driver for Motorcomm PHYs ++ * ++ * Author: Peter Geis ++ */ ++ ++#include ++#include ++#include ++ ++#define PHY_ID_YT8511 0x0000010a ++ ++#define YT8511_PAGE_SELECT 0x1e ++#define YT8511_PAGE 0x1f ++#define YT8511_EXT_CLK_GATE 0x0c ++#define YT8511_EXT_DELAY_DRIVE 0x0d ++#define YT8511_EXT_SLEEP_CTRL 0x27 ++ ++/* 2b00 25m from pll ++ * 2b01 25m from xtl *default* ++ * 2b10 62.m from pll ++ * 2b11 125m from pll ++ */ ++#define YT8511_CLK_125M (BIT(2) | BIT(1)) ++#define YT8511_PLLON_SLP BIT(14) ++ ++/* RX Delay enabled = 1.8ns 1000T, 8ns 10/100T */ ++#define YT8511_DELAY_RX BIT(0) ++ ++/* TX Gig-E Delay is bits 7:4, default 0x5 ++ * TX Fast-E Delay is bits 15:12, default 0xf ++ * Delay = 150ps * N - 250ps ++ * On = 2000ps, off = 50ps ++ */ ++#define YT8511_DELAY_GE_TX_EN (0xf << 4) ++#define YT8511_DELAY_GE_TX_DIS (0x2 << 4) ++#define YT8511_DELAY_FE_TX_EN (0xf << 12) ++#define YT8511_DELAY_FE_TX_DIS (0x2 << 12) ++ ++static int yt8511_read_page(struct phy_device *phydev) ++{ ++ return __phy_read(phydev, YT8511_PAGE_SELECT); ++}; ++ ++static int yt8511_write_page(struct phy_device *phydev, int page) ++{ ++ return __phy_write(phydev, YT8511_PAGE_SELECT, page); ++}; ++ ++static int yt8511_config_init(struct phy_device *phydev) ++{ ++ unsigned int ge, fe; ++ int ret, oldpage; ++ ++ /* set clock mode to 125mhz */ ++ oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); ++ if (oldpage < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* set rgmii delay mode */ ++ switch (phydev->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ ge = YT8511_DELAY_GE_TX_DIS; ++ fe = YT8511_DELAY_FE_TX_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_DIS; ++ fe = YT8511_DELAY_FE_TX_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ ge = YT8511_DELAY_GE_TX_EN; ++ fe = YT8511_DELAY_FE_TX_EN; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN; ++ fe = YT8511_DELAY_FE_TX_EN; ++ break; ++ default: /* leave everything alone in other modes */ ++ break; ++ } ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* fast ethernet delay is in a separate page */ ++ ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_DELAY_DRIVE); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, YT8511_DELAY_FE_TX_EN, fe); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* leave pll enabled in sleep */ ++ ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_SLEEP_CTRL); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_PLLON_SLP); ++ if (ret < 0) ++ goto err_restore_page; ++ ++err_restore_page: ++ return phy_restore_page(phydev, oldpage, ret); ++} ++ ++static struct phy_driver motorcomm_phy_drvs[] = { ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8511), ++ .name = "YT8511 Gigabit Ethernet", ++ .config_init = yt8511_config_init, ++ .suspend = genphy_suspend, ++ .resume = genphy_resume, ++ .read_page = yt8511_read_page, ++ .write_page = yt8511_write_page, ++ }, ++}; ++ ++module_phy_driver(motorcomm_phy_drvs); ++ ++MODULE_DESCRIPTION("Motorcomm PHY driver"); ++MODULE_AUTHOR("Peter Geis"); ++MODULE_LICENSE("GPL"); ++ ++static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { ++ { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, ++ { /* sentinal */ } ++}; ++ ++MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); +-- +2.30.2 + +From 9e2a06d3a2165c2d2e01aca6ab3a74d7a9623377 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 29 May 2021 07:05:55 -0400 +Subject: [PATCH 2/4] net: phy: fix yt8511 clang uninitialized variable warning + +clang doesn't preinitialize variables. If phy_select_page failed and +returned an error, phy_restore_page would be called with `ret` being +uninitialized. +Even though phy_restore_page won't use `ret` in this scenario, +initialize `ret` to silence the warning. + +Fixes: 48e8c6f1612b ("net: phy: add driver for Motorcomm yt8511 phy") +Reported-by: kernel test robot +Reviewed-by: Andrew Lunn +Signed-off-by: Peter Geis +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/motorcomm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +index 796b68f4b499..68cd19540c67 100644 +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -50,8 +50,8 @@ static int yt8511_write_page(struct phy_device *phydev, int page) + + static int yt8511_config_init(struct phy_device *phydev) + { ++ int oldpage, ret = 0; + unsigned int ge, fe; +- int ret, oldpage; + + /* set clock mode to 125mhz */ + oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); +-- +2.30.2 + +From 6e20d54c9574d980af58e83f0626991ba650dbd9 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Sat, 29 May 2021 07:05:56 -0400 +Subject: [PATCH 3/4] net: phy: abort loading yt8511 driver in unsupported + modes + +While investigating the clang `ge` uninitialized variable report, it was +discovered the default switch would have unintended consequences. Due to +the switch to __phy_modify, the driver would modify the ID values in the +default scenario. + +Fix this by promoting the interface mode switch and aborting when the +mode is not a supported RGMII mode. + +This prevents the `ge` and `fe` variables from ever being used +uninitialized. + +Fixes: 48e8c6f1612b ("net: phy: add driver for Motorcomm yt8511 phy") +Reported-by: kernel test robot +Reviewed-by: Andrew Lunn +Signed-off-by: Peter Geis +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/motorcomm.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c +index 68cd19540c67..7e6ac2c5e27e 100644 +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -53,15 +53,10 @@ static int yt8511_config_init(struct phy_device *phydev) + int oldpage, ret = 0; + unsigned int ge, fe; + +- /* set clock mode to 125mhz */ + oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE); + if (oldpage < 0) + goto err_restore_page; + +- ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); +- if (ret < 0) +- goto err_restore_page; +- + /* set rgmii delay mode */ + switch (phydev->interface) { + case PHY_INTERFACE_MODE_RGMII: +@@ -80,14 +75,20 @@ static int yt8511_config_init(struct phy_device *phydev) + ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN; + fe = YT8511_DELAY_FE_TX_EN; + break; +- default: /* leave everything alone in other modes */ +- break; ++ default: /* do not support other modes */ ++ ret = -EOPNOTSUPP; ++ goto err_restore_page; + } + + ret = __phy_modify(phydev, YT8511_PAGE, (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge); + if (ret < 0) + goto err_restore_page; + ++ /* set clock mode to 125mhz */ ++ ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M); ++ if (ret < 0) ++ goto err_restore_page; ++ + /* fast ethernet delay is in a separate page */ + ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_DELAY_DRIVE); + if (ret < 0) +-- +2.30.2 + diff --git a/patch/u-boot/u-boot-sunxi/board_pine64so/fix-sopine-spi-clusterboad.patch b/patch/u-boot/u-boot-sunxi/board_pine64so/fix-sopine-spi-clusterboad.patch deleted file mode 100644 index abd25a7131..0000000000 --- a/patch/u-boot/u-boot-sunxi/board_pine64so/fix-sopine-spi-clusterboad.patch +++ /dev/null @@ -1,343 +0,0 @@ -diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c -index c1706dcec1..2e06ee4ed2 100644 ---- a/arch/arm/cpu/armv8/generic_timer.c -+++ b/arch/arm/cpu/armv8/generic_timer.c -@@ -66,7 +66,7 @@ unsigned long timer_read_counter(void) - isb(); - do { - asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); -- } while (((cntpct + 1) & GENMASK(10, 0)) <= 1); -+ } while (((cntpct + 1) & GENMASK(9, 0)) <= 1); - - return cntpct; - } -diff --git a/arch/arm/dts/sun50i-a64-sopine-baseboard.dts b/arch/arm/dts/sun50i-a64-sopine-baseboard.dts -index 53fcc9098d..8dac3f135b 100644 ---- a/arch/arm/dts/sun50i-a64-sopine-baseboard.dts -+++ b/arch/arm/dts/sun50i-a64-sopine-baseboard.dts -@@ -55,6 +55,7 @@ - aliases { - ethernet0 = &emac; - serial0 = &uart0; -+ spi0 = &spi0; - }; - - chosen { -diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h -index ee387127f3..4aaa0932d7 100644 ---- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h -+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h -@@ -321,6 +321,7 @@ struct sunxi_ccm_reg { - #define AHB_GATE_OFFSET_MMC(n) (AHB_GATE_OFFSET_MMC0 + (n)) - #define AHB_GATE_OFFSET_DMA 6 - #define AHB_GATE_OFFSET_SS 5 -+#define AHB_GATE_OFFSET_SPI0 20 - - /* ahb_gate1 offsets */ - #define AHB_GATE_OFFSET_DRC0 25 -diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h -index 530e0dd73b..9bbd4d319e 100644 ---- a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h -+++ b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h -@@ -194,6 +194,7 @@ struct sunxi_ccm_reg { - - /* ahb gate1 field */ - #define AHB_GATE_OFFSET_DMA 24 -+#define AHB_GATE_OFFSET_SPI0 20 - - /* apb1_gate fields */ - #define APB1_GATE_UART_SHIFT 16 -diff --git a/configs/sopine_baseboard_defconfig b/configs/sopine_baseboard_defconfig -index 9ede081c08..af690c11c5 100644 ---- a/configs/sopine_baseboard_defconfig -+++ b/configs/sopine_baseboard_defconfig -@@ -18,3 +18,20 @@ CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-sopine-baseboard" - CONFIG_SUN8I_EMAC=y - CONFIG_USB_EHCI_HCD=y - CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y -+CONFIG_CMD_SF=y -+CONFIG_CMD_SPI=y -+CONFIG_DM_SPI=y -+CONFIG_DM_SPI_FLASH=y -+CONFIG_SPI=y -+CONFIG_SUN4I_SPI=y -+CONFIG_SPI_FLASH=y -+CONFIG_SPI_FLASH_ATMEL=y -+CONFIG_SPI_FLASH_EON=y -+CONFIG_SPI_FLASH_GIGADEVICE=y -+CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_SPI_FLASH_SPANSION=y -+CONFIG_SPI_FLASH_STMICRO=y -+CONFIG_SPI_FLASH_SST=y -+CONFIG_SPI_FLASH_WINBOND=y -+CONFIG_PHY_REALTEK=y -+CONFIG_RTL8211E_PINE64_GIGABIT_FIX=y -\ No newline at end of file -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index a7bb5b35c2..88e772cb1a 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -219,9 +219,9 @@ config STM32_QSPI - this ST IP core. - - config SUN4I_SPI -- bool "Allwinner A10 SoCs SPI controller" -+ bool "Allwinner SoCs SPI driver" - help -- SPI driver for Allwinner sun4i, sun5i and sun7i SoCs -+ SPI driver for Allwinner SoCs - - config TEGRA114_SPI - bool "nVidia Tegra114 SPI driver" -diff --git a/drivers/spi/sun4i_spi.c b/drivers/spi/sun4i_spi.c -index 38cc743c61..7af8be15cf 100644 ---- a/drivers/spi/sun4i_spi.c -+++ b/drivers/spi/sun4i_spi.c -@@ -37,6 +37,30 @@ - - #define SUN4I_TXDATA_REG 0x04 - -+#ifdef CONFIG_SUNXI_GEN_SUN6I -+#define SUN4I_CTL_REG 0x04 -+#define SUN4I_CTL_ENABLE BIT(0) -+#define SUN4I_CTL_MASTER BIT(1) -+#define SUN4I_CTL_TP BIT(7) -+#define SUN4I_CTL_SRST BIT(31) -+ -+#define SUN4I_CTL_CPHA BIT(0) -+#define SUN4I_CTL_CPOL BIT(1) -+#define SUN4I_CTL_CS_ACTIVE_LOW BIT(2) -+#define SUN4I_CTL_CS_MASK 0x30 -+#define SUN4I_CTL_CS(cs) (((cs) << 4) & SUN4I_CTL_CS_MASK) -+#define SUN4I_CTL_CS_MANUAL BIT(6) -+#define SUN4I_CTL_CS_LEVEL BIT(7) -+#define SUN4I_CTL_DHB BIT(8) -+#define SUN4I_CTL_XCH_MASK 0x80000000 -+#define SUN4I_CTL_XCH BIT(31) -+ -+#define SUN4I_CTL_RF_RST BIT(15) -+#define SUN4I_CTL_TF_RST BIT(31) -+ -+#else -+#define SUN4I_CTL_SRST 0 -+ - #define SUN4I_CTL_REG 0x08 - #define SUN4I_CTL_ENABLE BIT(0) - #define SUN4I_CTL_MASTER BIT(1) -@@ -54,6 +78,7 @@ - #define SUN4I_CTL_CS_MANUAL BIT(16) - #define SUN4I_CTL_CS_LEVEL BIT(17) - #define SUN4I_CTL_TP BIT(18) -+#endif - - #define SUN4I_INT_CTL_REG 0x0c - #define SUN4I_INT_CTL_RF_F34 BIT(4) -@@ -92,11 +117,39 @@ - #define SUN4I_SPI_DEFAULT_RATE 1000000 - #define SUN4I_SPI_TIMEOUT_US 1000000 - -+#ifdef CONFIG_SUNXI_GEN_SUN6I -+/* sun6i spi register set */ -+struct sun4i_spi_regs { -+ u32 res0; -+ u32 ctl; /* 0x04 */ -+ u32 tctl; /* 0x08 */ -+ u32 res1; -+ u32 intctl; /* 0x10 */ -+ u32 st; /* 0x14 */ -+ u32 fifo_ctl; /* 0x18 */ -+ u32 fifo_sta; /* 0x1c */ -+ u32 wait; /* 0x20 */ -+ u32 cctl; /* 0x24 */ -+ u32 res2[2]; -+ u32 bc; /* 0x30 */ -+ u32 tc; /* 0x34 */ -+ u32 bctl; /* 0x38 */ -+ u32 res3[113]; -+ u32 txdata; /* 0x200 */ -+ u32 res4[63]; -+ u32 rxdata; /* 0x300 */ -+}; -+#else - /* sun4i spi register set */ - struct sun4i_spi_regs { - u32 rxdata; - u32 txdata; -- u32 ctl; -+ union { -+ u32 ctl; -+ u32 tctl; -+ u32 fifo_ctl; -+ u32 bctl; -+ }; - u32 intctl; - u32 st; - u32 dmactl; -@@ -106,6 +159,7 @@ struct sun4i_spi_regs { - u32 tc; - u32 fifo_sta; - }; -+#endif - - struct sun4i_spi_platdata { - u32 base_addr; -@@ -149,7 +203,7 @@ static void sun4i_spi_set_cs(struct udevice *bus, u8 cs, bool enable) - struct sun4i_spi_priv *priv = dev_get_priv(bus); - u32 reg; - -- reg = readl(&priv->regs->ctl); -+ reg = readl(&priv->regs->tctl); - - reg &= ~SUN4I_CTL_CS_MASK; - reg |= SUN4I_CTL_CS(cs); -@@ -159,7 +213,7 @@ static void sun4i_spi_set_cs(struct udevice *bus, u8 cs, bool enable) - else - reg |= SUN4I_CTL_CS_LEVEL; - -- writel(reg, &priv->regs->ctl); -+ writel(reg, &priv->regs->tctl); - } - - static int sun4i_spi_parse_pins(struct udevice *dev) -@@ -231,7 +285,10 @@ static int sun4i_spi_parse_pins(struct udevice *dev) - if (pin < 0) - break; - -- sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SPI0); -+ if (IS_ENABLED(CONFIG_MACH_SUN50I)) -+ sunxi_gpio_set_cfgpin(pin, SUN50I_GPC_SPI0); -+ else -+ sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SPI0); - sunxi_gpio_set_drv(pin, drive); - sunxi_gpio_set_pull(pin, pull); - } -@@ -244,10 +301,27 @@ static inline void sun4i_spi_enable_clock(void) - struct sunxi_ccm_reg *const ccm = - (struct sunxi_ccm_reg *const)SUNXI_CCM_BASE; - -+#ifdef CONFIG_SUNXI_GEN_SUN6I -+ setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_GATE_OFFSET_SPI0)); -+#endif -+ - setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_SPI0)); - writel((1 << 31), &ccm->spi0_clk_cfg); - } - -+static inline void sun4i_spi_disable_clock(void) -+{ -+ struct sunxi_ccm_reg *const ccm = -+ (struct sunxi_ccm_reg *const)SUNXI_CCM_BASE; -+ -+ writel(0, &ccm->spi0_clk_cfg); -+ clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_SPI0)); -+ -+#ifdef CONFIG_SUNXI_GEN_SUN6I -+ clrbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_GATE_OFFSET_SPI0)); -+#endif -+} -+ - static int sun4i_spi_ofdata_to_platdata(struct udevice *bus) - { - struct sun4i_spi_platdata *plat = dev_get_platdata(bus); -@@ -269,7 +343,6 @@ static int sun4i_spi_probe(struct udevice *bus) - struct sun4i_spi_platdata *plat = dev_get_platdata(bus); - struct sun4i_spi_priv *priv = dev_get_priv(bus); - -- sun4i_spi_enable_clock(); - sun4i_spi_parse_pins(bus); - - priv->regs = (struct sun4i_spi_regs *)(uintptr_t)plat->base_addr; -@@ -282,9 +355,17 @@ static int sun4i_spi_claim_bus(struct udevice *dev) - { - struct sun4i_spi_priv *priv = dev_get_priv(dev->parent); - -+ sun4i_spi_enable_clock(); - writel(SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP | -- SUN4I_CTL_CS_MANUAL | SUN4I_CTL_CS_ACTIVE_LOW, -+ SUN4I_CTL_SRST, - &priv->regs->ctl); -+ -+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I)) -+ while (readl(&priv->regs->ctl) & SUN4I_CTL_SRST) -+ ; -+ -+ setbits_le32(&priv->regs->tctl, SUN4I_CTL_CS_MANUAL | -+ SUN4I_CTL_CS_ACTIVE_LOW); - return 0; - } - -@@ -296,6 +377,7 @@ static int sun4i_spi_release_bus(struct udevice *dev) - reg = readl(&priv->regs->ctl); - reg &= ~SUN4I_CTL_ENABLE; - writel(reg, &priv->regs->ctl); -+ sun4i_spi_disable_clock(); - - return 0; - } -@@ -323,10 +405,10 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen, - if (flags & SPI_XFER_BEGIN) - sun4i_spi_set_cs(bus, slave_plat->cs, true); - -- reg = readl(&priv->regs->ctl); -+ reg = readl(&priv->regs->fifo_ctl); - - /* Reset FIFOs */ -- writel(reg | SUN4I_CTL_RF_RST | SUN4I_CTL_TF_RST, &priv->regs->ctl); -+ writel(reg | SUN4I_CTL_RF_RST | SUN4I_CTL_TF_RST, &priv->regs->fifo_ctl); - - while (len) { - /* Setup the transfer now... */ -@@ -335,16 +417,18 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen, - /* Setup the counters */ - writel(SUN4I_BURST_CNT(nbytes), &priv->regs->bc); - writel(SUN4I_XMIT_CNT(nbytes), &priv->regs->tc); -+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I)) -+ writel(SUN4I_BURST_CNT(nbytes), &priv->regs->bctl); - - /* Fill the TX FIFO */ - sun4i_spi_fill_fifo(priv, nbytes); - - /* Start the transfer */ -- reg = readl(&priv->regs->ctl); -- writel(reg | SUN4I_CTL_XCH, &priv->regs->ctl); -+ reg = readl(&priv->regs->tctl); -+ writel(reg | SUN4I_CTL_XCH, &priv->regs->tctl); - - /* Wait transfer to complete */ -- ret = wait_for_bit_le32(&priv->regs->ctl, SUN4I_CTL_XCH_MASK, -+ ret = wait_for_bit_le32(&priv->regs->tctl, SUN4I_CTL_XCH_MASK, - false, SUN4I_SPI_TIMEOUT_US, false); - if (ret) { - printf("ERROR: sun4i_spi: Timeout transferring data\n"); -@@ -417,7 +501,7 @@ static int sun4i_spi_set_mode(struct udevice *dev, uint mode) - struct sun4i_spi_priv *priv = dev_get_priv(dev); - u32 reg; - -- reg = readl(&priv->regs->ctl); -+ reg = readl(&priv->regs->tctl); - reg &= ~(SUN4I_CTL_CPOL | SUN4I_CTL_CPHA); - - if (mode & SPI_CPOL) -@@ -427,7 +511,7 @@ static int sun4i_spi_set_mode(struct udevice *dev, uint mode) - reg |= SUN4I_CTL_CPHA; - - priv->mode = mode; -- writel(reg, &priv->regs->ctl); -+ writel(reg, &priv->regs->tctl); - - return 0; - } -@@ -441,7 +525,13 @@ static const struct dm_spi_ops sun4i_spi_ops = { - }; - - static const struct udevice_id sun4i_spi_ids[] = { -+#ifndef CONFIG_SUNXI_GEN_SUN6I - { .compatible = "allwinner,sun4i-a10-spi" }, -+#else -+ { .compatible = "allwinner,sun6i-a31-spi" }, -+ { .compatible = "allwinner,sun8i-h3-spi" }, -+ { .compatible = "allwinner,sun50i-a64-spi" }, -+#endif - { } - }; -