Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Freescale PowerQUICC Ethernet Driver -- MIIM bus implementation
0004  * Provides Bus interface for MIIM regs
0005  *
0006  * Author: Andy Fleming <afleming@freescale.com>
0007  * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
0008  *
0009  * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc.
0010  *
0011  * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips)
0012  */
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/string.h>
0016 #include <linux/errno.h>
0017 #include <linux/slab.h>
0018 #include <linux/delay.h>
0019 #include <linux/module.h>
0020 #include <linux/mii.h>
0021 #include <linux/of_address.h>
0022 #include <linux/of_mdio.h>
0023 #include <linux/of_device.h>
0024 
0025 #include <asm/io.h>
0026 #if IS_ENABLED(CONFIG_UCC_GETH)
0027 #include <soc/fsl/qe/ucc.h>
0028 #endif
0029 
0030 #include "gianfar.h"
0031 
0032 #define MIIMIND_BUSY        0x00000001
0033 #define MIIMIND_NOTVALID    0x00000004
0034 #define MIIMCFG_INIT_VALUE  0x00000007
0035 #define MIIMCFG_RESET       0x80000000
0036 
0037 #define MII_READ_COMMAND    0x00000001
0038 
0039 struct fsl_pq_mii {
0040     u32 miimcfg;    /* MII management configuration reg */
0041     u32 miimcom;    /* MII management command reg */
0042     u32 miimadd;    /* MII management address reg */
0043     u32 miimcon;    /* MII management control reg */
0044     u32 miimstat;   /* MII management status reg */
0045     u32 miimind;    /* MII management indication reg */
0046 };
0047 
0048 struct fsl_pq_mdio {
0049     u8 res1[16];
0050     u32 ieventm;    /* MDIO Interrupt event register (for etsec2)*/
0051     u32 imaskm; /* MDIO Interrupt mask register (for etsec2)*/
0052     u8 res2[4];
0053     u32 emapm;  /* MDIO Event mapping register (for etsec2)*/
0054     u8 res3[1280];
0055     struct fsl_pq_mii mii;
0056     u8 res4[28];
0057     u32 utbipar;    /* TBI phy address reg (only on UCC) */
0058     u8 res5[2728];
0059 } __packed;
0060 
0061 /* Number of microseconds to wait for an MII register to respond */
0062 #define MII_TIMEOUT 1000
0063 
0064 struct fsl_pq_mdio_priv {
0065     void __iomem *map;
0066     struct fsl_pq_mii __iomem *regs;
0067 };
0068 
0069 /*
0070  * Per-device-type data.  Each type of device tree node that we support gets
0071  * one of these.
0072  *
0073  * @mii_offset: the offset of the MII registers within the memory map of the
0074  * node.  Some nodes define only the MII registers, and some define the whole
0075  * MAC (which includes the MII registers).
0076  *
0077  * @get_tbipa: determines the address of the TBIPA register
0078  *
0079  * @ucc_configure: a special function for extra QE configuration
0080  */
0081 struct fsl_pq_mdio_data {
0082     unsigned int mii_offset;    /* offset of the MII registers */
0083     uint32_t __iomem * (*get_tbipa)(void __iomem *p);
0084     void (*ucc_configure)(phys_addr_t start, phys_addr_t end);
0085 };
0086 
0087 /*
0088  * Write value to the PHY at mii_id at register regnum, on the bus attached
0089  * to the local interface, which may be different from the generic mdio bus
0090  * (tied to a single interface), waiting until the write is done before
0091  * returning. This is helpful in programming interfaces like the TBI which
0092  * control interfaces like onchip SERDES and are always tied to the local
0093  * mdio pins, which may not be the same as system mdio bus, used for
0094  * controlling the external PHYs, for example.
0095  */
0096 static int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
0097         u16 value)
0098 {
0099     struct fsl_pq_mdio_priv *priv = bus->priv;
0100     struct fsl_pq_mii __iomem *regs = priv->regs;
0101     unsigned int timeout;
0102 
0103     /* Set the PHY address and the register address we want to write */
0104     iowrite32be((mii_id << 8) | regnum, &regs->miimadd);
0105 
0106     /* Write out the value we want */
0107     iowrite32be(value, &regs->miimcon);
0108 
0109     /* Wait for the transaction to finish */
0110     timeout = MII_TIMEOUT;
0111     while ((ioread32be(&regs->miimind) & MIIMIND_BUSY) && timeout) {
0112         cpu_relax();
0113         timeout--;
0114     }
0115 
0116     return timeout ? 0 : -ETIMEDOUT;
0117 }
0118 
0119 /*
0120  * Read the bus for PHY at addr mii_id, register regnum, and return the value.
0121  * Clears miimcom first.
0122  *
0123  * All PHY operation done on the bus attached to the local interface, which
0124  * may be different from the generic mdio bus.  This is helpful in programming
0125  * interfaces like the TBI which, in turn, control interfaces like on-chip
0126  * SERDES and are always tied to the local mdio pins, which may not be the
0127  * same as system mdio bus, used for controlling the external PHYs, for eg.
0128  */
0129 static int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
0130 {
0131     struct fsl_pq_mdio_priv *priv = bus->priv;
0132     struct fsl_pq_mii __iomem *regs = priv->regs;
0133     unsigned int timeout;
0134     u16 value;
0135 
0136     /* Set the PHY address and the register address we want to read */
0137     iowrite32be((mii_id << 8) | regnum, &regs->miimadd);
0138 
0139     /* Clear miimcom, and then initiate a read */
0140     iowrite32be(0, &regs->miimcom);
0141     iowrite32be(MII_READ_COMMAND, &regs->miimcom);
0142 
0143     /* Wait for the transaction to finish, normally less than 100us */
0144     timeout = MII_TIMEOUT;
0145     while ((ioread32be(&regs->miimind) &
0146            (MIIMIND_NOTVALID | MIIMIND_BUSY)) && timeout) {
0147         cpu_relax();
0148         timeout--;
0149     }
0150 
0151     if (!timeout)
0152         return -ETIMEDOUT;
0153 
0154     /* Grab the value of the register from miimstat */
0155     value = ioread32be(&regs->miimstat);
0156 
0157     dev_dbg(&bus->dev, "read %04x from address %x/%x\n", value, mii_id, regnum);
0158     return value;
0159 }
0160 
0161 /* Reset the MIIM registers, and wait for the bus to free */
0162 static int fsl_pq_mdio_reset(struct mii_bus *bus)
0163 {
0164     struct fsl_pq_mdio_priv *priv = bus->priv;
0165     struct fsl_pq_mii __iomem *regs = priv->regs;
0166     unsigned int timeout;
0167 
0168     mutex_lock(&bus->mdio_lock);
0169 
0170     /* Reset the management interface */
0171     iowrite32be(MIIMCFG_RESET, &regs->miimcfg);
0172 
0173     /* Setup the MII Mgmt clock speed */
0174     iowrite32be(MIIMCFG_INIT_VALUE, &regs->miimcfg);
0175 
0176     /* Wait until the bus is free */
0177     timeout = MII_TIMEOUT;
0178     while ((ioread32be(&regs->miimind) & MIIMIND_BUSY) && timeout) {
0179         cpu_relax();
0180         timeout--;
0181     }
0182 
0183     mutex_unlock(&bus->mdio_lock);
0184 
0185     if (!timeout) {
0186         dev_err(&bus->dev, "timeout waiting for MII bus\n");
0187         return -EBUSY;
0188     }
0189 
0190     return 0;
0191 }
0192 
0193 #if IS_ENABLED(CONFIG_GIANFAR)
0194 /*
0195  * Return the TBIPA address, starting from the address
0196  * of the mapped GFAR MDIO registers (struct gfar)
0197  * This is mildly evil, but so is our hardware for doing this.
0198  * Also, we have to cast back to struct gfar because of
0199  * definition weirdness done in gianfar.h.
0200  */
0201 static uint32_t __iomem *get_gfar_tbipa_from_mdio(void __iomem *p)
0202 {
0203     struct gfar __iomem *enet_regs = p;
0204 
0205     return &enet_regs->tbipa;
0206 }
0207 
0208 /*
0209  * Return the TBIPA address, starting from the address
0210  * of the mapped GFAR MII registers (gfar_mii_regs[] within struct gfar)
0211  */
0212 static uint32_t __iomem *get_gfar_tbipa_from_mii(void __iomem *p)
0213 {
0214     return get_gfar_tbipa_from_mdio(container_of(p, struct gfar, gfar_mii_regs));
0215 }
0216 
0217 /*
0218  * Return the TBIPAR address for an eTSEC2 node
0219  */
0220 static uint32_t __iomem *get_etsec_tbipa(void __iomem *p)
0221 {
0222     return p;
0223 }
0224 #endif
0225 
0226 #if IS_ENABLED(CONFIG_UCC_GETH)
0227 /*
0228  * Return the TBIPAR address for a QE MDIO node, starting from the address
0229  * of the mapped MII registers (struct fsl_pq_mii)
0230  */
0231 static uint32_t __iomem *get_ucc_tbipa(void __iomem *p)
0232 {
0233     struct fsl_pq_mdio __iomem *mdio = container_of(p, struct fsl_pq_mdio, mii);
0234 
0235     return &mdio->utbipar;
0236 }
0237 
0238 /*
0239  * Find the UCC node that controls the given MDIO node
0240  *
0241  * For some reason, the QE MDIO nodes are not children of the UCC devices
0242  * that control them.  Therefore, we need to scan all UCC nodes looking for
0243  * the one that encompases the given MDIO node.  We do this by comparing
0244  * physical addresses.  The 'start' and 'end' addresses of the MDIO node are
0245  * passed, and the correct UCC node will cover the entire address range.
0246  *
0247  * This assumes that there is only one QE MDIO node in the entire device tree.
0248  */
0249 static void ucc_configure(phys_addr_t start, phys_addr_t end)
0250 {
0251     static bool found_mii_master;
0252     struct device_node *np = NULL;
0253 
0254     if (found_mii_master)
0255         return;
0256 
0257     for_each_compatible_node(np, NULL, "ucc_geth") {
0258         struct resource res;
0259         const uint32_t *iprop;
0260         uint32_t id;
0261         int ret;
0262 
0263         ret = of_address_to_resource(np, 0, &res);
0264         if (ret < 0) {
0265             pr_debug("fsl-pq-mdio: no address range in node %pOF\n",
0266                  np);
0267             continue;
0268         }
0269 
0270         /* if our mdio regs fall within this UCC regs range */
0271         if ((start < res.start) || (end > res.end))
0272             continue;
0273 
0274         iprop = of_get_property(np, "cell-index", NULL);
0275         if (!iprop) {
0276             iprop = of_get_property(np, "device-id", NULL);
0277             if (!iprop) {
0278                 pr_debug("fsl-pq-mdio: no UCC ID in node %pOF\n",
0279                      np);
0280                 continue;
0281             }
0282         }
0283 
0284         id = be32_to_cpup(iprop);
0285 
0286         /*
0287          * cell-index and device-id for QE nodes are
0288          * numbered from 1, not 0.
0289          */
0290         if (ucc_set_qe_mux_mii_mng(id - 1) < 0) {
0291             pr_debug("fsl-pq-mdio: invalid UCC ID in node %pOF\n",
0292                  np);
0293             continue;
0294         }
0295 
0296         pr_debug("fsl-pq-mdio: setting node UCC%u to MII master\n", id);
0297         found_mii_master = true;
0298     }
0299 }
0300 
0301 #endif
0302 
0303 static const struct of_device_id fsl_pq_mdio_match[] = {
0304 #if IS_ENABLED(CONFIG_GIANFAR)
0305     {
0306         .compatible = "fsl,gianfar-tbi",
0307         .data = &(struct fsl_pq_mdio_data) {
0308             .mii_offset = 0,
0309             .get_tbipa = get_gfar_tbipa_from_mii,
0310         },
0311     },
0312     {
0313         .compatible = "fsl,gianfar-mdio",
0314         .data = &(struct fsl_pq_mdio_data) {
0315             .mii_offset = 0,
0316             .get_tbipa = get_gfar_tbipa_from_mii,
0317         },
0318     },
0319     {
0320         .type = "mdio",
0321         .compatible = "gianfar",
0322         .data = &(struct fsl_pq_mdio_data) {
0323             .mii_offset = offsetof(struct fsl_pq_mdio, mii),
0324             .get_tbipa = get_gfar_tbipa_from_mdio,
0325         },
0326     },
0327     {
0328         .compatible = "fsl,etsec2-tbi",
0329         .data = &(struct fsl_pq_mdio_data) {
0330             .mii_offset = offsetof(struct fsl_pq_mdio, mii),
0331             .get_tbipa = get_etsec_tbipa,
0332         },
0333     },
0334     {
0335         .compatible = "fsl,etsec2-mdio",
0336         .data = &(struct fsl_pq_mdio_data) {
0337             .mii_offset = offsetof(struct fsl_pq_mdio, mii),
0338             .get_tbipa = get_etsec_tbipa,
0339         },
0340     },
0341 #endif
0342 #if IS_ENABLED(CONFIG_UCC_GETH)
0343     {
0344         .compatible = "fsl,ucc-mdio",
0345         .data = &(struct fsl_pq_mdio_data) {
0346             .mii_offset = 0,
0347             .get_tbipa = get_ucc_tbipa,
0348             .ucc_configure = ucc_configure,
0349         },
0350     },
0351     {
0352         /* Legacy UCC MDIO node */
0353         .type = "mdio",
0354         .compatible = "ucc_geth_phy",
0355         .data = &(struct fsl_pq_mdio_data) {
0356             .mii_offset = 0,
0357             .get_tbipa = get_ucc_tbipa,
0358             .ucc_configure = ucc_configure,
0359         },
0360     },
0361 #endif
0362     /* No Kconfig option for Fman support yet */
0363     {
0364         .compatible = "fsl,fman-mdio",
0365         .data = &(struct fsl_pq_mdio_data) {
0366             .mii_offset = 0,
0367             /* Fman TBI operations are handled elsewhere */
0368         },
0369     },
0370 
0371     {},
0372 };
0373 MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match);
0374 
0375 static void set_tbipa(const u32 tbipa_val, struct platform_device *pdev,
0376               uint32_t __iomem * (*get_tbipa)(void __iomem *),
0377               void __iomem *reg_map, struct resource *reg_res)
0378 {
0379     struct device_node *np = pdev->dev.of_node;
0380     uint32_t __iomem *tbipa;
0381     bool tbipa_mapped;
0382 
0383     tbipa = of_iomap(np, 1);
0384     if (tbipa) {
0385         tbipa_mapped = true;
0386     } else {
0387         tbipa_mapped = false;
0388         tbipa = (*get_tbipa)(reg_map);
0389 
0390         /*
0391          * Add consistency check to make sure TBI is contained within
0392          * the mapped range (not because we would get a segfault,
0393          * rather to catch bugs in computing TBI address). Print error
0394          * message but continue anyway.
0395          */
0396         if ((void *)tbipa > reg_map + resource_size(reg_res) - 4)
0397             dev_err(&pdev->dev, "invalid register map (should be at least 0x%04zx to contain TBI address)\n",
0398                 ((void *)tbipa - reg_map) + 4);
0399     }
0400 
0401     iowrite32be(be32_to_cpu(tbipa_val), tbipa);
0402 
0403     if (tbipa_mapped)
0404         iounmap(tbipa);
0405 }
0406 
0407 static int fsl_pq_mdio_probe(struct platform_device *pdev)
0408 {
0409     const struct of_device_id *id =
0410         of_match_device(fsl_pq_mdio_match, &pdev->dev);
0411     const struct fsl_pq_mdio_data *data;
0412     struct device_node *np = pdev->dev.of_node;
0413     struct resource res;
0414     struct device_node *tbi;
0415     struct fsl_pq_mdio_priv *priv;
0416     struct mii_bus *new_bus;
0417     int err;
0418 
0419     if (!id) {
0420         dev_err(&pdev->dev, "Failed to match device\n");
0421         return -ENODEV;
0422     }
0423 
0424     data = id->data;
0425 
0426     dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible);
0427 
0428     new_bus = mdiobus_alloc_size(sizeof(*priv));
0429     if (!new_bus)
0430         return -ENOMEM;
0431 
0432     priv = new_bus->priv;
0433     new_bus->name = "Freescale PowerQUICC MII Bus";
0434     new_bus->read = &fsl_pq_mdio_read;
0435     new_bus->write = &fsl_pq_mdio_write;
0436     new_bus->reset = &fsl_pq_mdio_reset;
0437 
0438     err = of_address_to_resource(np, 0, &res);
0439     if (err < 0) {
0440         dev_err(&pdev->dev, "could not obtain address information\n");
0441         goto error;
0442     }
0443 
0444     snprintf(new_bus->id, MII_BUS_ID_SIZE, "%pOFn@%llx", np,
0445          (unsigned long long)res.start);
0446 
0447     priv->map = of_iomap(np, 0);
0448     if (!priv->map) {
0449         err = -ENOMEM;
0450         goto error;
0451     }
0452 
0453     /*
0454      * Some device tree nodes represent only the MII registers, and
0455      * others represent the MAC and MII registers.  The 'mii_offset' field
0456      * contains the offset of the MII registers inside the mapped register
0457      * space.
0458      */
0459     if (data->mii_offset > resource_size(&res)) {
0460         dev_err(&pdev->dev, "invalid register map\n");
0461         err = -EINVAL;
0462         goto error;
0463     }
0464     priv->regs = priv->map + data->mii_offset;
0465 
0466     new_bus->parent = &pdev->dev;
0467     platform_set_drvdata(pdev, new_bus);
0468 
0469     if (data->get_tbipa) {
0470         for_each_child_of_node(np, tbi) {
0471             if (of_node_is_type(tbi, "tbi-phy")) {
0472                 dev_dbg(&pdev->dev, "found TBI PHY node %pOFP\n",
0473                     tbi);
0474                 break;
0475             }
0476         }
0477 
0478         if (tbi) {
0479             const u32 *prop = of_get_property(tbi, "reg", NULL);
0480             if (!prop) {
0481                 dev_err(&pdev->dev,
0482                     "missing 'reg' property in node %pOF\n",
0483                     tbi);
0484                 err = -EBUSY;
0485                 goto error;
0486             }
0487             set_tbipa(*prop, pdev,
0488                   data->get_tbipa, priv->map, &res);
0489         }
0490     }
0491 
0492     if (data->ucc_configure)
0493         data->ucc_configure(res.start, res.end);
0494 
0495     err = of_mdiobus_register(new_bus, np);
0496     if (err) {
0497         dev_err(&pdev->dev, "cannot register %s as MDIO bus\n",
0498             new_bus->name);
0499         goto error;
0500     }
0501 
0502     return 0;
0503 
0504 error:
0505     if (priv->map)
0506         iounmap(priv->map);
0507 
0508     kfree(new_bus);
0509 
0510     return err;
0511 }
0512 
0513 
0514 static int fsl_pq_mdio_remove(struct platform_device *pdev)
0515 {
0516     struct device *device = &pdev->dev;
0517     struct mii_bus *bus = dev_get_drvdata(device);
0518     struct fsl_pq_mdio_priv *priv = bus->priv;
0519 
0520     mdiobus_unregister(bus);
0521 
0522     iounmap(priv->map);
0523     mdiobus_free(bus);
0524 
0525     return 0;
0526 }
0527 
0528 static struct platform_driver fsl_pq_mdio_driver = {
0529     .driver = {
0530         .name = "fsl-pq_mdio",
0531         .of_match_table = fsl_pq_mdio_match,
0532     },
0533     .probe = fsl_pq_mdio_probe,
0534     .remove = fsl_pq_mdio_remove,
0535 };
0536 
0537 module_platform_driver(fsl_pq_mdio_driver);
0538 
0539 MODULE_LICENSE("GPL");