mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-05 22:07:06 +08:00
qualcommax: ipq50xx: update patches for IPQ5018 GE PHY
Use latest patches sent upstream for review for IPQ5018 GE PHY support: - Move enablement of the LDO controller to the mdio-ipq4019 driver away from the CMN PLL driver - Remove the different patches to add CDT, MSE, AZ, and DAC support they are all contained in the upstreamed driver. Accordingly, also set the right property in the DTS for Linksys SPNMX56 to set the right DAC values to accommodate for the short cable length. Signed-off-by: George Moussalem <george.moussalem@outlook.com> Link: https://github.com/openwrt/openwrt/pull/18774 Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
parent
41a9ef2e8c
commit
1b3b59f2f4
@ -23,16 +23,14 @@ Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
|||||||
sleep_clk: sleep-clk {
|
sleep_clk: sleep-clk {
|
||||||
compatible = "fixed-clock";
|
compatible = "fixed-clock";
|
||||||
#clock-cells = <0>;
|
#clock-cells = <0>;
|
||||||
@@ -182,6 +188,19 @@
|
@@ -182,6 +188,17 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
+ cmn_pll: clock-controller@9b000 {
|
+ cmn_pll: clock-controller@9b000 {
|
||||||
+ compatible = "qcom,ipq9574-cmn-pll";
|
+ compatible = "qcom,ipq9574-cmn-pll";
|
||||||
+ reg = <0x0009b000 0x800>,
|
+ reg = <0x0009b000 0x800>;
|
||||||
+ <0x19475c4 0x4>;
|
+ reg-names = "cmn";
|
||||||
+ reg-names = "cmn",
|
|
||||||
+ "tcsr";
|
|
||||||
+ clocks = <&cmn_pll_ref_clk>,
|
+ clocks = <&cmn_pll_ref_clk>,
|
||||||
+ <&gcc GCC_CMN_BLK_AHB_CLK>,
|
+ <&gcc GCC_CMN_BLK_AHB_CLK>,
|
||||||
+ <&gcc GCC_CMN_BLK_SYS_CLK>;
|
+ <&gcc GCC_CMN_BLK_SYS_CLK>;
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
From 19600588e6403ff9f6c1e985fc025afb9160a56f Mon Sep 17 00:00:00 2001
|
||||||
|
From: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
Date: Wed, 28 May 2025 08:37:25 +0400
|
||||||
|
Subject: [PATCH v2 2/5] clk: qcom: gcc-ipq5018: fix GE PHY reset
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
Message-Id: <20250528-ipq5018-ge-phy-v2-2-68fc3a8248dd@outlook.com>
|
||||||
|
|
||||||
|
The MISC reset is supposed to trigger a resets across the MDC, DSP, and
|
||||||
|
RX & TX clocks of the IPQ5018 internal GE PHY. So let's set the bitmask
|
||||||
|
of the reset definition accordingly in the GCC as per the downstream
|
||||||
|
driver.
|
||||||
|
|
||||||
|
Link: https://git.codelinaro.org/clo/qsdk/oss/kernel/linux-ipq-5.4/-/commit/00743c3e82fa87cba4460e7a2ba32f473a9ce932
|
||||||
|
|
||||||
|
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
---
|
||||||
|
drivers/clk/qcom/gcc-ipq5018.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/clk/qcom/gcc-ipq5018.c
|
||||||
|
+++ b/drivers/clk/qcom/gcc-ipq5018.c
|
||||||
|
@@ -3660,7 +3660,7 @@ static const struct qcom_reset_map gcc_i
|
||||||
|
[GCC_WCSS_AXI_S_ARES] = { 0x59008, 6 },
|
||||||
|
[GCC_WCSS_Q6_BCR] = { 0x18004, 0 },
|
||||||
|
[GCC_WCSSAON_RESET] = { 0x59010, 0},
|
||||||
|
- [GCC_GEPHY_MISC_ARES] = { 0x56004, 0 },
|
||||||
|
+ [GCC_GEPHY_MISC_ARES] = { 0x56004, .bitmask = GENMASK(3, 0) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id gcc_ipq5018_match_table[] = {
|
@ -1,184 +0,0 @@
|
|||||||
From 77ad12b3a5e21cae859247c0b82cf9a5b661e531 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ziyang Huang <hzyitc@outlook.com>
|
|
||||||
Date: Sun, 8 Sep 2024 16:40:11 +0800
|
|
||||||
Subject: [PATCH 1/3] net: phy: qcom: Introduce IPQ5018 internal PHY driver
|
|
||||||
|
|
||||||
Introduce the internal GE PHY driver, part of the Qualcomm IPQ50xx SoC.
|
|
||||||
The driver registers two clock providers needed and referenced by the GCC
|
|
||||||
using DT properties and phandles.
|
|
||||||
|
|
||||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
|
||||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
|
||||||
---
|
|
||||||
drivers/net/phy/qcom/Kconfig | 6 ++
|
|
||||||
drivers/net/phy/qcom/Makefile | 1 +
|
|
||||||
drivers/net/phy/qcom/ipq5018.c | 138 +++++++++++++++++++++++++++++++++
|
|
||||||
3 files changed, 145 insertions(+)
|
|
||||||
create mode 100644 drivers/net/phy/qcom/ipq5018.c
|
|
||||||
|
|
||||||
--- a/drivers/net/phy/qcom/Kconfig
|
|
||||||
+++ b/drivers/net/phy/qcom/Kconfig
|
|
||||||
@@ -9,6 +9,12 @@ config AT803X_PHY
|
|
||||||
help
|
|
||||||
Currently supports the AR8030, AR8031, AR8033, AR8035 model
|
|
||||||
|
|
||||||
+config IPQ5018_PHY
|
|
||||||
+ tristate "Qualcomm IPQ5018 internal PHYs"
|
|
||||||
+ select QCOM_NET_PHYLIB
|
|
||||||
+ help
|
|
||||||
+ Currently supports the Qualcomm IPQ5018 internal PHY
|
|
||||||
+
|
|
||||||
config QCA83XX_PHY
|
|
||||||
tristate "Qualcomm Atheros QCA833x PHYs"
|
|
||||||
select QCOM_NET_PHYLIB
|
|
||||||
--- a/drivers/net/phy/qcom/Makefile
|
|
||||||
+++ b/drivers/net/phy/qcom/Makefile
|
|
||||||
@@ -1,6 +1,7 @@
|
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o
|
|
||||||
obj-$(CONFIG_AT803X_PHY) += at803x.o
|
|
||||||
+obj-$(CONFIG_IPQ5018_PHY) += ipq5018.o
|
|
||||||
obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o
|
|
||||||
obj-$(CONFIG_QCA808X_PHY) += qca808x.o
|
|
||||||
obj-$(CONFIG_QCA807X_PHY) += qca807x.o
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/drivers/net/phy/qcom/ipq5018.c
|
|
||||||
@@ -0,0 +1,138 @@
|
|
||||||
+#include <linux/bitfield.h>
|
|
||||||
+#include <linux/clk.h>
|
|
||||||
+#include <linux/clk-provider.h>
|
|
||||||
+#include <linux/phy.h>
|
|
||||||
+#include <linux/reset.h>
|
|
||||||
+
|
|
||||||
+#include "qcom.h"
|
|
||||||
+
|
|
||||||
+#define IPQ5018_PHY_ID 0x004dd0c0
|
|
||||||
+
|
|
||||||
+#define TX_RX_CLK_RATE 125000000 /* 125M */
|
|
||||||
+
|
|
||||||
+#define IPQ5018_PHY_FIFO_CONTROL 0x19
|
|
||||||
+#define IPQ5018_PHY_FIFO_RESET GENMASK(1, 0)
|
|
||||||
+
|
|
||||||
+struct ipq5018_phy {
|
|
||||||
+ int num_clks;
|
|
||||||
+ struct clk_bulk_data *clks;
|
|
||||||
+ struct reset_control *rst;
|
|
||||||
+
|
|
||||||
+ struct clk_hw *clk_rx, *clk_tx;
|
|
||||||
+ struct clk_hw_onecell_data *clk_data;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int ipq5018_probe(struct phy_device *phydev)
|
|
||||||
+{
|
|
||||||
+ struct ipq5018_phy *priv;
|
|
||||||
+ struct device *dev = &phydev->mdio.dev;
|
|
||||||
+ char name[64];
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
|
||||||
+ if (!priv)
|
|
||||||
+ return dev_err_probe(dev, -ENOMEM,
|
|
||||||
+ "failed to allocate priv\n");
|
|
||||||
+
|
|
||||||
+ priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks);
|
|
||||||
+ if (priv->num_clks < 0)
|
|
||||||
+ return dev_err_probe(dev, priv->num_clks,
|
|
||||||
+ "failed to acquire clocks\n");
|
|
||||||
+
|
|
||||||
+ ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
|
|
||||||
+ if (ret)
|
|
||||||
+ return dev_err_probe(dev, ret,
|
|
||||||
+ "failed to enable clocks\n");
|
|
||||||
+
|
|
||||||
+ priv->rst = devm_reset_control_array_get_exclusive(dev);
|
|
||||||
+ if (IS_ERR_OR_NULL(priv->rst))
|
|
||||||
+ return dev_err_probe(dev, PTR_ERR(priv->rst),
|
|
||||||
+ "failed to acquire reset\n");
|
|
||||||
+
|
|
||||||
+ ret = reset_control_reset(priv->rst);
|
|
||||||
+ if (ret)
|
|
||||||
+ return dev_err_probe(dev, ret,
|
|
||||||
+ "failed to reset\n");
|
|
||||||
+
|
|
||||||
+ snprintf(name, sizeof(name), "%s#rx", dev_name(dev));
|
|
||||||
+ priv->clk_rx = clk_hw_register_fixed_rate(dev, name, NULL, 0,
|
|
||||||
+ TX_RX_CLK_RATE);
|
|
||||||
+ if (IS_ERR_OR_NULL(priv->clk_rx))
|
|
||||||
+ return dev_err_probe(dev, PTR_ERR(priv->clk_rx),
|
|
||||||
+ "failed to register rx clock\n");
|
|
||||||
+
|
|
||||||
+ snprintf(name, sizeof(name), "%s#tx", dev_name(dev));
|
|
||||||
+ priv->clk_tx = clk_hw_register_fixed_rate(dev, name, NULL, 0,
|
|
||||||
+ TX_RX_CLK_RATE);
|
|
||||||
+ if (IS_ERR_OR_NULL(priv->clk_tx))
|
|
||||||
+ return dev_err_probe(dev, PTR_ERR(priv->clk_tx),
|
|
||||||
+ "failed to register tx clock\n");
|
|
||||||
+
|
|
||||||
+ priv->clk_data = devm_kzalloc(dev,
|
|
||||||
+ struct_size(priv->clk_data, hws, 2),
|
|
||||||
+ GFP_KERNEL);
|
|
||||||
+ if (!priv->clk_data)
|
|
||||||
+ return dev_err_probe(dev, -ENOMEM,
|
|
||||||
+ "failed to allocate clk_data\n");
|
|
||||||
+
|
|
||||||
+ priv->clk_data->num = 2;
|
|
||||||
+ priv->clk_data->hws[0] = priv->clk_rx;
|
|
||||||
+ priv->clk_data->hws[1] = priv->clk_tx;
|
|
||||||
+ ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
|
|
||||||
+ priv->clk_data);
|
|
||||||
+ if (ret)
|
|
||||||
+ return dev_err_probe(dev, ret,
|
|
||||||
+ "fail to register clock provider\n");
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int ipq5018_soft_reset(struct phy_device *phydev)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = phy_modify(phydev, IPQ5018_PHY_FIFO_CONTROL,
|
|
||||||
+ IPQ5018_PHY_FIFO_RESET, 0);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ msleep(50);
|
|
||||||
+
|
|
||||||
+ ret = phy_modify(phydev, IPQ5018_PHY_FIFO_CONTROL,
|
|
||||||
+ IPQ5018_PHY_FIFO_RESET, IPQ5018_PHY_FIFO_RESET);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int ipq5018_cable_test_start(struct phy_device *phydev)
|
|
||||||
+{
|
|
||||||
+ /* we do all the (time consuming) work later */
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct phy_driver ipq5018_internal_phy_driver[] = {
|
|
||||||
+ {
|
|
||||||
+ PHY_ID_MATCH_EXACT(IPQ5018_PHY_ID),
|
|
||||||
+ .name = "Qualcomm IPQ5018 internal PHY",
|
|
||||||
+ .flags = PHY_IS_INTERNAL | PHY_POLL_CABLE_TEST,
|
|
||||||
+ .probe = ipq5018_probe,
|
|
||||||
+ .soft_reset = ipq5018_soft_reset,
|
|
||||||
+ .read_status = at803x_read_status,
|
|
||||||
+ .config_intr = at803x_config_intr,
|
|
||||||
+ .handle_interrupt = at803x_handle_interrupt,
|
|
||||||
+ .cable_test_start = ipq5018_cable_test_start,
|
|
||||||
+ .cable_test_get_status = qca808x_cable_test_get_status,
|
|
||||||
+ },
|
|
||||||
+};
|
|
||||||
+module_phy_driver(ipq5018_internal_phy_driver);
|
|
||||||
+
|
|
||||||
+static struct mdio_device_id __maybe_unused ipq5018_internal_phy_ids[] = {
|
|
||||||
+ { PHY_ID_MATCH_EXACT(IPQ5018_PHY_ID) },
|
|
||||||
+ { }
|
|
||||||
+};
|
|
||||||
+MODULE_DEVICE_TABLE(mdio, ipq5018_internal_phy_ids);
|
|
||||||
+
|
|
||||||
+MODULE_DESCRIPTION("Qualcomm IPQ5018 internal PHY driver");
|
|
||||||
+MODULE_AUTHOR("Ziyang Huang <hzyitc@outlook.com>");
|
|
@ -1,47 +0,0 @@
|
|||||||
From d2cdc83fb2c7360856e598810b88211d815fc851 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ziyang Huang <hzyitc@outlook.com>
|
|
||||||
Date: Sun, 8 Sep 2024 16:40:12 +0800
|
|
||||||
Subject: [PATCH 2/3] arm64: dts: qcom: ipq5018: add mdio node
|
|
||||||
|
|
||||||
The IPQ5018 SoC contains two MDIO controllers. MDIO0 is used to control
|
|
||||||
its internal GE Phy, while MDIO1 is wired to external PHYs/switch.
|
|
||||||
|
|
||||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
|
||||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
|
||||||
---
|
|
||||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 20 ++++++++++++++++++++
|
|
||||||
1 file changed, 20 insertions(+)
|
|
||||||
|
|
||||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
|
||||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
|
||||||
@@ -188,6 +188,30 @@
|
|
||||||
status = "disabled";
|
|
||||||
};
|
|
||||||
|
|
||||||
+ mdio0: mdio@88000 {
|
|
||||||
+ compatible = "qcom,ipq5018-mdio", "qcom,qca-mdio";
|
|
||||||
+ reg = <0x00088000 0x64>;
|
|
||||||
+ #address-cells = <1>;
|
|
||||||
+ #size-cells = <0>;
|
|
||||||
+
|
|
||||||
+ clocks = <&gcc GCC_MDIO0_AHB_CLK>;
|
|
||||||
+ clock-names = "gcc_mdio_ahb_clk";
|
|
||||||
+
|
|
||||||
+ status = "disabled";
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ mdio1: mdio@90000 {
|
|
||||||
+ compatible = "qcom,ipq5018-mdio";
|
|
||||||
+ reg = <0x00090000 0x64>;
|
|
||||||
+ #address-cells = <1>;
|
|
||||||
+ #size-cells = <0>;
|
|
||||||
+
|
|
||||||
+ clocks = <&gcc GCC_MDIO1_AHB_CLK>;
|
|
||||||
+ clock-names = "gcc_mdio_ahb_clk";
|
|
||||||
+
|
|
||||||
+ status = "disabled";
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
cmn_pll: clock-controller@9b000 {
|
|
||||||
compatible = "qcom,ipq9574-cmn-pll";
|
|
||||||
reg = <0x0009b000 0x800>,
|
|
@ -0,0 +1,277 @@
|
|||||||
|
From 9a89cb300c1ed5b90bae5684c88c85895a15c849 Mon Sep 17 00:00:00 2001
|
||||||
|
From: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
Date: Mon, 02 Jun 2025 12:50:39 +0400
|
||||||
|
Subject: [PATCH v3 3/5] net: phy: qcom: at803x: Add Qualcomm IPQ5018 Internal PHY support
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
Message-Id: <20250602-ipq5018-ge-phy-v3-3-0d8f39f402a6@outlook.com>
|
||||||
|
|
||||||
|
The IPQ5018 SoC contains a single internal Gigabit Ethernet PHY which
|
||||||
|
provides an MDI interface directly to an RJ45 connector or an external
|
||||||
|
switch over a PHY to PHY link.
|
||||||
|
|
||||||
|
The PHY supports 10/100/1000 mbps link modes, CDT, auto-negotiation and
|
||||||
|
802.3az EEE.
|
||||||
|
|
||||||
|
Let's add support for this PHY in the at803x driver as it falls within
|
||||||
|
the Qualcomm Atheros OUI.
|
||||||
|
|
||||||
|
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
---
|
||||||
|
drivers/net/phy/qcom/Kconfig | 2 +-
|
||||||
|
drivers/net/phy/qcom/at803x.c | 185 ++++++++++++++++++++++++++++++++++++++++--
|
||||||
|
2 files changed, 178 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/qcom/Kconfig
|
||||||
|
+++ b/drivers/net/phy/qcom/Kconfig
|
||||||
|
@@ -7,7 +7,7 @@ config AT803X_PHY
|
||||||
|
select QCOM_NET_PHYLIB
|
||||||
|
depends on REGULATOR
|
||||||
|
help
|
||||||
|
- Currently supports the AR8030, AR8031, AR8033, AR8035 model
|
||||||
|
+ Currently supports the AR8030, AR8031, AR8033, AR8035, IPQ5018 model
|
||||||
|
|
||||||
|
config QCA83XX_PHY
|
||||||
|
tristate "Qualcomm Atheros QCA833x PHYs"
|
||||||
|
--- a/drivers/net/phy/qcom/at803x.c
|
||||||
|
+++ b/drivers/net/phy/qcom/at803x.c
|
||||||
|
@@ -7,19 +7,24 @@
|
||||||
|
* Author: Matus Ujhelyi <ujhelyi.m@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#include <linux/phy.h>
|
||||||
|
-#include <linux/module.h>
|
||||||
|
-#include <linux/string.h>
|
||||||
|
-#include <linux/netdevice.h>
|
||||||
|
+#include <linux/bitfield.h>
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
+#include <linux/clk-provider.h>
|
||||||
|
#include <linux/etherdevice.h>
|
||||||
|
#include <linux/ethtool_netlink.h>
|
||||||
|
-#include <linux/bitfield.h>
|
||||||
|
-#include <linux/regulator/of_regulator.h>
|
||||||
|
-#include <linux/regulator/driver.h>
|
||||||
|
-#include <linux/regulator/consumer.h>
|
||||||
|
+#include <linux/mfd/syscon.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/netdevice.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
+#include <linux/phy.h>
|
||||||
|
#include <linux/phylink.h>
|
||||||
|
+#include <linux/regmap.h>
|
||||||
|
+#include <linux/regulator/consumer.h>
|
||||||
|
+#include <linux/regulator/driver.h>
|
||||||
|
+#include <linux/regulator/of_regulator.h>
|
||||||
|
+#include <linux/reset.h>
|
||||||
|
#include <linux/sfp.h>
|
||||||
|
+#include <linux/string.h>
|
||||||
|
#include <dt-bindings/net/qca-ar803x.h>
|
||||||
|
|
||||||
|
#include "qcom.h"
|
||||||
|
@@ -96,6 +101,8 @@
|
||||||
|
#define ATH8035_PHY_ID 0x004dd072
|
||||||
|
#define AT8030_PHY_ID_MASK 0xffffffef
|
||||||
|
|
||||||
|
+#define IPQ5018_PHY_ID 0x004dd0c0
|
||||||
|
+
|
||||||
|
#define QCA9561_PHY_ID 0x004dd042
|
||||||
|
|
||||||
|
#define AT803X_PAGE_FIBER 0
|
||||||
|
@@ -108,6 +115,50 @@
|
||||||
|
/* disable hibernation mode */
|
||||||
|
#define AT803X_DISABLE_HIBERNATION_MODE BIT(2)
|
||||||
|
|
||||||
|
+#define IPQ5018_PHY_FIFO_CONTROL 0x19
|
||||||
|
+#define IPQ5018_PHY_FIFO_RESET GENMASK(1, 0)
|
||||||
|
+
|
||||||
|
+#define IPQ5018_PHY_DEBUG_EDAC 0x4380
|
||||||
|
+#define IPQ5018_PHY_MMD1_MDAC 0x8100
|
||||||
|
+#define IPQ5018_PHY_DAC_MASK GENMASK(15, 8)
|
||||||
|
+
|
||||||
|
+/* MDAC and EDAC values for short cable length */
|
||||||
|
+#define IPQ5018_PHY_DEBUG_EDAC_VAL 0x10
|
||||||
|
+#define IPQ5018_PHY_MMD1_MDAC_VAL 0x10
|
||||||
|
+
|
||||||
|
+#define IPQ5018_PHY_MMD1_MSE_THRESH1 0x1000
|
||||||
|
+#define IPQ5018_PHY_MMD1_MSE_THRESH2 0x1001
|
||||||
|
+#define IPQ5018_PHY_PCS_AZ_CTRL1 0x8008
|
||||||
|
+#define IPQ5018_PHY_PCS_AZ_CTRL2 0x8009
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL3 0x8074
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL4 0x8075
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL5 0x8076
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL6 0x8077
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL7 0x8078
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL9 0x807a
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL13 0x807e
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL14 0x807f
|
||||||
|
+
|
||||||
|
+#define IPQ5018_PHY_MMD1_MSE_THRESH1_VAL 0xf1
|
||||||
|
+#define IPQ5018_PHY_MMD1_MSE_THRESH2_VAL 0x1f6
|
||||||
|
+#define IPQ5018_PHY_PCS_AZ_CTRL1_VAL 0x7880
|
||||||
|
+#define IPQ5018_PHY_PCS_AZ_CTRL2_VAL 0xc8
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL3_VAL 0xc040
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL4_VAL 0xa060
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL5_VAL 0xc040
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL6_VAL 0xa060
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL7_VAL 0xc24c
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL9_VAL 0xc060
|
||||||
|
+#define IPQ5018_PHY_PCS_CDT_THRESH_CTRL13_VAL 0xb060
|
||||||
|
+#define IPQ5018_PHY_PCS_NEAR_ECHO_THRESH_VAL 0x90b0
|
||||||
|
+
|
||||||
|
+#define IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE 0x1
|
||||||
|
+#define IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_MASK GENMASK(7, 4)
|
||||||
|
+#define IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_DEFAULT 0x50
|
||||||
|
+#define IPQ5018_PHY_DEBUG_ANA_DAC_FILTER 0xa080
|
||||||
|
+
|
||||||
|
+#define IPQ5018_TCSR_ETH_LDO_READY BIT(0)
|
||||||
|
+
|
||||||
|
MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
|
||||||
|
MODULE_AUTHOR("Matus Ujhelyi");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
@@ -133,6 +184,11 @@ struct at803x_context {
|
||||||
|
u16 led_control;
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct ipq5018_priv {
|
||||||
|
+ struct reset_control *rst;
|
||||||
|
+ bool set_short_cable_dac;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static int at803x_write_page(struct phy_device *phydev, int page)
|
||||||
|
{
|
||||||
|
int mask;
|
||||||
|
@@ -987,6 +1043,105 @@ static int at8035_probe(struct phy_devic
|
||||||
|
return at8035_parse_dt(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int ipq5018_cable_test_start(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_CDT_THRESH_CTRL3,
|
||||||
|
+ IPQ5018_PHY_PCS_CDT_THRESH_CTRL3_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_CDT_THRESH_CTRL4,
|
||||||
|
+ IPQ5018_PHY_PCS_CDT_THRESH_CTRL4_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_CDT_THRESH_CTRL5,
|
||||||
|
+ IPQ5018_PHY_PCS_CDT_THRESH_CTRL5_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_CDT_THRESH_CTRL6,
|
||||||
|
+ IPQ5018_PHY_PCS_CDT_THRESH_CTRL6_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_CDT_THRESH_CTRL7,
|
||||||
|
+ IPQ5018_PHY_PCS_CDT_THRESH_CTRL7_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_CDT_THRESH_CTRL9,
|
||||||
|
+ IPQ5018_PHY_PCS_CDT_THRESH_CTRL9_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_CDT_THRESH_CTRL13,
|
||||||
|
+ IPQ5018_PHY_PCS_CDT_THRESH_CTRL13_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_CDT_THRESH_CTRL3,
|
||||||
|
+ IPQ5018_PHY_PCS_NEAR_ECHO_THRESH_VAL);
|
||||||
|
+
|
||||||
|
+ /* we do all the (time consuming) work later */
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ipq5018_config_init(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ struct ipq5018_priv *priv = phydev->priv;
|
||||||
|
+ u16 val = 0;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * set LDO efuse: first temporarily store ANA_DAC_FILTER value from
|
||||||
|
+ * debug register as it will be reset once the ANA_LDO_EFUSE register
|
||||||
|
+ * is written to
|
||||||
|
+ */
|
||||||
|
+ val = at803x_debug_reg_read(phydev, IPQ5018_PHY_DEBUG_ANA_DAC_FILTER);
|
||||||
|
+ at803x_debug_reg_mask(phydev, IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE,
|
||||||
|
+ IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_MASK,
|
||||||
|
+ IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_DEFAULT);
|
||||||
|
+ at803x_debug_reg_write(phydev, IPQ5018_PHY_DEBUG_ANA_DAC_FILTER, val);
|
||||||
|
+
|
||||||
|
+ /* set 8023AZ CTRL values */
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_AZ_CTRL1,
|
||||||
|
+ IPQ5018_PHY_PCS_AZ_CTRL1_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_PCS_AZ_CTRL2,
|
||||||
|
+ IPQ5018_PHY_PCS_AZ_CTRL2_VAL);
|
||||||
|
+
|
||||||
|
+ /* set MSE threshold values */
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MSE_THRESH1,
|
||||||
|
+ IPQ5018_PHY_MMD1_MSE_THRESH1_VAL);
|
||||||
|
+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MSE_THRESH2,
|
||||||
|
+ IPQ5018_PHY_MMD1_MSE_THRESH2_VAL);
|
||||||
|
+
|
||||||
|
+ /* PHY DAC values are optional and only set in a PHY to PHY link architecture */
|
||||||
|
+ if (priv->set_short_cable_dac) {
|
||||||
|
+ /* setting MDAC (Multi-level Digital-to-Analog Converter) in MMD1 */
|
||||||
|
+ phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MDAC,
|
||||||
|
+ IPQ5018_PHY_DAC_MASK, IPQ5018_PHY_MMD1_MDAC_VAL);
|
||||||
|
+
|
||||||
|
+ /* setting EDAC (Error-detection and Correction) in debug register */
|
||||||
|
+ at803x_debug_reg_mask(phydev, IPQ5018_PHY_DEBUG_EDAC,
|
||||||
|
+ IPQ5018_PHY_DAC_MASK, IPQ5018_PHY_DEBUG_EDAC_VAL);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void ipq5018_link_change_notify(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ mdiobus_modify_changed(phydev->mdio.bus, phydev->mdio.addr,
|
||||||
|
+ IPQ5018_PHY_FIFO_CONTROL, IPQ5018_PHY_FIFO_RESET,
|
||||||
|
+ phydev->link ? IPQ5018_PHY_FIFO_RESET : 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ipq5018_probe(struct phy_device *phydev)
|
||||||
|
+{
|
||||||
|
+ struct device *dev = &phydev->mdio.dev;
|
||||||
|
+ struct ipq5018_priv *priv;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||||
|
+ if (!priv)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ priv->set_short_cable_dac = of_property_read_bool(dev->of_node,
|
||||||
|
+ "qcom,dac-preset-short-cable");
|
||||||
|
+
|
||||||
|
+ priv->rst = devm_reset_control_array_get_exclusive(dev);
|
||||||
|
+ if (IS_ERR_OR_NULL(priv->rst))
|
||||||
|
+ return dev_err_probe(dev, PTR_ERR(priv->rst),
|
||||||
|
+ "failed to acquire reset\n");
|
||||||
|
+
|
||||||
|
+ ret = reset_control_reset(priv->rst);
|
||||||
|
+ if (ret)
|
||||||
|
+ return dev_err_probe(dev, ret, "failed to reset\n");
|
||||||
|
+
|
||||||
|
+ phydev->priv = priv;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct phy_driver at803x_driver[] = {
|
||||||
|
{
|
||||||
|
/* Qualcomm Atheros AR8035 */
|
||||||
|
@@ -1079,6 +1234,19 @@ static struct phy_driver at803x_driver[]
|
||||||
|
.soft_reset = genphy_soft_reset,
|
||||||
|
.config_aneg = at803x_config_aneg,
|
||||||
|
}, {
|
||||||
|
+ PHY_ID_MATCH_EXACT(IPQ5018_PHY_ID),
|
||||||
|
+ .name = "Qualcomm Atheros IPQ5018 internal PHY",
|
||||||
|
+ .flags = PHY_IS_INTERNAL | PHY_POLL_CABLE_TEST,
|
||||||
|
+ .probe = ipq5018_probe,
|
||||||
|
+ .config_init = ipq5018_config_init,
|
||||||
|
+ .link_change_notify = ipq5018_link_change_notify,
|
||||||
|
+ .read_status = at803x_read_status,
|
||||||
|
+ .config_intr = at803x_config_intr,
|
||||||
|
+ .handle_interrupt = at803x_handle_interrupt,
|
||||||
|
+ .cable_test_start = ipq5018_cable_test_start,
|
||||||
|
+ .cable_test_get_status = qca808x_cable_test_get_status,
|
||||||
|
+ .soft_reset = genphy_soft_reset,
|
||||||
|
+}, {
|
||||||
|
/* Qualcomm Atheros QCA9561 */
|
||||||
|
PHY_ID_MATCH_EXACT(QCA9561_PHY_ID),
|
||||||
|
.name = "Qualcomm Atheros QCA9561 built-in PHY",
|
||||||
|
@@ -1104,6 +1272,7 @@ static const struct mdio_device_id __may
|
||||||
|
{ PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
|
||||||
|
{ PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
|
||||||
|
{ PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
|
||||||
|
+ { PHY_ID_MATCH_EXACT(IPQ5018_PHY_ID) },
|
||||||
|
{ PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) },
|
||||||
|
{ }
|
||||||
|
};
|
@ -1,48 +0,0 @@
|
|||||||
From 28490d95fe9e059c5ce74b2289d66e0d7ede2d50 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ziyang Huang <hzyitc@outlook.com>
|
|
||||||
Date: Sun, 8 Sep 2024 16:40:12 +0800
|
|
||||||
Subject: [PATCH 3/3] arm64: dts: qcom: ipq5018: add ge_phy node
|
|
||||||
|
|
||||||
Add the GE PHY node and register the output clocks in the GCC node.
|
|
||||||
|
|
||||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
|
||||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
|
||||||
---
|
|
||||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 16 ++++++++++++++--
|
|
||||||
1 file changed, 14 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
|
||||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
|
||||||
@@ -198,6 +198,21 @@
|
|
||||||
clock-names = "gcc_mdio_ahb_clk";
|
|
||||||
|
|
||||||
status = "disabled";
|
|
||||||
+
|
|
||||||
+ ge_phy: ethernet-phy@7 {
|
|
||||||
+ compatible = "ethernet-phy-id004d.d0c0";
|
|
||||||
+ reg = <7>;
|
|
||||||
+ clocks = <&gcc GCC_GEPHY_RX_CLK>,
|
|
||||||
+ <&gcc GCC_GEPHY_TX_CLK>;
|
|
||||||
+
|
|
||||||
+ resets = <&gcc GCC_GEPHY_BCR>,
|
|
||||||
+ <&gcc GCC_GEPHY_MDC_SW_ARES>,
|
|
||||||
+ <&gcc GCC_GEPHY_DSP_HW_ARES>,
|
|
||||||
+ <&gcc GCC_GEPHY_RX_ARES>,
|
|
||||||
+ <&gcc GCC_GEPHY_TX_ARES>;
|
|
||||||
+
|
|
||||||
+ #clock-cells = <1>;
|
|
||||||
+ };
|
|
||||||
};
|
|
||||||
|
|
||||||
mdio1: mdio@90000 {
|
|
||||||
@@ -394,8 +409,8 @@
|
|
||||||
<&pcie0_phy>,
|
|
||||||
<&pcie1_phy>,
|
|
||||||
<0>,
|
|
||||||
- <0>,
|
|
||||||
- <0>,
|
|
||||||
+ <&ge_phy 0>,
|
|
||||||
+ <&ge_phy 1>,
|
|
||||||
<0>,
|
|
||||||
<0>;
|
|
||||||
#clock-cells = <1>;
|
|
@ -0,0 +1,55 @@
|
|||||||
|
From 97a159dd7747724619e54cb3460d9b8d4ed08be7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
Date: Mon, 02 Jun 2025 12:50:40 +0400
|
||||||
|
Subject: [PATCH v3 4/5] arm64: dts: qcom: ipq5018: Add MDIO buses
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
Message-Id: <20250602-ipq5018-ge-phy-v3-4-0d8f39f402a6@outlook.com>
|
||||||
|
|
||||||
|
IPQ5018 contains two mdio buses of which one bus is used to control the
|
||||||
|
SoC's internal GE PHY, while the other bus is connected to external PHYs
|
||||||
|
or switches.
|
||||||
|
|
||||||
|
There's already support for IPQ5018 in the mdio-ipq4019 driver, so let's
|
||||||
|
simply add the mdio nodes for them.
|
||||||
|
|
||||||
|
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
||||||
|
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
---
|
||||||
|
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 24 ++++++++++++++++++++++++
|
||||||
|
1 file changed, 24 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
|
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
|
@@ -188,6 +188,30 @@
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
+ mdio0: mdio@88000 {
|
||||||
|
+ compatible = "qcom,ipq5018-mdio";
|
||||||
|
+ reg = <0x00088000 0x64>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ clocks = <&gcc GCC_MDIO0_AHB_CLK>;
|
||||||
|
+ clock-names = "gcc_mdio_ahb_clk";
|
||||||
|
+
|
||||||
|
+ status = "disabled";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ mdio1: mdio@90000 {
|
||||||
|
+ compatible = "qcom,ipq5018-mdio";
|
||||||
|
+ reg = <0x00090000 0x64>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ clocks = <&gcc GCC_MDIO1_AHB_CLK>;
|
||||||
|
+ clock-names = "gcc_mdio_ahb_clk";
|
||||||
|
+
|
||||||
|
+ status = "disabled";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
cmn_pll: clock-controller@9b000 {
|
||||||
|
compatible = "qcom,ipq9574-cmn-pll";
|
||||||
|
reg = <0x0009b000 0x800>;
|
@ -0,0 +1,82 @@
|
|||||||
|
From 1b733e878ac1292c6e0f2e9a49685b80c35619b0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
Date: Mon, 02 Jun 2025 12:50:41 +0400
|
||||||
|
Subject: [PATCH v3 5/5] arm64: dts: qcom: ipq5018: Add GE PHY to internal mdio bus
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
Message-Id: <20250602-ipq5018-ge-phy-v3-5-0d8f39f402a6@outlook.com>
|
||||||
|
|
||||||
|
The IPQ5018 SoC contains an internal GE PHY, always at phy address 7.
|
||||||
|
As such, let's add the GE PHY node to the SoC dtsi.
|
||||||
|
|
||||||
|
The LDO controller found in the SoC must be enabled to provide constant
|
||||||
|
low voltages to the PHY. The mdio-ipq4019 driver already has support
|
||||||
|
for this, so adding the appropriate TCSR register offset.
|
||||||
|
|
||||||
|
In addition, the GE PHY outputs both the RX and TX clocks to the GCC
|
||||||
|
which gate controls them and routes them back to the PHY itself.
|
||||||
|
So let's create two DT fixed clocks and register them in the GCC node.
|
||||||
|
|
||||||
|
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
||||||
|
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
---
|
||||||
|
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 26 +++++++++++++++++++++++---
|
||||||
|
1 file changed, 23 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
|
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
|
@@ -22,6 +22,18 @@
|
||||||
|
#clock-cells = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
+ gephy_rx_clk: gephy-rx-clk {
|
||||||
|
+ compatible = "fixed-clock";
|
||||||
|
+ clock-frequency = <125000000>;
|
||||||
|
+ #clock-cells = <0>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ gephy_tx_clk: gephy-tx-clk {
|
||||||
|
+ compatible = "fixed-clock";
|
||||||
|
+ clock-frequency = <125000000>;
|
||||||
|
+ #clock-cells = <0>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
sleep_clk: sleep-clk {
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
#clock-cells = <0>;
|
||||||
|
@@ -190,7 +202,8 @@
|
||||||
|
|
||||||
|
mdio0: mdio@88000 {
|
||||||
|
compatible = "qcom,ipq5018-mdio";
|
||||||
|
- reg = <0x00088000 0x64>;
|
||||||
|
+ reg = <0x00088000 0x64>,
|
||||||
|
+ <0x019475c4 0x4>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
@@ -198,6 +211,13 @@
|
||||||
|
clock-names = "gcc_mdio_ahb_clk";
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
|
+
|
||||||
|
+ ge_phy: ethernet-phy@7 {
|
||||||
|
+ compatible = "ethernet-phy-id004d.d0c0";
|
||||||
|
+ reg = <7>;
|
||||||
|
+
|
||||||
|
+ resets = <&gcc GCC_GEPHY_MISC_ARES>;
|
||||||
|
+ };
|
||||||
|
};
|
||||||
|
|
||||||
|
mdio1: mdio@90000 {
|
||||||
|
@@ -392,8 +412,8 @@
|
||||||
|
<&pcie0_phy>,
|
||||||
|
<&pcie1_phy>,
|
||||||
|
<0>,
|
||||||
|
- <0>,
|
||||||
|
- <0>,
|
||||||
|
+ <&gephy_rx_clk>,
|
||||||
|
+ <&gephy_tx_clk>,
|
||||||
|
<0>,
|
||||||
|
<0>;
|
||||||
|
#clock-cells = <1>;
|
@ -1,111 +0,0 @@
|
|||||||
From: George Moussalem <george.moussalem@outlook.com>
|
|
||||||
Date: Sun, 19 Jan 2025 11:25:27 +0400
|
|
||||||
Subject: [PATCH] net: phy: qcom: ipq5018 enable configuration of DAC settings
|
|
||||||
|
|
||||||
Allow setting amplitude and bias current as needed on the IPQ5018 Internal
|
|
||||||
GE PHY. When the "qcom,dac" property is set in the DTS, the driver expects
|
|
||||||
a pair of u32 values:
|
|
||||||
|
|
||||||
(from QCA8337 datasheet)
|
|
||||||
11: follow DSP setting
|
|
||||||
10: bypass half amplitude and follow DSP half bias current
|
|
||||||
01: half amplitude follow DSP and bypass half bias current
|
|
||||||
00: full amplitude and full bias current
|
|
||||||
|
|
||||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
|
||||||
---
|
|
||||||
--- a/drivers/net/phy/qcom/ipq5018.c
|
|
||||||
+++ b/drivers/net/phy/qcom/ipq5018.c
|
|
||||||
@@ -13,6 +13,10 @@
|
|
||||||
#define IPQ5018_PHY_FIFO_CONTROL 0x19
|
|
||||||
#define IPQ5018_PHY_FIFO_RESET GENMASK(1, 0)
|
|
||||||
|
|
||||||
+#define IPQ5018_PHY_DEBUG_EDAC 0x4380
|
|
||||||
+#define IPQ5018_PHY_MMD1_MDAC 0x8100
|
|
||||||
+#define IPQ5018_PHY_DAC_MASK GENMASK(15,8)
|
|
||||||
+
|
|
||||||
struct ipq5018_phy {
|
|
||||||
int num_clks;
|
|
||||||
struct clk_bulk_data *clks;
|
|
||||||
@@ -20,20 +24,35 @@ struct ipq5018_phy {
|
|
||||||
|
|
||||||
struct clk_hw *clk_rx, *clk_tx;
|
|
||||||
struct clk_hw_onecell_data *clk_data;
|
|
||||||
+
|
|
||||||
+ u32 mdac;
|
|
||||||
+ u32 edac;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ipq5018_probe(struct phy_device *phydev)
|
|
||||||
{
|
|
||||||
- struct ipq5018_phy *priv;
|
|
||||||
struct device *dev = &phydev->mdio.dev;
|
|
||||||
+ struct ipq5018_phy *priv;
|
|
||||||
+ u32 mdac, edac = 0;
|
|
||||||
char name[64];
|
|
||||||
- int ret;
|
|
||||||
+ int ret, cnt;
|
|
||||||
|
|
||||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
|
||||||
if (!priv)
|
|
||||||
return dev_err_probe(dev, -ENOMEM,
|
|
||||||
"failed to allocate priv\n");
|
|
||||||
|
|
||||||
+ cnt = of_property_count_u32_elems(dev->of_node, "qcom,dac");
|
|
||||||
+ if (cnt == 2) {
|
|
||||||
+ ret = of_property_read_u32_index(dev->of_node, "qcom,dac", 0, &mdac);
|
|
||||||
+ if (!ret)
|
|
||||||
+ priv->mdac = mdac;
|
|
||||||
+
|
|
||||||
+ ret = of_property_read_u32_index(dev->of_node, "qcom,dac", 1, &edac);
|
|
||||||
+ if (!ret)
|
|
||||||
+ priv->edac = edac;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks);
|
|
||||||
if (priv->num_clks < 0)
|
|
||||||
return dev_err_probe(dev, priv->num_clks,
|
|
||||||
@@ -84,6 +103,8 @@ static int ipq5018_probe(struct phy_devi
|
|
||||||
return dev_err_probe(dev, ret,
|
|
||||||
"fail to register clock provider\n");
|
|
||||||
|
|
||||||
+ phydev->priv = priv;
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -112,12 +133,34 @@ static int ipq5018_cable_test_start(stru
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int ipq5018_config_init(struct phy_device *phydev)
|
|
||||||
+{
|
|
||||||
+ struct ipq5018_phy *priv = phydev->priv;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ /* setting mdac in MMD1 */
|
|
||||||
+ if (priv->mdac) {
|
|
||||||
+ ret = phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MDAC,
|
|
||||||
+ IPQ5018_PHY_DAC_MASK, priv->mdac);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* setting edac in debug register */
|
|
||||||
+ if (priv->edac)
|
|
||||||
+ return at803x_debug_reg_mask(phydev, IPQ5018_PHY_DEBUG_EDAC,
|
|
||||||
+ IPQ5018_PHY_DAC_MASK, priv->edac);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static struct phy_driver ipq5018_internal_phy_driver[] = {
|
|
||||||
{
|
|
||||||
PHY_ID_MATCH_EXACT(IPQ5018_PHY_ID),
|
|
||||||
.name = "Qualcomm IPQ5018 internal PHY",
|
|
||||||
.flags = PHY_IS_INTERNAL | PHY_POLL_CABLE_TEST,
|
|
||||||
.probe = ipq5018_probe,
|
|
||||||
+ .config_init = ipq5018_config_init,
|
|
||||||
.soft_reset = ipq5018_soft_reset,
|
|
||||||
.read_status = at803x_read_status,
|
|
||||||
.config_intr = at803x_config_intr,
|
|
@ -0,0 +1,20 @@
|
|||||||
|
From: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
Date: Wed, 28 May 2025 08:37:28 +0400
|
||||||
|
Subject: [PATCH] arm64: dts: qcom: ipq5018: Add vendor compatible to mdio bus
|
||||||
|
|
||||||
|
QCA SSDK needs to register the MDIO bus in its driver. Without a proper reference,
|
||||||
|
it will crash. Since it tries to look up the MDIO bus using compatible strings that
|
||||||
|
aren't upstreamed, add the vendor compatible.
|
||||||
|
|
||||||
|
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||||
|
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
|
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
|
@@ -201,7 +201,7 @@
|
||||||
|
};
|
||||||
|
|
||||||
|
mdio0: mdio@88000 {
|
||||||
|
- compatible = "qcom,ipq5018-mdio";
|
||||||
|
+ compatible = "qcom,ipq5018-mdio", "qcom,ipq40xx-mdio";
|
||||||
|
reg = <0x00088000 0x64>,
|
||||||
|
<0x019475c4 0x4>;
|
||||||
|
#address-cells = <1>;
|
@ -1,108 +0,0 @@
|
|||||||
From: George Moussalem <george.moussalem@outlook.com>
|
|
||||||
Date: Fri, 24 Jan 2025 17:18:12 +0400
|
|
||||||
Subject: [PATCH] net: phy: qcom: add IPQ5018 initvals and CDT feature
|
|
||||||
|
|
||||||
The Cable Diagnostics Test for IPQ5018 follows the same logic as qca808x.
|
|
||||||
However, the IPQ5018 GE PHY has its own threshold values. So let's set the
|
|
||||||
CDT thresholds for the IPQ5018 internal GE PHY. While add it, add and set
|
|
||||||
thesholds for MSE for signal quality measurement and 8023az for EEE.
|
|
||||||
|
|
||||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
|
||||||
---
|
|
||||||
--- a/drivers/net/phy/qcom/ipq5018.c
|
|
||||||
+++ b/drivers/net/phy/qcom/ipq5018.c
|
|
||||||
@@ -17,6 +17,38 @@
|
|
||||||
#define IPQ5018_PHY_MMD1_MDAC 0x8100
|
|
||||||
#define IPQ5018_PHY_DAC_MASK GENMASK(15,8)
|
|
||||||
|
|
||||||
+#define IPQ5018_PHY_MMD1_MSE_THRESH1 0x1000
|
|
||||||
+#define IPQ5018_PHY_MMD1_MSE_THRESH2 0x1001
|
|
||||||
+#define IPQ5018_PHY_MMD3_AZ_CTRL1 0x8008
|
|
||||||
+#define IPQ5018_PHY_MMD3_AZ_CTRL2 0x8009
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3 0x8074
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL4 0x8075
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL5 0x8076
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL6 0x8077
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL7 0x8078
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL9 0x807a
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL13 0x807e
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL14 0x807f
|
|
||||||
+
|
|
||||||
+#define IPQ5018_PHY_MMD1_MSE_THRESH1_VAL 0xf1
|
|
||||||
+#define IPQ5018_PHY_MMD1_MSE_THRESH2_VAL 0x1f6
|
|
||||||
+#define IPQ5018_PHY_MMD3_AZ_CTRL1_VAL 0x7880
|
|
||||||
+#define IPQ5018_PHY_MMD3_AZ_CTRL2_VAL 0xc8
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3_VAL 0xc040
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL4_VAL 0xa060
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL5_VAL 0xc040
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL6_VAL 0xa060
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL7_VAL 0xc24c
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL9_VAL 0xc060
|
|
||||||
+#define IPQ5018_PHY_MMD3_CDT_THRESH_CTRL13_VAL 0xb060
|
|
||||||
+#define IPQ5018_PHY_MMD3_NEAR_ECHO_THRESH_VAL 0x90b0
|
|
||||||
+
|
|
||||||
+#define IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE 0x1
|
|
||||||
+#define IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_MASK GENMASK(7,4)
|
|
||||||
+#define IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_DEFAULT 0x50
|
|
||||||
+
|
|
||||||
+#define IPQ5018_PHY_DEBUG_ANA_DAC_FILTER 0xa080
|
|
||||||
+
|
|
||||||
struct ipq5018_phy {
|
|
||||||
int num_clks;
|
|
||||||
struct clk_bulk_data *clks;
|
|
||||||
@@ -129,6 +161,24 @@ static int ipq5018_soft_reset(struct phy
|
|
||||||
|
|
||||||
static int ipq5018_cable_test_start(struct phy_device *phydev)
|
|
||||||
{
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3,
|
|
||||||
+ IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL4,
|
|
||||||
+ IPQ5018_PHY_MMD3_CDT_THRESH_CTRL4_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL5,
|
|
||||||
+ IPQ5018_PHY_MMD3_CDT_THRESH_CTRL5_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL6,
|
|
||||||
+ IPQ5018_PHY_MMD3_CDT_THRESH_CTRL6_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL7,
|
|
||||||
+ IPQ5018_PHY_MMD3_CDT_THRESH_CTRL7_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL9,
|
|
||||||
+ IPQ5018_PHY_MMD3_CDT_THRESH_CTRL9_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS,
|
|
||||||
+ IPQ5018_PHY_MMD3_CDT_THRESH_CTRL13,
|
|
||||||
+ IPQ5018_PHY_MMD3_CDT_THRESH_CTRL13_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_CDT_THRESH_CTRL3,
|
|
||||||
+ IPQ5018_PHY_MMD3_NEAR_ECHO_THRESH_VAL);
|
|
||||||
+
|
|
||||||
/* we do all the (time consuming) work later */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -136,8 +186,30 @@ static int ipq5018_cable_test_start(stru
|
|
||||||
static int ipq5018_config_init(struct phy_device *phydev)
|
|
||||||
{
|
|
||||||
struct ipq5018_phy *priv = phydev->priv;
|
|
||||||
+ u16 val = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
+ /* set LDO efuse: first temporarily store ANA_DAC_FILTER value from
|
|
||||||
+ debug register as it will be reset once the ANA_LDO_EFUSE register
|
|
||||||
+ is written to */
|
|
||||||
+ val = at803x_debug_reg_read(phydev, IPQ5018_PHY_DEBUG_ANA_DAC_FILTER);
|
|
||||||
+ at803x_debug_reg_mask(phydev, IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE,
|
|
||||||
+ IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_MASK,
|
|
||||||
+ IPQ5018_PHY_DEBUG_ANA_LDO_EFUSE_DEFAULT);
|
|
||||||
+ at803x_debug_reg_write(phydev, IPQ5018_PHY_DEBUG_ANA_DAC_FILTER, val);
|
|
||||||
+
|
|
||||||
+ /* set 8023AZ CTRL values */
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_AZ_CTRL1,
|
|
||||||
+ IPQ5018_PHY_MMD3_AZ_CTRL1_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS, IPQ5018_PHY_MMD3_AZ_CTRL2,
|
|
||||||
+ IPQ5018_PHY_MMD3_AZ_CTRL2_VAL);
|
|
||||||
+
|
|
||||||
+ /* set MSE threshold values */
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MSE_THRESH1,
|
|
||||||
+ IPQ5018_PHY_MMD1_MSE_THRESH1_VAL);
|
|
||||||
+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MSE_THRESH2,
|
|
||||||
+ IPQ5018_PHY_MMD1_MSE_THRESH2_VAL);
|
|
||||||
+
|
|
||||||
/* setting mdac in MMD1 */
|
|
||||||
if (priv->mdac) {
|
|
||||||
ret = phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MDAC,
|
|
@ -13,7 +13,7 @@ Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
|||||||
---
|
---
|
||||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
@@ -694,6 +694,225 @@
|
@@ -697,6 +697,225 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
|||||||
---
|
---
|
||||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||||
@@ -111,6 +111,11 @@
|
@@ -123,6 +123,11 @@
|
||||||
#size-cells = <2>;
|
#size-cells = <2>;
|
||||||
ranges;
|
ranges;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user