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. */ 4 5 #include <linux/delay.h> 6 #include <linux/io.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> 15 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 42 43 #define IPQ4019_MDIO_TIMEOUT 10000 44 #define IPQ4019_MDIO_SLEEP 10 45 46 /* MDIO clock source frequency is fixed to 100M */ 47 #define IPQ_MDIO_CLK_RATE 100000000 48 49 #define IPQ_PHY_SET_DELAY_US 100000 50 51 struct ipq4019_mdio_data { 52 void __iomem *membase; 53 void __iomem *eth_ldo_rdy; 54 struct clk *mdio_clk; 55 unsigned int mdc_rate; 56 }; 57 58 static int ipq4019_mdio_wait_busy(struct mii_bus *bus) 59 { 60 struct ipq4019_mdio_data *priv = bus->priv; 61 unsigned int busy; 62 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); 66 } 67 68 static int ipq4019_mdio_read_c45(struct mii_bus *bus, int mii_id, int mmd, 69 int reg) 70 { 71 struct ipq4019_mdio_data *priv = bus->priv; 72 unsigned int data; 73 unsigned int cmd; 74 75 if (ipq4019_mdio_wait_busy(bus)) 76 return -ETIMEDOUT; 77 78 data = readl(priv->membase + MDIO_MODE_REG); 79 80 data |= MDIO_MODE_C45; 81 82 writel(data, priv->membase + MDIO_MODE_REG); 83 84 /* issue the phy address and mmd */ 85 writel((mii_id << 8) | mmd, priv->membase + MDIO_ADDR_REG); 86 87 /* issue reg */ 88 writel(reg, priv->membase + MDIO_DATA_WRITE_REG); 89 90 cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_ADDR; 91 92 /* issue read command */ 93 writel(cmd, priv->membase + MDIO_CMD_REG); 94 95 /* Wait read complete */ 96 if (ipq4019_mdio_wait_busy(bus)) 97 return -ETIMEDOUT; 98 99 cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_READ; 100 101 writel(cmd, priv->membase + MDIO_CMD_REG); 102 103 if (ipq4019_mdio_wait_busy(bus)) 104 return -ETIMEDOUT; 105 106 /* Read and return data */ 107 return readl(priv->membase + MDIO_DATA_READ_REG); 108 } 109 110 static int ipq4019_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum) 111 { 112 struct ipq4019_mdio_data *priv = bus->priv; 113 unsigned int data; 114 unsigned int cmd; 115 116 if (ipq4019_mdio_wait_busy(bus)) 117 return -ETIMEDOUT; 118 119 data = readl(priv->membase + MDIO_MODE_REG); 120 121 data &= ~MDIO_MODE_C45; 122 123 writel(data, priv->membase + MDIO_MODE_REG); 124 125 /* issue the phy address and reg */ 126 writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG); 127 128 cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_READ; 129 130 /* issue read command */ 131 writel(cmd, priv->membase + MDIO_CMD_REG); 132 133 /* Wait read complete */ 134 if (ipq4019_mdio_wait_busy(bus)) 135 return -ETIMEDOUT; 136 137 /* Read and return data */ 138 return readl(priv->membase + MDIO_DATA_READ_REG); 139 } 140 141 static int ipq4019_mdio_write_c45(struct mii_bus *bus, int mii_id, int mmd, 142 int reg, u16 value) 143 { 144 struct ipq4019_mdio_data *priv = bus->priv; 145 unsigned int data; 146 unsigned int cmd; 147 148 if (ipq4019_mdio_wait_busy(bus)) 149 return -ETIMEDOUT; 150 151 data = readl(priv->membase + MDIO_MODE_REG); 152 153 data |= MDIO_MODE_C45; 154 155 writel(data, priv->membase + MDIO_MODE_REG); 156 157 /* issue the phy address and mmd */ 158 writel((mii_id << 8) | mmd, priv->membase + MDIO_ADDR_REG); 159 160 /* issue reg */ 161 writel(reg, priv->membase + MDIO_DATA_WRITE_REG); 162 163 cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_ADDR; 164 165 writel(cmd, priv->membase + MDIO_CMD_REG); 166 167 if (ipq4019_mdio_wait_busy(bus)) 168 return -ETIMEDOUT; 169 170 /* issue write data */ 171 writel(value, priv->membase + MDIO_DATA_WRITE_REG); 172 173 cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_WRITE; 174 writel(cmd, priv->membase + MDIO_CMD_REG); 175 176 /* Wait write complete */ 177 if (ipq4019_mdio_wait_busy(bus)) 178 return -ETIMEDOUT; 179 180 return 0; 181 } 182 183 static int ipq4019_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum, 184 u16 value) 185 { 186 struct ipq4019_mdio_data *priv = bus->priv; 187 unsigned int data; 188 unsigned int cmd; 189 190 if (ipq4019_mdio_wait_busy(bus)) 191 return -ETIMEDOUT; 192 193 /* Enter Clause 22 mode */ 194 data = readl(priv->membase + MDIO_MODE_REG); 195 196 data &= ~MDIO_MODE_C45; 197 198 writel(data, priv->membase + MDIO_MODE_REG); 199 200 /* issue the phy address and reg */ 201 writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG); 202 203 /* issue write data */ 204 writel(value, priv->membase + MDIO_DATA_WRITE_REG); 205 206 /* issue write command */ 207 cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_WRITE; 208 209 writel(cmd, priv->membase + MDIO_CMD_REG); 210 211 /* Wait write complete */ 212 if (ipq4019_mdio_wait_busy(bus)) 213 return -ETIMEDOUT; 214 215 return 0; 216 } 217 218 static int ipq4019_mdio_set_div(struct ipq4019_mdio_data *priv) 219 { 220 unsigned long ahb_rate; 221 int div; 222 u32 val; 223 224 /* If we don't have a clock for AHB use the fixed value */ 225 ahb_rate = IPQ_MDIO_CLK_RATE; 226 if (priv->mdio_clk) 227 ahb_rate = clk_get_rate(priv->mdio_clk); 228 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. 233 */ 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); 241 242 return 0; 243 } 244 } 245 246 /* The requested rate is not supported */ 247 return -EINVAL; 248 } 249 250 static int ipq_mdio_reset(struct mii_bus *bus) 251 { 252 struct ipq4019_mdio_data *priv = bus->priv; 253 u32 val; 254 int ret; 255 256 /* To indicate CMN_PLL that ethernet_ldo has been ready if platform resource 1 257 * is specified in the device tree. 258 */ 259 if (priv->eth_ldo_rdy) { 260 val = readl(priv->eth_ldo_rdy); 261 val |= BIT(0); 262 writel(val, priv->eth_ldo_rdy); 263 fsleep(IPQ_PHY_SET_DELAY_US); 264 } 265 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); 268 if (ret) 269 return ret; 270 271 ret = clk_prepare_enable(priv->mdio_clk); 272 if (ret) 273 return ret; 274 275 mdelay(10); 276 277 /* Restore MDC rate */ 278 return ipq4019_mdio_set_div(priv); 279 } 280 281 static void ipq4019_mdio_select_mdc_rate(struct platform_device *pdev, 282 struct ipq4019_mdio_data *priv) 283 { 284 unsigned long ahb_rate; 285 int div; 286 u32 val; 287 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", 290 &priv->mdc_rate)) 291 return; 292 293 /* If we don't have a clock for AHB use the fixed value */ 294 ahb_rate = IPQ_MDIO_CLK_RATE; 295 if (priv->mdio_clk) 296 ahb_rate = clk_get_rate(priv->mdio_clk); 297 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); 301 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. 305 */ 306 if (div != MDIO_MODE_DIV_256) { 307 priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div + 1); 308 return; 309 } 310 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 313 * 2.5MHz 314 */ 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 318 */ 319 if (DIV_ROUND_UP(ahb_rate, div) > 2500000) 320 break; 321 322 priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div); 323 } 324 } 325 326 static int ipq4019_mdio_probe(struct platform_device *pdev) 327 { 328 struct ipq4019_mdio_data *priv; 329 struct mii_bus *bus; 330 struct resource *res; 331 int ret; 332 333 bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv)); 334 if (!bus) 335 return -ENOMEM; 336 337 priv = bus->priv; 338 339 priv->membase = devm_platform_ioremap_resource(pdev, 0); 340 if (IS_ERR(priv->membase)) 341 return PTR_ERR(priv->membase); 342 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); 346 347 ipq4019_mdio_select_mdc_rate(pdev, priv); 348 ret = ipq4019_mdio_set_div(priv); 349 if (ret) 350 return ret; 351 352 /* The platform resource is provided on the chipset IPQ5018 */ 353 /* This resource is optional */ 354 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 355 if (res) 356 priv->eth_ldo_rdy = devm_ioremap_resource(&pdev->dev, res); 357 358 bus->name = "ipq4019_mdio"; 359 bus->read = ipq4019_mdio_read_c22; 360 bus->write = ipq4019_mdio_write_c22; 361 bus->read_c45 = ipq4019_mdio_read_c45; 362 bus->write_c45 = ipq4019_mdio_write_c45; 363 bus->reset = ipq_mdio_reset; 364 bus->parent = &pdev->dev; 365 snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id); 366 367 ret = of_mdiobus_register(bus, pdev->dev.of_node); 368 if (ret) { 369 dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); 370 return ret; 371 } 372 373 platform_set_drvdata(pdev, bus); 374 375 return 0; 376 } 377 378 static void ipq4019_mdio_remove(struct platform_device *pdev) 379 { 380 struct mii_bus *bus = platform_get_drvdata(pdev); 381 382 mdiobus_unregister(bus); 383 } 384 385 static const struct of_device_id ipq4019_mdio_dt_ids[] = { 386 { .compatible = "qcom,ipq4019-mdio" }, 387 { .compatible = "qcom,ipq5018-mdio" }, 388 { } 389 }; 390 MODULE_DEVICE_TABLE(of, ipq4019_mdio_dt_ids); 391 392 static struct platform_driver ipq4019_mdio_driver = { 393 .probe = ipq4019_mdio_probe, 394 .remove_new = ipq4019_mdio_remove, 395 .driver = { 396 .name = "ipq4019-mdio", 397 .of_match_table = ipq4019_mdio_dt_ids, 398 }, 399 }; 400 401 module_platform_driver(ipq4019_mdio_driver); 402 403 MODULE_DESCRIPTION("ipq4019 MDIO interface driver"); 404 MODULE_AUTHOR("Qualcomm Atheros"); 405 MODULE_LICENSE("Dual BSD/GPL"); 406