xref: /netbsd-src/sys/arch/powerpc/include/pci_machdep.h (revision 87fd18f8e547eaf74cc8b13c2004dc30f5ff1662)
1 /* $NetBSD: pci_machdep.h,v 1.15 2018/04/19 21:50:07 christos Exp $ */
2 
3 /*-
4  * Copyright (c) 2002,2007 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Klaus Klein and Tim Rightnour
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _PCI_MACHDEP_H_
33 #define _PCI_MACHDEP_H_
34 
35 #include <prop/proplib.h>
36 
37 /*
38  * Machine-specific definitions for PCI autoconfiguration.
39  */
40 
41 #define __HAVE_PCI_CONF_HOOK
42 #define __HAVE_PCI_MSI_MSIX
43 
44 /*
45  * Types provided to machine-independent PCI code
46  */
47 typedef struct genppc_pci_chipset *pci_chipset_tag_t;
48 typedef int pcitag_t;
49 typedef int pci_intr_handle_t;
50 
51 /*
52  * Forward declarations.
53  */
54 struct pci_attach_args;
55 struct pcibus_attach_args;
56 
57 static __inline pci_chipset_tag_t pcibus_attach_args_pc(
58     struct pcibus_attach_args *);
59 static __inline pci_chipset_tag_t pci_attach_args_pc(
60     const struct pci_attach_args *);
61 
62 #include <dev/pci/pcireg.h>
63 
64 #ifdef _KERNEL
65 extern struct powerpc_bus_dma_tag pci_bus_dma_tag;
66 
67 typedef enum {
68 	PCI_INTR_TYPE_INTX = 0,
69 	PCI_INTR_TYPE_MSI,
70 	PCI_INTR_TYPE_MSIX,
71 	PCI_INTR_TYPE_SIZE,
72 } pci_intr_type_t;
73 #endif
74 
75 
76 #if defined(_KERNEL) && (defined(_MODULE) || defined(__PCI_NOINLINE))
77 void		pci_attach_hook(device_t, device_t,
78 		    struct pcibus_attach_args *);
79 
80 int		pci_bus_maxdevs(pci_chipset_tag_t, int);
81 pcitag_t	pci_make_tag(pci_chipset_tag_t, int, int, int);
82 pcireg_t	pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
83 void		pci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
84 void		pci_decompose_tag(pci_chipset_tag_t, pcitag_t,
85 		    int *, int *, int *);
86 
87 const char *	pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t,
88 		    char *, size_t);
89 const struct evcnt *
90 		pci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t);
91 void *		pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
92 		    int, int (*)(void *), void *);
93 void *		pci_intr_establish_xname(pci_chipset_tag_t, pci_intr_handle_t,
94 		    int, int (*)(void *), void *, const char *);
95 void		pci_intr_disestablish(pci_chipset_tag_t, void *);
96 int		pci_intr_map(const struct pci_attach_args *,
97 		    pci_intr_handle_t *ihp);
98 int		pci_intr_setattr(pci_chipset_tag_t, pci_intr_handle_t *,
99 		    int, uint64_t);
100 
101 pci_intr_type_t	pci_intr_type(pci_chipset_tag_t, pci_intr_handle_t);
102 int		pci_intr_alloc(const struct pci_attach_args *,
103 		    pci_intr_handle_t **, int *, pci_intr_type_t);
104 void		pci_intr_release(pci_chipset_tag_t, pci_intr_handle_t *, int);
105 int		pci_intx_alloc(const struct pci_attach_args *,
106 		    pci_intr_handle_t **);
107 
108 /* experimental MSI support */
109 int		pci_msi_alloc(const struct pci_attach_args *,
110 		    pci_intr_handle_t **, int *);
111 int		pci_msi_alloc_exact(const struct pci_attach_args *,
112 		    pci_intr_handle_t **, int);
113 
114 /* experimental MSI-X support */
115 int		pci_msix_alloc(const struct pci_attach_args *,
116 		    pci_intr_handle_t **, int *);
117 int		pci_msix_alloc_exact(const struct pci_attach_args *,
118 		    pci_intr_handle_t **, int);
119 int		pci_msix_alloc_map(const struct pci_attach_args *,
120 		    pci_intr_handle_t **, u_int *, int);
121 
122 void		pci_conf_interrupt(pci_chipset_tag_t, int, int, int,
123 		    int, int *);
124 int		pci_conf_hook(pci_chipset_tag_t, int, int, int, pcireg_t);
125 #endif /* _KERNEL && (_MODULE || __PCI_NOINLINE) */
126 
127 /* Per bus information structure */
128 struct genppc_pci_chipset_businfo {
129 	SIMPLEQ_ENTRY(genppc_pci_chipset_businfo) next;
130 	prop_dictionary_t	pbi_properties; /* chipset properties */
131 };
132 
133 #if !defined(_MODULE)
134 /*
135  * Generic PPC PCI structure and type definitions.
136  * NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE.
137  */
138 struct genppc_pci_chipset {
139 	void		*pc_conf_v;
140 	void		(*pc_attach_hook)(device_t, device_t,
141 			    struct pcibus_attach_args *);
142 	int		(*pc_bus_maxdevs)(void *, int);
143 	pcitag_t	(*pc_make_tag)(void *, int, int, int);
144 	pcireg_t	(*pc_conf_read)(void *, pcitag_t, int);
145 	void		(*pc_conf_write)(void *, pcitag_t, int, pcireg_t);
146 
147 	void		*pc_intr_v;
148 	int		(*pc_intr_map)(const struct pci_attach_args *,
149 			    pci_intr_handle_t *);
150 	const char	*(*pc_intr_string)(void *, pci_intr_handle_t, char *,
151 			    size_t);
152 	const struct evcnt *(*pc_intr_evcnt)(void *, pci_intr_handle_t);
153 	void		*(*pc_intr_establish)(void *, pci_intr_handle_t,
154 			    int, int (*)(void *), void *, const char *);
155 	void		(*pc_intr_disestablish)(void *, void *);
156 	int		(*pc_intr_setattr)(void *, pci_intr_handle_t *,
157 			    int, uint64_t);
158 
159 	pci_intr_type_t	(*pc_intr_type)(void *, pci_intr_handle_t);
160 	int		(*pc_intr_alloc)(const struct pci_attach_args *,
161 			    pci_intr_handle_t **, int *, pci_intr_type_t);
162 	void		(*pc_intr_release)(void *, pci_intr_handle_t *, int);
163 	int		(*pc_intx_alloc)(const struct pci_attach_args *,
164 			    pci_intr_handle_t **);
165 
166 	/* experimental MSI support */
167 	void		*pc_msi_v;
168 	int		(*pc_msi_alloc)(const struct pci_attach_args *,
169 			    pci_intr_handle_t **, int *, bool);
170 
171 	/* experimental MSI-X support */
172 	void		*pc_msix_v;
173 	int		(*pc_msix_alloc)(const struct pci_attach_args *,
174 			    pci_intr_handle_t **, u_int *, int *, bool);
175 
176 	void		(*pc_conf_interrupt)(void *, int, int, int, int, int *);
177 	void		(*pc_decompose_tag)(void *, pcitag_t, int *,
178 			    int *, int *);
179 	int		(*pc_conf_hook)(void *, int, int, int, pcireg_t);
180 
181 	uint32_t	*pc_addr;
182 	uint32_t	*pc_data;
183 	int		pc_node;
184 	int		pc_ihandle;
185 	int		pc_bus;
186 	bus_space_tag_t	pc_memt;
187 	bus_space_tag_t	pc_iot;
188 
189 	SIMPLEQ_HEAD(, genppc_pci_chipset_businfo) pc_pbi;
190 };
191 
192 #ifdef _KERNEL
193 
194 #ifdef __PCI_NOINLINE
195 #define	__pci_inline
196 #else
197 #define	__pci_inline	static __inline
198 #endif
199 
200 /*
201  * Functions provided to machine-independent PCI code.
202  */
203 __pci_inline void
pci_attach_hook(device_t parent,device_t self,struct pcibus_attach_args * pba)204 pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
205 {
206 	(*pcibus_attach_args_pc(pba)->pc_attach_hook)(parent, self, pba);
207 }
208 
209 __pci_inline int
pci_bus_maxdevs(pci_chipset_tag_t pc,int busno)210 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
211 {
212 	return (*pc->pc_bus_maxdevs)(pc->pc_conf_v, busno);
213 }
214 
215 __pci_inline pcitag_t
pci_make_tag(pci_chipset_tag_t pc,int bus,int device,int function)216 pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
217 {
218 	return (*pc->pc_make_tag)(pc->pc_conf_v, bus, device, function);
219 }
220 
221 __pci_inline pcireg_t
pci_conf_read(pci_chipset_tag_t pc,pcitag_t tag,int reg)222 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
223 {
224 	return (*pc->pc_conf_read)(pc->pc_conf_v, tag, reg);
225 }
226 
227 __pci_inline void
pci_conf_write(pci_chipset_tag_t pc,pcitag_t tag,int reg,pcireg_t val)228 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val)
229 {
230 	(*pc->pc_conf_write)(pc->pc_conf_v, tag, reg, val);
231 }
232 
233 __pci_inline void
pci_decompose_tag(pci_chipset_tag_t pc,pcitag_t tag,int * bp,int * dp,int * fp)234 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp)
235 {
236 	(*pc->pc_decompose_tag)(pc->pc_conf_v, tag, bp, dp, fp);
237 }
238 
239 __pci_inline int
pci_intr_map(const struct pci_attach_args * pa,pci_intr_handle_t * ihp)240 pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
241 {
242 	return (*pci_attach_args_pc(pa)->pc_intr_map)(pa, ihp);
243 }
244 
245 __pci_inline const char	*
pci_intr_string(pci_chipset_tag_t pc,pci_intr_handle_t ih,char * buf,size_t len)246 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih, char * buf,
247     size_t len)
248 {
249 	return (*pc->pc_intr_string)(pc->pc_intr_v, ih, buf, len);
250 }
251 
252 __pci_inline const struct evcnt *
pci_intr_evcnt(pci_chipset_tag_t pc,pci_intr_handle_t ih)253 pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih)
254 {
255 	return (*pc->pc_intr_evcnt)(pc->pc_intr_v, ih);
256 }
257 
258 __pci_inline void *
pci_intr_establish(pci_chipset_tag_t pc,pci_intr_handle_t ih,int ipl,int (* handler)(void *),void * arg)259 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int ipl,
260     int (*handler)(void *), void *arg)
261 {
262 	return (*pc->pc_intr_establish)(pc->pc_intr_v, ih, ipl, handler, arg,
263 	    NULL);
264 }
265 
266 __pci_inline void *
pci_intr_establish_xname(pci_chipset_tag_t pc,pci_intr_handle_t ih,int ipl,int (* handler)(void *),void * arg,const char * xname)267 pci_intr_establish_xname(pci_chipset_tag_t pc, pci_intr_handle_t ih, int ipl,
268     int (*handler)(void *), void *arg, const char *xname)
269 {
270 	return (*pc->pc_intr_establish)(pc->pc_intr_v, ih, ipl, handler, arg,
271 	    xname);
272 }
273 
274 __pci_inline void
pci_intr_disestablish(pci_chipset_tag_t pc,void * cookie)275 pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
276 {
277 	(*pc->pc_intr_disestablish)(pc->pc_intr_v, cookie);
278 }
279 
280 __pci_inline int
pci_intr_setattr(pci_chipset_tag_t pc,pci_intr_handle_t * ihp,int attr,uint64_t data)281 pci_intr_setattr(pci_chipset_tag_t pc, pci_intr_handle_t *ihp, int attr,
282     uint64_t data)
283 {
284 	return (*pc->pc_intr_setattr)(pc->pc_intr_v, ihp, attr, data);
285 }
286 
287 __pci_inline pci_intr_type_t
pci_intr_type(pci_chipset_tag_t pc,pci_intr_handle_t ih)288 pci_intr_type(pci_chipset_tag_t pc, pci_intr_handle_t ih)
289 {
290 	return (*pc->pc_intr_type)(pc->pc_intr_v, ih);
291 }
292 
293 __pci_inline int
pci_intr_alloc(const struct pci_attach_args * pa,pci_intr_handle_t ** ihps,int * count,pci_intr_type_t max_type)294 pci_intr_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
295     int *count, pci_intr_type_t max_type)
296 {
297 	pci_chipset_tag_t pc = pci_attach_args_pc(pa);
298 	return (*pc->pc_intr_alloc)(pa, ihps, count, max_type);
299 }
300 
301 __pci_inline void
pci_intr_release(pci_chipset_tag_t pc,pci_intr_handle_t * ihp,int count)302 pci_intr_release(pci_chipset_tag_t pc, pci_intr_handle_t *ihp, int count)
303 {
304 	(*pc->pc_intr_release)(pc->pc_intr_v, ihp, count);
305 }
306 
307 __pci_inline int
pci_intx_alloc(const struct pci_attach_args * pa,pci_intr_handle_t ** ihps)308 pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps)
309 {
310 	pci_chipset_tag_t pc = pci_attach_args_pc(pa);
311 	return (*pc->pc_intx_alloc)(pa, ihps);
312 }
313 
314 
315 __pci_inline void
pci_conf_interrupt(pci_chipset_tag_t pc,int bus,int device,int pin,int swiz,int * iline)316 pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int device, int pin,
317     int swiz, int *iline)
318 {
319 	(*pc->pc_conf_interrupt)(pc->pc_conf_v, bus, device, pin, swiz, iline);
320 }
321 
322 __pci_inline int
pci_conf_hook(pci_chipset_tag_t pc,int bus,int device,int function,pcireg_t id)323 pci_conf_hook(pci_chipset_tag_t pc, int bus, int device, int function,
324     pcireg_t id)
325 {
326 	return (*pc->pc_conf_hook)(pc->pc_conf_v, bus, device, function, id);
327 }
328 
329 
330 /* experimental MSI support */
331 __pci_inline int
pci_msi_alloc(const struct pci_attach_args * pa,pci_intr_handle_t ** ihps,int * count)332 pci_msi_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
333     int *count)
334 {
335 	pci_chipset_tag_t pc = pci_attach_args_pc(pa);
336 	return (*pc->pc_msi_alloc)(pa, ihps, count, false);
337 }
338 
339 __pci_inline int
pci_msi_alloc_exact(const struct pci_attach_args * pa,pci_intr_handle_t ** ihps,int count)340 pci_msi_alloc_exact(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
341     int count)
342 {
343 	pci_chipset_tag_t pc = pci_attach_args_pc(pa);
344 	return (*pc->pc_msi_alloc)(pa, ihps, &count, true);
345 }
346 
347 /* experimental MSI-X support */
348 __pci_inline int
pci_msix_alloc(const struct pci_attach_args * pa,pci_intr_handle_t ** ihps,int * count)349 pci_msix_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
350     int *count)
351 {
352 	pci_chipset_tag_t pc = pci_attach_args_pc(pa);
353 	return (*pc->pc_msix_alloc)(pa, ihps, NULL, count, false);
354 }
355 
356 __pci_inline int
pci_msix_alloc_exact(const struct pci_attach_args * pa,pci_intr_handle_t ** ihps,int count)357 pci_msix_alloc_exact(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
358     int count)
359 {
360 	pci_chipset_tag_t pc = pci_attach_args_pc(pa);
361 	return (*pc->pc_msix_alloc)(pa, ihps, NULL, &count, true);
362 }
363 
364 __pci_inline int
pci_msix_alloc_map(const struct pci_attach_args * pa,pci_intr_handle_t ** ihps,u_int * table_indexes,int count)365 pci_msix_alloc_map(const struct pci_attach_args *pa, pci_intr_handle_t **ihps,
366     u_int *table_indexes, int count)
367 {
368 	pci_chipset_tag_t pc = pci_attach_args_pc(pa);
369 	return (*pc->pc_msix_alloc)(pa, ihps, table_indexes, &count, true);
370 }
371 
372 #undef	__pci_inline
373 
374 /*
375  * Generic PowerPC PCI functions.  Override if necc.
376  */
377 
378 int genppc_pci_bus_maxdevs(void *, int);
379 
380 int genppc_pci_intr_map(const struct pci_attach_args *,
381     pci_intr_handle_t *);
382 const char *genppc_pci_intr_string(void *, pci_intr_handle_t, char *, size_t);
383 const struct evcnt *genppc_pci_intr_evcnt(void *, pci_intr_handle_t);
384 void *genppc_pci_intr_establish(void *, pci_intr_handle_t, int, int (*)(void *),
385     void *, const char *);
386 void genppc_pci_intr_disestablish(void *, void *);
387 int genppc_pci_intr_setattr(void *, pci_intr_handle_t *, int, uint64_t);
388 pci_intr_type_t genppc_pci_intr_type(void *, pci_intr_handle_t);
389 int genppc_pci_intr_alloc(const struct pci_attach_args *, pci_intr_handle_t **,
390     int *, pci_intr_type_t);
391 void genppc_pci_intr_release(void *, pci_intr_handle_t *, int);
392 int genppc_pci_intx_alloc(const struct pci_attach_args *, pci_intr_handle_t **);
393 
394 /* experimental MSI support */
395 int genppc_pci_msi_alloc(const struct pci_attach_args *, pci_intr_handle_t **,
396     int *, bool);
397 
398 /* experimental MSI-X support */
399 int genppc_pci_msix_alloc(const struct pci_attach_args *, pci_intr_handle_t **,
400     u_int *, int *, bool);
401 
402 void genppc_pci_chipset_msi_init(pci_chipset_tag_t pc);
403 void genppc_pci_chipset_msix_init(pci_chipset_tag_t pc);
404 
405 #define GENPPC_PCI_MSI_INITIALIZER \
406 	.pc_msi_alloc = genppc_pci_msi_alloc
407 
408 #define GENPPC_PCI_MSIX_INITIALIZER \
409 	.pc_msix_alloc = genppc_pci_msix_alloc
410 
411 void genppc_pci_conf_interrupt(void *, int, int, int, int, int *);
412 int genppc_pci_conf_hook(void *, int, int, int, pcireg_t);
413 
414 /* generic indirect PCI functions */
415 void genppc_pci_indirect_attach_hook(device_t, device_t,
416     struct pcibus_attach_args *);
417 pcitag_t genppc_pci_indirect_make_tag(void *, int, int, int);
418 pcireg_t genppc_pci_indirect_conf_read(void *, pcitag_t, int);
419 void genppc_pci_indirect_conf_write(void *, pcitag_t, int, pcireg_t);
420 void genppc_pci_indirect_decompose_tag(void *, pcitag_t, int *, int *, int *);
421 
422 /* generic OFW method PCI functions */
423 void genppc_pci_ofmethod_attach_hook(device_t, device_t,
424     struct pcibus_attach_args *);
425 pcitag_t genppc_pci_ofmethod_make_tag(void *, int, int, int);
426 pcireg_t genppc_pci_ofmethod_conf_read(void *, pcitag_t, int);
427 void genppc_pci_ofmethod_conf_write(void *, pcitag_t, int, pcireg_t);
428 void genppc_pci_ofmethod_decompose_tag(void *, pcitag_t, int *, int *, int *);
429 
430 /* Generic OFW PCI functions */
431 
432 int genofw_find_picnode(int);
433 void genofw_find_ofpics(int);
434 void genofw_fixup_picnode_offsets(void);
435 void genofw_setup_pciintr_map(void *, struct genppc_pci_chipset_businfo *, int);
436 int genofw_find_node_by_devfunc(int, int, int, int);
437 int genofw_pci_intr_map(const struct pci_attach_args *, pci_intr_handle_t *);
438 int genofw_pci_conf_hook(void *, int, int, int, pcireg_t);
439 
440 /* OFW PCI structures and defines */
441 #define PICNODE_TYPE_OPENPIC	1
442 #define PICNODE_TYPE_8259	2
443 #define PICNODE_TYPE_HEATHROW	3
444 #define PICNODE_TYPE_OHARE	4
445 #define PICNODE_TYPE_IVR	5
446 
447 typedef struct _ofw_pic_node_t {
448 	int node;
449 	int parent;
450 	int16_t cells;
451 	int16_t intrs;
452 	int16_t offset;
453 	int16_t type;
454 } ofw_pic_node_t;
455 
456 #endif /* _KERNEL */
457 
458 #endif /* !_MODULE */
459 
460 #endif /* _PCI_MACHDEP_H_ */
461