2003-04-24 08:25:08 +02:00
|
|
|
/*
|
|
|
|
* PCI defines and function prototypes
|
|
|
|
* Copyright 1994, Drew Eckhardt
|
|
|
|
* Copyright 1997--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
|
|
|
|
*
|
|
|
|
* For more information, please consult the following manuals (look at
|
|
|
|
* http://www.pcisig.com/ for how to get them):
|
|
|
|
*
|
|
|
|
* PCI BIOS Specification
|
|
|
|
* PCI Local Bus Specification
|
|
|
|
* PCI to PCI Bridge Specification
|
|
|
|
* PCI System Design Guide
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef PCI_H
|
|
|
|
#define PCI_H
|
|
|
|
|
2014-02-12 13:18:50 +01:00
|
|
|
#if CONFIG_PCI
|
|
|
|
|
2010-11-05 00:23:47 +01:00
|
|
|
#include <stdint.h>
|
Make the device tree available in the rom stage
We thought about two ways to do this change. The way we decided to try
was to
1. drop all ops from devices in romstage
2. constify all devices in romstage (make them read-only) so we can
compile static.c into romstage
3. the device tree "devices" can be used to read configuration from
the device tree (and nothing else, really)
4. the device tree devices are accessed through struct device * in
romstage only. device_t stays the typedef to int in romstage
5. Use the same static.c file in ramstage and romstage
We declare structs as follows:
ROMSTAGE_CONST struct bus dev_root_links[];
ROMSTAGE_CONST is const in romstage and empty in ramstage; This
forces all of the device tree into the text area.
So a struct looks like this:
static ROMSTAGE_CONST struct device _dev21 = {
#ifndef __PRE_RAM__
.ops = 0,
#endif
.bus = &_dev7_links[0],
.path = {.type=DEVICE_PATH_PCI,{.pci={ .devfn = PCI_DEVFN(0x1c,3)}}},
.enabled = 0,
.on_mainboard = 1,
.subsystem_vendor = 0x1ae0,
.subsystem_device = 0xc000,
.link_list = NULL,
.sibling = &_dev22,
#ifndef __PRE_RAM__
.chip_ops = &southbridge_intel_bd82x6x_ops,
#endif
.chip_info = &southbridge_intel_bd82x6x_info_10,
.next=&_dev22
};
Change-Id: I722454d8d3c40baf7df989f5a6891f6ba7db5727
Signed-off-by: Ronald G. Minnich <rminnich@chromium.org>
Signed-off-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/1398
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2012-08-01 01:47:25 +02:00
|
|
|
#include <stddef.h>
|
2014-02-26 14:19:04 +01:00
|
|
|
#include <rules.h>
|
2014-02-11 18:56:57 +01:00
|
|
|
#include <arch/io.h>
|
2003-05-19 21:16:21 +02:00
|
|
|
#include <device/pci_def.h>
|
2003-04-24 08:25:08 +02:00
|
|
|
#include <device/resource.h>
|
|
|
|
#include <device/device.h>
|
|
|
|
#include <device/pci_ops.h>
|
2005-01-11 00:16:22 +01:00
|
|
|
#include <device/pci_rom.h>
|
2003-04-24 08:25:08 +02:00
|
|
|
|
2013-06-25 22:17:43 +02:00
|
|
|
#ifndef __SIMPLE_DEVICE__
|
|
|
|
|
2004-10-14 22:54:17 +02:00
|
|
|
/* Common pci operations without a standard interface */
|
|
|
|
struct pci_operations {
|
2004-11-25 18:37:19 +01:00
|
|
|
/* set the Subsystem IDs for the PCI device */
|
2004-10-14 22:54:17 +02:00
|
|
|
void (*set_subsystem)(device_t dev, unsigned vendor, unsigned device);
|
2014-10-03 19:14:44 +02:00
|
|
|
void (*set_L1_ss_latency)(device_t dev, unsigned int off);
|
2004-10-14 22:54:17 +02:00
|
|
|
};
|
|
|
|
|
2004-11-18 23:38:08 +01:00
|
|
|
/* Common pci bus operations */
|
|
|
|
struct pci_bus_operations {
|
2006-10-04 22:46:15 +02:00
|
|
|
uint8_t (*read8) (struct bus *pbus, int bus, int devfn, int where);
|
|
|
|
uint16_t (*read16) (struct bus *pbus, int bus, int devfn, int where);
|
|
|
|
uint32_t (*read32) (struct bus *pbus, int bus, int devfn, int where);
|
|
|
|
void (*write8) (struct bus *pbus, int bus, int devfn, int where, uint8_t val);
|
|
|
|
void (*write16) (struct bus *pbus, int bus, int devfn, int where, uint16_t val);
|
|
|
|
void (*write32) (struct bus *pbus, int bus, int devfn, int where, uint32_t val);
|
2004-11-18 23:38:08 +01:00
|
|
|
};
|
|
|
|
|
2003-04-24 08:25:08 +02:00
|
|
|
struct pci_driver {
|
2009-10-27 22:49:33 +01:00
|
|
|
const struct device_operations *ops;
|
2003-04-24 08:25:08 +02:00
|
|
|
unsigned short vendor;
|
|
|
|
unsigned short device;
|
2012-04-24 21:53:19 +02:00
|
|
|
const unsigned short *devices;
|
2003-04-24 08:25:08 +02:00
|
|
|
};
|
|
|
|
|
2004-10-14 22:54:17 +02:00
|
|
|
#define __pci_driver __attribute__ ((used,__section__(".rodata.pci_driver")))
|
2004-03-23 22:28:05 +01:00
|
|
|
/** start of compile time generated pci driver array */
|
2015-09-04 00:23:08 +02:00
|
|
|
extern struct pci_driver _pci_drivers[];
|
2004-03-23 22:28:05 +01:00
|
|
|
/** end of compile time generated pci driver array */
|
2015-09-04 00:23:08 +02:00
|
|
|
extern struct pci_driver _epci_drivers[];
|
2003-04-24 08:25:08 +02:00
|
|
|
|
|
|
|
|
2005-07-08 04:49:49 +02:00
|
|
|
extern struct device_operations default_pci_ops_dev;
|
|
|
|
extern struct device_operations default_pci_ops_bus;
|
2003-04-24 08:25:08 +02:00
|
|
|
|
2003-09-02 05:36:25 +02:00
|
|
|
void pci_dev_read_resources(device_t dev);
|
|
|
|
void pci_bus_read_resources(device_t dev);
|
|
|
|
void pci_dev_set_resources(device_t dev);
|
|
|
|
void pci_dev_enable_resources(device_t dev);
|
|
|
|
void pci_bus_enable_resources(device_t dev);
|
2005-07-08 04:49:49 +02:00
|
|
|
void pci_bus_reset(struct bus *bus);
|
|
|
|
device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn);
|
2015-03-18 12:09:47 +01:00
|
|
|
|
2015-03-19 20:04:23 +01:00
|
|
|
void do_pci_scan_bridge(device_t bus,
|
2015-03-18 12:09:47 +01:00
|
|
|
void (*do_scan_bus)(struct bus *bus,
|
|
|
|
unsigned min_devfn, unsigned max_devfn));
|
|
|
|
|
2015-03-19 20:04:23 +01:00
|
|
|
void pci_scan_bridge(device_t bus);
|
2015-03-18 12:09:47 +01:00
|
|
|
void pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn);
|
|
|
|
|
2005-07-08 04:49:49 +02:00
|
|
|
uint8_t pci_moving_config8(struct device *dev, unsigned reg);
|
|
|
|
uint16_t pci_moving_config16(struct device *dev, unsigned reg);
|
|
|
|
uint32_t pci_moving_config32(struct device *dev, unsigned reg);
|
2004-10-14 22:54:17 +02:00
|
|
|
struct resource *pci_get_resource(struct device *dev, unsigned long index);
|
2004-10-21 12:44:08 +02:00
|
|
|
void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device);
|
2008-12-18 19:24:11 +01:00
|
|
|
void pci_dev_init(struct device *dev);
|
2013-06-15 16:16:56 +02:00
|
|
|
unsigned int pci_match_simple_dev(device_t dev, pci_devfn_t sdev);
|
2009-07-21 23:36:41 +02:00
|
|
|
|
PCI IRQs: Swizzle PCI IRQs for PCI bridges
The PCI Specification states that devices that implement
a bridge and a secondary bus must swizzle (rotate) the
interrupt pins according to the table below:
Child Dev # Child PIN Parent PIN
0,4,8,12... A/B/C/D A/B/C/D
1,5,9,13... A/B/C/D B/C/D/A
2,6,10,14.. A/B/C/D C/D/A/B
3,7,11,15.. A/B/C/D D/A/B/C
Which is also described by this equation:
PIN_parent = (Pin_child + Dev_child) % 4
When a device is found and its bus number is greater than 0,
it is on a bridge and needs to be swizzled. Following the
string of parents up to the root bus and swizzling as we go
gives us the desired swizzling result. When BIOS_SPEW is
defined, it will print out each step of the swizzling process.
Change-Id: Icafeadd01983282c86e25f560c831c9482c74e68
Signed-off-by: Martin Roth <gaumless@gmail.com>
Reviewed-on: http://review.coreboot.org/5734
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marc.jones@se-eng.com>
Reviewed-by: Mike Loptien <mike.loptien@se-eng.com>
2014-05-13 05:46:31 +02:00
|
|
|
const char * pin_to_str(int pin);
|
|
|
|
int get_pci_irq_pins(device_t dev, device_t *parent_bdg);
|
2008-12-18 19:24:11 +01:00
|
|
|
void pci_assign_irqs(unsigned bus, unsigned slot,
|
|
|
|
const unsigned char pIntAtoD[4]);
|
2015-04-01 02:30:01 +02:00
|
|
|
const char *get_pci_class_name(device_t dev);
|
|
|
|
const char *get_pci_subclass_name(device_t dev);
|
2003-04-24 08:25:08 +02:00
|
|
|
|
|
|
|
#define PCI_IO_BRIDGE_ALIGN 4096
|
|
|
|
#define PCI_MEM_BRIDGE_ALIGN (1024*1024)
|
|
|
|
|
2004-11-18 23:38:08 +01:00
|
|
|
static inline const struct pci_operations *ops_pci(device_t dev)
|
2004-10-14 22:54:17 +02:00
|
|
|
{
|
2004-11-18 23:38:08 +01:00
|
|
|
const struct pci_operations *pops;
|
2004-10-14 22:54:17 +02:00
|
|
|
pops = 0;
|
|
|
|
if (dev && dev->ops) {
|
|
|
|
pops = dev->ops->ops_pci;
|
|
|
|
}
|
|
|
|
return pops;
|
|
|
|
}
|
|
|
|
|
2013-06-25 22:17:43 +02:00
|
|
|
#endif /* ! __SIMPLE_DEVICE__ */
|
2014-02-12 13:18:50 +01:00
|
|
|
|
2014-07-08 20:55:16 +02:00
|
|
|
#ifdef __PRE_RAM__
|
|
|
|
unsigned pci_find_next_capability(pci_devfn_t dev, unsigned cap, unsigned last);
|
|
|
|
unsigned pci_find_capability(pci_devfn_t dev, unsigned cap);
|
|
|
|
#else /* !__PRE_RAM__ */
|
2014-02-11 18:56:57 +01:00
|
|
|
unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last);
|
|
|
|
unsigned pci_find_capability(device_t dev, unsigned cap);
|
2014-07-08 20:55:16 +02:00
|
|
|
#endif /* __PRE_RAM__ */
|
|
|
|
|
2014-02-14 11:45:09 +01:00
|
|
|
void pci_early_bridge_init(void);
|
|
|
|
int pci_early_device_probe(u8 bus, u8 dev, u32 mmio_base);
|
2014-02-11 18:56:57 +01:00
|
|
|
|
2016-01-06 02:00:27 +01:00
|
|
|
#ifndef __ROMCC__
|
|
|
|
static inline int pci_base_address_is_memory_space(unsigned int attr)
|
|
|
|
{
|
|
|
|
return (attr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-02-12 13:18:50 +01:00
|
|
|
#endif /* CONFIG_PCI */
|
|
|
|
|
2003-04-24 08:25:08 +02:00
|
|
|
#endif /* PCI_H */
|