You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ra...@apache.org on 2024/01/20 13:10:25 UTC

(nuttx) 01/06: pcie: add framework

This is an automated email from the ASF dual-hosted git repository.

raiden00 pushed a commit to branch pci
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 4a6cf9bba2bf65ca2011933ad297b00f88043059
Author: Yang Chung-Fan <so...@gmail.com>
AuthorDate: Mon May 4 18:44:11 2020 +0900

    pcie: add framework
---
 Kconfig                   |  34 ++++
 drivers/Kconfig           |   1 +
 drivers/Makefile          |   1 +
 drivers/pcie/Kconfig      |  20 +++
 drivers/pcie/Make.defs    |  32 ++++
 drivers/pcie/pcie_root.c  | 442 ++++++++++++++++++++++++++++++++++++++++++++++
 include/debug.h           |  17 ++
 include/nuttx/pcie/pcie.h | 352 ++++++++++++++++++++++++++++++++++++
 8 files changed, 899 insertions(+)

diff --git a/Kconfig b/Kconfig
index 603c6f924d..b2901f17a3 100644
--- a/Kconfig
+++ b/Kconfig
@@ -2196,6 +2196,40 @@ config DEBUG_IPC_INFO
 
 endif # DEBUG_IPC
 
+config DEBUG_PCIE
+	bool "PCI-E Debug Features"
+	default n
+	depends on PCIE
+	---help---
+		Enable PCIE driver debug features.
+
+		Support for this debug option is architecture-specific and may not
+		be available for some MCUs.
+
+if DEBUG_PCIE
+
+config DEBUG_PCIE_ERROR
+	bool "PCI-E Error Output"
+	default n
+	depends on DEBUG_ERROR
+	---help---
+		Enable PCI-E driver error output to SYSLOG.
+
+config DEBUG_PCIE_WARN
+	bool "PCI-E Warnings Output"
+	default n
+	depends on DEBUG_WARN
+	---help---
+		Enable PCI-E driver warning output to SYSLOG.
+
+config DEBUG_PCIE_INFO
+	bool "PCI-E Informational Output"
+	default n
+	depends on DEBUG_INFO
+	---help---
+		Enable PCI-E driver informational output to SYSLOG.
+
+endif # DEBUG_PCIE
 endif # DEBUG_FEATURES
 
 config ARCH_HAVE_STACKCHECK
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 328b726641..43f8949994 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -59,3 +59,4 @@ source "drivers/usrsock/Kconfig"
 source "drivers/dma/Kconfig"
 source "drivers/devicetree/Kconfig"
 source "drivers/reset/Kconfig"
+source "drivers/pcie/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 197ceb3215..7f94dfd2da 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -77,6 +77,7 @@ include rc/Make.defs
 include segger/Make.defs
 include usrsock/Make.defs
 include reset/Make.defs
+include pcie/Make.defs
 
 ifeq ($(CONFIG_SPECIFIC_DRIVERS),y)
 -include platform/Make.defs
