root/arch/xtensa/lib/pci-auto.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pciauto_setup_bars
  2. pciauto_setup_irq
  3. pciauto_prescan_setup_bridge
  4. pciauto_postscan_setup_bridge
  5. pciauto_bus_scan

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * arch/xtensa/lib/pci-auto.c
   4  *
   5  * PCI autoconfiguration library
   6  *
   7  * Copyright (C) 2001 - 2005 Tensilica Inc.
   8  *
   9  * Chris Zankel <zankel@tensilica.com, cez@zankel.net>
  10  *
  11  * Based on work from Matt Porter <mporter@mvista.com>
  12  */
  13 
  14 #include <linux/kernel.h>
  15 #include <linux/init.h>
  16 #include <linux/pci.h>
  17 
  18 #include <asm/pci-bridge.h>
  19 
  20 
  21 /*
  22  *
  23  * Setting up a PCI
  24  *
  25  * pci_ctrl->first_busno = <first bus number (0)>
  26  * pci_ctrl->last_busno = <last bus number (0xff)>
  27  * pci_ctrl->ops = <PCI config operations>
  28  * pci_ctrl->map_irq = <function to return the interrupt number for a device>
  29  *
  30  * pci_ctrl->io_space.start = <IO space start address (PCI view)>
  31  * pci_ctrl->io_space.end = <IO space end address (PCI view)>
  32  * pci_ctrl->io_space.base = <IO space offset: address 0 from CPU space>
  33  * pci_ctrl->mem_space.start = <MEM space start address (PCI view)>
  34  * pci_ctrl->mem_space.end = <MEM space end address (PCI view)>
  35  * pci_ctrl->mem_space.base = <MEM space offset: address 0 from CPU space>
  36  *
  37  * pcibios_init_resource(&pci_ctrl->io_resource, <IO space start>,
  38  *                       <IO space end>, IORESOURCE_IO, "PCI host bridge");
  39  * pcibios_init_resource(&pci_ctrl->mem_resources[0], <MEM space start>,
  40  *                       <MEM space end>, IORESOURCE_MEM, "PCI host bridge");
  41  *
  42  * pci_ctrl->last_busno = pciauto_bus_scan(pci_ctrl,pci_ctrl->first_busno);
  43  *
  44  * int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus)
  45  *
  46  */
  47 
  48 static int pciauto_upper_iospc;
  49 static int pciauto_upper_memspc;
  50 
  51 static struct pci_dev pciauto_dev;
  52 static struct pci_bus pciauto_bus;
  53 
  54 /*
  55  * Helper functions
  56  */
  57 
  58 /* Initialize the bars of a PCI device.  */
  59 
  60 static void __init
  61 pciauto_setup_bars(struct pci_dev *dev, int bar_limit)
  62 {
  63         int bar_size;
  64         int bar, bar_nr;
  65         int *upper_limit;
  66         int found_mem64 = 0;
  67 
  68         for (bar = PCI_BASE_ADDRESS_0, bar_nr = 0;
  69              bar <= bar_limit;
  70              bar+=4, bar_nr++)
  71         {
  72                 /* Tickle the BAR and get the size */
  73                 pci_write_config_dword(dev, bar, 0xffffffff);
  74                 pci_read_config_dword(dev, bar, &bar_size);
  75 
  76                 /* If BAR is not implemented go to the next BAR */
  77                 if (!bar_size)
  78                         continue;
  79 
  80                 /* Check the BAR type and set our address mask */
  81                 if (bar_size & PCI_BASE_ADDRESS_SPACE_IO)
  82                 {
  83                         bar_size &= PCI_BASE_ADDRESS_IO_MASK;
  84                         upper_limit = &pciauto_upper_iospc;
  85                         pr_debug("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
  86                 }
  87                 else
  88                 {
  89                         if ((bar_size & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
  90                             PCI_BASE_ADDRESS_MEM_TYPE_64)
  91                                 found_mem64 = 1;
  92 
  93                         bar_size &= PCI_BASE_ADDRESS_MEM_MASK;
  94                         upper_limit = &pciauto_upper_memspc;
  95                         pr_debug("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
  96                 }
  97 
  98                 /* Allocate a base address (bar_size is negative!) */
  99                 *upper_limit = (*upper_limit + bar_size) & bar_size;
 100 
 101                 /* Write it out and update our limit */
 102                 pci_write_config_dword(dev, bar, *upper_limit);
 103 
 104                 /*
 105                  * If we are a 64-bit decoder then increment to the
 106                  * upper 32 bits of the bar and force it to locate
 107                  * in the lower 4GB of memory.
 108                  */
 109 
 110                 if (found_mem64)
 111                         pci_write_config_dword(dev, (bar+=4), 0x00000000);
 112 
 113                 pr_debug("size=0x%x, address=0x%x\n",
 114                          ~bar_size + 1, *upper_limit);
 115         }
 116 }
 117 
 118 /* Initialize the interrupt number. */
 119 
 120 static void __init
 121 pciauto_setup_irq(struct pci_controller* pci_ctrl,struct pci_dev *dev,int devfn)
 122 {
 123         u8 pin;
 124         int irq = 0;
 125 
 126         pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 127 
 128         /* Fix illegal pin numbers. */
 129 
 130         if (pin == 0 || pin > 4)
 131                 pin = 1;
 132 
 133         if (pci_ctrl->map_irq)
 134                 irq = pci_ctrl->map_irq(dev, PCI_SLOT(devfn), pin);
 135 
 136         if (irq == -1)
 137                 irq = 0;
 138 
 139         pr_debug("PCI Autoconfig: Interrupt %d, pin %d\n", irq, pin);
 140 
 141         pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 142 }
 143 
 144 
 145 static void __init
 146 pciauto_prescan_setup_bridge(struct pci_dev *dev, int current_bus,
 147                              int sub_bus, int *iosave, int *memsave)
 148 {
 149         /* Configure bus number registers */
 150         pci_write_config_byte(dev, PCI_PRIMARY_BUS, current_bus);
 151         pci_write_config_byte(dev, PCI_SECONDARY_BUS, sub_bus + 1);
 152         pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, 0xff);
 153 
 154         /* Round memory allocator to 1MB boundary */
 155         pciauto_upper_memspc &= ~(0x100000 - 1);
 156         *memsave = pciauto_upper_memspc;
 157 
 158         /* Round I/O allocator to 4KB boundary */
 159         pciauto_upper_iospc &= ~(0x1000 - 1);
 160         *iosave = pciauto_upper_iospc;
 161 
 162         /* Set up memory and I/O filter limits, assume 32-bit I/O space */
 163         pci_write_config_word(dev, PCI_MEMORY_LIMIT,
 164                               ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
 165         pci_write_config_byte(dev, PCI_IO_LIMIT,
 166                               ((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
 167         pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
 168                               ((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
 169 }
 170 
 171 static void __init
 172 pciauto_postscan_setup_bridge(struct pci_dev *dev, int current_bus, int sub_bus,
 173                               int *iosave, int *memsave)
 174 {
 175         int cmdstat;
 176 
 177         /* Configure bus number registers */
 178         pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, sub_bus);
 179 
 180         /*
 181          * Round memory allocator to 1MB boundary.
 182          * If no space used, allocate minimum.
 183          */
 184         pciauto_upper_memspc &= ~(0x100000 - 1);
 185         if (*memsave == pciauto_upper_memspc)
 186                 pciauto_upper_memspc -= 0x00100000;
 187 
 188         pci_write_config_word(dev, PCI_MEMORY_BASE, pciauto_upper_memspc >> 16);
 189 
 190         /* Allocate 1MB for pre-fretch */
 191         pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT,
 192                               ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
 193 
 194         pciauto_upper_memspc -= 0x100000;
 195 
 196         pci_write_config_word(dev, PCI_PREF_MEMORY_BASE,
 197                               pciauto_upper_memspc >> 16);
 198 
 199         /* Round I/O allocator to 4KB boundary */
 200         pciauto_upper_iospc &= ~(0x1000 - 1);
 201         if (*iosave == pciauto_upper_iospc)
 202                 pciauto_upper_iospc -= 0x1000;
 203 
 204         pci_write_config_byte(dev, PCI_IO_BASE,
 205                               (pciauto_upper_iospc & 0x0000f000) >> 8);
 206         pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
 207                               pciauto_upper_iospc >> 16);
 208 
 209         /* Enable memory and I/O accesses, enable bus master */
 210         pci_read_config_dword(dev, PCI_COMMAND, &cmdstat);
 211         pci_write_config_dword(dev, PCI_COMMAND,
 212                                cmdstat |
 213                                PCI_COMMAND_IO |
 214                                PCI_COMMAND_MEMORY |
 215                                PCI_COMMAND_MASTER);
 216 }
 217 
 218 /*
 219  * Scan the current PCI bus.
 220  */
 221 
 222 
 223 int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus)
 224 {
 225         int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0;
 226         unsigned short vid;
 227         unsigned char header_type;
 228         struct pci_dev *dev = &pciauto_dev;
 229 
 230         pciauto_dev.bus = &pciauto_bus;
 231         pciauto_dev.sysdata = pci_ctrl;
 232         pciauto_bus.ops = pci_ctrl->ops;
 233 
 234         /*
 235          * Fetch our I/O and memory space upper boundaries used
 236          * to allocated base addresses on this pci_controller.
 237          */
 238 
 239         if (current_bus == pci_ctrl->first_busno)
 240         {
 241                 pciauto_upper_iospc = pci_ctrl->io_resource.end + 1;
 242                 pciauto_upper_memspc = pci_ctrl->mem_resources[0].end + 1;
 243         }
 244 
 245         sub_bus = current_bus;
 246 
 247         for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++)
 248         {
 249                 /* Skip our host bridge */
 250                 if ((current_bus == pci_ctrl->first_busno) && (pci_devfn == 0))
 251                         continue;
 252 
 253                 if (PCI_FUNC(pci_devfn) && !found_multi)
 254                         continue;
 255 
 256                 pciauto_bus.number = current_bus;
 257                 pciauto_dev.devfn = pci_devfn;
 258 
 259                 /* If config space read fails from this device, move on */
 260                 if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type))
 261                         continue;
 262 
 263                 if (!PCI_FUNC(pci_devfn))
 264                         found_multi = header_type & 0x80;
 265                 pci_read_config_word(dev, PCI_VENDOR_ID, &vid);
 266 
 267                 if (vid == 0xffff || vid == 0x0000) {
 268                         found_multi = 0;
 269                         continue;
 270                 }
 271 
 272                 pci_read_config_dword(dev, PCI_CLASS_REVISION, &pci_class);
 273 
 274                 if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
 275 
 276                         int iosave, memsave;
 277 
 278                         pr_debug("PCI Autoconfig: Found P2P bridge, device %d\n",
 279                                  PCI_SLOT(pci_devfn));
 280 
 281                         /* Allocate PCI I/O and/or memory space */
 282                         pciauto_setup_bars(dev, PCI_BASE_ADDRESS_1);
 283 
 284                         pciauto_prescan_setup_bridge(dev, current_bus, sub_bus,
 285                                         &iosave, &memsave);
 286                         sub_bus = pciauto_bus_scan(pci_ctrl, sub_bus+1);
 287                         pciauto_postscan_setup_bridge(dev, current_bus, sub_bus,
 288                                         &iosave, &memsave);
 289                         pciauto_bus.number = current_bus;
 290 
 291                         continue;
 292 
 293                 }
 294 
 295                 /*
 296                  * Found a peripheral, enable some standard
 297                  * settings
 298                  */
 299 
 300                 pci_read_config_dword(dev, PCI_COMMAND, &cmdstat);
 301                 pci_write_config_dword(dev, PCI_COMMAND,
 302                                 cmdstat |
 303                                         PCI_COMMAND_IO |
 304                                         PCI_COMMAND_MEMORY |
 305                                         PCI_COMMAND_MASTER);
 306                 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
 307 
 308                 /* Allocate PCI I/O and/or memory space */
 309                 pr_debug("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
 310                          current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
 311 
 312                 pciauto_setup_bars(dev, PCI_BASE_ADDRESS_5);
 313                 pciauto_setup_irq(pci_ctrl, dev, pci_devfn);
 314         }
 315         return sub_bus;
 316 }

/* [<][>][^][v][top][bottom][index][help] */