xref: /illumos-gate/usr/src/uts/intel/io/intel_nb5000/nb_pci_cfg.c (revision 21ecdf64e1e200cd74cadf771fc7ddc3d0062080)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/cmn_err.h>
29 #include <sys/errno.h>
30 #include <sys/systm.h>
31 #include <sys/sunddi.h>
32 #include <sys/pci_cfgspace.h>
33 #include <sys/pci.h>
34 #include <sys/pcie.h>
35 #include <vm/seg_kmem.h>
36 #include <sys/mman.h>
37 #include <sys/cpu_module.h>
38 #include "nb5000.h"
39 
40 static ddi_acc_handle_t dev_16_hdl[NB_PCI_NFUNC];
41 static ddi_acc_handle_t dev_17_hdl[NB_PCI_NFUNC];
42 static ddi_acc_handle_t dev_pci_hdl[NB_PCI_DEV];
43 
44 void
45 nb_pci_cfg_setup(dev_info_t *dip)
46 {
47 	pci_regspec_t reg;
48 	int i;
49 
50 	reg.pci_phys_hi = 16 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=16, Func=0 */
51 	reg.pci_phys_mid = 0;
52 	reg.pci_phys_low = 0;
53 	reg.pci_size_hi = 0;
54 	reg.pci_size_low = PCIE_CONF_HDR_SIZE; /* overriden in pciex */
55 
56 	for (i = 0; i < NB_PCI_NFUNC; i++) {
57 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
58 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
59 		cmn_err(CE_WARN,
60 		    "nb_pci_cfg_setup: cannot create reg property");
61 
62 		if (pci_config_setup(dip, &dev_16_hdl[i]) != DDI_SUCCESS)
63 			cmn_err(CE_WARN,
64 			    "intel_nb5000: pci_config_setup failed");
65 		reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT;
66 	}
67 	reg.pci_phys_hi = 17 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=17, Func=0 */
68 	for (i = 0; i < NB_PCI_NFUNC; i++) {
69 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
70 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
71 		cmn_err(CE_WARN,
72 		    "nb_pci_cfg_setup: cannot create reg property");
73 
74 		if (pci_config_setup(dip, &dev_17_hdl[i]) != DDI_SUCCESS)
75 			cmn_err(CE_WARN,
76 			    "intel_nb5000: pci_config_setup failed");
77 		reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT;
78 	}
79 	reg.pci_phys_hi = 0;		/* Bus=0, Dev=0, Func=0 */
80 	for (i = 0; i < NB_PCI_DEV; i++) {
81 		if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg",
82 		    (int *)&reg, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS)
83 		cmn_err(CE_WARN,
84 		    "nb_pci_cfg_setup: cannot create reg property");
85 
86 		if (pci_config_setup(dip, &dev_pci_hdl[i]) != DDI_SUCCESS)
87 			cmn_err(CE_WARN,
88 			    "intel_nb5000: pci_config_setup failed");
89 		reg.pci_phys_hi += 1 << PCI_REG_DEV_SHIFT;
90 	}
91 	ddi_prop_remove_all(dip);
92 }
93 
94 void
95 nb_pci_cfg_free()
96 {
97 	int i;
98 
99 	for (i = 0; i < NB_PCI_NFUNC; i++) {
100 		pci_config_teardown(&dev_16_hdl[i]);
101 	}
102 	for (i = 0; i < NB_PCI_NFUNC; i++) {
103 		pci_config_teardown(&dev_17_hdl[i]);
104 	}
105 	for (i = 0; i < NB_PCI_DEV; i++)
106 		pci_config_teardown(&dev_pci_hdl[i]);
107 }
108 
109 static ddi_acc_handle_t
110 nb_get_hdl(int bus, int dev, int func)
111 {
112 	ddi_acc_handle_t hdl;
113 
114 	if (bus == 0 && dev == 16 && func < NB_PCI_NFUNC) {
115 		hdl = dev_16_hdl[func];
116 	} else if (bus == 0 && dev == 17 && func < NB_PCI_NFUNC) {
117 		hdl = dev_17_hdl[func];
118 	} else if (bus == 0 && dev < NB_PCI_DEV && func == 0) {
119 		hdl = dev_pci_hdl[dev];
120 	} else {
121 		hdl = 0;
122 	}
123 	return (hdl);
124 }
125 
126 uint8_t
127 nb_pci_getb(int bus, int dev, int func, int reg, int *interpose)
128 {
129 	ddi_acc_handle_t hdl;
130 
131 	hdl = nb_get_hdl(bus, dev, func);
132 	return (cmi_pci_getb(bus, dev, func, reg, interpose, hdl));
133 }
134 
135 uint16_t
136 nb_pci_getw(int bus, int dev, int func, int reg, int *interpose)
137 {
138 	ddi_acc_handle_t hdl;
139 
140 	hdl = nb_get_hdl(bus, dev, func);
141 	return (cmi_pci_getw(bus, dev, func, reg, interpose, hdl));
142 }
143 
144 uint32_t
145 nb_pci_getl(int bus, int dev, int func, int reg, int *interpose)
146 {
147 	ddi_acc_handle_t hdl;
148 
149 	hdl = nb_get_hdl(bus, dev, func);
150 	return (cmi_pci_getl(bus, dev, func, reg, interpose, hdl));
151 }
152 
153 void
154 nb_pci_putb(int bus, int dev, int func, int reg, uint8_t val)
155 {
156 	ddi_acc_handle_t hdl;
157 
158 	hdl = nb_get_hdl(bus, dev, func);
159 	cmi_pci_putb(bus, dev, func, reg, hdl, val);
160 }
161 
162 void
163 nb_pci_putw(int bus, int dev, int func, int reg, uint16_t val)
164 {
165 	ddi_acc_handle_t hdl;
166 
167 	hdl = nb_get_hdl(bus, dev, func);
168 	cmi_pci_putw(bus, dev, func, reg, hdl, val);
169 }
170 
171 void
172 nb_pci_putl(int bus, int dev, int func, int reg, uint32_t val)
173 {
174 	ddi_acc_handle_t hdl;
175 
176 	hdl = nb_get_hdl(bus, dev, func);
177 	cmi_pci_putl(bus, dev, func, reg, hdl, val);
178 }
179