ppc: Remove xpedite boards
[platform/kernel/u-boot.git] / include / pci.h
index 9668503..8e62235 100644 (file)
 #define  PCI_BASE_ADDRESS_IO_MASK      (~0x03ULL)
 /* bit 1 is reserved if address_space = 1 */
 
+/* Convert a regsister address (e.g. PCI_BASE_ADDRESS_1) to a bar # (e.g. 1) */
+#define pci_offset_to_barnum(offset)   \
+               (((offset) - PCI_BASE_ADDRESS_0) / sizeof(u32))
+
 /* Header type 0 (normal devices) */
 #define PCI_CARDBUS_CIS                0x28
 #define PCI_SUBSYSTEM_VENDOR_ID 0x2c
 #define  PCI_MSI_FLAGS_QSIZE   0x70    /* Message queue size configured */
 #define  PCI_MSI_FLAGS_QMASK   0x0e    /* Maximum queue size available */
 #define  PCI_MSI_FLAGS_ENABLE  0x01    /* MSI feature enabled */
+#define  PCI_MSI_FLAGS_MASKBIT 0x0100  /* Per-vector masking capable */
 #define PCI_MSI_RFU            3       /* Rest of capability flags */
 #define PCI_MSI_ADDRESS_LO     4       /* Lower 32 bits */
 #define PCI_MSI_ADDRESS_HI     8       /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
 #define PCI_EXT_CAP_ID_PTM     0x1F    /* Precision Time Measurement */
 #define PCI_EXT_CAP_ID_MAX     PCI_EXT_CAP_ID_PTM
 
+/* Enhanced Allocation Registers */
+#define PCI_EA_NUM_ENT         2       /* Number of Capability Entries */
+#define  PCI_EA_NUM_ENT_MASK   0x3f    /* Num Entries Mask */
+#define PCI_EA_FIRST_ENT       4       /* First EA Entry in List */
+#define  PCI_EA_ES             0x00000007 /* Entry Size */
+#define  PCI_EA_BEI            0x000000f0 /* BAR Equivalent Indicator */
+/* 9-14 map to VF BARs 0-5 respectively */
+#define  PCI_EA_BEI_VF_BAR0    9
+#define  PCI_EA_BEI_VF_BAR5    14
+/* Base, MaxOffset registers */
+/* bit 0 is reserved */
+#define  PCI_EA_IS_64          0x00000002      /* 64-bit field flag */
+#define  PCI_EA_FIELD_MASK     0xfffffffc      /* For Base & Max Offset */
+
+/* PCI Express capabilities */
+#define PCI_EXP_FLAGS          2       /* Capabilities register */
+#define  PCI_EXP_FLAGS_TYPE    0x00f0  /* Device/Port type */
+#define  PCI_EXP_TYPE_ROOT_PORT 0x4    /* Root Port */
+#define PCI_EXP_DEVCAP         4       /* Device capabilities */
+#define  PCI_EXP_DEVCAP_FLR    0x10000000 /* Function Level Reset */
+#define PCI_EXP_DEVCTL         8       /* Device Control */
+#define  PCI_EXP_DEVCTL_BCR_FLR        0x8000  /* Bridge Configuration Retry / FLR */
+#define PCI_EXP_LNKCAP         12      /* Link Capabilities */
+#define  PCI_EXP_LNKCAP_SLS    0x0000000f /* Supported Link Speeds */
+#define  PCI_EXP_LNKCAP_MLW    0x000003f0 /* Maximum Link Width */
+#define  PCI_EXP_LNKCAP_DLLLARC        0x00100000 /* Data Link Layer Link Active Reporting Capable */
+#define PCI_EXP_LNKSTA         18      /* Link Status */
+#define  PCI_EXP_LNKSTA_CLS    0x000f  /* Current Link Speed */
+#define  PCI_EXP_LNKSTA_CLS_2_5GB 0x0001 /* Current Link Speed 2.5GT/s */
+#define  PCI_EXP_LNKSTA_CLS_5_0GB 0x0002 /* Current Link Speed 5.0GT/s */
+#define  PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 /* Current Link Speed 8.0GT/s */
+#define  PCI_EXP_LNKSTA_NLW    0x03f0  /* Negotiated Link Width */
+#define  PCI_EXP_LNKSTA_NLW_SHIFT 4    /* start of NLW mask in link status */
+#define  PCI_EXP_LNKSTA_DLLLA  0x2000  /* Data Link Layer Link Active */
+#define PCI_EXP_SLTCAP         20      /* Slot Capabilities */
+#define  PCI_EXP_SLTCAP_PSN    0xfff80000 /* Physical Slot Number */
+#define PCI_EXP_DEVCAP2                36      /* Device Capabilities 2 */
+#define  PCI_EXP_DEVCAP2_ARI   0x00000020 /* ARI Forwarding Supported */
+#define PCI_EXP_DEVCTL2                40      /* Device Control 2 */
+#define  PCI_EXP_DEVCTL2_ARI   0x0020 /* Alternative Routing-ID */
+
+#define PCI_EXP_LNKCTL2                48      /* Link Control 2 */
+/* Single Root I/O Virtualization Registers */
+#define PCI_SRIOV_CAP          0x04    /* SR-IOV Capabilities */
+#define PCI_SRIOV_CTRL         0x08    /* SR-IOV Control */
+#define  PCI_SRIOV_CTRL_VFE    0x01    /* VF Enable */
+#define  PCI_SRIOV_CTRL_MSE    0x08    /* VF Memory Space Enable */
+#define  PCI_SRIOV_CTRL_ARI    0x10    /* ARI Capable Hierarchy */
+#define PCI_SRIOV_INITIAL_VF   0x0c    /* Initial VFs */
+#define PCI_SRIOV_TOTAL_VF     0x0e    /* Total VFs */
+#define PCI_SRIOV_NUM_VF       0x10    /* Number of VFs */
+#define PCI_SRIOV_VF_OFFSET    0x14    /* First VF Offset */
+#define PCI_SRIOV_VF_STRIDE    0x16    /* Following VF Stride */
+#define PCI_SRIOV_VF_DID       0x1a    /* VF Device ID */
+
 /* Include the ID list */
 
 #include <pci_ids.h>
 
 #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 {
@@ -507,7 +569,7 @@ typedef int pci_dev_t;
  * 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.
+ * the remark from above (input is in bits 15-8 instead of 7-0.
  */
 #define PCI_DEV(d)             (((d) >> 11) & 0x1f)
 #define PCI_FUNC(d)            (((d) >> 8) & 0x7)
@@ -519,6 +581,9 @@ typedef int pci_dev_t;
 #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 */
@@ -545,23 +610,24 @@ extern void pci_cfgfunc_do_nothing(struct pci_controller* hose, pci_dev_t dev,
 extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev,
                                      struct pci_config_table *);
 
-#ifdef CONFIG_NR_DRAM_BANKS
-#define MAX_PCI_REGIONS (CONFIG_NR_DRAM_BANKS + 7)
-#else
-#define MAX_PCI_REGIONS 7
-#endif
-
 #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
@@ -584,7 +650,7 @@ struct pci_controller {
         * for PCI controllers and a separate UCLASS (or perhaps
         * UCLASS_PCI_GENERIC) is used for bridges.
         */
-       struct pci_region regions[MAX_PCI_REGIONS];
+       struct pci_region *regions;
        int region_count;
 
        struct pci_config_table *config_table;
@@ -762,12 +828,6 @@ int pci_find_next_ext_capability(struct pci_controller *hose,
 int pci_hose_find_ext_capability(struct pci_controller *hose,
                                 pci_dev_t dev, int cap);
 
-#ifdef CONFIG_PCI_FIXUP_DEV
-extern void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev,
-                               unsigned short vendor,
-                               unsigned short device,
-                               unsigned short class);
-#endif
 #endif /* !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT) */
 
 const char * pci_class_str(u8 class);
@@ -833,23 +893,31 @@ struct udevice;
 
 #ifdef CONFIG_DM_PCI
 /**
- * struct pci_child_platdata - information stored about each PCI device
+ * struct pci_child_plat - information stored about each PCI device
  *
  * Every device on a PCI bus has this per-child data.
  *
- * It can be accessed using dev_get_parent_platdata(dev) if dev->parent is a
+ * It can be accessed using dev_get_parent_plat(dev) if dev->parent is a
  * PCI bus (i.e. UCLASS_PCI)
  *
  * @devfn:     Encoded device and function index - see PCI_DEVFN()
  * @vendor:    PCI vendor ID (see pci_ids.h)
  * @device:    PCI device ID (see pci_ids.h)
  * @class:     PCI class, 3 bytes: (base, sub, prog-if)
+ * @is_virtfn: True for Virtual Function device
+ * @pfdev:     Handle to Physical Function device
+ * @virtid:    Virtual Function Index
  */
-struct pci_child_platdata {
+struct pci_child_plat {
        int devfn;
        unsigned short vendor;
        unsigned short device;
        unsigned int class;
+
+       /* Variables for CONFIG_PCI_SRIOV */
+       bool is_virtfn;
+       struct udevice *pfdev;
+       int virtid;
 };
 
 /* PCI bus operations */
@@ -860,7 +928,7 @@ struct dm_pci_ops {
         * PCI buses must support reading and writing configuration values
         * so that the bus can be scanned and its devices configured.
         *
-        * Normally PCI_BUS(@bdf) is the same as @bus->seq, but not always.
+        * Normally PCI_BUS(@bdf) is the same as @dev_seq(bus), but not always.
         * If bridges exist it is possible to use the top-level bus to
         * access a sub-bus. In that case @bus will be the top-level bus
         * and PCI_BUS(bdf) will be a different (higher) value
@@ -872,8 +940,8 @@ struct dm_pci_ops {
         * @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
         *
@@ -897,7 +965,7 @@ struct dm_pci_ops {
  * @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
@@ -947,7 +1015,7 @@ int dm_pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp);
  * @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);
 
 /**
@@ -1040,7 +1108,7 @@ int dm_pci_hose_probe_bus(struct udevice *bus);
  * @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);
 
 /**
@@ -1075,12 +1143,12 @@ int pci_bus_clrset_config32(struct udevice *bus, pci_dev_t bdf, int offset,
  * 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);
@@ -1128,8 +1196,9 @@ int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep);
  * 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,
@@ -1153,13 +1222,33 @@ int pci_generic_mmap_write_config(
  * 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,
        enum pci_size_t size);
 
+#if defined(CONFIG_PCI_SRIOV)
+/**
+ * pci_sriov_init() - Scan Virtual Function devices
+ *
+ * @pdev:      Physical Function udevice handle
+ * @vf_en:     Number of Virtual Function devices to enable
+ * @return 0 on success, -ve on error
+ */
+int pci_sriov_init(struct udevice *pdev, int vf_en);
+
+/**
+ * pci_sriov_get_totalvfs() - Get total available Virtual Function devices
+ *
+ * @pdev:      Physical Function udevice handle
+ * @return count on success, -ve on error
+ */
+int pci_sriov_get_totalvfs(struct udevice *pdev);
+#endif
+
 #ifdef CONFIG_DM_PCI_COMPAT
 /* Compatibility with old naming */
 static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,
@@ -1265,7 +1354,8 @@ struct udevice *pci_get_controller(struct udevice *dev);
  */
 int pci_get_regions(struct udevice *dev, struct pci_region **iop,
                    struct pci_region **memp, struct pci_region **prefp);
-
+int
+pci_get_dma_regions(struct udevice *dev, struct pci_region *memp, int index);
 /**
  * dm_pci_write_bar32() - Write the address of a BAR
  *
@@ -1284,7 +1374,7 @@ void dm_pci_write_bar32(struct udevice *dev, int barnum, u32 addr);
  * @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
@@ -1312,12 +1402,16 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
  * 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
+ * that corresponds to it.
+ * Can be used for 32b BARs 0-5 on type 0 functions and for 32b BARs 0-1 on
+ * type 1 functions.
+ * Can also be used on type 0 functions that support Enhanced Allocation for
+ * 32b/64b BARs.  Note that duplicate BEI entries are not supported.
  *
  * @dev:       Device to check
- * @bar:       Bar number to read (numbered from 0)
+ * @bar:       Bar register offset (PCI_BASE_ADDRESS_...)
  * @flags:     Flags for the region type (PCI_REGION_...)
- * @return: pointer to the virtual address to use
+ * @return: pointer to the virtual address to use or 0 on error
  */
 void *dm_pci_map_bar(struct udevice *dev, int bar, int flags);
 
@@ -1414,6 +1508,14 @@ int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap);
  */
 int dm_pci_find_ext_capability(struct udevice *dev, int cap);
 
+/**
+ * dm_pci_flr() - Perform FLR if the device suppoorts it
+ *
+ * @dev:       PCI device to reset
+ * @return:    0 if OK, -ENOENT if FLR is not supported by dev
+ */
+int dm_pci_flr(struct udevice *dev);
+
 #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) \
@@ -1461,17 +1563,21 @@ int dm_pci_find_device(unsigned int vendor, unsigned int device, int index,
 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 {
        /**
-        * get_devfn(): Check which device and function this emulators
-        *
-        * @dev:        device to check
-        * @return the device and function this emulates, or -ve on error
-        */
-       int (*get_devfn)(struct udevice *dev);
-       /**
         * read_config() - Read a PCI configuration value
         *
         * @dev:        Emulated device to read from
@@ -1480,8 +1586,8 @@ 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
         *
@@ -1566,18 +1672,25 @@ struct dm_pci_emul_ops {
  * @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
+ * sandbox_pci_get_client() - Find the client for an emulation device
  *
- * Get devfn from fdt_pci_addr of the specifified device
+ * @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 sandbox_pci_get_client(struct udevice *emul, struct udevice **devp);
+
+/**
+ * board_pci_fixup_dev() - Board callback for PCI device fixups
  *
+ * @bus:       PCI bus
  * @dev:       PCI device
- * @return devfn in bits 15...8 if found, -ENODEV if not found
  */
-int pci_get_devfn(struct udevice *dev);
+extern void board_pci_fixup_dev(struct udevice *bus, struct udevice *dev);
 
 #endif /* CONFIG_DM_PCI */