1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Freescale PowerQUICC Ethernet Driver -- MIIM bus implementation 4 * Provides Bus interface for MIIM regs 5 * 6 * Author: Andy Fleming <afleming@freescale.com> 7 * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> 8 * 9 * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc. 10 * 11 * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips) 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/platform_device.h> 16 #include <linux/string.h> 17 #include <linux/errno.h> 18 #include <linux/slab.h> 19 #include <linux/delay.h> 20 #include <linux/module.h> 21 #include <linux/mii.h> 22 #include <linux/of.h> 23 #include <linux/of_address.h> 24 #include <linux/of_mdio.h> 25 #include <linux/property.h> 26 27 #include <asm/io.h> 28 #if IS_ENABLED(CONFIG_UCC_GETH) 29 #include <soc/fsl/qe/ucc.h> 30 #endif 31 32 #include "gianfar.h" 33 34 #define MIIMIND_BUSY 0x00000001 35 #define MIIMIND_NOTVALID 0x00000004 36 #define MIIMCFG_INIT_VALUE 0x00000007 37 #define MIIMCFG_RESET 0x80000000 38 39 #define MII_READ_COMMAND 0x00000001 40 41 struct fsl_pq_mii { 42 u32 miimcfg; /* MII management configuration reg */ 43 u32 miimcom; /* MII management command reg */ 44 u32 miimadd; /* MII management address reg */ 45 u32 miimcon; /* MII management control reg */ 46 u32 miimstat; /* MII management status reg */ 47 u32 miimind; /* MII management indication reg */ 48 }; 49 50 struct fsl_pq_mdio { 51 u8 res1[16]; 52 u32 ieventm; /* MDIO Interrupt event register (for etsec2)*/ 53 u32 imaskm; /* MDIO Interrupt mask register (for etsec2)*/ 54 u8 res2[4]; 55 u32 emapm; /* MDIO Event mapping register (for etsec2)*/ 56 u8 res3[1280]; 57 struct fsl_pq_mii mii; 58 u8 res4[28]; 59 u32 utbipar; /* TBI phy address reg (only on UCC) */ 60 u8 res5[2728]; 61 } __packed; 62 63 /* Number of microseconds to wait for an MII register to respond */ 64 #define MII_TIMEOUT 1000 65 66 struct fsl_pq_mdio_priv { 67 void __iomem *map; 68 struct fsl_pq_mii __iomem *regs; 69 }; 70 71 /* 72 * Per-device-type data. Each type of device tree node that we support gets 73 * one of these. 74 * 75 * @mii_offset: the offset of the MII registers within the memory map of the 76 * node. Some nodes define only the MII registers, and some define the whole 77 * MAC (which includes the MII registers). 78 * 79 * @get_tbipa: determines the address of the TBIPA register 80 * 81 * @ucc_configure: a special function for extra QE configuration 82 */ 83 struct fsl_pq_mdio_data { 84 unsigned int mii_offset; /* offset of the MII registers */ 85 uint32_t __iomem * (*get_tbipa)(void __iomem *p); 86 void (*ucc_configure)(phys_addr_t start, phys_addr_t end); 87 }; 88 89 /* 90 * Write value to the PHY at mii_id at register regnum, on the bus attached 91 * to the local interface, which may be different from the generic mdio bus 92 * (tied to a single interface), waiting until the write is done before 93 * returning. This is helpful in programming interfaces like the TBI which 94 * control interfaces like onchip SERDES and are always tied to the local 95 * mdio pins, which may not be the same as system mdio bus, used for 96 * controlling the external PHYs, for example. 97 */ 98 static int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, 99 u16 value) 100 { 101 struct fsl_pq_mdio_priv *priv = bus->priv; 102 struct fsl_pq_mii __iomem *regs = priv->regs; 103 unsigned int timeout; 104 105 /* Set the PHY address and the register address we want to write */ 106 iowrite32be((mii_id << 8) | regnum, ®s->miimadd); 107 108 /* Write out the value we want */ 109 iowrite32be(value, ®s->miimcon); 110 111 /* Wait for the transaction to finish */ 112 timeout = MII_TIMEOUT; 113 while ((ioread32be(®s->miimind) & MIIMIND_BUSY) && timeout) { 114 cpu_relax(); 115 timeout--; 116 } 117 118 return timeout ? 0 : -ETIMEDOUT; 119 } 120 121 /* 122 * Read the bus for PHY at addr mii_id, register regnum, and return the value. 123 * Clears miimcom first. 124 * 125 * All PHY operation done on the bus attached to the local interface, which 126 * may be different from the generic mdio bus. This is helpful in programming 127 * interfaces like the TBI which, in turn, control interfaces like on-chip 128 * SERDES and are always tied to the local mdio pins, which may not be the 129 * same as system mdio bus, used for controlling the external PHYs, for eg. 130 */ 131 static int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 132 { 133 struct fsl_pq_mdio_priv *priv = bus->priv; 134 struct fsl_pq_mii __iomem *regs = priv->regs; 135 unsigned int timeout; 136 u16 value; 137 138 /* Set the PHY address and the register address we want to read */ 139 iowrite32be((mii_id << 8) | regnum, ®s->miimadd); 140 141 /* Clear miimcom, and then initiate a read */ 142 iowrite32be(0, ®s->miimcom); 143 iowrite32be(MII_READ_COMMAND, ®s->miimcom); 144 145 /* Wait for the transaction to finish, normally less than 100us */ 146 timeout = MII_TIMEOUT; 147 while ((ioread32be(®s->miimind) & 148 (MIIMIND_NOTVALID | MIIMIND_BUSY)) && timeout) { 149 cpu_relax(); 150 timeout--; 151 } 152 153 if (!timeout) 154 return -ETIMEDOUT; 155 156 /* Grab the value of the register from miimstat */ 157 value = ioread32be(®s->miimstat); 158 159 dev_dbg(&bus->dev, "read %04x from address %x/%x\n", value, mii_id, regnum); 160 return value; 161 } 162 163 /* Reset the MIIM registers, and wait for the bus to free */ 164 static int fsl_pq_mdio_reset(struct mii_bus *bus) 165 { 166 struct fsl_pq_mdio_priv *priv = bus->priv; 167 struct fsl_pq_mii __iomem *regs = priv->regs; 168 unsigned int timeout; 169 170 mutex_lock(&bus->mdio_lock); 171 172 /* Reset the management interface */ 173 iowrite32be(MIIMCFG_RESET, ®s->miimcfg); 174 175 /* Setup the MII Mgmt clock speed */ 176 iowrite32be(MIIMCFG_INIT_VALUE, ®s->miimcfg); 177 178 /* Wait until the bus is free */ 179 timeout = MII_TIMEOUT; 180 while ((ioread32be(®s->miimind) & MIIMIND_BUSY) && timeout) { 181 cpu_relax(); 182 timeout--; 183 } 184 185 mutex_unlock(&bus->mdio_lock); 186 187 if (!timeout) { 188 dev_err(&bus->dev, "timeout waiting for MII bus\n"); 189 return -EBUSY; 190 } 191 192 return 0; 193 } 194 195 #if IS_ENABLED(CONFIG_GIANFAR) 196 /* 197 * Return the TBIPA address, starting from the address 198 * of the mapped GFAR MDIO registers (struct gfar) 199 * This is mildly evil, but so is our hardware for doing this. 200 * Also, we have to cast back to struct gfar because of 201 * definition weirdness done in gianfar.h. 202 */ 203 static uint32_t __iomem *get_gfar_tbipa_from_mdio(void __iomem *p) 204 { 205 struct gfar __iomem *enet_regs = p; 206 207 return &enet_regs->tbipa; 208 } 209 210 /* 211 * Return the TBIPA address, starting from the address 212 * of the mapped GFAR MII registers (gfar_mii_regs[] within struct gfar) 213 */ 214 static uint32_t __iomem *get_gfar_tbipa_from_mii(void __iomem *p) 215 { 216 return get_gfar_tbipa_from_mdio(container_of(p, struct gfar, gfar_mii_regs)); 217 } 218 219 /* 220 * Return the TBIPAR address for an eTSEC2 node 221 */ 222 static uint32_t __iomem *get_etsec_tbipa(void __iomem *p) 223 { 224 return p; 225 } 226 #endif 227 228 #if IS_ENABLED(CONFIG_UCC_GETH) 229 /* 230 * Return the TBIPAR address for a QE MDIO node, starting from the address 231 * of the mapped MII registers (struct fsl_pq_mii) 232 */ 233 static uint32_t __iomem *get_ucc_tbipa(void __iomem *p) 234 { 235 struct fsl_pq_mdio __iomem *mdio = container_of(p, struct fsl_pq_mdio, mii); 236 237 return &mdio->utbipar; 238 } 239 240 /* 241 * Find the UCC node that controls the given MDIO node 242 * 243 * For some reason, the QE MDIO nodes are not children of the UCC devices 244 * that control them. Therefore, we need to scan all UCC nodes looking for 245 * the one that encompases the given MDIO node. We do this by comparing 246 * physical addresses. The 'start' and 'end' addresses of the MDIO node are 247 * passed, and the correct UCC node will cover the entire address range. 248 * 249 * This assumes that there is only one QE MDIO node in the entire device tree. 250 */ 251 static void ucc_configure(phys_addr_t start, phys_addr_t end) 252 { 253 static bool found_mii_master; 254 struct device_node *np = NULL; 255 256 if (found_mii_master) 257 return; 258 259 for_each_compatible_node(np, NULL, "ucc_geth") { 260 struct resource res; 261 const uint32_t *iprop; 262 uint32_t id; 263 int ret; 264 265 ret = of_address_to_resource(np, 0, &res); 266 if (ret < 0) { 267 pr_debug("fsl-pq-mdio: no address range in node %pOF\n", 268 np); 269 continue; 270 } 271 272 /* if our mdio regs fall within this UCC regs range */ 273 if ((start < res.start) || (end > res.end)) 274 continue; 275 276 iprop = of_get_property(np, "cell-index", NULL); 277 if (!iprop) { 278 iprop = of_get_property(np, "device-id", NULL); 279 if (!iprop) { 280 pr_debug("fsl-pq-mdio: no UCC ID in node %pOF\n", 281 np); 282 continue; 283 } 284 } 285 286 id = be32_to_cpup(iprop); 287 288 /* 289 * cell-index and device-id for QE nodes are 290 * numbered from 1, not 0. 291 */ 292 if (ucc_set_qe_mux_mii_mng(id - 1) < 0) { 293 pr_debug("fsl-pq-mdio: invalid UCC ID in node %pOF\n", 294 np); 295 continue; 296 } 297 298 pr_debug("fsl-pq-mdio: setting node UCC%u to MII master\n", id); 299 found_mii_master = true; 300 } 301 } 302 303 #endif 304 305 static const struct of_device_id fsl_pq_mdio_match[] = { 306 #if IS_ENABLED(CONFIG_GIANFAR) 307 { 308 .compatible = "fsl,gianfar-tbi", 309 .data = &(struct fsl_pq_mdio_data) { 310 .mii_offset = 0, 311 .get_tbipa = get_gfar_tbipa_from_mii, 312 }, 313 }, 314 { 315 .compatible = "fsl,gianfar-mdio", 316 .data = &(struct fsl_pq_mdio_data) { 317 .mii_offset = 0, 318 .get_tbipa = get_gfar_tbipa_from_mii, 319 }, 320 }, 321 { 322 .type = "mdio", 323 .compatible = "gianfar", 324 .data = &(struct fsl_pq_mdio_data) { 325 .mii_offset = offsetof(struct fsl_pq_mdio, mii), 326 .get_tbipa = get_gfar_tbipa_from_mdio, 327 }, 328 }, 329 { 330 .compatible = "fsl,etsec2-tbi", 331 .data = &(struct fsl_pq_mdio_data) { 332 .mii_offset = offsetof(struct fsl_pq_mdio, mii), 333 .get_tbipa = get_etsec_tbipa, 334 }, 335 }, 336 { 337 .compatible = "fsl,etsec2-mdio", 338 .data = &(struct fsl_pq_mdio_data) { 339 .mii_offset = offsetof(struct fsl_pq_mdio, mii), 340 .get_tbipa = get_etsec_tbipa, 341 }, 342 }, 343 #endif 344 #if IS_ENABLED(CONFIG_UCC_GETH) 345 { 346 .compatible = "fsl,ucc-mdio", 347 .data = &(struct fsl_pq_mdio_data) { 348 .mii_offset = 0, 349 .get_tbipa = get_ucc_tbipa, 350 .ucc_configure = ucc_configure, 351 }, 352 }, 353 { 354 /* Legacy UCC MDIO node */ 355 .type = "mdio", 356 .compatible = "ucc_geth_phy", 357 .data = &(struct fsl_pq_mdio_data) { 358 .mii_offset = 0, 359 .get_tbipa = get_ucc_tbipa, 360 .ucc_configure = ucc_configure, 361 }, 362 }, 363 #endif 364 /* No Kconfig option for Fman support yet */ 365 { 366 .compatible = "fsl,fman-mdio", 367 .data = &(struct fsl_pq_mdio_data) { 368 .mii_offset = 0, 369 /* Fman TBI operations are handled elsewhere */ 370 }, 371 }, 372 373 {}, 374 }; 375 MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); 376 377 static void set_tbipa(const u32 tbipa_val, struct platform_device *pdev, 378 uint32_t __iomem * (*get_tbipa)(void __iomem *), 379 void __iomem *reg_map, struct resource *reg_res) 380 { 381 struct device_node *np = pdev->dev.of_node; 382 uint32_t __iomem *tbipa; 383 bool tbipa_mapped; 384 385 tbipa = of_iomap(np, 1); 386 if (tbipa) { 387 tbipa_mapped = true; 388 } else { 389 tbipa_mapped = false; 390 tbipa = (*get_tbipa)(reg_map); 391 392 /* 393 * Add consistency check to make sure TBI is contained within 394 * the mapped range (not because we would get a segfault, 395 * rather to catch bugs in computing TBI address). Print error 396 * message but continue anyway. 397 */ 398 if ((void *)tbipa > reg_map + resource_size(reg_res) - 4) 399 dev_err(&pdev->dev, "invalid register map (should be at least 0x%04zx to contain TBI address)\n", 400 ((void *)tbipa - reg_map) + 4); 401 } 402 403 iowrite32be(be32_to_cpu(tbipa_val), tbipa); 404 405 if (tbipa_mapped) 406 iounmap(tbipa); 407 } 408 409 static int fsl_pq_mdio_probe(struct platform_device *pdev) 410 { 411 const struct fsl_pq_mdio_data *data; 412 struct device_node *np = pdev->dev.of_node; 413 struct resource res; 414 struct device_node *tbi; 415 struct fsl_pq_mdio_priv *priv; 416 struct mii_bus *new_bus; 417 int err; 418 419 data = device_get_match_data(&pdev->dev); 420 if (!data) { 421 dev_err(&pdev->dev, "Failed to match device\n"); 422 return -ENODEV; 423 } 424 425 new_bus = mdiobus_alloc_size(sizeof(*priv)); 426 if (!new_bus) 427 return -ENOMEM; 428 429 priv = new_bus->priv; 430 new_bus->name = "Freescale PowerQUICC MII Bus"; 431 new_bus->read = &fsl_pq_mdio_read; 432 new_bus->write = &fsl_pq_mdio_write; 433 new_bus->reset = &fsl_pq_mdio_reset; 434 435 err = of_address_to_resource(np, 0, &res); 436 if (err < 0) { 437 dev_err(&pdev->dev, "could not obtain address information\n"); 438 goto error; 439 } 440 441 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%pOFn@%llx", np, 442 (unsigned long long)res.start); 443 444 priv->map = of_iomap(np, 0); 445 if (!priv->map) { 446 err = -ENOMEM; 447 goto error; 448 } 449 450 /* 451 * Some device tree nodes represent only the MII registers, and 452 * others represent the MAC and MII registers. The 'mii_offset' field 453 * contains the offset of the MII registers inside the mapped register 454 * space. 455 */ 456 if (data->mii_offset > resource_size(&res)) { 457 dev_err(&pdev->dev, "invalid register map\n"); 458 err = -EINVAL; 459 goto error; 460 } 461 priv->regs = priv->map + data->mii_offset; 462 463 new_bus->parent = &pdev->dev; 464 platform_set_drvdata(pdev, new_bus); 465 466 if (data->get_tbipa) { 467 for_each_child_of_node(np, tbi) { 468 if (of_node_is_type(tbi, "tbi-phy")) { 469 dev_dbg(&pdev->dev, "found TBI PHY node %pOFP\n", 470 tbi); 471 break; 472 } 473 } 474 475 if (tbi) { 476 const u32 *prop = of_get_property(tbi, "reg", NULL); 477 if (!prop) { 478 dev_err(&pdev->dev, 479 "missing 'reg' property in node %pOF\n", 480 tbi); 481 err = -EBUSY; 482 goto error; 483 } 484 set_tbipa(*prop, pdev, 485 data->get_tbipa, priv->map, &res); 486 } 487 } 488 489 if (data->ucc_configure) 490 data->ucc_configure(res.start, res.end); 491 492 err = of_mdiobus_register(new_bus, np); 493 if (err) { 494 dev_err(&pdev->dev, "cannot register %s as MDIO bus\n", 495 new_bus->name); 496 goto error; 497 } 498 499 return 0; 500 501 error: 502 if (priv->map) 503 iounmap(priv->map); 504 505 kfree(new_bus); 506 507 return err; 508 } 509 510 511 static void fsl_pq_mdio_remove(struct platform_device *pdev) 512 { 513 struct device *device = &pdev->dev; 514 struct mii_bus *bus = dev_get_drvdata(device); 515 struct fsl_pq_mdio_priv *priv = bus->priv; 516 517 mdiobus_unregister(bus); 518 519 iounmap(priv->map); 520 mdiobus_free(bus); 521 } 522 523 static struct platform_driver fsl_pq_mdio_driver = { 524 .driver = { 525 .name = "fsl-pq_mdio", 526 .of_match_table = fsl_pq_mdio_match, 527 }, 528 .probe = fsl_pq_mdio_probe, 529 .remove_new = fsl_pq_mdio_remove, 530 }; 531 532 module_platform_driver(fsl_pq_mdio_driver); 533 534 MODULE_DESCRIPTION("Freescale PQ MDIO helpers"); 535 MODULE_LICENSE("GPL"); 536