78111f7982e25d9807001425e2fa6d0c016d275d
[openwrt/staging/stintel.git] /
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
5 QCA8084
6
7 Parse the PHY package clocks from the PHY package DTS node.
8 These package level clocks will be enabled in the PHY package
9 init function.
10
11 Deassert PHY package reset, which is necessary for accessing
12 the PHY registers.
13
14 Change-Id: I254d0aa0a1155d3618c6f1fc7d7a5b6ecadccbaa
15 Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
16 ---
17 drivers/net/phy/qcom/qca808x.c | 67 ++++++++++++++++++++++++++++++++--
18 1 file changed, 64 insertions(+), 3 deletions(-)
19
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
24 @@ -4,6 +4,7 @@
25 #include <linux/module.h>
26 #include <linux/of.h>
27 #include <linux/clk.h>
28 +#include <linux/reset.h>
29
30 #include "qcom.h"
31
32 @@ -148,10 +149,35 @@ MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
33 MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
34 MODULE_LICENSE("GPL");
35
36 +enum {
37 + APB_BRIDGE_CLK,
38 + AHB_CLK,
39 + SEC_CTRL_AHB_CLK,
40 + TLMM_CLK,
41 + TLMM_AHB_CLK,
42 + CNOC_AHB_CLK,
43 + MDIO_AHB_CLK,
44 + PACKAGE_CLK_MAX
45 +};
46 +
47 struct qca808x_priv {
48 int led_polarity_mode;
49 };
50
51 +struct qca808x_shared_priv {
52 + struct clk *clk[PACKAGE_CLK_MAX];
53 +};
54 +
55 +static const char *const qca8084_package_clk_name[PACKAGE_CLK_MAX] = {
56 + [APB_BRIDGE_CLK] = "apb_bridge",
57 + [AHB_CLK] = "ahb",
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",
63 +};
64 +
65 static int __qca8084_set_page(struct mii_bus *bus, u16 sw_addr, u16 page)
66 {
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);
70 }
71
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
75 + * to support SGMII.
76 + *
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.
81 + */
82 static int qca8084_phy_package_probe_once(struct phy_device *phydev)
83 {
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;
90 + struct clk *clk;
91
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]);
97
98 - return qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
99 + ret = qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
100 + if (ret)
101 + return ret;
102 +
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]);
107 + if (IS_ERR(clk))
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;
112 + }
113 +
114 + rstc = of_reset_control_get_exclusive(shared->np, NULL);
115 + if (IS_ERR(rstc))
116 + return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
117 + "package reset not ready\n");
118 +
119 + /* Deassert PHY package. */
120 + return reset_control_deassert(rstc);
121 }
122
123 static int qca8084_probe(struct phy_device *phydev)
124 {
125 + struct qca808x_shared_priv *shared_priv;
126 struct device *dev = &phydev->mdio.dev;
127 struct reset_control *rstc;
128 struct clk *clk;
129 int ret;
130
131 - ret = devm_of_phy_package_join(dev, phydev, 0);
132 + ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv));
133 if (ret)
134 return ret;
135
136 --
137 2.45.2
138