1 /* 2 * Sonics Silicon Backplane 3 * Broadcom Gigabit Ethernet core driver 4 * 5 * Copyright 2008, Broadcom Corporation 6 * Copyright 2008, Michael Buesch <m@bues.ch> 7 * 8 * Licensed under the GNU/GPL. See COPYING for details. 9 */ 10 11 #include <linux/ssb/ssb.h> 12 #include <linux/ssb/ssb_driver_gige.h> 13 #include <linux/pci.h> 14 #include <linux/pci_regs.h> 15 #include <linux/slab.h> 16 17 18 /* 19 MODULE_DESCRIPTION("SSB Broadcom Gigabit Ethernet driver"); 20 MODULE_AUTHOR("Michael Buesch"); 21 MODULE_LICENSE("GPL"); 22 */ 23 24 static const struct ssb_device_id ssb_gige_tbl[] = { 25 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_ETHERNET_GBIT, SSB_ANY_REV), 26 SSB_DEVTABLE_END 27 }; 28 /* MODULE_DEVICE_TABLE(ssb, ssb_gige_tbl); */ 29 30 31 static inline u8 gige_read8(struct ssb_gige *dev, u16 offset) 32 { 33 return ssb_read8(dev->dev, offset); 34 } 35 36 static inline u16 gige_read16(struct ssb_gige *dev, u16 offset) 37 { 38 return ssb_read16(dev->dev, offset); 39 } 40 41 static inline u32 gige_read32(struct ssb_gige *dev, u16 offset) 42 { 43 return ssb_read32(dev->dev, offset); 44 } 45 46 static inline void gige_write8(struct ssb_gige *dev, 47 u16 offset, u8 value) 48 { 49 ssb_write8(dev->dev, offset, value); 50 } 51 52 static inline void gige_write16(struct ssb_gige *dev, 53 u16 offset, u16 value) 54 { 55 ssb_write16(dev->dev, offset, value); 56 } 57 58 static inline void gige_write32(struct ssb_gige *dev, 59 u16 offset, u32 value) 60 { 61 ssb_write32(dev->dev, offset, value); 62 } 63 64 static inline 65 u8 gige_pcicfg_read8(struct ssb_gige *dev, unsigned int offset) 66 { 67 BUG_ON(offset >= 256); 68 return gige_read8(dev, SSB_GIGE_PCICFG + offset); 69 } 70 71 static inline 72 u16 gige_pcicfg_read16(struct ssb_gige *dev, unsigned int offset) 73 { 74 BUG_ON(offset >= 256); 75 return gige_read16(dev, SSB_GIGE_PCICFG + offset); 76 } 77 78 static inline 79 u32 gige_pcicfg_read32(struct ssb_gige *dev, unsigned int offset) 80 { 81 BUG_ON(offset >= 256); 82 return gige_read32(dev, SSB_GIGE_PCICFG + offset); 83 } 84 85 static inline 86 void gige_pcicfg_write8(struct ssb_gige *dev, 87 unsigned int offset, u8 value) 88 { 89 BUG_ON(offset >= 256); 90 gige_write8(dev, SSB_GIGE_PCICFG + offset, value); 91 } 92 93 static inline 94 void gige_pcicfg_write16(struct ssb_gige *dev, 95 unsigned int offset, u16 value) 96 { 97 BUG_ON(offset >= 256); 98 gige_write16(dev, SSB_GIGE_PCICFG + offset, value); 99 } 100 101 static inline 102 void gige_pcicfg_write32(struct ssb_gige *dev, 103 unsigned int offset, u32 value) 104 { 105 BUG_ON(offset >= 256); 106 gige_write32(dev, SSB_GIGE_PCICFG + offset, value); 107 } 108 109 static int __devinit ssb_gige_pci_read_config(struct pci_bus *bus, 110 unsigned int devfn, int reg, 111 int size, u32 *val) 112 { 113 struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); 114 unsigned long flags; 115 116 if ((PCI_SLOT(devfn) > 0) || (PCI_FUNC(devfn) > 0)) 117 return PCIBIOS_DEVICE_NOT_FOUND; 118 if (reg >= 256) 119 return PCIBIOS_DEVICE_NOT_FOUND; 120 121 spin_lock_irqsave(&dev->lock, flags); 122 switch (size) { 123 case 1: 124 *val = gige_pcicfg_read8(dev, reg); 125 break; 126 case 2: 127 *val = gige_pcicfg_read16(dev, reg); 128 break; 129 case 4: 130 *val = gige_pcicfg_read32(dev, reg); 131 break; 132 default: 133 WARN_ON(1); 134 } 135 spin_unlock_irqrestore(&dev->lock, flags); 136 137 return PCIBIOS_SUCCESSFUL; 138 } 139 140 static int __devinit ssb_gige_pci_write_config(struct pci_bus *bus, 141 unsigned int devfn, int reg, 142 int size, u32 val) 143 { 144 struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); 145 unsigned long flags; 146 147 if ((PCI_SLOT(devfn) > 0) || (PCI_FUNC(devfn) > 0)) 148 return PCIBIOS_DEVICE_NOT_FOUND; 149 if (reg >= 256) 150 return PCIBIOS_DEVICE_NOT_FOUND; 151 152 spin_lock_irqsave(&dev->lock, flags); 153 switch (size) { 154 case 1: 155 gige_pcicfg_write8(dev, reg, val); 156 break; 157 case 2: 158 gige_pcicfg_write16(dev, reg, val); 159 break; 160 case 4: 161 gige_pcicfg_write32(dev, reg, val); 162 break; 163 default: 164 WARN_ON(1); 165 } 166 spin_unlock_irqrestore(&dev->lock, flags); 167 168 return PCIBIOS_SUCCESSFUL; 169 } 170 171 static int __devinit ssb_gige_probe(struct ssb_device *sdev, 172 const struct ssb_device_id *id) 173 { 174 struct ssb_gige *dev; 175 u32 base, tmslow, tmshigh; 176 177 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 178 if (!dev) 179 return -ENOMEM; 180 dev->dev = sdev; 181 182 spin_lock_init(&dev->lock); 183 dev->pci_controller.pci_ops = &dev->pci_ops; 184 dev->pci_controller.io_resource = &dev->io_resource; 185 dev->pci_controller.mem_resource = &dev->mem_resource; 186 dev->pci_controller.io_map_base = 0x800; 187 dev->pci_ops.read = ssb_gige_pci_read_config; 188 dev->pci_ops.write = ssb_gige_pci_write_config; 189 190 dev->io_resource.name = SSB_GIGE_IO_RES_NAME; 191 dev->io_resource.start = 0x800; 192 dev->io_resource.end = 0x8FF; 193 dev->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED; 194 195 if (!ssb_device_is_enabled(sdev)) 196 ssb_device_enable(sdev, 0); 197 198 /* Setup BAR0. This is a 64k MMIO region. */ 199 base = ssb_admatch_base(ssb_read32(sdev, SSB_ADMATCH1)); 200 gige_pcicfg_write32(dev, PCI_BASE_ADDRESS_0, base); 201 gige_pcicfg_write32(dev, PCI_BASE_ADDRESS_1, 0); 202 203 dev->mem_resource.name = SSB_GIGE_MEM_RES_NAME; 204 dev->mem_resource.start = base; 205 dev->mem_resource.end = base + 0x10000 - 1; 206 dev->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED; 207 208 /* Enable the memory region. */ 209 gige_pcicfg_write16(dev, PCI_COMMAND, 210 gige_pcicfg_read16(dev, PCI_COMMAND) 211 | PCI_COMMAND_MEMORY); 212 213 /* Write flushing is controlled by the Flush Status Control register. 214 * We want to flush every register write with a timeout and we want 215 * to disable the IRQ mask while flushing to avoid concurrency. 216 * Note that automatic write flushing does _not_ work from 217 * an IRQ handler. The driver must flush manually by reading a register. 218 */ 219 gige_write32(dev, SSB_GIGE_SHIM_FLUSHSTAT, 0x00000068); 220 221 /* Check if we have an RGMII or GMII PHY-bus. 222 * On RGMII do not bypass the DLLs */ 223 tmslow = ssb_read32(sdev, SSB_TMSLOW); 224 tmshigh = ssb_read32(sdev, SSB_TMSHIGH); 225 if (tmshigh & SSB_GIGE_TMSHIGH_RGMII) { 226 tmslow &= ~SSB_GIGE_TMSLOW_TXBYPASS; 227 tmslow &= ~SSB_GIGE_TMSLOW_RXBYPASS; 228 dev->has_rgmii = 1; 229 } else { 230 tmslow |= SSB_GIGE_TMSLOW_TXBYPASS; 231 tmslow |= SSB_GIGE_TMSLOW_RXBYPASS; 232 dev->has_rgmii = 0; 233 } 234 tmslow |= SSB_GIGE_TMSLOW_DLLEN; 235 ssb_write32(sdev, SSB_TMSLOW, tmslow); 236 237 ssb_set_drvdata(sdev, dev); 238 register_pci_controller(&dev->pci_controller); 239 240 return 0; 241 } 242 243 bool pdev_is_ssb_gige_core(struct pci_dev *pdev) 244 { 245 if (!pdev->resource[0].name) 246 return 0; 247 return (strcmp(pdev->resource[0].name, SSB_GIGE_MEM_RES_NAME) == 0); 248 } 249 EXPORT_SYMBOL(pdev_is_ssb_gige_core); 250 251 int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, 252 struct pci_dev *pdev) 253 { 254 struct ssb_gige *dev = ssb_get_drvdata(sdev); 255 struct resource *res; 256 257 if (pdev->bus->ops != &dev->pci_ops) { 258 /* The PCI device is not on this SSB GigE bridge device. */ 259 return -ENODEV; 260 } 261 262 /* Fixup the PCI resources. */ 263 res = &(pdev->resource[0]); 264 res->flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED; 265 res->name = dev->mem_resource.name; 266 res->start = dev->mem_resource.start; 267 res->end = dev->mem_resource.end; 268 269 /* Fixup interrupt lines. */ 270 pdev->irq = ssb_mips_irq(sdev) + 2; 271 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, pdev->irq); 272 273 return 0; 274 } 275 276 int ssb_gige_map_irq(struct ssb_device *sdev, 277 const struct pci_dev *pdev) 278 { 279 struct ssb_gige *dev = ssb_get_drvdata(sdev); 280 281 if (pdev->bus->ops != &dev->pci_ops) { 282 /* The PCI device is not on this SSB GigE bridge device. */ 283 return -ENODEV; 284 } 285 286 return ssb_mips_irq(sdev) + 2; 287 } 288 289 static struct ssb_driver ssb_gige_driver = { 290 .name = "BCM-GigE", 291 .id_table = ssb_gige_tbl, 292 .probe = ssb_gige_probe, 293 }; 294 295 int ssb_gige_init(void) 296 { 297 return ssb_driver_register(&ssb_gige_driver); 298 } 299