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-08-25     GuEe-GUI     first version
9  */
10 
11 #ifndef __PCI_ENDPOINT_H__
12 #define __PCI_ENDPOINT_H__
13 
14 #include <drivers/pci.h>
15 
16 enum rt_pci_ep_pin
17 {
18     RT_PCI_EP_PIN_UNKNOWN,
19     RT_PCI_EP_PIN_INTA,
20     RT_PCI_EP_PIN_INTB,
21     RT_PCI_EP_PIN_INTC,
22     RT_PCI_EP_PIN_INTD,
23 };
24 
25 enum rt_pci_ep_irq
26 {
27     RT_PCI_EP_IRQ_UNKNOWN,
28     RT_PCI_EP_IRQ_LEGACY,
29     RT_PCI_EP_IRQ_MSI,
30     RT_PCI_EP_IRQ_MSIX,
31 };
32 
33 struct rt_pci_ep_header
34 {
35     rt_uint16_t vendor;
36     rt_uint16_t device;
37     rt_uint8_t revision;
38     rt_uint8_t progif;
39     rt_uint8_t subclass;
40     rt_uint8_t class_code;
41     rt_uint8_t cache_line_size;
42     rt_uint16_t subsystem_vendor;
43     rt_uint16_t subsystem_device;
44 
45     enum rt_pci_ep_pin intx;
46 };
47 
48 struct rt_pci_ep_bar
49 {
50     /* To PCI Bus */
51     struct rt_pci_bus_resource bus;
52     /* To CPU */
53     rt_ubase_t cpu_addr;
54 };
55 
56 /*
57  * Type of MSI-X table, For more format detail,
58  * please read `components/drivers/include/drivers/pci_msi.h`
59  */
60 struct rt_pci_ep_msix_tbl
61 {
62     union
63     {
64         rt_uint64_t msg_addr;
65         struct
66         {
67             rt_uint32_t msg_addr_upper;
68             rt_uint32_t msg_addr_lower;
69         };
70     };
71     rt_uint32_t msg_data;
72     rt_uint32_t vector_ctrl;
73 };
74 
75 struct rt_pci_ep_ops;
76 struct rt_pci_ep_mem;
77 
78 struct rt_pci_ep
79 {
80     rt_list_t list;
81     const char *name;
82 
83     struct rt_ref ref;
84 
85     const struct rt_device *rc_dev;
86     const struct rt_pci_ep_ops *ops;
87 
88     rt_size_t mems_nr;
89     struct rt_pci_ep_mem *mems;
90 
91     rt_uint8_t max_functions;
92     RT_BITMAP_DECLARE(functions_map, 8);
93     rt_list_t epf_nodes;
94     struct rt_mutex lock;
95 
96     void *priv;
97 };
98 
99 struct rt_pci_ep_mem
100 {
101     rt_ubase_t cpu_addr;
102     rt_size_t size;
103     rt_size_t page_size;
104 
105     rt_bitmap_t *map;
106     rt_size_t bits;
107 };
108 
109 struct rt_pci_epf
110 {
111     rt_list_t list;
112     const char *name;
113 
114     struct rt_pci_ep_header *header;
115     struct rt_pci_ep_bar bar[PCI_STD_NUM_BARS];
116 
117     rt_uint8_t  msi_interrupts;
118     rt_uint16_t msix_interrupts;
119     rt_uint8_t func_no;
120 
121     struct rt_pci_ep *ep;
122 };
123 
124 struct rt_pci_ep_ops
125 {
126     rt_err_t (*write_header)(struct rt_pci_ep *ep, rt_uint8_t func_no,
127             struct rt_pci_ep_header *hdr);
128 
129     rt_err_t (*set_bar)(struct rt_pci_ep *ep, rt_uint8_t func_no,
130             struct rt_pci_ep_bar *bar, int bar_idx);
131     rt_err_t (*clear_bar)(struct rt_pci_ep *ep, rt_uint8_t func_no,
132             struct rt_pci_ep_bar *bar, int bar_idx);
133 
134     rt_err_t (*map_addr)(struct rt_pci_ep *ep, rt_uint8_t func_no,
135             rt_ubase_t addr, rt_uint64_t pci_addr, rt_size_t size);
136     rt_err_t (*unmap_addr)(struct rt_pci_ep *ep, rt_uint8_t func_no, rt_ubase_t addr);
137 
138     rt_err_t (*set_msi)(struct rt_pci_ep *ep, rt_uint8_t func_no,
139             unsigned irq_nr);
140     rt_err_t (*get_msi)(struct rt_pci_ep *ep, rt_uint8_t func_no,
141             unsigned *out_irq_nr);
142 
143     rt_err_t (*set_msix)(struct rt_pci_ep *ep, rt_uint8_t func_no,
144             unsigned irq_nr, int bar_idx, rt_off_t offset);
145     rt_err_t (*get_msix)(struct rt_pci_ep *ep, rt_uint8_t func_no,
146             unsigned *out_irq_nr);
147 
148     rt_err_t (*raise_irq)(struct rt_pci_ep *ep, rt_uint8_t func_no,
149             enum rt_pci_ep_irq type, unsigned irq);
150 
151     rt_err_t (*start)(struct rt_pci_ep *ep);
152     rt_err_t (*stop)(struct rt_pci_ep *ep);
153 };
154 
155 rt_err_t rt_pci_ep_write_header(struct rt_pci_ep *ep, rt_uint8_t func_no,
156         struct rt_pci_ep_header *hdr);
157 
158 rt_err_t rt_pci_ep_set_bar(struct rt_pci_ep *ep, rt_uint8_t func_no,
159         struct rt_pci_ep_bar *bar, int bar_idx);
160 rt_err_t rt_pci_ep_clear_bar(struct rt_pci_ep *ep, rt_uint8_t func_no,
161         struct rt_pci_ep_bar *bar, int bar_idx);
162 
163 rt_err_t rt_pci_ep_map_addr(struct rt_pci_ep *ep, rt_uint8_t func_no,
164         rt_ubase_t addr, rt_uint64_t pci_addr, rt_size_t size);
165 rt_err_t rt_pci_ep_unmap_addr(struct rt_pci_ep *ep, rt_uint8_t func_no,
166         rt_ubase_t addr);
167 
168 rt_err_t rt_pci_ep_set_msi(struct rt_pci_ep *ep, rt_uint8_t func_no,
169         unsigned irq_nr);
170 rt_err_t rt_pci_ep_get_msi(struct rt_pci_ep *ep, rt_uint8_t func_no,
171         unsigned *out_irq_nr);
172 
173 rt_err_t rt_pci_ep_set_msix(struct rt_pci_ep *ep, rt_uint8_t func_no,
174         unsigned irq_nr, int bar_idx, rt_off_t offset);
175 rt_err_t rt_pci_ep_get_msix(struct rt_pci_ep *ep, rt_uint8_t func_no,
176         unsigned *out_irq_nr);
177 
178 rt_err_t rt_pci_ep_raise_irq(struct rt_pci_ep *ep, rt_uint8_t func_no,
179         enum rt_pci_ep_irq type, unsigned irq);
180 
181 rt_err_t rt_pci_ep_start(struct rt_pci_ep *ep);
182 rt_err_t rt_pci_ep_stop(struct rt_pci_ep *ep);
183 
184 rt_err_t rt_pci_ep_register(struct rt_pci_ep *ep);
185 rt_err_t rt_pci_ep_unregister(struct rt_pci_ep *ep);
186 
187 rt_err_t rt_pci_ep_mem_array_init(struct rt_pci_ep *ep,
188         struct rt_pci_ep_mem *mems, rt_size_t mems_nr);
189 rt_err_t rt_pci_ep_mem_init(struct rt_pci_ep *ep,
190         rt_ubase_t cpu_addr, rt_size_t size, rt_size_t page_size);
191 
192 void *rt_pci_ep_mem_alloc(struct rt_pci_ep *ep,
193         rt_ubase_t *out_cpu_addr, rt_size_t size);
194 void rt_pci_ep_mem_free(struct rt_pci_ep *ep,
195         void *vaddr, rt_ubase_t cpu_addr, rt_size_t size);
196 
197 rt_err_t rt_pci_ep_add_epf(struct rt_pci_ep *ep, struct rt_pci_epf *epf);
198 rt_err_t rt_pci_ep_remove_epf(struct rt_pci_ep *ep, struct rt_pci_epf *epf);
199 
200 struct rt_pci_ep *rt_pci_ep_get(const char *name);
201 void rt_pci_ep_put(struct rt_pci_ep *ep);
202 
203 #endif /* __PCI_ENDPOINT_H__ */
204