2 * Sonics Silicon Backplane
3 * Broadcom Gigabit Ethernet core driver
5 * Copyright 2008, Broadcom Corporation
6 * Copyright 2008, Michael Buesch <mb@bu3sch.de>
8 * Licensed under the GNU/GPL. See COPYING for details.
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>
19 MODULE_DESCRIPTION("SSB Broadcom Gigabit Ethernet driver");
20 MODULE_AUTHOR("Michael Buesch");
21 MODULE_LICENSE("GPL");
24 static const struct ssb_device_id ssb_gige_tbl
[] = {
25 SSB_DEVICE(SSB_VENDOR_BROADCOM
, SSB_DEV_ETHERNET_GBIT
, SSB_ANY_REV
),
28 /* MODULE_DEVICE_TABLE(ssb, ssb_gige_tbl); */
31 static inline u8
gige_read8(struct ssb_gige
*dev
, u16 offset
)
33 return ssb_read8(dev
->dev
, offset
);
36 static inline u16
gige_read16(struct ssb_gige
*dev
, u16 offset
)
38 return ssb_read16(dev
->dev
, offset
);
41 static inline u32
gige_read32(struct ssb_gige
*dev
, u16 offset
)
43 return ssb_read32(dev
->dev
, offset
);
46 static inline void gige_write8(struct ssb_gige
*dev
,
49 ssb_write8(dev
->dev
, offset
, value
);
52 static inline void gige_write16(struct ssb_gige
*dev
,
53 u16 offset
, u16 value
)
55 ssb_write16(dev
->dev
, offset
, value
);
58 static inline void gige_write32(struct ssb_gige
*dev
,
59 u16 offset
, u32 value
)
61 ssb_write32(dev
->dev
, offset
, value
);
65 u8
gige_pcicfg_read8(struct ssb_gige
*dev
, unsigned int offset
)
67 BUG_ON(offset
>= 256);
68 return gige_read8(dev
, SSB_GIGE_PCICFG
+ offset
);
72 u16
gige_pcicfg_read16(struct ssb_gige
*dev
, unsigned int offset
)
74 BUG_ON(offset
>= 256);
75 return gige_read16(dev
, SSB_GIGE_PCICFG
+ offset
);
79 u32
gige_pcicfg_read32(struct ssb_gige
*dev
, unsigned int offset
)
81 BUG_ON(offset
>= 256);
82 return gige_read32(dev
, SSB_GIGE_PCICFG
+ offset
);
86 void gige_pcicfg_write8(struct ssb_gige
*dev
,
87 unsigned int offset
, u8 value
)
89 BUG_ON(offset
>= 256);
90 gige_write8(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
94 void gige_pcicfg_write16(struct ssb_gige
*dev
,
95 unsigned int offset
, u16 value
)
97 BUG_ON(offset
>= 256);
98 gige_write16(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
102 void gige_pcicfg_write32(struct ssb_gige
*dev
,
103 unsigned int offset
, u32 value
)
105 BUG_ON(offset
>= 256);
106 gige_write32(dev
, SSB_GIGE_PCICFG
+ offset
, value
);
109 static int ssb_gige_pci_read_config(struct pci_bus
*bus
, unsigned int devfn
,
110 int reg
, int size
, u32
*val
)
112 struct ssb_gige
*dev
= container_of(bus
->ops
, struct ssb_gige
, pci_ops
);
115 if ((PCI_SLOT(devfn
) > 0) || (PCI_FUNC(devfn
) > 0))
116 return PCIBIOS_DEVICE_NOT_FOUND
;
118 return PCIBIOS_DEVICE_NOT_FOUND
;
120 spin_lock_irqsave(&dev
->lock
, flags
);
123 *val
= gige_pcicfg_read8(dev
, reg
);
126 *val
= gige_pcicfg_read16(dev
, reg
);
129 *val
= gige_pcicfg_read32(dev
, reg
);
134 spin_unlock_irqrestore(&dev
->lock
, flags
);
136 return PCIBIOS_SUCCESSFUL
;
139 static int ssb_gige_pci_write_config(struct pci_bus
*bus
, unsigned int devfn
,
140 int reg
, int size
, u32 val
)
142 struct ssb_gige
*dev
= container_of(bus
->ops
, struct ssb_gige
, pci_ops
);
145 if ((PCI_SLOT(devfn
) > 0) || (PCI_FUNC(devfn
) > 0))
146 return PCIBIOS_DEVICE_NOT_FOUND
;
148 return PCIBIOS_DEVICE_NOT_FOUND
;
150 spin_lock_irqsave(&dev
->lock
, flags
);
153 gige_pcicfg_write8(dev
, reg
, val
);
156 gige_pcicfg_write16(dev
, reg
, val
);
159 gige_pcicfg_write32(dev
, reg
, val
);
164 spin_unlock_irqrestore(&dev
->lock
, flags
);
166 return PCIBIOS_SUCCESSFUL
;
169 static int ssb_gige_probe(struct ssb_device
*sdev
, const struct ssb_device_id
*id
)
171 struct ssb_gige
*dev
;
172 u32 base
, tmslow
, tmshigh
;
174 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
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
;
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
;
192 if (!ssb_device_is_enabled(sdev
))
193 ssb_device_enable(sdev
, 0);
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);
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
;
205 /* Enable the memory region. */
206 gige_pcicfg_write16(dev
, PCI_COMMAND
,
207 gige_pcicfg_read16(dev
, PCI_COMMAND
)
208 | PCI_COMMAND_MEMORY
);
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.
216 gige_write32(dev
, SSB_GIGE_SHIM_FLUSHSTAT
, 0x00000068);
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
;
227 tmslow
|= SSB_GIGE_TMSLOW_TXBYPASS
;
228 tmslow
|= SSB_GIGE_TMSLOW_RXBYPASS
;
231 tmslow
|= SSB_GIGE_TMSLOW_DLLEN
;
232 ssb_write32(sdev
, SSB_TMSLOW
, tmslow
);
234 ssb_set_drvdata(sdev
, dev
);
235 register_pci_controller(&dev
->pci_controller
);
240 bool pdev_is_ssb_gige_core(struct pci_dev
*pdev
)
242 if (!pdev
->resource
[0].name
)
244 return (strcmp(pdev
->resource
[0].name
, SSB_GIGE_MEM_RES_NAME
) == 0);
246 EXPORT_SYMBOL(pdev_is_ssb_gige_core
);
248 int ssb_gige_pcibios_plat_dev_init(struct ssb_device
*sdev
,
249 struct pci_dev
*pdev
)
251 struct ssb_gige
*dev
= ssb_get_drvdata(sdev
);
252 struct resource
*res
;
254 if (pdev
->bus
->ops
!= &dev
->pci_ops
) {
255 /* The PCI device is not on this SSB GigE bridge device. */
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
;
266 /* Fixup interrupt lines. */
267 pdev
->irq
= ssb_mips_irq(sdev
) + 2;
268 pci_write_config_byte(pdev
, PCI_INTERRUPT_LINE
, pdev
->irq
);
273 int ssb_gige_map_irq(struct ssb_device
*sdev
,
274 const struct pci_dev
*pdev
)
276 struct ssb_gige
*dev
= ssb_get_drvdata(sdev
);
278 if (pdev
->bus
->ops
!= &dev
->pci_ops
) {
279 /* The PCI device is not on this SSB GigE bridge device. */
283 return ssb_mips_irq(sdev
) + 2;
286 static struct ssb_driver ssb_gige_driver
= {
288 .id_table
= ssb_gige_tbl
,
289 .probe
= ssb_gige_probe
,
292 int ssb_gige_init(void)
294 return ssb_driver_register(&ssb_gige_driver
);