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