1 /* 2 * Sonics Silicon Backplane 3 * Broadcom Gigabit Ethernet core driver 4 * 5 * Copyright 2008, Broadcom Corporation 6 * Copyright 2008, Michael Buesch <mb@bu3sch.de> 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 ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn, 110 int reg, int size, u32 *val) 111 { 112 struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); 113 unsigned long flags; 114 115 if ((PCI_SLOT(devfn) > 0) || (PCI_FUNC(devfn) > 0)) 116 return PCIBIOS_DEVICE_NOT_FOUND; 117 if (reg >= 256) 118 return PCIBIOS_DEVICE_NOT_FOUND; 119 120 spin_lock_irqsave(&dev->lock, flags); 121 switch (size) { 122 case 1: 123 *val = gige_pcicfg_read8(dev, reg); 124 break; 125 case 2: 126 *val = gige_pcicfg_read16(dev, reg); 127 break; 128 case 4: 129 *val = gige_pcicfg_read32(dev, reg); 130 break; 131 default: 132 WARN_ON(1); 133 } 134 spin_unlock_irqrestore(&dev->lock, flags); 135 136 return PCIBIOS_SUCCESSFUL; 137 } 138 139 static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn, 140 int reg, int size, u32 val) 141 { 142 struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); 143 unsigned long flags; 144 145 if ((PCI_SLOT(devfn) > 0) || (PCI_FUNC(devfn) > 0)) 146 return PCIBIOS_DEVICE_NOT_FOUND; 147 if (reg >= 256) 148 return PCIBIOS_DEVICE_NOT_FOUND; 149 150 spin_lock_irqsave(&dev->lock, flags); 151 switch (size) { 152 case 1: 153 gige_pcicfg_write8(dev, reg, val); 154 break; 155 case 2: 156 gige_pcicfg_write16(dev, reg, val); 157 break; 158 case 4: 159 gige_pcicfg_write32(dev, reg, val); 160 break; 161 default: 162 WARN_ON(1); 163 } 164 spin_unlock_irqrestore(&dev->lock, flags); 165 166 return PCIBIOS_SUCCESSFUL; 167 } 168 169 static int ssb_gige_probe(struct ssb_device *sdev, const struct ssb_device_id *id) 170 { 171 struct ssb_gige *dev; 172 u32 base, tmslow, tmshigh; 173 174 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 175 if (!dev) 176 return -ENOMEM; 177 dev->dev = sdev; 178 179 spin_lock_init(&dev->lock); 180 dev->pci_controller.pci_ops = &dev->pci_ops; 181 dev->pci_controller.io_resource = &dev->io_resource; 182 dev->pci_controller.mem_resource = &dev->mem_resource; 183 dev->pci_controller.io_map_base = 0x800; 184 dev->pci_ops.read = ssb_gige_pci_read_config; 185 dev->pci_ops.write = ssb_gige_pci_write_config; 186 187 dev->io_resource.name = SSB_GIGE_IO_RES_NAME; 188 dev->io_resource.start = 0x800; 189 dev->io_resource.end = 0x8FF; 190 dev->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED; 191 192 if (!ssb_device_is_enabled(sdev)) 193 ssb_device_enable(sdev, 0); 194 195 /* Setup BAR0. This is a 64k MMIO region. */ 196 base = ssb_admatch_base(ssb_read32(sdev, SSB_ADMATCH1)); 197 gige_pcicfg_write32(dev, PCI_BASE_ADDRESS_0, base); 198 gige_pcicfg_write32(dev, PCI_BASE_ADDRESS_1, 0); 199 200 dev->mem_resource.name = SSB_GIGE_MEM_RES_NAME; 201 dev->mem_resource.start = base; 202 dev->mem_resource.end = base + 0x10000 - 1; 203 dev->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED; 204 205 /* Enable the memory region. */ 206 gige_pcicfg_write16(dev, PCI_COMMAND, 207 gige_pcicfg_read16(dev, PCI_COMMAND) 208 | PCI_COMMAND_MEMORY); 209 210 /* Write flushing is controlled by the Flush Status Control register. 211 * We want to flush every register write with a timeout and we want 212 * to disable the IRQ mask while flushing to avoid concurrency. 213 * Note that automatic write flushing does _not_ work from 214 * an IRQ handler. The driver must flush manually by reading a register. 215 */ 216 gige_write32(dev, SSB_GIGE_SHIM_FLUSHSTAT, 0x00000068); 217 218 /* Check if we have an RGMII or GMII PHY-bus. 219 * On RGMII do not bypass the DLLs */ 220 tmslow = ssb_read32(sdev, SSB_TMSLOW); 221 tmshigh = ssb_read32(sdev, SSB_TMSHIGH); 222 if (tmshigh & SSB_GIGE_TMSHIGH_RGMII) { 223 tmslow &= ~SSB_GIGE_TMSLOW_TXBYPASS; 224 tmslow &= ~SSB_GIGE_TMSLOW_RXBYPASS; 225 dev->has_rgmii = 1; 226 } else { 227 tmslow |= SSB_GIGE_TMSLOW_TXBYPASS; 228 tmslow |= SSB_GIGE_TMSLOW_RXBYPASS; 229 dev->has_rgmii = 0; 230 } 231 tmslow |= SSB_GIGE_TMSLOW_DLLEN; 232 ssb_write32(sdev, SSB_TMSLOW, tmslow); 233 234 ssb_set_drvdata(sdev, dev); 235 register_pci_controller(&dev->pci_controller); 236 237 return 0; 238 } 239 240 bool pdev_is_ssb_gige_core(struct pci_dev *pdev) 241 { 242 if (!pdev->resource[0].name) 243 return 0; 244 return (strcmp(pdev->resource[0].name, SSB_GIGE_MEM_RES_NAME) == 0); 245 } 246 EXPORT_SYMBOL(pdev_is_ssb_gige_core); 247 248 int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, 249 struct pci_dev *pdev) 250 { 251 struct ssb_gige *dev = ssb_get_drvdata(sdev); 252 struct resource *res; 253 254 if (pdev->bus->ops != &dev->pci_ops) { 255 /* The PCI device is not on this SSB GigE bridge device. */ 256 return -ENODEV; 257 } 258 259 /* Fixup the PCI resources. */ 260 res = &(pdev->resource[0]); 261 res->flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED; 262 res->name = dev->mem_resource.name; 263 res->start = dev->mem_resource.start; 264 res->end = dev->mem_resource.end; 265 266 /* Fixup interrupt lines. */ 267 pdev->irq = ssb_mips_irq(sdev) + 2; 268 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, pdev->irq); 269 270 return 0; 271 } 272 273 int ssb_gige_map_irq(struct ssb_device *sdev, 274 const struct pci_dev *pdev) 275 { 276 struct ssb_gige *dev = ssb_get_drvdata(sdev); 277 278 if (pdev->bus->ops != &dev->pci_ops) { 279 /* The PCI device is not on this SSB GigE bridge device. */ 280 return -ENODEV; 281 } 282 283 return ssb_mips_irq(sdev) + 2; 284 } 285 286 static struct ssb_driver ssb_gige_driver = { 287 .name = "BCM-GigE", 288 .id_table = ssb_gige_tbl, 289 .probe = ssb_gige_probe, 290 }; 291 292 int ssb_gige_init(void) 293 { 294 return ssb_driver_register(&ssb_gige_driver); 295 } 296