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