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