1 From 324c5b908a5294390ed9659a6439758cb20ecd61 Mon Sep 17 00:00:00 2001
2 From: Luo Jie <quic_luoj@quicinc.com>
3 Date: Tue, 9 Apr 2024 16:30:55 +0800
4 Subject: [PATCH 07/50] net: phy: qca808x: Add package clocks and resets for
7 Parse the PHY package clocks from the PHY package DTS node.
8 These package level clocks will be enabled in the PHY package
11 Deassert PHY package reset, which is necessary for accessing
14 Change-Id: I254d0aa0a1155d3618c6f1fc7d7a5b6ecadccbaa
15 Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
17 drivers/net/phy/qcom/qca808x.c | 67 ++++++++++++++++++++++++++++++++--
18 1 file changed, 64 insertions(+), 3 deletions(-)
20 diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c
21 index 85bb299fe0a3..632cad1ad190 100644
22 --- a/drivers/net/phy/qcom/qca808x.c
23 +++ b/drivers/net/phy/qcom/qca808x.c
25 #include <linux/module.h>
27 #include <linux/clk.h>
28 +#include <linux/reset.h>
32 @@ -148,10 +149,35 @@ MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
33 MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
34 MODULE_LICENSE("GPL");
48 int led_polarity_mode;
51 +struct qca808x_shared_priv {
52 + struct clk *clk[PACKAGE_CLK_MAX];
55 +static const char *const qca8084_package_clk_name[PACKAGE_CLK_MAX] = {
56 + [APB_BRIDGE_CLK] = "apb_bridge",
58 + [SEC_CTRL_AHB_CLK] = "sec_ctrl_ahb",
59 + [TLMM_CLK] = "tlmm",
60 + [TLMM_AHB_CLK] = "tlmm_ahb",
61 + [CNOC_AHB_CLK] = "cnoc_ahb",
62 + [MDIO_AHB_CLK] = "mdio_ahb",
65 static int __qca8084_set_page(struct mii_bus *bus, u16 sw_addr, u16 page)
67 return __mdiobus_write(bus, QCA8084_HIGH_ADDR_PREFIX | (sw_addr >> 5),
68 @@ -853,11 +879,24 @@ static void qca8084_link_change_notify(struct phy_device *phydev)
69 QCA8084_IPG_10_TO_11_EN : 0);
72 +/* QCA8084 is a four-port PHY, which integrates the clock controller,
73 + * 4 PHY devices and 2 PCS interfaces (PCS0 and PCS1). PCS1 includes
74 + * XPCS and PCS to support 10G-QXGMII and SGMII. PCS0 includes one PCS
77 + * The clocks and resets are sourced from the integrated clock controller
78 + * of the PHY package. This integrated clock controller is driven by a
79 + * QCA8K clock provider that supplies the clocks and resets to the four
80 + * PHYs, PCS and PHY package.
82 static int qca8084_phy_package_probe_once(struct phy_device *phydev)
84 int addr[QCA8084_MDIO_DEVICE_NUM] = {0, 1, 2, 3, 4, 5, 6};
85 struct phy_package_shared *shared = phydev->shared;
86 - int ret, clear, set;
87 + struct qca808x_shared_priv *shared_priv;
88 + struct reset_control *rstc;
89 + int i, ret, clear, set;
92 /* Program the MDIO address of PHY and PCS optionally, the MDIO
93 * address 0-6 is used for PHY and PCS MDIO devices by default.
94 @@ -889,17 +928,39 @@ static int qca8084_phy_package_probe_once(struct phy_device *phydev)
95 set |= FIELD_PREP(QCA8084_PCS_ADDR1_MASK, addr[5]);
96 set |= FIELD_PREP(QCA8084_PCS_ADDR2_MASK, addr[6]);
98 - return qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
99 + ret = qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
103 + shared_priv = shared->priv;
104 + for (i = 0; i < ARRAY_SIZE(qca8084_package_clk_name); i++) {
105 + clk = of_clk_get_by_name(shared->np,
106 + qca8084_package_clk_name[i]);
108 + return dev_err_probe(&phydev->mdio.dev, PTR_ERR(clk),
109 + "package clock %s not ready\n",
110 + qca8084_package_clk_name[i]);
111 + shared_priv->clk[i] = clk;
114 + rstc = of_reset_control_get_exclusive(shared->np, NULL);
116 + return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
117 + "package reset not ready\n");
119 + /* Deassert PHY package. */
120 + return reset_control_deassert(rstc);
123 static int qca8084_probe(struct phy_device *phydev)
125 + struct qca808x_shared_priv *shared_priv;
126 struct device *dev = &phydev->mdio.dev;
127 struct reset_control *rstc;
131 - ret = devm_of_phy_package_join(dev, phydev, 0);
132 + ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv));