apalis_imx6: unify sd/mmc drive strength with linux kernel settings
[oweals/u-boot.git] / include / pci.h
index ed135a51227cc6adab0e173e0d26a5630438ecd7..5fb212cab1a9eada9b0bc9ca5b9fdd2ad1ca0ad3 100644 (file)
@@ -1,11 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  * Andreas Heppel <aheppel@sysgo.de>
  *
  * (C) Copyright 2002
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #ifndef _PCI_H
@@ -18,6 +17,7 @@
  * Under PCI, each device has 256 bytes of configuration address space,
  * of which the first 64 bytes are standardized as follows:
  */
+#define PCI_STD_HEADER_SIZEOF  64
 #define PCI_VENDOR_ID          0x00    /* 16 bits */
 #define PCI_DEVICE_ID          0x02    /* 16 bits */
 #define PCI_COMMAND            0x04    /* 16 bits */
 #define  PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
 #define  PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
 
-/* From 440ep */
-#define PCI_ERREN       0x48     /* Error Enable */
-#define PCI_ERRSTS      0x49     /* Error Status */
-#define PCI_BRDGOPT1    0x4A     /* PCI Bridge Options 1 */
-#define PCI_PLBSESR0    0x4C     /* PCI PLB Slave Error Syndrome 0 */
-#define PCI_PLBSESR1    0x50     /* PCI PLB Slave Error Syndrome 1 */
-#define PCI_PLBSEAR     0x54     /* PCI PLB Slave Error Address */
-#define PCI_CAPID       0x58     /* Capability Identifier */
-#define PCI_NEXTITEMPTR 0x59     /* Next Item Pointer */
-#define PCI_PMC         0x5A     /* Power Management Capabilities */
-#define PCI_PMCSR       0x5C     /* Power Management Control Status */
-#define PCI_PMCSRBSE    0x5E     /* PMCSR PCI to PCI Bridge Support Extensions */
-#define PCI_BRDGOPT2    0x60     /* PCI Bridge Options 2 */
-#define PCI_PMSCRR      0x64     /* Power Management State Change Request Re. */
-
 /* Header type 2 (CardBus bridges) */
 #define PCI_CB_CAPABILITY_LIST 0x14
 /* 0x15 reserved */
 #define  PCI_CAP_ID_SLOTID     0x04    /* Slot Identification */
 #define  PCI_CAP_ID_MSI                0x05    /* Message Signalled Interrupts */
 #define  PCI_CAP_ID_CHSWP      0x06    /* CompactPCI HotSwap */
-#define  PCI_CAP_ID_EXP        0x10    /* PCI Express */
+#define  PCI_CAP_ID_PCIX       0x07    /* PCI-X */
+#define  PCI_CAP_ID_HT         0x08    /* HyperTransport */
+#define  PCI_CAP_ID_VNDR       0x09    /* Vendor-Specific */
+#define  PCI_CAP_ID_DBG                0x0A    /* Debug port */
+#define  PCI_CAP_ID_CCRC       0x0B    /* CompactPCI Central Resource Control */
+#define  PCI_CAP_ID_SHPC       0x0C    /* PCI Standard Hot-Plug Controller */
+#define  PCI_CAP_ID_SSVID      0x0D    /* Bridge subsystem vendor/device ID */
+#define  PCI_CAP_ID_AGP3       0x0E    /* AGP Target PCI-PCI bridge */
+#define  PCI_CAP_ID_SECDEV     0x0F    /* Secure Device */
+#define  PCI_CAP_ID_EXP                0x10    /* PCI Express */
+#define  PCI_CAP_ID_MSIX       0x11    /* MSI-X */
+#define  PCI_CAP_ID_SATA       0x12    /* SATA Data/Index Conf. */
+#define  PCI_CAP_ID_AF         0x13    /* PCI Advanced Features */
+#define  PCI_CAP_ID_EA         0x14    /* PCI Enhanced Allocation */
+#define  PCI_CAP_ID_MAX                PCI_CAP_ID_EA
 #define PCI_CAP_LIST_NEXT      1       /* Next capability in the list */
 #define PCI_CAP_FLAGS          2       /* Capability defined flags (16 bits) */
 #define PCI_CAP_SIZEOF         4
 #define PCI_EXT_CAP_ID_SECPCI  0x19    /* Secondary PCIe Capability */
 #define PCI_EXT_CAP_ID_PMUX    0x1A    /* Protocol Multiplexing */
 #define PCI_EXT_CAP_ID_PASID   0x1B    /* Process Address Space ID */
+#define PCI_EXT_CAP_ID_DPC     0x1D    /* Downstream Port Containment */
+#define PCI_EXT_CAP_ID_L1SS    0x1E    /* L1 PM Substates */
+#define PCI_EXT_CAP_ID_PTM     0x1F    /* Precision Time Measurement */
+#define PCI_EXT_CAP_ID_MAX     PCI_EXT_CAP_ID_PTM
 
 /* Include the ID list */
 
@@ -496,9 +499,20 @@ static inline void pci_set_region(struct pci_region *reg,
 typedef int pci_dev_t;
 
 #define PCI_BUS(d)             (((d) >> 16) & 0xff)
+
+/*
+ * Please note the difference in DEVFN usage in U-Boot vs Linux. U-Boot
+ * uses DEVFN in bits 15-8 but Linux instead expects DEVFN in bits 7-0.
+ * Please see the Linux header include/uapi/linux/pci.h for more details.
+ * This is relevant for the following macros:
+ * PCI_DEV, PCI_FUNC, PCI_DEVFN
+ * The U-Boot macro PCI_DEV is equivalent to the Linux PCI_SLOT version with
+ * the remark from above (input d in bits 15-8 instead of 7-0.
+ */
 #define PCI_DEV(d)             (((d) >> 11) & 0x1f)
 #define PCI_FUNC(d)            (((d) >> 8) & 0x7)
 #define PCI_DEVFN(d, f)                ((d) << 11 | (f) << 8)
+
 #define PCI_MASK_BUS(bdf)      ((bdf) & 0xffff)
 #define PCI_ADD_BUS(bus, devfn)        (((bus) << 16) | (devfn))
 #define PCI_BDF(b, d, f)       ((b) << 16 | PCI_DEVFN(d, f))
@@ -537,6 +551,8 @@ extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev
 
 /*
  * Structure of a PCI controller (host bridge)
+ *
+ * With driver model this is dev_get_uclass_priv(bus)
  */
 struct pci_controller {
 #ifdef CONFIG_DM_PCI
@@ -583,8 +599,6 @@ struct pci_controller {
        /* Used by auto config */
        struct pci_region *pci_mem, *pci_io, *pci_prefetch;
 
-       /* Used by ppc405 autoconfig*/
-       struct pci_region *pci_fb;
 #ifndef CONFIG_DM_PCI
        int current_busno;
 
@@ -619,6 +633,7 @@ static inline void pci_set_ops(struct pci_controller *hose,
 extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
 #endif
 
+#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
 extern phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
                                        pci_addr_t addr, unsigned long flags);
 extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose,
@@ -666,6 +681,7 @@ extern int pci_hose_write_config_word(struct pci_controller *hose,
                                      pci_dev_t dev, int where, u16 val);
 extern int pci_hose_write_config_dword(struct pci_controller *hose,
                                       pci_dev_t dev, int where, u32 val);
+#endif
 
 #ifndef CONFIG_DM_PCI
 extern int pci_read_config_byte(pci_dev_t dev, int where, u8 *val);
@@ -676,6 +692,26 @@ extern int pci_write_config_word(pci_dev_t dev, int where, u16 val);
 extern int pci_write_config_dword(pci_dev_t dev, int where, u32 val);
 #endif
 
+void pciauto_region_init(struct pci_region *res);
+void pciauto_region_align(struct pci_region *res, pci_size_t size);
+void pciauto_config_init(struct pci_controller *hose);
+
+/**
+ * pciauto_region_allocate() - Allocate resources from a PCI resource region
+ *
+ * Allocates @size bytes from the PCI resource @res. If @supports_64bit is
+ * false, the result will be guaranteed to fit in 32 bits.
+ *
+ * @res:               PCI region to allocate from
+ * @size:              Amount of bytes to allocate
+ * @bar:               Returns the PCI bus address of the allocated resource
+ * @supports_64bit:    Whether to allow allocations above the 32-bit boundary
+ * @return 0 if successful, -1 on failure
+ */
+int pciauto_region_allocate(struct pci_region *res, pci_size_t size,
+                           pci_addr_t *bar, bool supports_64bit);
+
+#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
 extern int pci_hose_read_config_byte_via_dword(struct pci_controller *hose,
                                               pci_dev_t dev, int where, u8 *val);
 extern int pci_hose_read_config_word_via_dword(struct pci_controller *hose,
@@ -689,14 +725,12 @@ extern void *pci_map_bar(pci_dev_t pdev, int bar, int flags);
 extern void pci_register_hose(struct pci_controller* hose);
 extern struct pci_controller* pci_bus_to_hose(int bus);
 extern struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr);
+extern struct pci_controller *pci_get_hose_head(void);
 
 extern int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev);
 extern int pci_hose_scan(struct pci_controller *hose);
 extern int pci_hose_scan_bus(struct pci_controller *hose, int bus);
 
-extern void pciauto_region_init(struct pci_region* res);
-extern void pciauto_region_align(struct pci_region *res, pci_size_t size);
-extern int pciauto_region_allocate(struct pci_region* res, pci_size_t size, pci_addr_t *bar);
 extern void pciauto_setup_device(struct pci_controller *hose,
                                 pci_dev_t dev, int bars_num,
                                 struct pci_region *mem,
@@ -706,19 +740,12 @@ extern void pciauto_prescan_setup_bridge(struct pci_controller *hose,
                                 pci_dev_t dev, int sub_bus);
 extern void pciauto_postscan_setup_bridge(struct pci_controller *hose,
                                 pci_dev_t dev, int sub_bus);
-extern void pciauto_config_init(struct pci_controller *hose);
 extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
 
 extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index);
 extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index);
 pci_dev_t pci_find_class(unsigned int find_class, int index);
 
-extern int pci_hose_config_device(struct pci_controller *hose,
-                                 pci_dev_t dev,
-                                 unsigned long io,
-                                 pci_addr_t mem,
-                                 unsigned long command);
-
 extern int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev,
                                    int cap);
 extern int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
