]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/pci_auto.c
Merge git://www.denx.de/git/u-boot
[karo-tx-uboot.git] / drivers / pci_auto.c
index 969167555ea27369008b7c5b53dc76f75bc9a46f..acfda83ba50b325f0f2076c8e9544796f8629d91 100644 (file)
 
 #define        PCIAUTO_IDE_MODE_MASK           0x05
 
+/* the user can define CFG_PCI_CACHE_LINE_SIZE to avoid problems */
+#ifndef CFG_PCI_CACHE_LINE_SIZE
+#define CFG_PCI_CACHE_LINE_SIZE        8
+#endif
+
 /*
  *
  */
 
 void pciauto_region_init(struct pci_region* res)
 {
-       res->bus_lower = res->bus_start;
+       /*
+        * Avoid allocating PCI resources from address 0 -- this is illegal
+        * according to PCI 2.1 and moreover, this is known to cause Linux IDE
+        * drivers to fail. Use a reasonable starting value of 0x1000 instead.
+        */
+       res->bus_lower = res->bus_start ? res->bus_start : 0x1000;
 }
 
 void pciauto_region_align(struct pci_region *res, unsigned long size)
@@ -60,7 +70,7 @@ int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned
 
        res->bus_lower = addr + size;
 
-       DEBUGF("address=0x%lx", addr);
+       DEBUGF("address=0x%lx bus_lower=%x", addr, res->bus_lower);
 
        *bar = addr;
        return 0;
@@ -89,7 +99,7 @@ void pciauto_setup_device(struct pci_controller *hose,
        pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
        cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER;
 
-       for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4) {
+       for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4) {
                /* Tickle the BAR and get the response */
                pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
                pci_hose_read_config_dword(hose, dev, bar, &bar_response);
@@ -145,11 +155,12 @@ void pciauto_setup_device(struct pci_controller *hose,
        }
 
        pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
-       pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+       pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE,
+               CFG_PCI_CACHE_LINE_SIZE);
        pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
 }
 
-static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+void pciauto_prescan_setup_bridge(struct pci_controller *hose,
                                         pci_dev_t dev, int sub_bus)
 {
        struct pci_region *pci_mem = hose->pci_mem;
@@ -160,8 +171,10 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
        pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
 
        /* Configure bus number registers */
-       pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev));
-       pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus);
+       pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS,
+                                  PCI_BUS(dev) - hose->first_busno);
+       pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS,
+                                  sub_bus - hose->first_busno);
        pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
 
        if (pci_mem) {
@@ -206,7 +219,7 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
        pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
 }
 
-static void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+void pciauto_postscan_setup_bridge(struct pci_controller *hose,
                                          pci_dev_t dev, int sub_bus)
 {
        struct pci_region *pci_mem = hose->pci_mem;
@@ -214,7 +227,8 @@ static void pciauto_postscan_setup_bridge(struct pci_controller *hose,
        struct pci_region *pci_io = hose->pci_io;
 
        /* Configure bus number registers */
-       pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, sub_bus);
+       pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS,
+                                  sub_bus - hose->first_busno);
 
        if (pci_mem) {
                /* Round memory allocator to 1MB boundary */
@@ -277,25 +291,36 @@ void pciauto_config_init(struct pci_controller *hose)
        if (hose->pci_mem) {
                pciauto_region_init(hose->pci_mem);
 
-               DEBUGF("PCI Autoconfig: Memory region: [%lx-%lx]\n",
+               DEBUGF("PCI Autoconfig: Bus Memory region: [%lx-%lx],\n"
+                      "\t\tPhysical Memory [%x-%x]\n",
                    hose->pci_mem->bus_start,
-                   hose->pci_mem->bus_start + hose->pci_mem->size - 1);
+                   hose->pci_mem->bus_start + hose->pci_mem->size - 1,
+                   hose->pci_mem->phys_start,
+                   hose->pci_mem->phys_start + hose->pci_mem->size - 1);
        }
 
        if (hose->pci_prefetch) {
                pciauto_region_init(hose->pci_prefetch);
 
-               DEBUGF("PCI Autoconfig: Prefetchable Memory region: [%lx-%lx]\n",
+               DEBUGF("PCI Autoconfig: Bus Prefetchable Mem: [%lx-%lx],\n"
+                      "\t\tPhysical Memory [%x-%x]\n",
                    hose->pci_prefetch->bus_start,
-                   hose->pci_prefetch->bus_start + hose->pci_prefetch->size - 1);
+                   hose->pci_prefetch->bus_start + hose->pci_prefetch->size - 1,
+                   hose->pci_prefetch->phys_start,
+                   hose->pci_prefetch->phys_start +
+                               hose->pci_prefetch->size - 1);
        }
 
        if (hose->pci_io) {
                pciauto_region_init(hose->pci_io);
 
-               DEBUGF("PCI Autoconfig: I/O region: [%lx-%lx]\n",
+               DEBUGF("PCI Autoconfig: Bus I/O region: [%lx-%lx],\n"
+                      "\t\tPhysical Memory: [%x-%x]\n",
                    hose->pci_io->bus_start,
-                   hose->pci_io->bus_start + hose->pci_io->size - 1);
+                   hose->pci_io->bus_start + hose->pci_io->size - 1,
+                   hose->pci_io->phys_start,
+                   hose->pci_io->phys_start + hose->pci_io->size - 1);
+
        }
 }
 
@@ -312,6 +337,12 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
        pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
 
        switch(class) {
+       case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */
+               DEBUGF("PCI AutoConfig: Found PowerPC device\n");
+               pciauto_setup_device(hose, dev, 6, hose->pci_mem,
+                                    hose->pci_prefetch, hose->pci_io);
+               break;
+
        case PCI_CLASS_BRIDGE_PCI:
                hose->current_busno++;
                pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_prefetch, hose->pci_io);