Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/ssb/driver_pcicore.c (Version 2.6.25.8) and /linux/drivers/ssb/driver_pcicore.c (Version 2.6.11.8)


  1 /*                                                  1 
  2  * Sonics Silicon Backplane                       
  3  * Broadcom PCI-core driver                       
  4  *                                                
  5  * Copyright 2005, Broadcom Corporation           
  6  * Copyright 2006, 2007, Michael Buesch <mb@bu    
  7  *                                                
  8  * Licensed under the GNU/GPL. See COPYING for    
  9  */                                               
 10                                                   
 11 #include <linux/ssb/ssb.h>                        
 12 #include <linux/pci.h>                            
 13 #include <linux/delay.h>                          
 14 #include <linux/ssb/ssb_embedded.h>               
 15                                                   
 16 #include "ssb_private.h"                          
 17                                                   
 18                                                   
 19 static inline                                     
 20 u32 pcicore_read32(struct ssb_pcicore *pc, u16    
 21 {                                                 
 22         return ssb_read32(pc->dev, offset);       
 23 }                                                 
 24                                                   
 25 static inline                                     
 26 void pcicore_write32(struct ssb_pcicore *pc, u    
 27 {                                                 
 28         ssb_write32(pc->dev, offset, value);      
 29 }                                                 
 30                                                   
 31 static inline                                     
 32 u16 pcicore_read16(struct ssb_pcicore *pc, u16    
 33 {                                                 
 34         return ssb_read16(pc->dev, offset);       
 35 }                                                 
 36                                                   
 37 static inline                                     
 38 void pcicore_write16(struct ssb_pcicore *pc, u    
 39 {                                                 
 40         ssb_write16(pc->dev, offset, value);      
 41 }                                                 
 42                                                   
 43 /*********************************************    
 44  * Code for hostmode operation.                   
 45  *********************************************    
 46                                                   
 47 #ifdef CONFIG_SSB_PCICORE_HOSTMODE                
 48                                                   
 49 #include <asm/paccess.h>                          
 50 /* Probe a 32bit value on the bus and catch bu    
 51  * Returns nonzero on a bus exception.            
 52  * This is MIPS specific */                       
 53 #define mips_busprobe32(val, addr)      get_db    
 54                                                   
 55 /* Assume one-hot slot wiring */                  
 56 #define SSB_PCI_SLOT_MAX        16                
 57                                                   
 58 /* Global lock is OK, as we won't have more th    
 59 static DEFINE_SPINLOCK(cfgspace_lock);            
 60 /* Core to access the external PCI config spac    
 61 static struct ssb_pcicore *extpci_core;           
 62                                                   
 63 static u32 ssb_pcicore_pcibus_iobase = 0x100;     
 64 static u32 ssb_pcicore_pcibus_membase = SSB_PC    
 65                                                   
 66 int pcibios_plat_dev_init(struct pci_dev *d)      
 67 {                                                 
 68         struct resource *res;                     
 69         int pos, size;                            
 70         u32 *base;                                
 71                                                   
 72         ssb_printk(KERN_INFO "PCI: Fixing up d    
 73                    pci_name(d));                  
 74                                                   
 75         /* Fix up resource bases */               
 76         for (pos = 0; pos < 6; pos++) {           
 77                 res = &d->resource[pos];          
 78                 if (res->flags & IORESOURCE_IO    
 79                         base = &ssb_pcicore_pc    
 80                 else                              
 81                         base = &ssb_pcicore_pc    
 82                 res->flags |= IORESOURCE_PCI_F    
 83                 if (res->end) {                   
 84                         size = res->end - res-    
 85                         if (*base & (size - 1)    
 86                                 *base = (*base    
 87                         res->start = *base;       
 88                         res->end = res->start     
 89                         *base += size;            
 90                         pci_write_config_dword    
 91                 }                                 
 92                 /* Fix up PCI bridge BAR0 only    
 93                 if (d->bus->number == 0 && PCI    
 94                         break;                    
 95         }                                         
 96         /* Fix up interrupt lines */              
 97         d->irq = ssb_mips_irq(extpci_core->dev    
 98         pci_write_config_byte(d, PCI_INTERRUPT    
 99                                                   
100         return 0;                                 
101 }                                                 
102                                                   
103 static void __init ssb_fixup_pcibridge(struct     
104 {                                                 
105         u8 lat;                                   
106                                                   
107         if (dev->bus->number != 0 || PCI_SLOT(    
108                 return;                           
109                                                   
110         ssb_printk(KERN_INFO "PCI: Fixing up b    
111                                                   
112         /* Enable PCI bridge bus mastering and    
113         pci_set_master(dev);                      
114         if (pcibios_enable_device(dev, ~0) < 0    
115                 ssb_printk(KERN_ERR "PCI: SSB     
116                 return;                           
117         }                                         
118                                                   
119         /* Enable PCI bridge BAR1 prefetch and    
120         pci_write_config_dword(dev, SSB_BAR1_C    
121                                                   
122         /* Make sure our latency is high enoug    
123         lat = 168;                                
124         ssb_printk(KERN_INFO "PCI: Fixing late    
125                    pci_name(dev), lat);           
126         pci_write_config_byte(dev, PCI_LATENCY    
127 }                                                 
128 DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID    
129                                                   
130 int __init pcibios_map_irq(const struct pci_de    
131 {                                                 
132         return ssb_mips_irq(extpci_core->dev)     
133 }                                                 
134                                                   
135 static u32 get_cfgspace_addr(struct ssb_pcicor    
136                              unsigned int bus,    
137                              unsigned int func    
138 {                                                 
139         u32 addr = 0;                             
140         u32 tmp;                                  
141                                                   
142         /* We do only have one cardbus device     
143         if (pc->cardbusmode && (dev >= 1))        
144                 goto out;                         
145                                                   
146         if (bus == 0) {                           
147                 /* Type 0 transaction */          
148                 if (unlikely(dev >= SSB_PCI_SL    
149                         goto out;                 
150                 /* Slide the window */            
151                 tmp = SSB_PCICORE_SBTOPCI_CFG0    
152                 tmp |= ((1 << (dev + 16)) & SS    
153                 pcicore_write32(pc, SSB_PCICOR    
154                 /* Calculate the address */       
155                 addr = SSB_PCI_CFG;               
156                 addr |= ((1 << (dev + 16)) & ~    
157                 addr |= (func << 8);              
158                 addr |= (off & ~3);               
159         } else {                                  
160                 /* Type 1 transaction */          
161                 pcicore_write32(pc, SSB_PCICOR    
162                                 SSB_PCICORE_SB    
163                 /* Calculate the address */       
164                 addr = SSB_PCI_CFG;               
165                 addr |= (bus << 16);              
166                 addr |= (dev << 11);              
167                 addr |= (func << 8);              
168                 addr |= (off & ~3);               
169         }                                         
170 out:                                              
171         return addr;                              
172 }                                                 
173                                                   
174 static int ssb_extpci_read_config(struct ssb_p    
175                                   unsigned int    
176                                   unsigned int    
177                                   void *buf, i    
178 {                                                 
179         int err = -EINVAL;                        
180         u32 addr, val;                            
181         void __iomem *mmio;                       
182                                                   
183         SSB_WARN_ON(!pc->hostmode);               
184         if (unlikely(len != 1 && len != 2 && l    
185                 goto out;                         
186         addr = get_cfgspace_addr(pc, bus, dev,    
187         if (unlikely(!addr))                      
188                 goto out;                         
189         err = -ENOMEM;                            
190         mmio = ioremap_nocache(addr, len);        
191         if (!mmio)                                
192                 goto out;                         
193                                                   
194         if (mips_busprobe32(val, mmio)) {         
195                 val = 0xffffffff;                 
196                 goto unmap;                       
197         }                                         
198                                                   
199         val = readl(mmio);                        
200         val >>= (8 * (off & 3));                  
201                                                   
202         switch (len) {                            
203         case 1:                                   
204                 *((u8 *)buf) = (u8)val;           
205                 break;                            
206         case 2:                                   
207                 *((u16 *)buf) = (u16)val;         
208                 break;                            
209         case 4:                                   
210                 *((u32 *)buf) = (u32)val;         
211                 break;                            
212         }                                         
213         err = 0;                                  
214 unmap:                                            
215         iounmap(mmio);                            
216 out:                                              
217         return err;                               
218 }                                                 
219                                                   
220 static int ssb_extpci_write_config(struct ssb_    
221                                    unsigned in    
222                                    unsigned in    
223                                    const void     
224 {                                                 
225         int err = -EINVAL;                        
226         u32 addr, val = 0;                        
227         void __iomem *mmio;                       
228                                                   
229         SSB_WARN_ON(!pc->hostmode);               
230         if (unlikely(len != 1 && len != 2 && l    
231                 goto out;                         
232         addr = get_cfgspace_addr(pc, bus, dev,    
233         if (unlikely(!addr))                      
234                 goto out;                         
235         err = -ENOMEM;                            
236         mmio = ioremap_nocache(addr, len);        
237         if (!mmio)                                
238                 goto out;                         
239                                                   
240         if (mips_busprobe32(val, mmio)) {         
241                 val = 0xffffffff;                 
242                 goto unmap;                       
243         }                                         
244                                                   
245         switch (len) {                            
246         case 1:                                   
247                 val = readl(mmio);                
248                 val &= ~(0xFF << (8 * (off & 3    
249                 val |= *((const u8 *)buf) << (    
250                 break;                            
251         case 2:                                   
252                 val = readl(mmio);                
253                 val &= ~(0xFFFF << (8 * (off &    
254                 val |= *((const u16 *)buf) <<     
255                 break;                            
256         case 4:                                   
257                 val = *((const u32 *)buf);        
258                 break;                            
259         }                                         
260         writel(val, mmio);                        
261                                                   
262         err = 0;                                  
263 unmap:                                            
264         iounmap(mmio);                            
265 out:                                              
266         return err;                               
267 }                                                 
268                                                   
269 static int ssb_pcicore_read_config(struct pci_    
270                                    int reg, in    
271 {                                                 
272         unsigned long flags;                      
273         int err;                                  
274                                                   
275         spin_lock_irqsave(&cfgspace_lock, flag    
276         err = ssb_extpci_read_config(extpci_co    
277                                      PCI_FUNC(    
278         spin_unlock_irqrestore(&cfgspace_lock,    
279                                                   
280         return err ? PCIBIOS_DEVICE_NOT_FOUND     
281 }                                                 
282                                                   
283 static int ssb_pcicore_write_config(struct pci    
284                                     int reg, i    
285 {                                                 
286         unsigned long flags;                      
287         int err;                                  
288                                                   
289         spin_lock_irqsave(&cfgspace_lock, flag    
290         err = ssb_extpci_write_config(extpci_c    
291                                       PCI_FUNC    
292         spin_unlock_irqrestore(&cfgspace_lock,    
293                                                   
294         return err ? PCIBIOS_DEVICE_NOT_FOUND     
295 }                                                 
296                                                   
297 static struct pci_ops ssb_pcicore_pciops = {      
298         .read   = ssb_pcicore_read_config,        
299         .write  = ssb_pcicore_write_config,       
300 };                                                
301                                                   
302 static struct resource ssb_pcicore_mem_resourc    
303         .name   = "SSB PCIcore external memory    
304         .start  = SSB_PCI_DMA,                    
305         .end    = SSB_PCI_DMA + SSB_PCI_DMA_SZ    
306         .flags  = IORESOURCE_MEM | IORESOURCE_    
307 };                                                
308                                                   
309 static struct resource ssb_pcicore_io_resource    
310         .name   = "SSB PCIcore external I/O",     
311         .start  = 0x100,                          
312         .end    = 0x7FF,                          
313         .flags  = IORESOURCE_IO | IORESOURCE_P    
314 };                                                
315                                                   
316 static struct pci_controller ssb_pcicore_contr    
317         .pci_ops        = &ssb_pcicore_pciops,    
318         .io_resource    = &ssb_pcicore_io_reso    
319         .mem_resource   = &ssb_pcicore_mem_res    
320         .mem_offset     = 0x24000000,             
321 };                                                
322                                                   
323 static void ssb_pcicore_init_hostmode(struct s    
324 {                                                 
325         u32 val;                                  
326                                                   
327         if (WARN_ON(extpci_core))                 
328                 return;                           
329         extpci_core = pc;                         
330                                                   
331         ssb_dprintk(KERN_INFO PFX "PCIcore in     
332         /* Reset devices on the external PCI b    
333         val = SSB_PCICORE_CTL_RST_OE;             
334         val |= SSB_PCICORE_CTL_CLK_OE;            
335         pcicore_write32(pc, SSB_PCICORE_CTL, v    
336         val |= SSB_PCICORE_CTL_CLK; /* Clock o    
337         pcicore_write32(pc, SSB_PCICORE_CTL, v    
338         udelay(150); /* Assertion time demande    
339         val |= SSB_PCICORE_CTL_RST; /* Deasser    
340         pcicore_write32(pc, SSB_PCICORE_CTL, v    
341         val = SSB_PCICORE_ARBCTL_INTERN;          
342         pcicore_write32(pc, SSB_PCICORE_ARBCTL    
343         udelay(1); /* Assertion time demanded     
344                                                   
345         if (pc->dev->bus->has_cardbus_slot) {     
346                 ssb_dprintk(KERN_INFO PFX "Car    
347                 pc->cardbusmode = 1;              
348                 /* GPIO 1 resets the bridge */    
349                 ssb_gpio_out(pc->dev->bus, 1,     
350                 ssb_gpio_outen(pc->dev->bus, 1    
351                 pcicore_write16(pc, SSB_PCICOR    
352                                 pcicore_read16    
353                                 | 0x0400);        
354         }                                         
355                                                   
356         /* 64MB I/O window */                     
357         pcicore_write32(pc, SSB_PCICORE_SBTOPC    
358                         SSB_PCICORE_SBTOPCI_IO    
359         /* 64MB config space */                   
360         pcicore_write32(pc, SSB_PCICORE_SBTOPC    
361                         SSB_PCICORE_SBTOPCI_CF    
362         /* 1GB memory window */                   
363         pcicore_write32(pc, SSB_PCICORE_SBTOPC    
364                         SSB_PCICORE_SBTOPCI_ME    
365                                                   
366         /* Enable PCI bridge BAR0 prefetch and    
367         val = PCI_COMMAND_MASTER | PCI_COMMAND    
368         ssb_extpci_write_config(pc, 0, 0, 0, P    
369         /* Clear error conditions */              
370         val = 0;                                  
371         ssb_extpci_write_config(pc, 0, 0, 0, P    
372                                                   
373         /* Enable PCI interrupts */               
374         pcicore_write32(pc, SSB_PCICORE_IMASK,    
375                         SSB_PCICORE_IMASK_INTA    
376                                                   
377         /* Ok, ready to run, register it to th    
378          * The following needs change, if we w    
379          * to non-MIPS platform. */               
380         ssb_pcicore_controller.io_map_base = (    
381         set_io_port_base(ssb_pcicore_controlle    
382         /* Give some time to the PCI controlle    
383          * values. Not waiting at this point c    
384         mdelay(10);                               
385         register_pci_controller(&ssb_pcicore_c    
386 }                                                 
387                                                   
388 static int pcicore_is_in_hostmode(struct ssb_p    
389 {                                                 
390         struct ssb_bus *bus = pc->dev->bus;       
391         u16 chipid_top;                           
392         u32 tmp;                                  
393                                                   
394         chipid_top = (bus->chip_id & 0xFF00);     
395         if (chipid_top != 0x4700 &&               
396             chipid_top != 0x5300)                 
397                 return 0;                         
398                                                   
399         if (bus->sprom.boardflags_lo & SSB_PCI    
400                 return 0;                         
401                                                   
402         /* The 200-pin BCM4712 package does no    
403          * PCI is bonded out, some boards may     
404         if (bus->chip_id == 0x4712) {             
405                 if (bus->chip_package == SSB_C    
406                         return 0;                 
407                 if (bus->chip_package == SSB_C    
408                         return 0;                 
409         }                                         
410         if (bus->chip_id == 0x5350)               
411                 return 0;                         
412                                                   
413         return !mips_busprobe32(tmp, (bus->mmi    
414 }                                                 
415 #endif /* CONFIG_SSB_PCICORE_HOSTMODE */          
416                                                   
417                                                   
418 /*********************************************    
419  * Generic and Clientmode operation code.         
420  *********************************************    
421                                                   
422 static void ssb_pcicore_init_clientmode(struct    
423 {                                                 
424         /* Disable PCI interrupts. */             
425         ssb_write32(pc->dev, SSB_INTVEC, 0);      
426 }                                                 
427                                                   
428 void ssb_pcicore_init(struct ssb_pcicore *pc)     
429 {                                                 
430         struct ssb_device *dev = pc->dev;         
431         struct ssb_bus *bus;                      
432                                                   
433         if (!dev)                                 
434                 return;                           
435         bus = dev->bus;                           
436         if (!ssb_device_is_enabled(dev))          
437                 ssb_device_enable(dev, 0);        
438                                                   
439 #ifdef CONFIG_SSB_PCICORE_HOSTMODE                
440         pc->hostmode = pcicore_is_in_hostmode(    
441         if (pc->hostmode)                         
442                 ssb_pcicore_init_hostmode(pc);    
443 #endif /* CONFIG_SSB_PCICORE_HOSTMODE */          
444         if (!pc->hostmode)                        
445                 ssb_pcicore_init_clientmode(pc    
446 }                                                 
447                                                   
448 static u32 ssb_pcie_read(struct ssb_pcicore *p    
449 {                                                 
450         pcicore_write32(pc, 0x130, address);      
451         return pcicore_read32(pc, 0x134);         
452 }                                                 
453                                                   
454 static void ssb_pcie_write(struct ssb_pcicore     
455 {                                                 
456         pcicore_write32(pc, 0x130, address);      
457         pcicore_write32(pc, 0x134, data);         
458 }                                                 
459                                                   
460 static void ssb_pcie_mdio_write(struct ssb_pci    
461                                 u8 address, u1    
462 {                                                 
463         const u16 mdio_control = 0x128;           
464         const u16 mdio_data = 0x12C;              
465         u32 v;                                    
466         int i;                                    
467                                                   
468         v = 0x80; /* Enable Preamble Sequence     
469         v |= 0x2; /* MDIO Clock Divisor */        
470         pcicore_write32(pc, mdio_control, v);     
471                                                   
472         v = (1 << 30); /* Start of Transaction    
473         v |= (1 << 28); /* Write Transaction *    
474         v |= (1 << 17); /* Turnaround */          
475         v |= (u32)device << 22;                   
476         v |= (u32)address << 18;                  
477         v |= data;                                
478         pcicore_write32(pc, mdio_data, v);        
479         /* Wait for the device to complete the    
480         udelay(10);                               
481         for (i = 0; i < 10; i++) {                
482                 v = pcicore_read32(pc, mdio_co    
483                 if (v & 0x100 /* Trans complet    
484                         break;                    
485                 msleep(1);                        
486         }                                         
487         pcicore_write32(pc, mdio_control, 0);     
488 }                                                 
489                                                   
490 static void ssb_broadcast_value(struct ssb_dev    
491                                 u32 address, u    
492 {                                                 
493         /* This is used for both, PCI and Chip    
494         BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR !=    
495         BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA !=    
496                                                   
497         ssb_write32(dev, SSB_PCICORE_BCAST_ADD    
498         ssb_read32(dev, SSB_PCICORE_BCAST_ADDR    
499         ssb_write32(dev, SSB_PCICORE_BCAST_DAT    
500         ssb_read32(dev, SSB_PCICORE_BCAST_DATA    
501 }                                                 
502                                                   
503 static void ssb_commit_settings(struct ssb_bus    
504 {                                                 
505         struct ssb_device *dev;                   
506                                                   
507         dev = bus->chipco.dev ? bus->chipco.de    
508         if (WARN_ON(!dev))                        
509                 return;                           
510         /* This forces an update of the cached    
511         ssb_broadcast_value(dev, 0xFD8, 0);       
512 }                                                 
513                                                   
514 int ssb_pcicore_dev_irqvecs_enable(struct ssb_    
515                                    struct ssb_    
516 {                                                 
517         struct ssb_device *pdev = pc->dev;        
518         struct ssb_bus *bus;                      
519         int err = 0;                              
520         u32 tmp;                                  
521                                                   
522         if (!pdev)                                
523                 goto out;                         
524         bus = pdev->bus;                          
525                                                   
526         might_sleep_if(pdev->id.coreid != SSB_    
527                                                   
528         /* Enable interrupts for this device.     
529         if (bus->host_pci &&                      
530             ((pdev->id.revision >= 6) || (pdev    
531                 u32 coremask;                     
532                                                   
533                 /* Calculate the "coremask" fo    
534                 coremask = (1 << dev->core_ind    
535                                                   
536                 err = pci_read_config_dword(bu    
537                 if (err)                          
538                         goto out;                 
539                 tmp |= coremask << 8;             
540                 err = pci_write_config_dword(b    
541                 if (err)                          
542                         goto out;                 
543         } else {                                  
544                 u32 intvec;                       
545                                                   
546                 intvec = ssb_read32(pdev, SSB_    
547                 if ((bus->chip_id & 0xFF00) ==    
548                         /* Workaround: On the     
549                          * bit is wrong. Use a    
550                         intvec |= 0x00000002;     
551                 } else {                          
552                         tmp = ssb_read32(dev,     
553                         tmp &= SSB_TPSFLAG_BPF    
554                         intvec |= (1 << tmp);     
555                 }                                 
556                 ssb_write32(pdev, SSB_INTVEC,     
557         }                                         
558                                                   
559         /* Setup PCIcore operation. */            
560         if (pc->setup_done)                       
561                 goto out;                         
562         if (pdev->id.coreid == SSB_DEV_PCI) {     
563                 tmp = pcicore_read32(pc, SSB_P    
564                 tmp |= SSB_PCICORE_SBTOPCI_PRE    
565                 tmp |= SSB_PCICORE_SBTOPCI_BUR    
566                 pcicore_write32(pc, SSB_PCICOR    
567                                                   
568                 if (pdev->id.revision < 5) {      
569                         tmp = ssb_read32(pdev,    
570                         tmp &= ~SSB_IMCFGLO_SE    
571                         tmp |= 2;                 
572                         tmp &= ~SSB_IMCFGLO_RE    
573                         tmp |= 3 << SSB_IMCFGL    
574                         ssb_write32(pdev, SSB_    
575                         ssb_commit_settings(bu    
576                 } else if (pdev->id.revision >    
577                         tmp = pcicore_read32(p    
578                         tmp |= SSB_PCICORE_SBT    
579                         pcicore_write32(pc, SS    
580                 }                                 
581         } else {                                  
582                 WARN_ON(pdev->id.coreid != SSB    
583                 //TODO: Better make defines fo    
584                 if ((pdev->id.revision == 0) |    
585                         /* TLP Workaround regi    
586                         tmp = ssb_pcie_read(pc    
587                         tmp |= 0x8;               
588                         ssb_pcie_write(pc, 0x4    
589                 }                                 
590                 if (pdev->id.revision == 0) {     
591                         const u8 serdes_rx_dev    
592                                                   
593                         ssb_pcie_mdio_write(pc    
594                                             2     
595                         ssb_pcie_mdio_write(pc    
596                                             6     
597                         ssb_pcie_mdio_write(pc    
598                                             7     
599                 } else if (pdev->id.revision =    
600                         /* DLLP Link Control r    
601                         tmp = ssb_pcie_read(pc    
602                         tmp |= 0x40;              
603                         ssb_pcie_write(pc, 0x1    
604                 }                                 
605         }                                         
606         pc->setup_done = 1;                       
607 out:                                              
608         return err;                               
609 }                                                 
610 EXPORT_SYMBOL(ssb_pcicore_dev_irqvecs_enable);    
611                                                   
  This page was automatically generated by the LXR engine.