1 From: George Moussalem <george.moussalem@outlook.com>
2 Date: Sun, 19 Jan 2025 11:25:27 +0400
3 Subject: [PATCH] net: phy: qcom: ipq5018 enable configuration of DAC settings
5 Allow setting amplitude and bias current as needed on the IPQ5018 Internal
6 GE PHY. When the "qcom,dac" property is set in the DTS, the driver expects
9 (from QCA8337 datasheet)
10 11: follow DSP setting
11 10: bypass half amplitude and follow DSP half bias current
12 01: half amplitude follow DSP and bypass half bias current
13 00: full amplitude and full bias current
15 Signed-off-by: George Moussalem <george.moussalem@outlook.com>
17 --- a/drivers/net/phy/qcom/ipq5018.c
18 +++ b/drivers/net/phy/qcom/ipq5018.c
20 #define IPQ5018_PHY_FIFO_CONTROL 0x19
21 #define IPQ5018_PHY_FIFO_RESET GENMASK(1, 0)
23 +#define IPQ5018_PHY_DEBUG_EDAC 0x4380
24 +#define IPQ5018_PHY_MMD1_MDAC 0x8100
25 +#define IPQ5018_PHY_DAC_MASK GENMASK(15,8)
29 struct clk_bulk_data *clks;
30 @@ -20,20 +24,35 @@ struct ipq5018_phy {
32 struct clk_hw *clk_rx, *clk_tx;
33 struct clk_hw_onecell_data *clk_data;
39 static int ipq5018_probe(struct phy_device *phydev)
41 - struct ipq5018_phy *priv;
42 struct device *dev = &phydev->mdio.dev;
43 + struct ipq5018_phy *priv;
49 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
51 return dev_err_probe(dev, -ENOMEM,
52 "failed to allocate priv\n");
54 + cnt = of_property_count_u32_elems(dev->of_node, "qcom,dac");
56 + ret = of_property_read_u32_index(dev->of_node, "qcom,dac", 0, &mdac);
60 + ret = of_property_read_u32_index(dev->of_node, "qcom,dac", 1, &edac);
65 priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks);
66 if (priv->num_clks < 0)
67 return dev_err_probe(dev, priv->num_clks,
68 @@ -84,6 +103,8 @@ static int ipq5018_probe(struct phy_devi
69 return dev_err_probe(dev, ret,
70 "fail to register clock provider\n");
72 + phydev->priv = priv;
77 @@ -112,12 +133,34 @@ static int ipq5018_cable_test_start(stru
81 +static int ipq5018_config_init(struct phy_device *phydev)
83 + struct ipq5018_phy *priv = phydev->priv;
86 + /* setting mdac in MMD1 */
88 + ret = phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, IPQ5018_PHY_MMD1_MDAC,
89 + IPQ5018_PHY_DAC_MASK, priv->mdac);
94 + /* setting edac in debug register */
96 + return at803x_debug_reg_mask(phydev, IPQ5018_PHY_DEBUG_EDAC,
97 + IPQ5018_PHY_DAC_MASK, priv->edac);
102 static struct phy_driver ipq5018_internal_phy_driver[] = {
104 PHY_ID_MATCH_EXACT(IPQ5018_PHY_ID),
105 .name = "Qualcomm IPQ5018 internal PHY",
106 .flags = PHY_IS_INTERNAL | PHY_POLL_CABLE_TEST,
107 .probe = ipq5018_probe,
108 + .config_init = ipq5018_config_init,
109 .soft_reset = ipq5018_soft_reset,
110 .read_status = at803x_read_status,
111 .config_intr = at803x_config_intr,