0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/acpi.h>
0016 #include <linux/acpi_mdio.h>
0017 #include <linux/clk.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/kernel.h>
0020 #include <linux/mdio.h>
0021 #include <linux/module.h>
0022 #include <linux/of_address.h>
0023 #include <linux/of_mdio.h>
0024 #include <linux/of_platform.h>
0025 #include <linux/phy.h>
0026 #include <linux/slab.h>
0027
0028
0029 #define TIMEOUT 1000
0030
0031 struct tgec_mdio_controller {
0032 __be32 reserved[12];
0033 __be32 mdio_stat;
0034 __be32 mdio_ctl;
0035 __be32 mdio_data;
0036 __be32 mdio_addr;
0037 } __packed;
0038
0039 #define MDIO_STAT_ENC BIT(6)
0040 #define MDIO_STAT_CLKDIV(x) (((x) & 0x1ff) << 7)
0041 #define MDIO_STAT_BSY BIT(0)
0042 #define MDIO_STAT_RD_ER BIT(1)
0043 #define MDIO_STAT_PRE_DIS BIT(5)
0044 #define MDIO_CTL_DEV_ADDR(x) (x & 0x1f)
0045 #define MDIO_CTL_PORT_ADDR(x) ((x & 0x1f) << 5)
0046 #define MDIO_CTL_PRE_DIS BIT(10)
0047 #define MDIO_CTL_SCAN_EN BIT(11)
0048 #define MDIO_CTL_POST_INC BIT(14)
0049 #define MDIO_CTL_READ BIT(15)
0050
0051 #define MDIO_DATA(x) (x & 0xffff)
0052
0053 struct mdio_fsl_priv {
0054 struct tgec_mdio_controller __iomem *mdio_base;
0055 struct clk *enet_clk;
0056 u32 mdc_freq;
0057 bool is_little_endian;
0058 bool has_a009885;
0059 bool has_a011043;
0060 };
0061
0062 static u32 xgmac_read32(void __iomem *regs,
0063 bool is_little_endian)
0064 {
0065 if (is_little_endian)
0066 return ioread32(regs);
0067 else
0068 return ioread32be(regs);
0069 }
0070
0071 static void xgmac_write32(u32 value,
0072 void __iomem *regs,
0073 bool is_little_endian)
0074 {
0075 if (is_little_endian)
0076 iowrite32(value, regs);
0077 else
0078 iowrite32be(value, regs);
0079 }
0080
0081
0082
0083
0084 static int xgmac_wait_until_free(struct device *dev,
0085 struct tgec_mdio_controller __iomem *regs,
0086 bool is_little_endian)
0087 {
0088 unsigned int timeout;
0089
0090
0091 timeout = TIMEOUT;
0092 while ((xgmac_read32(®s->mdio_stat, is_little_endian) &
0093 MDIO_STAT_BSY) && timeout) {
0094 cpu_relax();
0095 timeout--;
0096 }
0097
0098 if (!timeout) {
0099 dev_err(dev, "timeout waiting for bus to be free\n");
0100 return -ETIMEDOUT;
0101 }
0102
0103 return 0;
0104 }
0105
0106
0107
0108
0109 static int xgmac_wait_until_done(struct device *dev,
0110 struct tgec_mdio_controller __iomem *regs,
0111 bool is_little_endian)
0112 {
0113 unsigned int timeout;
0114
0115
0116 timeout = TIMEOUT;
0117 while ((xgmac_read32(®s->mdio_stat, is_little_endian) &
0118 MDIO_STAT_BSY) && timeout) {
0119 cpu_relax();
0120 timeout--;
0121 }
0122
0123 if (!timeout) {
0124 dev_err(dev, "timeout waiting for operation to complete\n");
0125 return -ETIMEDOUT;
0126 }
0127
0128 return 0;
0129 }
0130
0131
0132
0133
0134
0135
0136 static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
0137 {
0138 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv;
0139 struct tgec_mdio_controller __iomem *regs = priv->mdio_base;
0140 uint16_t dev_addr;
0141 u32 mdio_ctl, mdio_stat;
0142 int ret;
0143 bool endian = priv->is_little_endian;
0144
0145 mdio_stat = xgmac_read32(®s->mdio_stat, endian);
0146 if (regnum & MII_ADDR_C45) {
0147
0148 dev_addr = (regnum >> 16) & 0x1f;
0149 mdio_stat |= MDIO_STAT_ENC;
0150 } else {
0151
0152 dev_addr = regnum & 0x1f;
0153 mdio_stat &= ~MDIO_STAT_ENC;
0154 }
0155
0156 xgmac_write32(mdio_stat, ®s->mdio_stat, endian);
0157
0158 ret = xgmac_wait_until_free(&bus->dev, regs, endian);
0159 if (ret)
0160 return ret;
0161
0162
0163 mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
0164 xgmac_write32(mdio_ctl, ®s->mdio_ctl, endian);
0165
0166
0167 if (regnum & MII_ADDR_C45) {
0168 xgmac_write32(regnum & 0xffff, ®s->mdio_addr, endian);
0169
0170 ret = xgmac_wait_until_free(&bus->dev, regs, endian);
0171 if (ret)
0172 return ret;
0173 }
0174
0175
0176 xgmac_write32(MDIO_DATA(value), ®s->mdio_data, endian);
0177
0178 ret = xgmac_wait_until_done(&bus->dev, regs, endian);
0179 if (ret)
0180 return ret;
0181
0182 return 0;
0183 }
0184
0185
0186
0187
0188
0189
0190 static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
0191 {
0192 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv;
0193 struct tgec_mdio_controller __iomem *regs = priv->mdio_base;
0194 unsigned long flags;
0195 uint16_t dev_addr;
0196 uint32_t mdio_stat;
0197 uint32_t mdio_ctl;
0198 int ret;
0199 bool endian = priv->is_little_endian;
0200
0201 mdio_stat = xgmac_read32(®s->mdio_stat, endian);
0202 if (regnum & MII_ADDR_C45) {
0203 dev_addr = (regnum >> 16) & 0x1f;
0204 mdio_stat |= MDIO_STAT_ENC;
0205 } else {
0206 dev_addr = regnum & 0x1f;
0207 mdio_stat &= ~MDIO_STAT_ENC;
0208 }
0209
0210 xgmac_write32(mdio_stat, ®s->mdio_stat, endian);
0211
0212 ret = xgmac_wait_until_free(&bus->dev, regs, endian);
0213 if (ret)
0214 return ret;
0215
0216
0217 mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
0218 xgmac_write32(mdio_ctl, ®s->mdio_ctl, endian);
0219
0220
0221 if (regnum & MII_ADDR_C45) {
0222 xgmac_write32(regnum & 0xffff, ®s->mdio_addr, endian);
0223
0224 ret = xgmac_wait_until_free(&bus->dev, regs, endian);
0225 if (ret)
0226 return ret;
0227 }
0228
0229 if (priv->has_a009885)
0230
0231
0232
0233 local_irq_save(flags);
0234
0235
0236 xgmac_write32(mdio_ctl | MDIO_CTL_READ, ®s->mdio_ctl, endian);
0237
0238 ret = xgmac_wait_until_done(&bus->dev, regs, endian);
0239 if (ret)
0240 goto irq_restore;
0241
0242
0243 if ((xgmac_read32(®s->mdio_stat, endian) & MDIO_STAT_RD_ER) &&
0244 !priv->has_a011043) {
0245 dev_dbg(&bus->dev,
0246 "Error while reading PHY%d reg at %d.%d\n",
0247 phy_id, dev_addr, regnum);
0248 ret = 0xffff;
0249 } else {
0250 ret = xgmac_read32(®s->mdio_data, endian) & 0xffff;
0251 dev_dbg(&bus->dev, "read %04x\n", ret);
0252 }
0253
0254 irq_restore:
0255 if (priv->has_a009885)
0256 local_irq_restore(flags);
0257
0258 return ret;
0259 }
0260
0261 static int xgmac_mdio_set_mdc_freq(struct mii_bus *bus)
0262 {
0263 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv;
0264 struct tgec_mdio_controller __iomem *regs = priv->mdio_base;
0265 struct device *dev = bus->parent;
0266 u32 mdio_stat, div;
0267
0268 if (device_property_read_u32(dev, "clock-frequency", &priv->mdc_freq))
0269 return 0;
0270
0271 priv->enet_clk = devm_clk_get(dev, NULL);
0272 if (IS_ERR(priv->enet_clk)) {
0273 dev_err(dev, "Input clock unknown, not changing MDC frequency");
0274 return PTR_ERR(priv->enet_clk);
0275 }
0276
0277 div = ((clk_get_rate(priv->enet_clk) / priv->mdc_freq) - 1) / 2;
0278 if (div < 5 || div > 0x1ff) {
0279 dev_err(dev, "Requested MDC frequency is out of range, ignoring");
0280 return -EINVAL;
0281 }
0282
0283 mdio_stat = xgmac_read32(®s->mdio_stat, priv->is_little_endian);
0284 mdio_stat &= ~MDIO_STAT_CLKDIV(0x1ff);
0285 mdio_stat |= MDIO_STAT_CLKDIV(div);
0286 xgmac_write32(mdio_stat, ®s->mdio_stat, priv->is_little_endian);
0287 return 0;
0288 }
0289
0290 static void xgmac_mdio_set_suppress_preamble(struct mii_bus *bus)
0291 {
0292 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv;
0293 struct tgec_mdio_controller __iomem *regs = priv->mdio_base;
0294 struct device *dev = bus->parent;
0295 u32 mdio_stat;
0296
0297 if (!device_property_read_bool(dev, "suppress-preamble"))
0298 return;
0299
0300 mdio_stat = xgmac_read32(®s->mdio_stat, priv->is_little_endian);
0301 mdio_stat |= MDIO_STAT_PRE_DIS;
0302 xgmac_write32(mdio_stat, ®s->mdio_stat, priv->is_little_endian);
0303 }
0304
0305 static int xgmac_mdio_probe(struct platform_device *pdev)
0306 {
0307 struct fwnode_handle *fwnode;
0308 struct mdio_fsl_priv *priv;
0309 struct resource *res;
0310 struct mii_bus *bus;
0311 int ret;
0312
0313
0314
0315
0316
0317
0318 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0319 if (!res) {
0320 dev_err(&pdev->dev, "could not obtain address\n");
0321 return -EINVAL;
0322 }
0323
0324 bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(struct mdio_fsl_priv));
0325 if (!bus)
0326 return -ENOMEM;
0327
0328 bus->name = "Freescale XGMAC MDIO Bus";
0329 bus->read = xgmac_mdio_read;
0330 bus->write = xgmac_mdio_write;
0331 bus->parent = &pdev->dev;
0332 bus->probe_capabilities = MDIOBUS_C22_C45;
0333 snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res->start);
0334
0335 priv = bus->priv;
0336 priv->mdio_base = devm_ioremap(&pdev->dev, res->start,
0337 resource_size(res));
0338 if (!priv->mdio_base)
0339 return -ENOMEM;
0340
0341
0342
0343
0344 priv->is_little_endian = device_property_read_bool(&pdev->dev,
0345 "little-endian");
0346
0347 priv->has_a009885 = device_property_read_bool(&pdev->dev,
0348 "fsl,erratum-a009885");
0349 priv->has_a011043 = device_property_read_bool(&pdev->dev,
0350 "fsl,erratum-a011043");
0351
0352 xgmac_mdio_set_suppress_preamble(bus);
0353
0354 ret = xgmac_mdio_set_mdc_freq(bus);
0355 if (ret)
0356 return ret;
0357
0358 fwnode = pdev->dev.fwnode;
0359 if (is_of_node(fwnode))
0360 ret = of_mdiobus_register(bus, to_of_node(fwnode));
0361 else if (is_acpi_node(fwnode))
0362 ret = acpi_mdiobus_register(bus, fwnode);
0363 else
0364 ret = -EINVAL;
0365 if (ret) {
0366 dev_err(&pdev->dev, "cannot register MDIO bus\n");
0367 return ret;
0368 }
0369
0370 platform_set_drvdata(pdev, bus);
0371
0372 return 0;
0373 }
0374
0375 static const struct of_device_id xgmac_mdio_match[] = {
0376 {
0377 .compatible = "fsl,fman-xmdio",
0378 },
0379 {
0380 .compatible = "fsl,fman-memac-mdio",
0381 },
0382 {},
0383 };
0384 MODULE_DEVICE_TABLE(of, xgmac_mdio_match);
0385
0386 static const struct acpi_device_id xgmac_acpi_match[] = {
0387 { "NXP0006" },
0388 { }
0389 };
0390 MODULE_DEVICE_TABLE(acpi, xgmac_acpi_match);
0391
0392 static struct platform_driver xgmac_mdio_driver = {
0393 .driver = {
0394 .name = "fsl-fman_xmdio",
0395 .of_match_table = xgmac_mdio_match,
0396 .acpi_match_table = xgmac_acpi_match,
0397 },
0398 .probe = xgmac_mdio_probe,
0399 };
0400
0401 module_platform_driver(xgmac_mdio_driver);
0402
0403 MODULE_DESCRIPTION("Freescale QorIQ 10G MDIO Controller");
0404 MODULE_LICENSE("GPL v2");