321 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * drivers/net/ethernet/ibm/emac/zmii.c4 *5 * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.6 *7 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.8 * <benh@kernel.crashing.org>9 *10 * Based on the arch/ppc version of the driver:11 *12 * Copyright (c) 2004, 2005 Zultys Technologies.13 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>14 *15 * Based on original work by16 * Armin Kuster <akuster@mvista.com>17 * Copyright 2001 MontaVista Softare Inc.18 */19#include <linux/slab.h>20#include <linux/kernel.h>21#include <linux/ethtool.h>22#include <linux/mod_devicetable.h>23#include <linux/of_address.h>24#include <linux/platform_device.h>25#include <asm/io.h>26 27#include "emac.h"28#include "core.h"29 30/* ZMIIx_FER */31#define ZMII_FER_MDI(idx) (0x80000000 >> ((idx) * 4))32#define ZMII_FER_MDI_ALL (ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \33 ZMII_FER_MDI(2) | ZMII_FER_MDI(3))34 35#define ZMII_FER_SMII(idx) (0x40000000 >> ((idx) * 4))36#define ZMII_FER_RMII(idx) (0x20000000 >> ((idx) * 4))37#define ZMII_FER_MII(idx) (0x10000000 >> ((idx) * 4))38 39/* ZMIIx_SSR */40#define ZMII_SSR_SCI(idx) (0x40000000 >> ((idx) * 4))41#define ZMII_SSR_FSS(idx) (0x20000000 >> ((idx) * 4))42#define ZMII_SSR_SP(idx) (0x10000000 >> ((idx) * 4))43 44/* ZMII only supports MII, RMII and SMII45 * we also support autodetection for backward compatibility46 */47static inline int zmii_valid_mode(int mode)48{49 return mode == PHY_INTERFACE_MODE_MII ||50 mode == PHY_INTERFACE_MODE_RMII ||51 mode == PHY_INTERFACE_MODE_SMII ||52 mode == PHY_INTERFACE_MODE_NA;53}54 55static inline const char *zmii_mode_name(int mode)56{57 switch (mode) {58 case PHY_INTERFACE_MODE_MII:59 return "MII";60 case PHY_INTERFACE_MODE_RMII:61 return "RMII";62 case PHY_INTERFACE_MODE_SMII:63 return "SMII";64 default:65 BUG();66 }67}68 69static inline u32 zmii_mode_mask(int mode, int input)70{71 switch (mode) {72 case PHY_INTERFACE_MODE_MII:73 return ZMII_FER_MII(input);74 case PHY_INTERFACE_MODE_RMII:75 return ZMII_FER_RMII(input);76 case PHY_INTERFACE_MODE_SMII:77 return ZMII_FER_SMII(input);78 default:79 return 0;80 }81}82 83int zmii_attach(struct platform_device *ofdev, int input,84 phy_interface_t *mode)85{86 struct zmii_instance *dev = platform_get_drvdata(ofdev);87 struct zmii_regs __iomem *p = dev->base;88 89 ZMII_DBG(dev, "init(%d, %d)" NL, input, *mode);90 91 if (!zmii_valid_mode(*mode)) {92 /* Probably an EMAC connected to RGMII,93 * but it still may need ZMII for MDIO so94 * we don't fail here.95 */96 dev->users++;97 return 0;98 }99 100 mutex_lock(&dev->lock);101 102 /* Autodetect ZMII mode if not specified.103 * This is only for backward compatibility with the old driver.104 * Please, always specify PHY mode in your board port to avoid105 * any surprises.106 */107 if (dev->mode == PHY_INTERFACE_MODE_NA) {108 if (*mode == PHY_INTERFACE_MODE_NA) {109 u32 r = dev->fer_save;110 111 ZMII_DBG(dev, "autodetecting mode, FER = 0x%08x" NL, r);112 113 if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))114 dev->mode = PHY_INTERFACE_MODE_MII;115 else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))116 dev->mode = PHY_INTERFACE_MODE_RMII;117 else118 dev->mode = PHY_INTERFACE_MODE_SMII;119 } else {120 dev->mode = *mode;121 }122 printk(KERN_NOTICE "%pOF: bridge in %s mode\n",123 ofdev->dev.of_node,124 zmii_mode_name(dev->mode));125 } else {126 /* All inputs must use the same mode */127 if (*mode != PHY_INTERFACE_MODE_NA && *mode != dev->mode) {128 printk(KERN_ERR129 "%pOF: invalid mode %d specified for input %d\n",130 ofdev->dev.of_node, *mode, input);131 mutex_unlock(&dev->lock);132 return -EINVAL;133 }134 }135 136 /* Report back correct PHY mode,137 * it may be used during PHY initialization.138 */139 *mode = dev->mode;140 141 /* Enable this input */142 out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));143 ++dev->users;144 145 mutex_unlock(&dev->lock);146 147 return 0;148}149 150void zmii_get_mdio(struct platform_device *ofdev, int input)151{152 struct zmii_instance *dev = platform_get_drvdata(ofdev);153 u32 fer;154 155 ZMII_DBG2(dev, "get_mdio(%d)" NL, input);156 157 mutex_lock(&dev->lock);158 159 fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL;160 out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input));161}162 163void zmii_put_mdio(struct platform_device *ofdev, int input)164{165 struct zmii_instance *dev = platform_get_drvdata(ofdev);166 167 ZMII_DBG2(dev, "put_mdio(%d)" NL, input);168 mutex_unlock(&dev->lock);169}170 171 172void zmii_set_speed(struct platform_device *ofdev, int input, int speed)173{174 struct zmii_instance *dev = platform_get_drvdata(ofdev);175 u32 ssr;176 177 mutex_lock(&dev->lock);178 179 ssr = in_be32(&dev->base->ssr);180 181 ZMII_DBG(dev, "speed(%d, %d)" NL, input, speed);182 183 if (speed == SPEED_100)184 ssr |= ZMII_SSR_SP(input);185 else186 ssr &= ~ZMII_SSR_SP(input);187 188 out_be32(&dev->base->ssr, ssr);189 190 mutex_unlock(&dev->lock);191}192 193void zmii_detach(struct platform_device *ofdev, int input)194{195 struct zmii_instance *dev = platform_get_drvdata(ofdev);196 197 BUG_ON(!dev || dev->users == 0);198 199 mutex_lock(&dev->lock);200 201 ZMII_DBG(dev, "detach(%d)" NL, input);202 203 /* Disable this input */204 out_be32(&dev->base->fer,205 in_be32(&dev->base->fer) & ~zmii_mode_mask(dev->mode, input));206 207 --dev->users;208 209 mutex_unlock(&dev->lock);210}211 212int zmii_get_regs_len(struct platform_device *ofdev)213{214 return sizeof(struct emac_ethtool_regs_subhdr) +215 sizeof(struct zmii_regs);216}217 218void *zmii_dump_regs(struct platform_device *ofdev, void *buf)219{220 struct zmii_instance *dev = platform_get_drvdata(ofdev);221 struct emac_ethtool_regs_subhdr *hdr = buf;222 struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);223 224 hdr->version = 0;225 hdr->index = 0; /* for now, are there chips with more than one226 * zmii ? if yes, then we'll add a cell_index227 * like we do for emac228 */229 memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs));230 return regs + 1;231}232 233static int zmii_probe(struct platform_device *ofdev)234{235 struct device_node *np = ofdev->dev.of_node;236 struct zmii_instance *dev;237 struct resource regs;238 int rc;239 240 rc = -ENOMEM;241 dev = kzalloc(sizeof(struct zmii_instance), GFP_KERNEL);242 if (dev == NULL)243 goto err_gone;244 245 mutex_init(&dev->lock);246 dev->ofdev = ofdev;247 dev->mode = PHY_INTERFACE_MODE_NA;248 249 rc = -ENXIO;250 if (of_address_to_resource(np, 0, ®s)) {251 printk(KERN_ERR "%pOF: Can't get registers address\n", np);252 goto err_free;253 }254 255 rc = -ENOMEM;256 dev->base = (struct zmii_regs __iomem *)ioremap(regs.start,257 sizeof(struct zmii_regs));258 if (dev->base == NULL) {259 printk(KERN_ERR "%pOF: Can't map device registers!\n", np);260 goto err_free;261 }262 263 /* We may need FER value for autodetection later */264 dev->fer_save = in_be32(&dev->base->fer);265 266 /* Disable all inputs by default */267 out_be32(&dev->base->fer, 0);268 269 printk(KERN_INFO "ZMII %pOF initialized\n", ofdev->dev.of_node);270 wmb();271 platform_set_drvdata(ofdev, dev);272 273 return 0;274 275 err_free:276 kfree(dev);277 err_gone:278 return rc;279}280 281static void zmii_remove(struct platform_device *ofdev)282{283 struct zmii_instance *dev = platform_get_drvdata(ofdev);284 285 WARN_ON(dev->users != 0);286 287 iounmap(dev->base);288 kfree(dev);289}290 291static const struct of_device_id zmii_match[] =292{293 {294 .compatible = "ibm,zmii",295 },296 /* For backward compat with old DT */297 {298 .type = "emac-zmii",299 },300 {},301};302 303static struct platform_driver zmii_driver = {304 .driver = {305 .name = "emac-zmii",306 .of_match_table = zmii_match,307 },308 .probe = zmii_probe,309 .remove_new = zmii_remove,310};311 312int __init zmii_init(void)313{314 return platform_driver_register(&zmii_driver);315}316 317void zmii_exit(void)318{319 platform_driver_unregister(&zmii_driver);320}321