1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright (c) 2015, The Linux Foundation. All rights reserved. */
3 /* Copyright (c) 2020 Sartura Ltd. */
5 #include <linux/delay.h>
7 #include <linux/iopoll.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/of_address.h>
11 #include <linux/of_mdio.h>
12 #include <linux/phy.h>
13 #include <linux/platform_device.h>
14 #include <linux/clk.h>
16 #define MDIO_MODE_REG 0x40
17 #define MDIO_MODE_MDC_MODE BIT(12)
18 /* 0 = Clause 22, 1 = Clause 45 */
19 #define MDIO_MODE_C45 BIT(8)
20 #define MDIO_MODE_DIV_MASK GENMASK(7, 0)
21 #define MDIO_MODE_DIV(x) FIELD_PREP(MDIO_MODE_DIV_MASK, (x) - 1)
22 #define MDIO_MODE_DIV_1 0x0
23 #define MDIO_MODE_DIV_2 0x1
24 #define MDIO_MODE_DIV_4 0x3
25 #define MDIO_MODE_DIV_8 0x7
26 #define MDIO_MODE_DIV_16 0xf
27 #define MDIO_MODE_DIV_32 0x1f
28 #define MDIO_MODE_DIV_64 0x3f
29 #define MDIO_MODE_DIV_128 0x7f
30 #define MDIO_MODE_DIV_256 0xff
31 #define MDIO_ADDR_REG 0x44
32 #define MDIO_DATA_WRITE_REG 0x48
33 #define MDIO_DATA_READ_REG 0x4c
34 #define MDIO_CMD_REG 0x50
35 #define MDIO_CMD_ACCESS_BUSY BIT(16)
36 #define MDIO_CMD_ACCESS_START BIT(8)
37 #define MDIO_CMD_ACCESS_CODE_READ 0
38 #define MDIO_CMD_ACCESS_CODE_WRITE 1
39 #define MDIO_CMD_ACCESS_CODE_C45_ADDR 0
40 #define MDIO_CMD_ACCESS_CODE_C45_WRITE 1
41 #define MDIO_CMD_ACCESS_CODE_C45_READ 2
43 #define IPQ4019_MDIO_TIMEOUT 10000
44 #define IPQ4019_MDIO_SLEEP 10
46 /* MDIO clock source frequency is fixed to 100M */
47 #define IPQ_MDIO_CLK_RATE 100000000
49 #define IPQ_PHY_SET_DELAY_US 100000
51 struct ipq4019_mdio_data
{
52 void __iomem
*membase
;
53 void __iomem
*eth_ldo_rdy
;
55 unsigned int mdc_rate
;
58 static int ipq4019_mdio_wait_busy(struct mii_bus
*bus
)
60 struct ipq4019_mdio_data
*priv
= bus
->priv
;
63 return readl_poll_timeout(priv
->membase
+ MDIO_CMD_REG
, busy
,
64 (busy
& MDIO_CMD_ACCESS_BUSY
) == 0,
65 IPQ4019_MDIO_SLEEP
, IPQ4019_MDIO_TIMEOUT
);
68 static int ipq4019_mdio_read_c45(struct mii_bus
*bus
, int mii_id
, int mmd
,
71 struct ipq4019_mdio_data
*priv
= bus
->priv
;
75 if (ipq4019_mdio_wait_busy(bus
))
78 data
= readl(priv
->membase
+ MDIO_MODE_REG
);
80 data
|= MDIO_MODE_C45
;
82 writel(data
, priv
->membase
+ MDIO_MODE_REG
);
84 /* issue the phy address and mmd */
85 writel((mii_id
<< 8) | mmd
, priv
->membase
+ MDIO_ADDR_REG
);
88 writel(reg
, priv
->membase
+ MDIO_DATA_WRITE_REG
);
90 cmd
= MDIO_CMD_ACCESS_START
| MDIO_CMD_ACCESS_CODE_C45_ADDR
;
92 /* issue read command */
93 writel(cmd
, priv
->membase
+ MDIO_CMD_REG
);
95 /* Wait read complete */
96 if (ipq4019_mdio_wait_busy(bus
))
99 cmd
= MDIO_CMD_ACCESS_START
| MDIO_CMD_ACCESS_CODE_C45_READ
;
101 writel(cmd
, priv
->membase
+ MDIO_CMD_REG
);
103 if (ipq4019_mdio_wait_busy(bus
))
106 /* Read and return data */
107 return readl(priv
->membase
+ MDIO_DATA_READ_REG
);
110 static int ipq4019_mdio_read_c22(struct mii_bus
*bus
, int mii_id
, int regnum
)
112 struct ipq4019_mdio_data
*priv
= bus
->priv
;
116 if (ipq4019_mdio_wait_busy(bus
))
119 data
= readl(priv
->membase
+ MDIO_MODE_REG
);
121 data
&= ~MDIO_MODE_C45
;
123 writel(data
, priv
->membase
+ MDIO_MODE_REG
);
125 /* issue the phy address and reg */
126 writel((mii_id
<< 8) | regnum
, priv
->membase
+ MDIO_ADDR_REG
);
128 cmd
= MDIO_CMD_ACCESS_START
| MDIO_CMD_ACCESS_CODE_READ
;
130 /* issue read command */
131 writel(cmd
, priv
->membase
+ MDIO_CMD_REG
);
133 /* Wait read complete */
134 if (ipq4019_mdio_wait_busy(bus
))
137 /* Read and return data */
138 return readl(priv
->membase
+ MDIO_DATA_READ_REG
);
141 static int ipq4019_mdio_write_c45(struct mii_bus
*bus
, int mii_id
, int mmd
,
144 struct ipq4019_mdio_data
*priv
= bus
->priv
;
148 if (ipq4019_mdio_wait_busy(bus
))
151 data
= readl(priv
->membase
+ MDIO_MODE_REG
);
153 data
|= MDIO_MODE_C45
;
155 writel(data
, priv
->membase
+ MDIO_MODE_REG
);
157 /* issue the phy address and mmd */
158 writel((mii_id
<< 8) | mmd
, priv
->membase
+ MDIO_ADDR_REG
);
161 writel(reg
, priv
->membase
+ MDIO_DATA_WRITE_REG
);
163 cmd
= MDIO_CMD_ACCESS_START
| MDIO_CMD_ACCESS_CODE_C45_ADDR
;
165 writel(cmd
, priv
->membase
+ MDIO_CMD_REG
);
167 if (ipq4019_mdio_wait_busy(bus
))
170 /* issue write data */
171 writel(value
, priv
->membase
+ MDIO_DATA_WRITE_REG
);
173 cmd
= MDIO_CMD_ACCESS_START
| MDIO_CMD_ACCESS_CODE_C45_WRITE
;
174 writel(cmd
, priv
->membase
+ MDIO_CMD_REG
);
176 /* Wait write complete */
177 if (ipq4019_mdio_wait_busy(bus
))
183 static int ipq4019_mdio_write_c22(struct mii_bus
*bus
, int mii_id
, int regnum
,
186 struct ipq4019_mdio_data
*priv
= bus
->priv
;
190 if (ipq4019_mdio_wait_busy(bus
))
193 /* Enter Clause 22 mode */
194 data
= readl(priv
->membase
+ MDIO_MODE_REG
);
196 data
&= ~MDIO_MODE_C45
;
198 writel(data
, priv
->membase
+ MDIO_MODE_REG
);
200 /* issue the phy address and reg */
201 writel((mii_id
<< 8) | regnum
, priv
->membase
+ MDIO_ADDR_REG
);
203 /* issue write data */
204 writel(value
, priv
->membase
+ MDIO_DATA_WRITE_REG
);
206 /* issue write command */
207 cmd
= MDIO_CMD_ACCESS_START
| MDIO_CMD_ACCESS_CODE_WRITE
;
209 writel(cmd
, priv
->membase
+ MDIO_CMD_REG
);
211 /* Wait write complete */
212 if (ipq4019_mdio_wait_busy(bus
))
218 static int ipq4019_mdio_set_div(struct ipq4019_mdio_data
*priv
)
220 unsigned long ahb_rate
;
224 /* If we don't have a clock for AHB use the fixed value */
225 ahb_rate
= IPQ_MDIO_CLK_RATE
;
227 ahb_rate
= clk_get_rate(priv
->mdio_clk
);
229 /* MDC rate is ahb_rate/(MDIO_MODE_DIV + 1)
230 * While supported, internal documentation doesn't
231 * assure correct functionality of the MDIO bus
232 * with divider of 1, 2 or 4.
234 for (div
= 8; div
<= 256; div
*= 2) {
235 /* The requested rate is supported by the div */
236 if (priv
->mdc_rate
== DIV_ROUND_UP(ahb_rate
, div
)) {
237 val
= readl(priv
->membase
+ MDIO_MODE_REG
);
238 val
&= ~MDIO_MODE_DIV_MASK
;
239 val
|= MDIO_MODE_DIV(div
);
240 writel(val
, priv
->membase
+ MDIO_MODE_REG
);
246 /* The requested rate is not supported */
250 static int ipq_mdio_reset(struct mii_bus
*bus
)
252 struct ipq4019_mdio_data
*priv
= bus
->priv
;
256 /* To indicate CMN_PLL that ethernet_ldo has been ready if platform resource 1
257 * is specified in the device tree.
259 if (priv
->eth_ldo_rdy
) {
260 val
= readl(priv
->eth_ldo_rdy
);
262 writel(val
, priv
->eth_ldo_rdy
);
263 fsleep(IPQ_PHY_SET_DELAY_US
);
266 /* Configure MDIO clock source frequency if clock is specified in the device tree */
267 ret
= clk_set_rate(priv
->mdio_clk
, IPQ_MDIO_CLK_RATE
);
271 ret
= clk_prepare_enable(priv
->mdio_clk
);
277 /* Restore MDC rate */
278 return ipq4019_mdio_set_div(priv
);
281 static void ipq4019_mdio_select_mdc_rate(struct platform_device
*pdev
,
282 struct ipq4019_mdio_data
*priv
)
284 unsigned long ahb_rate
;
288 /* MDC rate defined in DT, we don't have to decide a default value */
289 if (!of_property_read_u32(pdev
->dev
.of_node
, "clock-frequency",
293 /* If we don't have a clock for AHB use the fixed value */
294 ahb_rate
= IPQ_MDIO_CLK_RATE
;
296 ahb_rate
= clk_get_rate(priv
->mdio_clk
);
298 /* Check what is the current div set */
299 val
= readl(priv
->membase
+ MDIO_MODE_REG
);
300 div
= FIELD_GET(MDIO_MODE_DIV_MASK
, val
);
302 /* div is not set to the default value of /256
303 * Probably someone changed that (bootloader, other drivers)
304 * Keep this and don't overwrite it.
306 if (div
!= MDIO_MODE_DIV_256
) {
307 priv
->mdc_rate
= DIV_ROUND_UP(ahb_rate
, div
+ 1);
311 /* If div is /256 assume nobody have set this value and
312 * try to find one MDC rate that is close the 802.3 spec of
315 for (div
= 256; div
>= 8; div
/= 2) {
316 /* Stop as soon as we found a divider that
317 * reached the closest value to 2.5MHz
319 if (DIV_ROUND_UP(ahb_rate
, div
) > 2500000)
322 priv
->mdc_rate
= DIV_ROUND_UP(ahb_rate
, div
);
326 static int ipq4019_mdio_probe(struct platform_device
*pdev
)
328 struct ipq4019_mdio_data
*priv
;
330 struct resource
*res
;
333 bus
= devm_mdiobus_alloc_size(&pdev
->dev
, sizeof(*priv
));
339 priv
->membase
= devm_platform_ioremap_resource(pdev
, 0);
340 if (IS_ERR(priv
->membase
))
341 return PTR_ERR(priv
->membase
);
343 priv
->mdio_clk
= devm_clk_get_optional(&pdev
->dev
, "gcc_mdio_ahb_clk");
344 if (IS_ERR(priv
->mdio_clk
))
345 return PTR_ERR(priv
->mdio_clk
);
347 ipq4019_mdio_select_mdc_rate(pdev
, priv
);
348 ret
= ipq4019_mdio_set_div(priv
);
352 /* The platform resource is provided on the chipset IPQ5018 */
353 /* This resource is optional */
354 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
356 priv
->eth_ldo_rdy
= devm_ioremap_resource(&pdev
->dev
, res
);
357 if (IS_ERR(priv
->eth_ldo_rdy
))
358 return PTR_ERR(priv
->eth_ldo_rdy
);
361 bus
->name
= "ipq4019_mdio";
362 bus
->read
= ipq4019_mdio_read_c22
;
363 bus
->write
= ipq4019_mdio_write_c22
;
364 bus
->read_c45
= ipq4019_mdio_read_c45
;
365 bus
->write_c45
= ipq4019_mdio_write_c45
;
366 bus
->reset
= ipq_mdio_reset
;
367 bus
->parent
= &pdev
->dev
;
368 snprintf(bus
->id
, MII_BUS_ID_SIZE
, "%s%d", pdev
->name
, pdev
->id
);
370 ret
= of_mdiobus_register(bus
, pdev
->dev
.of_node
);
372 dev_err(&pdev
->dev
, "Cannot register MDIO bus!\n");
376 platform_set_drvdata(pdev
, bus
);
381 static void ipq4019_mdio_remove(struct platform_device
*pdev
)
383 struct mii_bus
*bus
= platform_get_drvdata(pdev
);
385 mdiobus_unregister(bus
);
388 static const struct of_device_id ipq4019_mdio_dt_ids
[] = {
389 { .compatible
= "qcom,ipq4019-mdio" },
390 { .compatible
= "qcom,ipq5018-mdio" },
393 MODULE_DEVICE_TABLE(of
, ipq4019_mdio_dt_ids
);
395 static struct platform_driver ipq4019_mdio_driver
= {
396 .probe
= ipq4019_mdio_probe
,
397 .remove
= ipq4019_mdio_remove
,
399 .name
= "ipq4019-mdio",
400 .of_match_table
= ipq4019_mdio_dt_ids
,
404 module_platform_driver(ipq4019_mdio_driver
);
406 MODULE_DESCRIPTION("ipq4019 MDIO interface driver");
407 MODULE_AUTHOR("Qualcomm Atheros");
408 MODULE_LICENSE("Dual BSD/GPL");