openwrt/target/linux/qualcommax/patches-6.6/0714-net-phy-qcom-IPQ5018-enable-configuration-of-DAC-settings.patch
George Moussalem 34d9172655 qualcommax: add ipq50xx target
Introduce support for the Qualcomm IPQ50xx SoC.
This series adds support for the following components:
- minimal boot support: GCC/pinctrl/watchdog/CPUFreq/SDI (upstreamed)
- USB2 (upstreamed)
- Thermal/Tsens
- PCIe gen2 1&2-lane PHY and controller
- PWM and PWM LED
- QPIC SPI NAND controller
- CMN PLL Block (provider of fixed rate clocks to GCC/ethernet/more.)
- Ethernet: IPQ5018 Internal GE PHY (1 gbps)
- Remoteproc MPD driver for IPQ5018 (2.4G) & QCN6122 (5/6G) Wifi

Co-developed-by: Ziyang Huang <hzyitc@outlook.com>
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/17182
Signed-off-by: Robert Marko <robimarko@gmail.com>
2025-02-06 09:51:13 +01:00

112 lines
3.0 KiB
Diff

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,