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