1/* 2 * drivers/net/ibm_newemac/rgmii.c 3 * 4 * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support. 5 * 6 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp. 7 * <benh@kernel.crashing.org> 8 * 9 * Based on the arch/ppc version of the driver: 10 * 11 * Copyright (c) 2004, 2005 Zultys Technologies. 12 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> 13 * 14 * Based on original work by 15 * Matt Porter <mporter@kernel.crashing.org> 16 * Copyright 2004 MontaVista Software, Inc. 17 * 18 * This program is free software; you can redistribute it and/or modify it 19 * under the terms of the GNU General Public License as published by the 20 * Free Software Foundation; either version 2 of the License, or (at your 21 * option) any later version. 22 * 23 */ 24#include <linux/slab.h> 25#include <linux/kernel.h> 26#include <linux/ethtool.h> 27#include <asm/io.h> 28 29#include "emac.h" 30#include "debug.h" 31 32// thus need to take that into account and possibly change some 33// of the bit settings below that don't seem to quite match the 34// AXON spec 35 36/* RGMIIx_FER */ 37#define RGMII_FER_MASK(idx) (0x7 << ((idx) * 4)) 38#define RGMII_FER_RTBI(idx) (0x4 << ((idx) * 4)) 39#define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4)) 40#define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4)) 41#define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4)) 42#define RGMII_FER_MII(idx) RGMII_FER_GMII(idx) 43 44/* RGMIIx_SSR */ 45#define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) 46#define RGMII_SSR_100(idx) (0x2 << ((idx) * 8)) 47#define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8)) 48 49/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */ 50static inline int rgmii_valid_mode(int phy_mode) 51{ 52 return phy_mode == PHY_MODE_GMII || 53 phy_mode == PHY_MODE_MII || 54 phy_mode == PHY_MODE_RGMII || 55 phy_mode == PHY_MODE_TBI || 56 phy_mode == PHY_MODE_RTBI; 57} 58 59static inline const char *rgmii_mode_name(int mode) 60{ 61 switch (mode) { 62 case PHY_MODE_RGMII: 63 return "RGMII"; 64 case PHY_MODE_TBI: 65 return "TBI"; 66 case PHY_MODE_GMII: 67 return "GMII"; 68 case PHY_MODE_MII: 69 return "MII"; 70 case PHY_MODE_RTBI: 71 return "RTBI"; 72 default: 73 BUG(); 74 } 75} 76 77static inline u32 rgmii_mode_mask(int mode, int input) 78{ 79 switch (mode) { 80 case PHY_MODE_RGMII: 81 return RGMII_FER_RGMII(input); 82 case PHY_MODE_TBI: 83 return RGMII_FER_TBI(input); 84 case PHY_MODE_GMII: 85 return RGMII_FER_GMII(input); 86 case PHY_MODE_MII: 87 return RGMII_FER_MII(input); 88 case PHY_MODE_RTBI: 89 return RGMII_FER_RTBI(input); 90 default: 91 BUG(); 92 } 93} 94 95int __devinit rgmii_attach(struct platform_device *ofdev, int input, int mode) 96{ 97 struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); 98 struct rgmii_regs __iomem *p = dev->base; 99 100 RGMII_DBG(dev, "attach(%d)" NL, input); 101 102 /* Check if we need to attach to a RGMII */ 103 if (input < 0 || !rgmii_valid_mode(mode)) { 104 printk(KERN_ERR "%s: unsupported settings !\n", 105 ofdev->dev.of_node->full_name); 106 return -ENODEV; 107 } 108 109 mutex_lock(&dev->lock); 110 111 /* Enable this input */ 112 out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input)); 113 114 printk(KERN_NOTICE "%s: input %d in %s mode\n", 115 ofdev->dev.of_node->full_name, input, rgmii_mode_name(mode)); 116 117 ++dev->users; 118 119 mutex_unlock(&dev->lock); 120 121 return 0; 122} 123 124void rgmii_set_speed(struct platform_device *ofdev, int input, int speed) 125{ 126 struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); 127 struct rgmii_regs __iomem *p = dev->base; 128 u32 ssr; 129 130 mutex_lock(&dev->lock); 131 132 ssr = in_be32(&p->ssr) & ~RGMII_SSR_MASK(input); 133 134 RGMII_DBG(dev, "speed(%d, %d)" NL, input, speed); 135 136 if (speed == SPEED_1000) 137 ssr |= RGMII_SSR_1000(input); 138 else if (speed == SPEED_100) 139 ssr |= RGMII_SSR_100(input); 140 141 out_be32(&p->ssr, ssr); 142 143 mutex_unlock(&dev->lock); 144} 145 146void rgmii_get_mdio(struct platform_device *ofdev, int input) 147{ 148 struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); 149 struct rgmii_regs __iomem *p = dev->base; 150 u32 fer; 151 152 RGMII_DBG2(dev, "get_mdio(%d)" NL, input); 153 154 if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO)) 155 return; 156 157 mutex_lock(&dev->lock); 158 159 fer = in_be32(&p->fer); 160 fer |= 0x00080000u >> input; 161 out_be32(&p->fer, fer); 162 (void)in_be32(&p->fer); 163 164 DBG2(dev, " fer = 0x%08x\n", fer); 165} 166 167void rgmii_put_mdio(struct platform_device *ofdev, int input) 168{ 169 struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); 170 struct rgmii_regs __iomem *p = dev->base; 171 u32 fer; 172 173 RGMII_DBG2(dev, "put_mdio(%d)" NL, input); 174 175 if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO)) 176 return; 177 178 fer = in_be32(&p->fer); 179 fer &= ~(0x00080000u >> input); 180 out_be32(&p->fer, fer); 181 (void)in_be32(&p->fer); 182 183 DBG2(dev, " fer = 0x%08x\n", fer); 184 185 mutex_unlock(&dev->lock); 186} 187 188void rgmii_detach(struct platform_device *ofdev, int input) 189{ 190 struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); 191 struct rgmii_regs __iomem *p; 192 193 BUG_ON(!dev || dev->users == 0); 194 p = dev->base; 195 196 mutex_lock(&dev->lock); 197 198 RGMII_DBG(dev, "detach(%d)" NL, input); 199 200 /* Disable this input */ 201 out_be32(&p->fer, in_be32(&p->fer) & ~RGMII_FER_MASK(input)); 202 203 --dev->users; 204 205 mutex_unlock(&dev->lock); 206} 207 208int rgmii_get_regs_len(struct platform_device *ofdev) 209{ 210 return sizeof(struct emac_ethtool_regs_subhdr) + 211 sizeof(struct rgmii_regs); 212} 213 214void *rgmii_dump_regs(struct platform_device *ofdev, void *buf) 215{ 216 struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); 217 struct emac_ethtool_regs_subhdr *hdr = buf; 218 struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1); 219 220 hdr->version = 0; 221 hdr->index = 0; /* for now, are there chips with more than one 222 * rgmii ? if yes, then we'll add a cell_index 223 * like we do for emac 224 */ 225 memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs)); 226 return regs + 1; 227} 228 229 230static int __devinit rgmii_probe(struct platform_device *ofdev, 231 const struct of_device_id *match) 232{ 233 struct device_node *np = ofdev->dev.of_node; 234 struct rgmii_instance *dev; 235 struct resource regs; 236 int rc; 237 238 rc = -ENOMEM; 239 dev = kzalloc(sizeof(struct rgmii_instance), GFP_KERNEL); 240 if (dev == NULL) { 241 printk(KERN_ERR "%s: could not allocate RGMII device!\n", 242 np->full_name); 243 goto err_gone; 244 } 245 246 mutex_init(&dev->lock); 247 dev->ofdev = ofdev; 248 249 rc = -ENXIO; 250 if (of_address_to_resource(np, 0, ®s)) { 251 printk(KERN_ERR "%s: Can't get registers address\n", 252 np->full_name); 253 goto err_free; 254 } 255 256 rc = -ENOMEM; 257 dev->base = (struct rgmii_regs __iomem *)ioremap(regs.start, 258 sizeof(struct rgmii_regs)); 259 if (dev->base == NULL) { 260 printk(KERN_ERR "%s: Can't map device registers!\n", 261 np->full_name); 262 goto err_free; 263 } 264 265 /* Check for RGMII flags */ 266 if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL)) 267 dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO; 268 269 /* CAB lacks the right properties, fix this up */ 270 if (of_device_is_compatible(ofdev->dev.of_node, "ibm,rgmii-axon")) 271 dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO; 272 273 DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n", 274 in_be32(&dev->base->fer), in_be32(&dev->base->ssr)); 275 276 /* Disable all inputs by default */ 277 out_be32(&dev->base->fer, 0); 278 279 printk(KERN_INFO 280 "RGMII %s initialized with%s MDIO support\n", 281 ofdev->dev.of_node->full_name, 282 (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out"); 283 284 wmb(); 285 dev_set_drvdata(&ofdev->dev, dev); 286 287 return 0; 288 289 err_free: 290 kfree(dev); 291 err_gone: 292 return rc; 293} 294 295static int __devexit rgmii_remove(struct platform_device *ofdev) 296{ 297 struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); 298 299 dev_set_drvdata(&ofdev->dev, NULL); 300 301 WARN_ON(dev->users != 0); 302 303 iounmap(dev->base); 304 kfree(dev); 305 306 return 0; 307} 308 309static struct of_device_id rgmii_match[] = 310{ 311 { 312 .compatible = "ibm,rgmii", 313 }, 314 { 315 .type = "emac-rgmii", 316 }, 317 {}, 318}; 319 320static struct of_platform_driver rgmii_driver = { 321 .driver = { 322 .name = "emac-rgmii", 323 .owner = THIS_MODULE, 324 .of_match_table = rgmii_match, 325 }, 326 .probe = rgmii_probe, 327 .remove = rgmii_remove, 328}; 329 330int __init rgmii_init(void) 331{ 332 return of_register_platform_driver(&rgmii_driver); 333} 334 335void rgmii_exit(void) 336{ 337 of_unregister_platform_driver(&rgmii_driver); 338} 339