@@ -737,6 +764,7 @@ extern void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev,
                                unsigned short device,
                                unsigned short class);
 #endif
+#endif /* !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT) */
 
 const char * pci_class_str(u8 class);
 int pci_last_busno(void);
@@ -745,10 +773,17 @@ int pci_last_busno(void);
 extern void pci_mpc85xx_init (struct pci_controller *hose);
 #endif
 
+#ifdef CONFIG_PCIE_IMX
+extern void imx_pcie_remove(void);
+#endif
+
+#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT)
 /**
  * pci_write_bar32() - Write the address of a BAR including control bits
  *
- * This writes a raw address (with control bits) to a bar
+ * This writes a raw address (with control bits) to a bar. This can be used
+ * with devices which require hard-coded addresses, not part of the normal
+ * PCI enumeration process.
  *
  * @hose:      PCI hose to use
  * @dev:       PCI device to update
@@ -756,7 +791,7 @@ extern void pci_mpc85xx_init (struct pci_controller *hose);
  * @addr:      BAR address with control bits
  */
 void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
-                    u32 addr_and_ctrl);
+                    u32 addr);
 
 /**
  * pci_read_bar32() - read the address of a bar
@@ -781,6 +816,7 @@ u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum);
  */
 pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
                                struct pci_device_id *ids, int *indexp);
+#endif /* !CONFIG_DM_PCI || CONFIG_DM_PCI_COMPAT */
 
 /* Access sizes for PCI reads and writes */
 enum pci_size_t {
@@ -797,7 +833,7 @@ struct udevice;
  *
  * Every device on a PCI bus has this per-child data.
  *
- * It can be accessed using dev_get_parent_priv(dev) if dev->parent is a
+ * It can be accessed using dev_get_parent_platdata(dev) if dev->parent is a
  * PCI bus (i.e. UCLASS_PCI)
  *
  * @devfn:     Encoded device and function index - see PCI_DEVFN()
@@ -852,12 +888,12 @@ struct dm_pci_ops {
 #define pci_get_ops(dev)       ((struct dm_pci_ops *)(dev)->driver->ops)
 
 /**
- * pci_get_bdf() - Get the BDF value for a device
+ * dm_pci_get_bdf() - Get the BDF value for a device
  *
  * @dev:       Device to check
  * @return bus/device/function value (see PCI_BDF())
  */
-pci_dev_t pci_get_bdf(struct udevice *dev);
+pci_dev_t dm_pci_get_bdf(struct udevice *dev);
 
 /**
  * pci_bind_bus_devices() - scan a PCI bus and bind devices
@@ -892,13 +928,13 @@ int pci_bind_bus_devices(struct udevice *bus);
 int pci_auto_config_devices(struct udevice *bus);
 
 /**
- * pci_bus_find_bdf() - Find a device given its PCI bus address
+ * dm_pci_bus_find_bdf() - Find a device given its PCI bus address
  *
  * @bdf:       PCI device address: bus, device and function -see PCI_BDF()
  * @devp:      Returns the device for this address, if found
  * @return 0 if OK, -ENODEV if not found
  */
-int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp);
+int dm_pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp);
 
 /**
  * pci_bus_find_devfn() - Find a device on a bus
@@ -985,7 +1021,7 @@ int pci_find_device_id(struct pci_device_id *ids, int index,
  * @bdf:       PCI bus address to scan (PCI_BUS(bdf) is the bus number)
  * @return 0 if OK, -ve on error
  */
-int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf);
+int dm_pci_hose_probe_bus(struct udevice *bus);
 
 /**
  * pci_bus_read_config() - Read a configuration value from a device
@@ -995,6 +1031,7 @@ int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf);
  *
  * @bus:       Bus to read from
  * @bdf:       PCI device address: bus, device and function -see PCI_BDF()
+ * @offset:    Register offset to read
  * @valuep:    Place to put the returned value
  * @size:      Access size
  * @return 0 if OK, -ve on error
@@ -1007,6 +1044,7 @@ int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
  *
  * @bus:       Bus to write from
  * @bdf:       PCI device address: bus, device and function -see PCI_BDF()
+ * @offset:    Register offset to write
  * @value:     Value to write
  * @size:      Access size
  * @return 0 if OK, -ve on error
@@ -1014,6 +1052,21 @@ int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
 int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
                         unsigned long value, enum pci_size_t size);
 
+/**
+ * pci_bus_clrset_config32() - Update a configuration value for a device
+ *
+ * The register at @offset is updated to (oldvalue & ~clr) | set.
+ *
+ * @bus:       Bus to access
+ * @bdf:       PCI device address: bus, device and function -see PCI_BDF()
+ * @offset:    Register offset to update
+ * @clr:       Bits to clear
+ * @set:       Bits to set
+ * @return 0 if OK, -ve on error
+ */
+int pci_bus_clrset_config32(struct udevice *bus, pci_dev_t bdf, int offset,
+                           u32 clr, u32 set);
+
 /**
  * Driver model PCI config access functions. Use these in preference to others
  * when you have a valid device
@@ -1032,13 +1085,78 @@ int dm_pci_write_config8(struct udevice *dev, int offset, u8 value);
 int dm_pci_write_config16(struct udevice *dev, int offset, u16 value);
 int dm_pci_write_config32(struct udevice *dev, int offset, u32 value);
 
+/**
+ * These permit convenient read/modify/write on PCI configuration. The
+ * register is updated to (oldvalue & ~clr) | set.
+ */
+int dm_pci_clrset_config8(struct udevice *dev, int offset, u32 clr, u32 set);
+int dm_pci_clrset_config16(struct udevice *dev, int offset, u32 clr, u32 set);
+int dm_pci_clrset_config32(struct udevice *dev, int offset, u32 clr, u32 set);
+
 /*
  * The following functions provide access to the above without needing the
  * size parameter. We are trying to encourage the use of the 8/16/32-style
  * functions, rather than byte/word/dword. But both are supported.
  */
 int pci_write_config32(pci_dev_t pcidev, int offset, u32 value);