diff --git a/drivers/pcie/Kconfig b/drivers/pcie/Kconfig
new file mode 100644
index 0000000000..7ac9db568b
--- /dev/null
+++ b/drivers/pcie/Kconfig
@@ -0,0 +1,20 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+menuconfig PCIE
+	bool "Support for PCI-E Bus"
+	default n
+	---help---
+		Enables support for the PCI-E bus.
+		Backend bust be provided by per-arch or per-board implementation..
+
+if PCIE
+config PCIE_MAX_BDF
+	hex "Maximum bdf to scan on PCI-E bus"
+	default 0x10000
+	---help---
+		The maximum bdf number to be scaned on PCI-E bus
+
+endif
diff --git a/drivers/pcie/Make.defs b/drivers/pcie/Make.defs
new file mode 100644
index 0000000000..68efee8123
--- /dev/null
+++ b/drivers/pcie/Make.defs
@@ -0,0 +1,32 @@
+############################################################################
+# drivers/pcie/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+# Don't build anything if there is no CAN support
+
+ifeq ($(CONFIG_PCIE),y)
+
+CSRCS += pcie_root.c
+
+# Include PCIE device driver build support
+
+DEPPATH += --dep-path pcie
+VPATH += :pcie
+CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)pcie}
+endif
diff --git a/drivers/pcie/pcie_root.c b/drivers/pcie/pcie_root.c
new file mode 100644
index 0000000000..25718aa5ae
--- /dev/null
+++ b/drivers/pcie/pcie_root.c
@@ -0,0 +1,442 @@
+/****************************************************************************
+ * nuttx/drivers/pcie/pcie_root.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/pcie/pcie.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+struct pcie_dev_type_s *pci_device_types[] =
+{
+  NULL,
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pci_enumerate
+ *
+ * Description:
+ *  Scan the PCI bus and enumerate the devices.
+ *  Initialize any recognized devices, given in types.
+ *
+ * Input Parameters:
+ *   bus    - PCI-E bus structure
+ *   type   - List of pointers to devices types recognized, NULL terminated
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_enumerate(FAR struct pcie_bus_s *bus,
+                  FAR struct pcie_dev_type_s **types)
+{
+  unsigned int bdf;
+  uint16_t vid;
+  uint16_t id;
+  uint16_t rev;
+  struct pcie_dev_s tmp_dev;
+  struct pcie_dev_type_s tmp_type =
+    {
+      .name = "Unknown",
+      .vendor = PCI_ID_ANY,
+      .device = PCI_ID_ANY,
+      .class_rev = PCI_ID_ANY,
+      .probe = NULL,
+    };
+
+  if (!bus)
+      return -EINVAL;
+  if (!types)
+      return -EINVAL;
+
+  for (bdf = 0; bdf < CONFIG_PCIE_MAX_BDF; bdf++)
+    {
+      tmp_dev.bus = bus;
+      tmp_dev.type = &tmp_type;
+      tmp_dev.bdf = bdf;
+
+      bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_VENDOR_ID, &vid, 2);
+      bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_DEVICE_ID, &id, 2);
+      bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_REVERSION, &rev, 2);
+
+      if (vid == PCI_ID_ANY)
+        continue;
+
+      pciinfo("[%02x:%02x.%x] Found %04x:%04x, class/reversion %08x\n",
+              bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3,
+              vid, id, rev);
+
+      for (int i = 0; types[i] != NULL; i++)
+        {
+          if (types[i]->vendor == PCI_ID_ANY ||
+              types[i]->vendor == vid)
+            {
+              if (types[i]->device == PCI_ID_ANY ||
+                  types[i]->device == id)
+                {
+                  if (types[i]->class_rev == PCI_ID_ANY ||
+                      types[i]->class_rev == rev)
+                    {
+                      if (types[i]->probe)
+                        {
+                          pciinfo("[%02x:%02x.%x] %s\n",
+                                  bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3,
+                                  types[i]->name);
+                          types[i]->probe(bus, types[i], bdf);
+                        }
+                      else
+                        {
+                          pcierr("[%02x:%02x.%x] Error: Invalid \
+                                  device probe function\n",
+                                  bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3);
+                        }
+                      break;
+                    }
+                }
+            }
+        }
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pcie_initialize
+ *
+ * Description:
+ *  Initialize the PCI-E bus and enumerate the devices with give devices
+ *  type array
+ *
+ * Input Parameters:
+ *   bus    - An PCIE bus
+ *   types  - A array of PCIE device types
+ *   num    - Number of device types
+ *
+ * Returned Value:
+ *   OK if the driver was successfully register; A negated errno value is
+ *   returned on any failure.
+ *
+ ****************************************************************************/
+
+int pcie_initialize(FAR struct pcie_bus_s *bus)
+{
+  return pci_enumerate(bus, pci_device_types);
+}
+
+/****************************************************************************
+ * Name: pci_enable_device
+ *
+ * Description:
+ *  Enable device with MMIO
+ *
+ * Input Parameters:
+ *   dev - device
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_enable_device(FAR struct pcie_dev_s *dev)
+{
+  uint16_t old_cmd;
+  uint16_t cmd;
+
+  dev->bus->ops->pci_cfg_read(dev, PCI_CFG_COMMAND, &old_cmd, 2);
+
+  cmd = old_cmd | (PCI_CMD_MASTER | PCI_CMD_MEM);
+
+  dev->bus->ops->pci_cfg_write(dev, PCI_CFG_COMMAND, &cmd, 2);
+
+  pciinfo("%02x:%02x.%x, CMD: %x -> %x\n",
+          dev->bdf >> 8, (dev->bdf >> 3) & 0x1f, dev->bdf & 0x3,
+          old_cmd, cmd);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_find_cap
+ *
+ * Description:
+ *  Search through the PCI-e device capability list to find given capability.
+ *
+ * Input Parameters:
+ *   dev - Device
+ *   cap - Bitmask of capability
+ *
+ * Returned Value:
+ *   -1: Capability not supported
+ *   other: the offset in PCI configuration space to the capability structure
+ *
+ ****************************************************************************/
+
+int pci_find_cap(FAR struct pcie_dev_s *dev, uint16_t cap)
+{
+  uint8_t pos = PCI_CFG_CAP_PTR - 1;
+  uint16_t status;
+  uint8_t rcap;
+
+  dev->bus->ops->pci_cfg_read(dev, PCI_CFG_STATUS, &status, 2);
+
+  if (!(status & PCI_STS_CAPS))
+      return -EINVAL;
+
+  while (1)
+    {
+      dev->bus->ops->pci_cfg_read(dev, pos + 1, &pos, 1);
+      if (pos == 0)
+          return -EINVAL;
+
+      dev->bus->ops->pci_cfg_read(dev, pos, &rcap, 1);
+
+      if (rcap == cap)
+          return pos;
+    }
+}
+
+/****************************************************************************
+ * Name: pci_get_bar
+ *
+ * Description:
+ *  Get a 32 bits bar
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   ret    - Bar Content
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_get_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+                uint32_t *ret)
+{
+  if (bar > 5)
+      return -EINVAL;
+
+  dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, ret, 4);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_get_bar64
+ *
+ * Description:
+ *  Get a 64 bits bar
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   ret    - Bar Content
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_get_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+                  uint64_t *ret)
+{
+  if (bar > 4 || ((bar % 2) != 0))
+      return -EINVAL;
+
+  uint32_t barmem1;
+  uint32_t barmem2;
+
+  dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
+  dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
+
+  *ret = ((uint64_t)barmem2 << 32) | barmem1;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_set_bar
+ *
+ * Description:
+ *  Set a 32 bits bar
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   val    - Bar Content
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_set_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+                uint32_t val)
+{
+  if (bar > 5)
+      return -EINVAL;
+
+  dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4, &val, 4);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_set_bar64
+ *
+ * Description:
+ *  Set a 64 bits bar
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   val    - Bar Content
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_set_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+                  uint64_t val)
+{
+  if (bar > 4 || ((bar % 2) != 0))
+      return -EINVAL;
+
+  uint32_t barmem1 = (uint32_t)val;
+  uint32_t barmem2 = (uint32_t)(val >> 32);
+
+  dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
+  dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_map_bar
+ *
+ * Description:
+ *  Map address in a 32 bits bar in the flat memory address space
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   length - Map length, multiple of PAGE_SIZE
+ *   ret    - Bar Content if not NULL
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+                unsigned long length, uint32_t *ret)
+{
+  if (bar > 5)
+      return -EINVAL;
+
+  uint32_t barmem;
+
+  dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem, 4);
+
+  if (((bar % 2) == 0 &&
+      (barmem & PCI_BAR_64BIT) == PCI_BAR_64BIT) ||
+      (barmem & PCI_BAR_IO)    == PCI_BAR_IO)
+      return -EINVAL;
+
+  if (!dev->bus->ops->pci_map_bar)
+      return -EINVAL;
+
+  dev->bus->ops->pci_map_bar(dev, barmem, length);
+
+  if (ret)
+    *ret = barmem;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_map_bar64
+ *
+ * Description:
+ *  Map address in a 64 bits bar in the flat memory address space
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   length - Map length, multiple of PAGE_SIZE
+ *   ret    - Bar Content if not NULL
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_map_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+                  unsigned long length, uint64_t *ret)
+{
+  if (bar > 4 || ((bar % 2) != 0))
+      return -EINVAL;
+
+  uint32_t barmem1;
+  uint32_t barmem2;
+  uint64_t barmem;
+
+  dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
+
+  if ((barmem1 & PCI_BAR_64BIT) != PCI_BAR_64BIT ||
+      (barmem1 & PCI_BAR_IO)    == PCI_BAR_IO)
+      return -EINVAL;
+
+  dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
+
+  barmem = ((uint64_t)barmem2 << 32) | barmem1;
+
+  if (!dev->bus->ops->pci_map_bar64)
+      return -EINVAL;
+
+  dev->bus->ops->pci_map_bar64(dev, barmem, length);
+
+  if (ret)
+    *ret = barmem;
+
+  return OK;
+}
diff --git a/include/debug.h b/include/debug.h
index e6b9163cd7..b3171e40fc 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -918,6 +918,23 @@
 #  define ipcinfo     _info
 #else
 #  define ipcinfo     _none
+
+#ifdef CONFIG_DEBUG_PCIE_ERROR
+#  define pcierr       _err
+#else
+#  define pcierr      _none
+#endif
+
+#ifdef CONFIG_DEBUG_PCIE_WARN
+#  define pciwarn     _warn
+#else
+#  define pciwarn     _none
+#endif
+
+#ifdef CONFIG_DEBUG_PCIE_INFO
+#  define pciinfo     _info
+#else
+#  define pciinfo     _none
 #endif
 
 /* Buffer dumping macros do not depend on varargs */
