Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp615163rwd; Mon, 12 Jun 2023 20:01:38 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6HTRFgv8oZkkZtcmCj+xr1Ki8P3okiAWrpp5faMx3P1OoW//vZZVeN3EwxvgMJg//HmeaO X-Received: by 2002:a05:6402:54f:b0:514:983a:993b with SMTP id i15-20020a056402054f00b00514983a993bmr6170835edx.24.1686625298252; Mon, 12 Jun 2023 20:01:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686625298; cv=none; d=google.com; s=arc-20160816; b=wzD8NoomwpBgjhSGSQzhZSgYkk2PZANvVvOS4hc7VS/NW783h7YVowZ50OQd5trSyZ 0DoUATL5jG2qygb421uAvIcALiU4Yy301kVsb6Etpkyxw4zSM0JX4tL5W8S6ppJ4yRN+ II2tR+RNNF1pQCDZiYa9XSJNQvFXi5WTsezLIN1oi3LkSnKwfRmvG5UvzgZtIhIGXRHS FNTyVhPwKC7Zgy6ij+Kr+5j7kOawUwPt134kNbzv1RMPOCiJkZsLAkQbZJFeP1WUjBHA kmArPqE/fctrTuNhjvVyv4X5rz05A6zgJc5aGNzCtUSzUMRfRysc0L3pFM8ufM4Cmkpd wAjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-disposition:mime-version:message-id :subject:to:from:date; bh=15jQgvHf6tIMTzUiPldE7ATdrQotSVvFW1aREMgdHoc=; b=Q2U1J0tdrcjNDpHaQmXE9xkXdH3SUsWRqyfirF/ls0oljGkAbyCVKV42B48GbkAS3r cy+XorsAb7kbw6tcS8JfRrTU8TnGb+NUD6yS0NLHh2HrAkOYCtWsRsYD9A2yz5lijhWF pTjyIeI6PULf68/jKP2NBzKOiscTxUkXfPT6+boTjt/qap9MbAjwDpF3tnI12VCZXC30 hqRtOaIuCpzY85BkdQqhP6IqVmBflQrhdQpoo2O50TC73qOIdSJ8spvrqFYU3dqmXHdB UeA6xzGvvFAUuctO7uoCeDSRi/6iYIukSCaQ+SfGbRJfoqmDg2w3bjc5StrSLAv+5t7r lH8w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e20-20020a50ec94000000b00514ce4b01dfsi6974144edr.197.2023.06.12.20.01.14; Mon, 12 Jun 2023 20:01:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230353AbjFMC2F (ORCPT + 99 others); Mon, 12 Jun 2023 22:28:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229674AbjFMC2E (ORCPT ); Mon, 12 Jun 2023 22:28:04 -0400 Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 230B010EC; Mon, 12 Jun 2023 19:28:02 -0700 (PDT) Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.96) (envelope-from ) id 1q8tlF-0006QG-1C; Tue, 13 Jun 2023 02:27:57 +0000 Date: Tue, 13 Jun 2023 03:27:14 +0100 From: Daniel Golle To: netdev@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Matthias Brugger , Paolo Abeni , Jakub Kicinski , Eric Dumazet , "David S. Miller" , Russell King , Heiner Kallweit , Andrew Lunn , SkyLake Huang , Qingfang Deng Subject: [PATCH net-next] net: phy: mediatek-ge-soc: initialize MT7988 PHY LEDs default state Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- drivers/net/phy/mediatek-ge-soc.c | 144 ++++++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 8 deletions(-) diff --git a/drivers/net/phy/mediatek-ge-soc.c b/drivers/net/phy/mediatek-ge-soc.c index 95369171a7ba6..7bdcb4415509f 100644 --- 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 +#include #include #include #include #include #include #include +#include #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 phy_device *phydev) 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_driver[] = { .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, -- 2.41.0