#ifndef __ASSEMBLY__
+#include <dm/pci.h>
+
#ifdef CONFIG_SYS_PCI_64BIT
typedef u64 pci_addr_t;
typedef u64 pci_size_t;
#else
-typedef u32 pci_addr_t;
-typedef u32 pci_size_t;
+typedef unsigned long pci_addr_t;
+typedef unsigned long pci_size_t;
#endif
struct pci_region {
#define PCI_VENDEV(v, d) (((v) << 16) | (d))
#define PCI_ANY_ID (~0)
+/* Convert from Linux format to U-Boot format */
+#define PCI_TO_BDF(val) ((val) << 8)
+
struct pci_device_id {
unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
#define INDIRECT_TYPE_NO_PCIE_LINK 1
-/*
+/**
* Structure of a PCI controller (host bridge)
*
* With driver model this is dev_get_uclass_priv(bus)
+ *
+ * @skip_auto_config_until_reloc: true to avoid auto-config until U-Boot has
+ * relocated. Normally if PCI is used before relocation, this happens
+ * before relocation also. Some platforms set up static configuration in
+ * TPL/SPL to reduce code size and boot time, since these phases only know
+ * about a small subset of PCI devices. This is normally false.
*/
struct pci_controller {
#ifdef CONFIG_DM_PCI
struct udevice *bus;
struct udevice *ctlr;
+ bool skip_auto_config_until_reloc;
#else
struct pci_controller *next;
#endif
* @size: Access size
* @return 0 if OK, -ve on error
*/
- int (*read_config)(struct udevice *bus, pci_dev_t bdf, uint offset,
- ulong *valuep, enum pci_size_t size);
+ int (*read_config)(const struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong *valuep, enum pci_size_t size);
/**
* write_config() - Write a PCI configuration value
*
* @dev: Device to check
* @return bus/device/function value (see PCI_BDF())
*/
-pci_dev_t dm_pci_get_bdf(struct udevice *dev);
+pci_dev_t dm_pci_get_bdf(const struct udevice *dev);
/**
* pci_bind_bus_devices() - scan a PCI bus and bind devices
* @devp: Returns the device for this address, if found
* @return 0 if OK, -ENODEV if not found
*/
-int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
+int pci_bus_find_devfn(const struct udevice *bus, pci_dev_t find_devfn,
struct udevice **devp);
/**
* @size: Access size
* @return 0 if OK, -ve on error
*/
-int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
+int pci_bus_read_config(const struct udevice *bus, pci_dev_t bdf, int offset,
unsigned long *valuep, enum pci_size_t size);
/**
* Driver model PCI config access functions. Use these in preference to others
* when you have a valid device
*/
-int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep,
- enum pci_size_t size);
+int dm_pci_read_config(const struct udevice *dev, int offset,
+ unsigned long *valuep, enum pci_size_t size);
-int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep);
-int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep);
-int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep);
+int dm_pci_read_config8(const struct udevice *dev, int offset, u8 *valuep);
+int dm_pci_read_config16(const struct udevice *dev, int offset, u16 *valuep);
+int dm_pci_read_config32(const struct udevice *dev, int offset, u32 *valuep);
int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value,
enum pci_size_t size);
* Return: 0 on success, else -EINVAL
*/
int pci_generic_mmap_write_config(
- struct udevice *bus,
- int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp),
+ const struct udevice *bus,
+ int (*addr_f)(const struct udevice *bus, pci_dev_t bdf, uint offset,
+ void **addrp),
pci_dev_t bdf,
uint offset,
ulong value,
* Return: 0 on success, else -EINVAL
*/
int pci_generic_mmap_read_config(
- struct udevice *bus,
- int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp),
+ const struct udevice *bus,
+ int (*addr_f)(const struct udevice *bus, pci_dev_t bdf, uint offset,
+ void **addrp),
pci_dev_t bdf,
uint offset,
ulong *valuep,
* @barnum: Bar number to read (numbered from 0)
* @return: value of BAR
*/
-u32 dm_pci_read_bar32(struct udevice *dev, int barnum);
+u32 dm_pci_read_bar32(const struct udevice *dev, int barnum);
/**
* dm_pci_bus_to_phys() - convert a PCI bus address to a physical address
int dm_pci_find_class(uint find_class, int index, struct udevice **devp);
/**
+ * struct pci_emul_uc_priv - holds info about an emulator device
+ *
+ * There is always at most one emulator per client
+ *
+ * @client: Client device if any, else NULL
+ */
+struct pci_emul_uc_priv {
+ struct udevice *client;
+};
+
+/**
* struct dm_pci_emul_ops - PCI device emulator operations
*/
struct dm_pci_emul_ops {
* @size: Access size
* @return 0 if OK, -ve on error
*/
- int (*read_config)(struct udevice *dev, uint offset, ulong *valuep,
- enum pci_size_t size);
+ int (*read_config)(const struct udevice *dev, uint offset,
+ ulong *valuep, enum pci_size_t size);
/**
* write_config() - Write a PCI configuration value
*
* @emulp: Returns emulated device if found
* @return 0 if found, -ENODEV if not found
*/
-int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+int sandbox_pci_get_emul(const struct udevice *bus, pci_dev_t find_devfn,
struct udevice **containerp, struct udevice **emulp);
/**
- * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device
- *
- * Get devfn from fdt_pci_addr of the specified device
+ * sandbox_pci_get_client() - Find the client for an emulation device
*
- * @dev: PCI device
- * @return devfn in bits 15...8 if found, -ENODEV if not found
+ * @emul: Emulation device to check
+ * @devp: Returns the client device emulated by this device
+ * @return 0 if OK, -ENOENT if the device has no client yet
*/
-int pci_get_devfn(struct udevice *dev);
+int sandbox_pci_get_client(struct udevice *emul, struct udevice **devp);
#endif /* CONFIG_DM_PCI */