diff --git a/include/nuttx/pcie/pcie.h b/include/nuttx/pcie/pcie.h
new file mode 100644
index 0000000000..fffc791a2d
--- /dev/null
+++ b/include/nuttx/pcie/pcie.h
@@ -0,0 +1,352 @@
+/****************************************************************************
+ * include/nuttx/pcie/pcie.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_PCIE_PCIE_H
+#define __INCLUDE_NUTTX_PCIE_PCIE_H
+
+#ifdef CONFIG_PCIE
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#include <nuttx/fs/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define PCI_CFG_VENDOR_ID       0x000
+#define PCI_CFG_DEVICE_ID       0x002
+#define PCI_CFG_COMMAND         0x004
+# define PCI_CMD_IO             (1 << 0)
+# define PCI_CMD_MEM            (1 << 1)
+# define PCI_CMD_MASTER         (1 << 2)
+# define PCI_CMD_INTX_OFF       (1 << 10)
+#define PCI_CFG_STATUS          0x006
+# define PCI_STS_INT            (1 << 3)
+# define PCI_STS_CAPS           (1 << 4)
+#define PCI_CFG_REVERSION       0x008
+#define PCI_CFG_BAR             0x010
+# define PCI_BAR_IO             0x1
+# define PCI_BAR_1M             0x2
+# define PCI_BAR_64BIT          0x4
+#define PCI_CFG_CAP_PTR         0x034
+
+#define PCI_ID_ANY              0xffff
+#define PCI_DEV_CLASS_OTHER     0xff
+
+#define PCI_CAP_PM              0x01
+
+#define PCI_CAP_MSI             0x05
+# define PCI_MSI_MCR            0x02
+# define PCI_MSI_MCR_SIZE       2
+# define PCI_MSI_MCR_EN         (1 << 0)
+# define PCI_MSI_MCR_64         (1 << 7)
+# define PCI_MSI_MAR            0x04
+# define PCI_MSI_MAR_SIZE       4
+# define PCI_MSI_MDR            0x08
+# define PCI_MSI_MDR_SIZE       2
+# define PCI_MSI_MAR64_HI       0x08
+# define PCI_MSI_MAR64_HI_SIZE  4
+# define PCI_MSI_MDR64          0x0c
+# define PCI_MSI_MDR64_SIZE     2
+# define PCI_MSI_APIC_ID_OFFSET 0xc
+
+#define PCI_CAP_MSIX            0x11
+# define PCI_MSIX_MCR           0x02
+# define PCI_MSIX_MCR_SIZE      2
+# define PCI_MSIX_MCR_EN        (1 << 15)
+# define PCI_MSIX_MCR_FMASK     0x4000
+# define PCI_MSIX_MCR_TBL_MASK  0x03ff
+# define PCI_MSIX_TBL           0x04
+# define PCI_MSIX_TBL_SIZE      4
+# define PCI_MSIX_PBA           0x08
+# define PCI_MSIX_PBA_SIZE      4
+# define PCI_MSIX_BIR_MASK      0x07
+# define PCI_MSIX_TBL_ENTRY_SIZE 0x10
+# define PCI_MSIX_TBL_LO_ADDR   0x0
+# define PCI_MSIX_TBL_HI_ADDR   0x4
+# define PCI_MSIX_TBL_MSG_DATA  0x8
+# define PCI_MSIX_TBL_VEC_CTL   0xc
+# define PCI_MSIX_APIC_ID_OFFSET 0xc
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* The PCIE driver interface */
+
+struct pcie_bus_s;
+struct pcie_dev_type_s;
+struct pcie_dev_s;
+
+/* Bus related operations */
+
+struct pcie_bus_ops_s
+{
+    CODE int (*pcie_enumerate)(FAR struct pcie_bus_s *bus,
+                               FAR struct pcie_dev_type_s **types);
+
+    CODE int (*pci_cfg_write)(FAR struct pcie_dev_s *dev, uintptr_t addr,
+                              FAR const void *buffer, unsigned int size);
+
+    CODE int (*pci_cfg_read)(FAR struct pcie_dev_s *dev, uintptr_t addr,
+                             FAR void *buffer, unsigned int size);
+
+    CODE int (*pci_map_bar)(FAR struct pcie_dev_s *dev, uint32_t addr,
+                            unsigned long length);
+
+    CODE int (*pci_map_bar64)(FAR struct pcie_dev_s *dev, uint64_t addr,
+                            unsigned long length);
+
+    CODE int (*pci_msi_register)(FAR struct pcie_dev_s *dev,
+                                 uint16_t vector);
+
+    CODE int (*pci_msix_register)(FAR struct pcie_dev_s *dev,
+                                  uint32_t vector, uint32_t index);
+};
+
+/* PCIE bus private data. */
+
+struct pcie_bus_s
+{
+  FAR const struct pcie_bus_ops_s *ops; /* operations */
+};
+
+/* PCIE device type, defines by vendor ID and device ID */
+
+struct pcie_dev_type_s
+{
+  uint16_t      vendor;            /* Device vendor ID */
+  uint16_t      device;            /* Device ID */
+  uint32_t      class_rev;         /* Device reversion */
+  const char    *name;             /* Human readable name */
+
+  /* Call back function when a device is probed */
+
+  CODE int (*probe)(FAR struct pcie_bus_s *bus,
+                    FAR struct pcie_dev_type_s *type, uint16_t bdf);
+};
+
+/* PCIE device private data. */
+
+struct pcie_dev_s
+{
+    FAR struct pcie_bus_s       *bus;
+    FAR struct pcie_dev_type_s  *type;
+    uint16_t                    bdf;
+};
+
+/****************************************************************************
+ * Public Functions Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: pcie_initialize
+ *
+ * Description:
+ *  Initialize the PCI-E bus and enumerate the devices with give devices
+ *  type array
+ *
+ * Input Parameters:
+ *   bus    - An PCIE bus
+ *   types  - A array of PCIE device types
+ *   num    - Number of device types
+ *
+ * Returned Value:
+ *   OK if the driver was successfully register; A negated errno value is
+ *   returned on any failure.
+ *
+ ****************************************************************************/
+
+int pcie_initialize(FAR struct pcie_bus_s *bus);
+
+/****************************************************************************
+ * Name: pci_enable_device
+ *
+ * Description:
+ *  Enable device with MMIO
+ *
+ * Input Parameters:
+ *   dev - device
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_enable_device(FAR struct pcie_dev_s *dev);
+
+/****************************************************************************
+ * Name: pci_find_cap
+ *
+ * Description:
+ *  Search through the PCI-e device capability list to find given capability.
+ *
+ * Input Parameters:
+ *   dev - Device
+ *   cap - Bitmask of capability
+ *
+ * Returned Value:
+ *   -1: Capability not supported
+ *   other: the offset in PCI configuration space to the capability structure
+ *
+ ****************************************************************************/
+
+int pci_find_cap(FAR struct pcie_dev_s *dev, uint16_t cap);
+
+/****************************************************************************
+ * Name: pci_map_bar
+ *
+ * Description:
+ *  Map address in a 32 bits bar in the flat memory address space
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   length - Map length, multiple of PAGE_SIZE
+ *   ret    - Bar Contentif not NULL
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+                unsigned long length, uint32_t *ret);
+
+/****************************************************************************
+ * Name: pci_map_bar64
+ *
+ * Description:
+ *  Map address in a 64 bits bar in the flat memory address space
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   length - Map length, multiple of PAGE_SIZE
+ *   ret    - Bar Content if not NULL
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_map_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+                  unsigned long length, uint64_t *ret);
+
+/****************************************************************************
+ * Name: pci_get_bar
+ *
+ * Description:
+ *  Get a 32 bits bar
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   ret    - Bar Content
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_get_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+                uint32_t *ret);
+
+/****************************************************************************
+ * Name: pci_get_bar64
+ *
+ * Description:
+ *  Get a 64 bits bar
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   ret    - Bar Content
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_get_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+                  uint64_t *ret);
+
+/****************************************************************************
+ * Name: pci_set_bar
+ *
+ * Description:
+ *  Set a 32 bits bar
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   val    - Bar Content
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_set_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+                uint32_t val);
+
+/****************************************************************************
+ * Name: pci_set_bar64
+ *
+ * Description:
+ *  Set a 64 bits bar
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   bar    - Bar number
+ *   val    - Bar Content
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_set_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+                  uint64_t val);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif
+#endif /* __INCLUDE_NUTTX_I2C_I2C_MASTER_H */