+int pci_write_config16(pci_dev_t pcidev, int offset, u16 value);
+int pci_write_config8(pci_dev_t pcidev, int offset, u8 value);
+int pci_read_config32(pci_dev_t pcidev, int offset, u32 *valuep);
+int pci_read_config16(pci_dev_t pcidev, int offset, u16 *valuep);
+int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep);
 
+/**
+ * pci_generic_mmap_write_config() - Generic helper for writing to
+ * memory-mapped PCI configuration space.
+ * @bus: Pointer to the PCI bus
+ * @addr_f: Callback for calculating the config space address
+ * @bdf: Identifies the PCI device to access
+ * @offset: The offset into the device's configuration space
+ * @value: The value to write
+ * @size: Indicates the size of access to perform
+ *
+ * Write the value @value of size @size from offset @offset within the
+ * configuration space of the device identified by the bus, device & function
+ * numbers in @bdf on the PCI bus @bus. The callback function @addr_f is
+ * responsible for calculating the CPU address of the respective configuration
+ * space offset.
+ *
+ * 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),
+       pci_dev_t bdf,
+       uint offset,
+       ulong value,
+       enum pci_size_t size);
+
+/**
+ * pci_generic_mmap_read_config() - Generic helper for reading from
+ * memory-mapped PCI configuration space.
+ * @bus: Pointer to the PCI bus
+ * @addr_f: Callback for calculating the config space address
+ * @bdf: Identifies the PCI device to access
+ * @offset: The offset into the device's configuration space
+ * @valuep: A pointer at which to store the read value
+ * @size: Indicates the size of access to perform
+ *
+ * Read a value of size @size from offset @offset within the configuration
+ * space of the device identified by the bus, device & function numbers in @bdf
+ * on the PCI bus @bus. The callback function @addr_f is responsible for
+ * calculating the CPU address of the respective configuration space offset.
+ *
+ * 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),
+       pci_dev_t bdf,
+       uint offset,
+       ulong *valuep,
+       enum pci_size_t size);
+
+#ifdef CONFIG_DM_PCI_COMPAT
 /* Compatibility with old naming */
 static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,
                                         u32 value)
@@ -1046,8 +1164,6 @@ static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,
        return pci_write_config32(pcidev, offset, value);
 }
 
-int pci_write_config16(pci_dev_t pcidev, int offset, u16 value);
-
 /* Compatibility with old naming */
 static inline int pci_write_config_word(pci_dev_t pcidev, int offset,
                                        u16 value)
@@ -1055,8 +1171,6 @@ static inline int pci_write_config_word(pci_dev_t pcidev, int offset,
        return pci_write_config16(pcidev, offset, value);
 }
 
-int pci_write_config8(pci_dev_t pcidev, int offset, u8 value);
-
 /* Compatibility with old naming */
 static inline int pci_write_config_byte(pci_dev_t pcidev, int offset,
                                        u8 value)
@@ -1064,8 +1178,6 @@ static inline int pci_write_config_byte(pci_dev_t pcidev, int offset,
        return pci_write_config8(pcidev, offset, value);
 }
 
