
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>
112 lines
3.0 KiB
Diff
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,
|