1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-10-24     GuEe-GUI     first version
9  */
10 
11 #ifndef __RT_PCI_ECAM_H__
12 #define __RT_PCI_ECAM_H__
13 
14 #include <drivers/pci.h>
15 #include <drivers/ofw.h>
16 #include <drivers/ofw_io.h>
17 #include <drivers/platform.h>
18 
19 /*
20  * Memory address shift values for the byte-level address that
21  * can be used when accessing the PCI Express Configuration Space.
22  */
23 
24 /*
25  * Enhanced Configuration Access Mechanism (ECAM)
26  *
27  * See PCI Express Base Specification, Revision 5.0, Version 1.0,
28  * Section 7.2.2, Table 7-1, p. 677.
29  */
30 #define PCIE_ECAM_BUS_SHIFT     20 /* Bus number */
31 #define PCIE_ECAM_DEVFN_SHIFT   12 /* Device and Function number */
32 
33 #define PCIE_ECAM_BUS_MASK      0xff
34 #define PCIE_ECAM_DEVFN_MASK    0xff
35 #define PCIE_ECAM_REG_MASK      0xfff /* Limit offset to a maximum of 4K */
36 
37 #define PCIE_ECAM_BUS(x)        (((x) & PCIE_ECAM_BUS_MASK) << PCIE_ECAM_BUS_SHIFT)
38 #define PCIE_ECAM_DEVFN(x)      (((x) & PCIE_ECAM_DEVFN_MASK) << PCIE_ECAM_DEVFN_SHIFT)
39 #define PCIE_ECAM_REG(x)        ((x) & PCIE_ECAM_REG_MASK)
40 
41 #define PCIE_ECAM_OFFSET(bus, devfn, where) \
42         (PCIE_ECAM_BUS(bus) |  PCIE_ECAM_DEVFN(devfn) | PCIE_ECAM_REG(where))
43 
44 struct pci_ecam_ops
45 {
46     rt_uint32_t bus_shift;
47     const struct rt_pci_ops pci_ops;
48 };
49 
50 struct pci_ecam_config_window
51 {
52     rt_uint32_t *bus_range;
53     rt_uint32_t bus_shift;
54 
55     void *win;
56     void *priv;
57     const struct pci_ecam_ops *ops;
58 };
59 
60 /* Default ECAM ops */
61 extern const struct pci_ecam_ops pci_generic_ecam_ops;
62 
63 void *pci_ecam_map(struct rt_pci_bus *bus, rt_uint32_t devfn, int where);
64 struct pci_ecam_config_window *pci_ecam_create(struct rt_pci_host_bridge *host_bridge,
65         const struct pci_ecam_ops *ops);
66 rt_err_t pci_host_common_probe(struct rt_platform_device *pdev);
67 rt_err_t pci_host_common_remove(struct rt_platform_device *pdev);
68 
69 #endif /* __RT_PCI_ECAM_H__ */
70