-int pci_read_config32(pci_dev_t pcidev, int offset, u32 *valuep);
-
 /* Compatibility with old naming */
 static inline int pci_read_config_dword(pci_dev_t pcidev, int offset,
                                        u32 *valuep)
@@ -1073,8 +1185,6 @@ static inline int pci_read_config_dword(pci_dev_t pcidev, int offset,
        return pci_read_config32(pcidev, offset, valuep);
 }
 
-int pci_read_config16(pci_dev_t pcidev, int offset, u16 *valuep);
-
 /* Compatibility with old naming */
 static inline int pci_read_config_word(pci_dev_t pcidev, int offset,
                                       u16 *valuep)
@@ -1082,14 +1192,269 @@ static inline int pci_read_config_word(pci_dev_t pcidev, int offset,
        return pci_read_config16(pcidev, offset, valuep);
 }
 
-int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep);
-
 /* Compatibility with old naming */
 static inline int pci_read_config_byte(pci_dev_t pcidev, int offset,
                                       u8 *valuep)
 {
        return pci_read_config8(pcidev, offset, valuep);
 }
+#endif /* CONFIG_DM_PCI_COMPAT */
+
+/**
+ * dm_pciauto_config_device() - configure a device ready for use
+ *
+ * Space is allocated for each PCI base address register (BAR) so that the
+ * devices are mapped into memory and I/O space ready for use.
+ *
+ * @dev:       Device to configure
+ * @return 0 if OK, -ve on error
+ */
+int dm_pciauto_config_device(struct udevice *dev);
+
+/**
+ * pci_conv_32_to_size() - convert a 32-bit read value to the given size
+ *
+ * Some PCI buses must always perform 32-bit reads. The data must then be
+ * shifted and masked to reflect the required access size and offset. This
+ * function performs this transformation.
+ *
+ * @value:     Value to transform (32-bit value read from @offset & ~3)
+ * @offset:    Register offset that was read
+ * @size:      Required size of the result
+ * @return the value that would have been obtained if the read had been
+ * performed at the given offset with the correct size
+ */
+ulong pci_conv_32_to_size(ulong value, uint offset, enum pci_size_t size);
+
+/**
+ * pci_conv_size_to_32() - update a 32-bit value to prepare for a write
+ *
+ * Some PCI buses must always perform 32-bit writes. To emulate a smaller
+ * write the old 32-bit data must be read, updated with the required new data
+ * and written back as a 32-bit value. This function performs the
+ * transformation from the old value to the new value.
+ *
+ * @value:     Value to transform (32-bit value read from @offset & ~3)
+ * @offset:    Register offset that should be written
+ * @size:      Required size of the write
+ * @return the value that should be written as a 32-bit access to @offset & ~3.
+ */
+ulong pci_conv_size_to_32(ulong old, ulong value, uint offset,
+                         enum pci_size_t size);
+
+/**
+ * pci_get_controller() - obtain the controller to use for a bus
+ *
+ * @dev:       Device to check
+ * @return pointer to the controller device for this bus
+ */
+struct udevice *pci_get_controller(struct udevice *dev);
+
+/**
+ * pci_get_regions() - obtain pointers to all the region types
+ *
+ * @dev:       Device to check
+ * @iop:       Returns a pointer to the I/O region, or NULL if none
+ * @memp:      Returns a pointer to the memory region, or NULL if none
+ * @prefp:     Returns a pointer to the pre-fetch region, or NULL if none
+ * @return the number of non-NULL regions returned, normally 3
+ */
+int pci_get_regions(struct udevice *dev, struct pci_region **iop,
+                   struct pci_region **memp, struct pci_region **prefp);
+
+/**
+ * dm_pci_write_bar32() - Write the address of a BAR
+ *
+ * This writes a raw address to a bar
+ *
+ * @dev:       PCI device to update
+ * @barnum:    BAR number (0-5)
+ * @addr:      BAR address
+ */
+void dm_pci_write_bar32(struct udevice *dev, int barnum, u32 addr);
+
+/**
+ * dm_pci_read_bar32() - read a base address register from a device
+ *
+ * @dev:       Device to check
+ * @barnum:    Bar number to read (numbered from 0)
+ * @return: value of BAR
+ */
+u32 dm_pci_read_bar32(struct udevice *dev, int barnum);
+
+/**
+ * dm_pci_bus_to_phys() - convert a PCI bus address to a physical address
+ *
+ * @dev:       Device containing the PCI address
+ * @addr:      PCI address to convert
+ * @flags:     Flags for the region type (PCI_REGION_...)
+ * @return physical address corresponding to that PCI bus address
+ */
+phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr,
+                              unsigned long flags);
+
+/**
+ * dm_pci_phys_to_bus() - convert a physical address to a PCI bus address
+ *
+ * @dev:       Device containing the bus address
+ * @addr:      Physical address to convert
+ * @flags:     Flags for the region type (PCI_REGION_...)
+ * @return PCI bus address corresponding to that physical address
+ */
+pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
+                             unsigned long flags);
+
+/**
+ * dm_pci_map_bar() - get a virtual address associated with a BAR region
+ *
+ * Looks up a base address register and finds the physical memory address
+ * that corresponds to it
+ *
+ * @dev:       Device to check
+ * @bar:       Bar number to read (numbered from 0)
+ * @flags:     Flags for the region type (PCI_REGION_...)
+ * @return: pointer to the virtual address to use
+ */
+void *dm_pci_map_bar(struct udevice *dev, int bar, int flags);
+
+/**
+ * dm_pci_find_next_capability() - find a capability starting from an offset
+ *
+ * Tell if a device supports a given PCI capability. Returns the
+ * address of the requested capability structure within the device's
+ * PCI configuration space or 0 in case the device does not support it.
+ *
+ * Possible values for @cap:
+ *
+ *  %PCI_CAP_ID_MSI    Message Signalled Interrupts
+ *  %PCI_CAP_ID_PCIX   PCI-X
+ *  %PCI_CAP_ID_EXP    PCI Express
+ *  %PCI_CAP_ID_MSIX   MSI-X
+ *
+ * See PCI_CAP_ID_xxx for the complete capability ID codes.
+ *
+ * @dev:       PCI device to query
+ * @start:     offset to start from
+ * @cap:       capability code
+ * @return:    capability address or 0 if not supported
+ */
+int dm_pci_find_next_capability(struct udevice *dev, u8 start, int cap);
+
+/**
+ * dm_pci_find_capability() - find a capability
+ *
+ * Tell if a device supports a given PCI capability. Returns the
+ * address of the requested capability structure within the device's
+ * PCI configuration space or 0 in case the device does not support it.
+ *
+ * Possible values for @cap:
+ *
+ *  %PCI_CAP_ID_MSI    Message Signalled Interrupts
+ *  %PCI_CAP_ID_PCIX   PCI-X
+ *  %PCI_CAP_ID_EXP    PCI Express
+ *  %PCI_CAP_ID_MSIX   MSI-X
+ *
+ * See PCI_CAP_ID_xxx for the complete capability ID codes.
+ *
+ * @dev:       PCI device to query
+ * @cap:       capability code
+ * @return:    capability address or 0 if not supported
+ */
+int dm_pci_find_capability(struct udevice *dev, int cap);
+
+/**
+ * dm_pci_find_next_ext_capability() - find an extended capability
+ *                                    starting from an offset
+ *
+ * Tell if a device supports a given PCI express extended capability.
+ * Returns the address of the requested extended capability structure
+ * within the device's PCI configuration space or 0 in case the device
+ * does not support it.
+ *
+ * Possible values for @cap:
+ *
+ *  %PCI_EXT_CAP_ID_ERR        Advanced Error Reporting
+ *  %PCI_EXT_CAP_ID_VC Virtual Channel
+ *  %PCI_EXT_CAP_ID_DSN        Device Serial Number
+ *  %PCI_EXT_CAP_ID_PWR        Power Budgeting
+ *
+ * See PCI_EXT_CAP_ID_xxx for the complete extended capability ID codes.
+ *
+ * @dev:       PCI device to query
+ * @start:     offset to start from
+ * @cap:       extended capability code
+ * @return:    extended capability address or 0 if not supported
+ */
+int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap);
+
+/**
+ * dm_pci_find_ext_capability() - find an extended capability
+ *
+ * Tell if a device supports a given PCI express extended capability.
+ * Returns the address of the requested extended capability structure
+ * within the device's PCI configuration space or 0 in case the device
+ * does not support it.
+ *
+ * Possible values for @cap:
+ *
+ *  %PCI_EXT_CAP_ID_ERR        Advanced Error Reporting
+ *  %PCI_EXT_CAP_ID_VC Virtual Channel
+ *  %PCI_EXT_CAP_ID_DSN        Device Serial Number
+ *  %PCI_EXT_CAP_ID_PWR        Power Budgeting
+ *
+ * See PCI_EXT_CAP_ID_xxx for the complete extended capability ID codes.
+ *
+ * @dev:       PCI device to query
+ * @cap:       extended capability code
+ * @return:    extended capability address or 0 if not supported
+ */
+int dm_pci_find_ext_capability(struct udevice *dev, int cap);
+
+#define dm_pci_virt_to_bus(dev, addr, flags) \
+       dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
+#define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
+       map_physmem(dm_pci_bus_to_phys(dev, (addr), (flags)), \
+                   (len), (map_flags))
+
+#define dm_pci_phys_to_mem(dev, addr) \
+       dm_pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
+#define dm_pci_mem_to_phys(dev, addr) \
+       dm_pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
+#define dm_pci_phys_to_io(dev, addr) \
+       dm_pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
+#define dm_pci_io_to_phys(dev, addr) \
+       dm_pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
+
+#define dm_pci_virt_to_mem(dev, addr) \
+       dm_pci_virt_to_bus((dev), (addr), PCI_REGION_MEM)
+#define dm_pci_mem_to_virt(dev, addr, len, map_flags) \
+       dm_pci_bus_to_virt((dev), (addr), PCI_REGION_MEM, (len), (map_flags))
+#define dm_pci_virt_to_io(dev, addr) \
+       dm_pci_virt_to_bus((dev), (addr), PCI_REGION_IO)
+#define dm_pci_io_to_virt(dev, addr, len, map_flags) \
+       dm_pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags))
+
+/**
+ * dm_pci_find_device() - find a device by vendor/device ID
+ *
+ * @vendor:    Vendor ID
+ * @device:    Device ID
+ * @index:     0 to find the first match, 1 for second, etc.
+ * @devp:      Returns pointer to the device, if found
+ * @return 0 if found, -ve on error
+ */
+int dm_pci_find_device(unsigned int vendor, unsigned int device, int index,
+                      struct udevice **devp);
+
+/**
+ * dm_pci_find_class() - find a device by class
+ *
+ * @find_class: 3-byte (24-bit) class value to find
+ * @index:     0 to find the first match, 1 for second, etc.
+ * @devp:      Returns pointer to the device, if found
+ * @return 0 if found, -ve on error
+ */
+int dm_pci_find_class(uint find_class, int index, struct udevice **devp);
 
 /**
  * struct dm_pci_emul_ops - PCI device emulator operations
@@ -1193,11 +1558,22 @@ struct dm_pci_emul_ops {
  *
  * @bus:       PCI bus to search
  * @find_devfn:        PCI device and function address (PCI_DEVFN())
+ * @containerp:        Returns container device if found
  * @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,
-                        struct udevice **emulp);
+                        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 specifified device
+ *
+ * @dev:       PCI device
+ * @return devfn in bits 15...8 if found, -ENODEV if not found
+ */
+int pci_get_devfn(struct udevice *dev);
 
 #endif /* CONFIG_DM_PCI */