sti_pci.c revision 1.1.6.2 1 1.1.6.2 rmind /* $NetBSD: sti_pci.c,v 1.1.6.2 2011/03/05 20:53:58 rmind Exp $ */
2 1.1.6.2 rmind
3 1.1.6.2 rmind /* $OpenBSD: sti_pci.c,v 1.7 2009/02/06 22:51:04 miod Exp $ */
4 1.1.6.2 rmind
5 1.1.6.2 rmind /*
6 1.1.6.2 rmind * Copyright (c) 2006, 2007 Miodrag Vallat.
7 1.1.6.2 rmind *
8 1.1.6.2 rmind * Permission to use, copy, modify, and distribute this software for any
9 1.1.6.2 rmind * purpose with or without fee is hereby granted, provided that the above
10 1.1.6.2 rmind * copyright notice, this permission notice, and the disclaimer below
11 1.1.6.2 rmind * appear in all copies.
12 1.1.6.2 rmind *
13 1.1.6.2 rmind * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 1.1.6.2 rmind * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 1.1.6.2 rmind * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 1.1.6.2 rmind * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 1.1.6.2 rmind * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 1.1.6.2 rmind * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 1.1.6.2 rmind * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 1.1.6.2 rmind */
21 1.1.6.2 rmind
22 1.1.6.2 rmind #include <sys/param.h>
23 1.1.6.2 rmind #include <sys/systm.h>
24 1.1.6.2 rmind #include <sys/device.h>
25 1.1.6.2 rmind
26 1.1.6.2 rmind #include <dev/pci/pcireg.h>
27 1.1.6.2 rmind #include <dev/pci/pcivar.h>
28 1.1.6.2 rmind #include <dev/pci/pcidevs.h>
29 1.1.6.2 rmind
30 1.1.6.2 rmind #include <dev/wscons/wsdisplayvar.h>
31 1.1.6.2 rmind
32 1.1.6.2 rmind #include <dev/ic/stireg.h>
33 1.1.6.2 rmind #include <dev/ic/stivar.h>
34 1.1.6.2 rmind
35 1.1.6.2 rmind #ifdef STIDEBUG
36 1.1.6.2 rmind #define DPRINTF(s) do { \
37 1.1.6.2 rmind if (stidebug) \
38 1.1.6.2 rmind printf s; \
39 1.1.6.2 rmind } while(0)
40 1.1.6.2 rmind
41 1.1.6.2 rmind extern int stidebug;
42 1.1.6.2 rmind #else
43 1.1.6.2 rmind #define DPRINTF(s) /* */
44 1.1.6.2 rmind #endif
45 1.1.6.2 rmind
46 1.1.6.2 rmind int sti_pci_match(device_t, cfdata_t, void *);
47 1.1.6.2 rmind void sti_pci_attach(device_t, device_t, void *);
48 1.1.6.2 rmind
49 1.1.6.2 rmind void sti_pci_end_attach(device_t dev);
50 1.1.6.2 rmind
51 1.1.6.2 rmind struct sti_pci_softc {
52 1.1.6.2 rmind device_t sc_dev;
53 1.1.6.2 rmind
54 1.1.6.2 rmind struct sti_softc sc_base;
55 1.1.6.2 rmind
56 1.1.6.2 rmind pci_chipset_tag_t sc_pc;
57 1.1.6.2 rmind pcitag_t sc_tag;
58 1.1.6.2 rmind
59 1.1.6.2 rmind bus_space_handle_t sc_romh;
60 1.1.6.2 rmind };
61 1.1.6.2 rmind
62 1.1.6.2 rmind CFATTACH_DECL_NEW(sti_pci, sizeof(struct sti_pci_softc),
63 1.1.6.2 rmind sti_pci_match, sti_pci_attach, NULL, NULL);
64 1.1.6.2 rmind
65 1.1.6.2 rmind int sti_readbar(struct sti_softc *, struct pci_attach_args *, u_int, int);
66 1.1.6.2 rmind int sti_check_rom(struct sti_pci_softc *, struct pci_attach_args *);
67 1.1.6.2 rmind void sti_pci_enable_rom(struct sti_softc *);
68 1.1.6.2 rmind void sti_pci_disable_rom(struct sti_softc *);
69 1.1.6.2 rmind void sti_pci_enable_rom_internal(struct sti_pci_softc *);
70 1.1.6.2 rmind void sti_pci_disable_rom_internal(struct sti_pci_softc *);
71 1.1.6.2 rmind
72 1.1.6.2 rmind int sti_pci_is_console(struct pci_attach_args *, bus_addr_t *);
73 1.1.6.2 rmind
74 1.1.6.2 rmind #define PCI_ROM_ENABLE 0x00000001
75 1.1.6.2 rmind #define PCI_ROM_ADDR_MASK 0xfffff800
76 1.1.6.2 rmind #define PCI_ROM_ADDR(mr) \
77 1.1.6.2 rmind ((mr) & PCI_ROM_ADDR_MASK)
78 1.1.6.2 rmind #define PCI_ROM_SIZE(mr) \
79 1.1.6.2 rmind (PCI_ROM_ADDR(mr) & -PCI_ROM_ADDR(mr))
80 1.1.6.2 rmind
81 1.1.6.2 rmind int
82 1.1.6.2 rmind sti_pci_match(device_t parent, cfdata_t cf, void *aux)
83 1.1.6.2 rmind {
84 1.1.6.2 rmind struct pci_attach_args *paa = aux;
85 1.1.6.2 rmind
86 1.1.6.2 rmind if (PCI_VENDOR(paa->pa_id) != PCI_VENDOR_HP)
87 1.1.6.2 rmind return 0;
88 1.1.6.2 rmind
89 1.1.6.2 rmind if (PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_EG ||
90 1.1.6.2 rmind PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FX2 ||
91 1.1.6.2 rmind PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FX4 ||
92 1.1.6.2 rmind PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FX6 ||
93 1.1.6.2 rmind PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FXE)
94 1.1.6.2 rmind return 1;
95 1.1.6.2 rmind
96 1.1.6.2 rmind return 0;
97 1.1.6.2 rmind }
98 1.1.6.2 rmind
99 1.1.6.2 rmind void
100 1.1.6.2 rmind sti_pci_attach(device_t parent, device_t self, void *aux)
101 1.1.6.2 rmind {
102 1.1.6.2 rmind struct sti_pci_softc *spc = device_private(self);
103 1.1.6.2 rmind struct pci_attach_args *paa = aux;
104 1.1.6.2 rmind int ret;
105 1.1.6.2 rmind
106 1.1.6.2 rmind spc->sc_dev = self;
107 1.1.6.2 rmind
108 1.1.6.2 rmind spc->sc_pc = paa->pa_pc;
109 1.1.6.2 rmind spc->sc_tag = paa->pa_tag;
110 1.1.6.2 rmind spc->sc_base.sc_dev = self;
111 1.1.6.2 rmind spc->sc_base.sc_enable_rom = sti_pci_enable_rom;
112 1.1.6.2 rmind spc->sc_base.sc_disable_rom = sti_pci_disable_rom;
113 1.1.6.2 rmind
114 1.1.6.2 rmind aprint_normal("\n");
115 1.1.6.2 rmind
116 1.1.6.2 rmind if (sti_check_rom(spc, paa) != 0)
117 1.1.6.2 rmind return;
118 1.1.6.2 rmind
119 1.1.6.2 rmind aprint_normal("%s", device_xname(self));
120 1.1.6.2 rmind ret = sti_pci_is_console(paa, spc->sc_base. bases);
121 1.1.6.2 rmind if (ret != 0)
122 1.1.6.2 rmind spc->sc_base.sc_flags |= STI_CONSOLE;
123 1.1.6.2 rmind
124 1.1.6.2 rmind ret = sti_attach_common(&spc->sc_base, paa->pa_iot, paa->pa_memt,
125 1.1.6.2 rmind spc->sc_romh, STI_CODEBASE_MAIN);
126 1.1.6.2 rmind if (ret == 0)
127 1.1.6.2 rmind config_interrupts(self, sti_pci_end_attach);
128 1.1.6.2 rmind
129 1.1.6.2 rmind }
130 1.1.6.2 rmind
131 1.1.6.2 rmind void sti_pci_end_attach(device_t dev)
132 1.1.6.2 rmind {
133 1.1.6.2 rmind struct sti_pci_softc *spc = device_private(dev);
134 1.1.6.2 rmind struct sti_softc *sc = &spc->sc_base;
135 1.1.6.2 rmind
136 1.1.6.2 rmind sti_end_attach(sc);
137 1.1.6.2 rmind }
138 1.1.6.2 rmind
139 1.1.6.2 rmind
140 1.1.6.2 rmind /*
141 1.1.6.2 rmind * Grovel the STI ROM image.
142 1.1.6.2 rmind */
143 1.1.6.2 rmind int
144 1.1.6.2 rmind sti_check_rom(struct sti_pci_softc *spc, struct pci_attach_args *pa)
145 1.1.6.2 rmind {
146 1.1.6.2 rmind struct sti_softc *sc = &spc->sc_base;
147 1.1.6.2 rmind pcireg_t address, mask;
148 1.1.6.2 rmind bus_space_handle_t romh;
149 1.1.6.2 rmind bus_size_t romsize, subsize, stiromsize;
150 1.1.6.2 rmind bus_addr_t selected, offs, suboffs;
151 1.1.6.2 rmind uint32_t tmp;
152 1.1.6.2 rmind int i;
153 1.1.6.2 rmind int rc;
154 1.1.6.2 rmind
155 1.1.6.2 rmind /* sort of inline sti_pci_enable_rom(sc) */
156 1.1.6.2 rmind address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM);
157 1.1.6.2 rmind pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM, ~PCI_ROM_ENABLE);
158 1.1.6.2 rmind mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM);
159 1.1.6.2 rmind address |= PCI_ROM_ENABLE;
160 1.1.6.2 rmind pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM, address);
161 1.1.6.2 rmind sc->sc_flags |= STI_ROM_ENABLED;
162 1.1.6.2 rmind /*
163 1.1.6.2 rmind * Map the complete ROM for now.
164 1.1.6.2 rmind */
165 1.1.6.2 rmind
166 1.1.6.2 rmind romsize = PCI_ROM_SIZE(mask);
167 1.1.6.2 rmind DPRINTF(("%s: mapping rom @ %lx for %lx\n", __func__,
168 1.1.6.2 rmind (long)PCI_ROM_ADDR(address), (long)romsize));
169 1.1.6.2 rmind
170 1.1.6.2 rmind rc = bus_space_map(pa->pa_memt, PCI_ROM_ADDR(address), romsize,
171 1.1.6.2 rmind 0, &romh);
172 1.1.6.2 rmind if (rc != 0) {
173 1.1.6.2 rmind aprint_error_dev(sc->sc_dev, "can't map PCI ROM (%d)\n", rc);
174 1.1.6.2 rmind goto fail2;
175 1.1.6.2 rmind }
176 1.1.6.2 rmind
177 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
178 1.1.6.2 rmind /*
179 1.1.6.2 rmind * Iterate over the ROM images, pick the best candidate.
180 1.1.6.2 rmind */
181 1.1.6.2 rmind
182 1.1.6.2 rmind selected = (bus_addr_t)-1;
183 1.1.6.2 rmind for (offs = 0; offs < romsize; offs += subsize) {
184 1.1.6.2 rmind sti_pci_enable_rom_internal(spc);
185 1.1.6.2 rmind /*
186 1.1.6.2 rmind * Check for a valid ROM header.
187 1.1.6.2 rmind */
188 1.1.6.2 rmind tmp = bus_space_read_4(pa->pa_memt, romh, offs + 0);
189 1.1.6.2 rmind tmp = le32toh(tmp);
190 1.1.6.2 rmind if (tmp != 0x55aa0000) {
191 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
192 1.1.6.2 rmind if (offs == 0) {
193 1.1.6.2 rmind aprint_error_dev(sc->sc_dev,
194 1.1.6.2 rmind "invalid PCI ROM header signature (%08x)\n",
195 1.1.6.2 rmind tmp);
196 1.1.6.2 rmind rc = EINVAL;
197 1.1.6.2 rmind }
198 1.1.6.2 rmind break;
199 1.1.6.2 rmind }
200 1.1.6.2 rmind
201 1.1.6.2 rmind /*
202 1.1.6.2 rmind * Check ROM type.
203 1.1.6.2 rmind */
204 1.1.6.2 rmind tmp = bus_space_read_4(pa->pa_memt, romh, offs + 4);
205 1.1.6.2 rmind tmp = le32toh(tmp);
206 1.1.6.2 rmind if (tmp != 0x00000001) { /* 1 == STI ROM */
207 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
208 1.1.6.2 rmind if (offs == 0) {
209 1.1.6.2 rmind aprint_error_dev(sc->sc_dev,
210 1.1.6.2 rmind "invalid PCI ROM type (%08x)\n", tmp);
211 1.1.6.2 rmind rc = EINVAL;
212 1.1.6.2 rmind }
213 1.1.6.2 rmind break;
214 1.1.6.2 rmind }
215 1.1.6.2 rmind
216 1.1.6.2 rmind subsize = (bus_addr_t)bus_space_read_2(pa->pa_memt, romh,
217 1.1.6.2 rmind offs + 0x0c);
218 1.1.6.2 rmind subsize <<= 9;
219 1.1.6.2 rmind
220 1.1.6.2 rmind #ifdef STIDEBUG
221 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
222 1.1.6.2 rmind DPRINTF(("ROM offset %08x size %08x type %08x",
223 1.1.6.2 rmind (u_int)offs, (u_int)subsize, tmp));
224 1.1.6.2 rmind sti_pci_enable_rom_internal(spc);
225 1.1.6.2 rmind #endif
226 1.1.6.2 rmind
227 1.1.6.2 rmind /*
228 1.1.6.2 rmind * Check for a valid ROM data structure.
229 1.1.6.2 rmind * We do not need it except to know what architecture the ROM
230 1.1.6.2 rmind * code is for.
231 1.1.6.2 rmind */
232 1.1.6.2 rmind
233 1.1.6.2 rmind suboffs = offs +(bus_addr_t)bus_space_read_2(pa->pa_memt, romh,
234 1.1.6.2 rmind offs + 0x18);
235 1.1.6.2 rmind tmp = bus_space_read_4(pa->pa_memt, romh, suboffs + 0);
236 1.1.6.2 rmind tmp = le32toh(tmp);
237 1.1.6.2 rmind if (tmp != 0x50434952) { /* PCIR */
238 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
239 1.1.6.2 rmind if (offs == 0) {
240 1.1.6.2 rmind aprint_error_dev(sc->sc_dev, "invalid PCI data"
241 1.1.6.2 rmind " signature (%08x)\n", tmp);
242 1.1.6.2 rmind rc = EINVAL;
243 1.1.6.2 rmind } else {
244 1.1.6.2 rmind DPRINTF((" invalid PCI data signature %08x\n",
245 1.1.6.2 rmind tmp));
246 1.1.6.2 rmind continue;
247 1.1.6.2 rmind }
248 1.1.6.2 rmind }
249 1.1.6.2 rmind
250 1.1.6.2 rmind tmp = bus_space_read_1(pa->pa_memt, romh, suboffs + 0x14);
251 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
252 1.1.6.2 rmind DPRINTF((" code %02x", tmp));
253 1.1.6.2 rmind
254 1.1.6.2 rmind switch (tmp) {
255 1.1.6.2 rmind #ifdef __hppa__
256 1.1.6.2 rmind case 0x10:
257 1.1.6.2 rmind if (selected == (bus_addr_t)-1)
258 1.1.6.2 rmind selected = offs;
259 1.1.6.2 rmind break;
260 1.1.6.2 rmind #endif
261 1.1.6.2 rmind #ifdef __i386__
262 1.1.6.2 rmind case 0x00:
263 1.1.6.2 rmind if (selected == (bus_addr_t)-1)
264 1.1.6.2 rmind selected = offs;
265 1.1.6.2 rmind break;
266 1.1.6.2 rmind #endif
267 1.1.6.2 rmind default:
268 1.1.6.2 rmind #ifdef STIDEBUG
269 1.1.6.2 rmind DPRINTF((" (wrong architecture)"));
270 1.1.6.2 rmind #endif
271 1.1.6.2 rmind break;
272 1.1.6.2 rmind }
273 1.1.6.2 rmind DPRINTF(("%s\n", selected == offs ? " -> SELECTED" : ""));
274 1.1.6.2 rmind }
275 1.1.6.2 rmind
276 1.1.6.2 rmind if (selected == (bus_addr_t)-1) {
277 1.1.6.2 rmind if (rc == 0) {
278 1.1.6.2 rmind aprint_error_dev(sc->sc_dev, "found no ROM with "
279 1.1.6.2 rmind "correct microcode architecture\n");
280 1.1.6.2 rmind rc = ENOEXEC;
281 1.1.6.2 rmind }
282 1.1.6.2 rmind goto fail;
283 1.1.6.2 rmind }
284 1.1.6.2 rmind
285 1.1.6.2 rmind /*
286 1.1.6.2 rmind * Read the STI region BAR assignments.
287 1.1.6.2 rmind */
288 1.1.6.2 rmind
289 1.1.6.2 rmind sti_pci_enable_rom_internal(spc);
290 1.1.6.2 rmind offs = selected +
291 1.1.6.2 rmind (bus_addr_t)bus_space_read_2(pa->pa_memt, romh, selected + 0x0e);
292 1.1.6.2 rmind for (i = 0; i < STI_REGION_MAX; i++) {
293 1.1.6.2 rmind rc = sti_readbar(sc, pa, i,
294 1.1.6.2 rmind bus_space_read_1(pa->pa_memt, romh, offs + i));
295 1.1.6.2 rmind if (rc != 0)
296 1.1.6.2 rmind goto fail;
297 1.1.6.2 rmind }
298 1.1.6.2 rmind
299 1.1.6.2 rmind /*
300 1.1.6.2 rmind * Find out where the STI ROM itself lies, and its size.
301 1.1.6.2 rmind */
302 1.1.6.2 rmind
303 1.1.6.2 rmind offs = selected +
304 1.1.6.2 rmind (bus_addr_t)bus_space_read_4(pa->pa_memt, romh, selected + 0x08);
305 1.1.6.2 rmind stiromsize = (bus_addr_t)bus_space_read_4(pa->pa_memt, romh,
306 1.1.6.2 rmind offs + 0x18);
307 1.1.6.2 rmind stiromsize = le32toh(stiromsize);
308 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
309 1.1.6.2 rmind
310 1.1.6.2 rmind /*
311 1.1.6.2 rmind * Replace our mapping with a smaller mapping of only the area
312 1.1.6.2 rmind * we are interested in.
313 1.1.6.2 rmind */
314 1.1.6.2 rmind
315 1.1.6.2 rmind DPRINTF(("remapping rom @ %lx for %lx\n",
316 1.1.6.2 rmind (long)(PCI_ROM_ADDR(address) + offs), (long)stiromsize));
317 1.1.6.2 rmind bus_space_unmap(pa->pa_memt, romh, romsize);
318 1.1.6.2 rmind rc = bus_space_map(pa->pa_memt, PCI_ROM_ADDR(address) + offs,
319 1.1.6.2 rmind stiromsize, 0, &spc->sc_romh);
320 1.1.6.2 rmind if (rc != 0) {
321 1.1.6.2 rmind aprint_error_dev(sc->sc_dev, "can't map STI ROM (%d)\n",
322 1.1.6.2 rmind rc);
323 1.1.6.2 rmind goto fail2;
324 1.1.6.2 rmind }
325 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
326 1.1.6.2 rmind sc->sc_flags &= ~STI_ROM_ENABLED;
327 1.1.6.2 rmind
328 1.1.6.2 rmind return 0;
329 1.1.6.2 rmind
330 1.1.6.2 rmind fail:
331 1.1.6.2 rmind bus_space_unmap(pa->pa_memt, romh, romsize);
332 1.1.6.2 rmind fail2:
333 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
334 1.1.6.2 rmind
335 1.1.6.2 rmind return rc;
336 1.1.6.2 rmind }
337 1.1.6.2 rmind
338 1.1.6.2 rmind /*
339 1.1.6.2 rmind * Decode a BAR register.
340 1.1.6.2 rmind */
341 1.1.6.2 rmind int
342 1.1.6.2 rmind sti_readbar(struct sti_softc *sc, struct pci_attach_args *pa, u_int region,
343 1.1.6.2 rmind int bar)
344 1.1.6.2 rmind {
345 1.1.6.2 rmind bus_addr_t addr;
346 1.1.6.2 rmind bus_size_t size;
347 1.1.6.2 rmind uint32_t cf;
348 1.1.6.2 rmind int rc;
349 1.1.6.2 rmind
350 1.1.6.2 rmind if (bar == 0) {
351 1.1.6.2 rmind sc->bases[region] = 0;
352 1.1.6.2 rmind return (0);
353 1.1.6.2 rmind }
354 1.1.6.2 rmind
355 1.1.6.2 rmind #ifdef DIAGNOSTIC
356 1.1.6.2 rmind if (bar < PCI_MAPREG_START || bar > PCI_MAPREG_PPB_END) {
357 1.1.6.2 rmind sti_pci_disable_rom(sc);
358 1.1.6.2 rmind printf("%s: unexpected bar %02x for region %d\n",
359 1.1.6.2 rmind device_xname(sc->sc_dev), bar, region);
360 1.1.6.2 rmind sti_pci_enable_rom(sc);
361 1.1.6.2 rmind }
362 1.1.6.2 rmind #endif
363 1.1.6.2 rmind
364 1.1.6.2 rmind cf = pci_conf_read(pa->pa_pc, pa->pa_tag, bar);
365 1.1.6.2 rmind
366 1.1.6.2 rmind rc = pci_mapreg_info(pa->pa_pc, pa->pa_tag, bar, PCI_MAPREG_TYPE(cf),
367 1.1.6.2 rmind &addr, &size, NULL);
368 1.1.6.2 rmind
369 1.1.6.2 rmind if (rc != 0) {
370 1.1.6.2 rmind sti_pci_disable_rom(sc);
371 1.1.6.2 rmind aprint_error_dev(sc->sc_dev, "invalid bar %02x for region %d\n",
372 1.1.6.2 rmind bar, region);
373 1.1.6.2 rmind sti_pci_enable_rom(sc);
374 1.1.6.2 rmind return (rc);
375 1.1.6.2 rmind }
376 1.1.6.2 rmind
377 1.1.6.2 rmind sc->bases[region] = addr;
378 1.1.6.2 rmind return (0);
379 1.1.6.2 rmind }
380 1.1.6.2 rmind
381 1.1.6.2 rmind /*
382 1.1.6.2 rmind * Enable PCI ROM.
383 1.1.6.2 rmind */
384 1.1.6.2 rmind void
385 1.1.6.2 rmind sti_pci_enable_rom_internal(struct sti_pci_softc *spc)
386 1.1.6.2 rmind {
387 1.1.6.2 rmind pcireg_t address;
388 1.1.6.2 rmind
389 1.1.6.2 rmind KASSERT(spc != NULL);
390 1.1.6.2 rmind
391 1.1.6.2 rmind address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM);
392 1.1.6.2 rmind address |= PCI_ROM_ENABLE;
393 1.1.6.2 rmind pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM, address);
394 1.1.6.2 rmind }
395 1.1.6.2 rmind
396 1.1.6.2 rmind void
397 1.1.6.2 rmind sti_pci_enable_rom(struct sti_softc *sc)
398 1.1.6.2 rmind {
399 1.1.6.2 rmind struct sti_pci_softc *spc = device_private(sc->sc_dev);
400 1.1.6.2 rmind
401 1.1.6.2 rmind if (!ISSET(sc->sc_flags, STI_ROM_ENABLED)) {
402 1.1.6.2 rmind sti_pci_enable_rom_internal(spc);
403 1.1.6.2 rmind }
404 1.1.6.2 rmind SET(sc->sc_flags, STI_ROM_ENABLED);
405 1.1.6.2 rmind }
406 1.1.6.2 rmind
407 1.1.6.2 rmind /*
408 1.1.6.2 rmind * Disable PCI ROM.
409 1.1.6.2 rmind */
410 1.1.6.2 rmind void
411 1.1.6.2 rmind sti_pci_disable_rom_internal(struct sti_pci_softc *spc)
412 1.1.6.2 rmind {
413 1.1.6.2 rmind pcireg_t address;
414 1.1.6.2 rmind
415 1.1.6.2 rmind KASSERT(spc != NULL);
416 1.1.6.2 rmind
417 1.1.6.2 rmind address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM);
418 1.1.6.2 rmind address &= ~PCI_ROM_ENABLE;
419 1.1.6.2 rmind pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM, address);
420 1.1.6.2 rmind }
421 1.1.6.2 rmind
422 1.1.6.2 rmind void
423 1.1.6.2 rmind sti_pci_disable_rom(struct sti_softc *sc)
424 1.1.6.2 rmind {
425 1.1.6.2 rmind struct sti_pci_softc *spc = device_private(sc->sc_dev);
426 1.1.6.2 rmind
427 1.1.6.2 rmind if (ISSET(sc->sc_flags, STI_ROM_ENABLED)) {
428 1.1.6.2 rmind sti_pci_disable_rom_internal(spc);
429 1.1.6.2 rmind }
430 1.1.6.2 rmind CLR(sc->sc_flags, STI_ROM_ENABLED);
431 1.1.6.2 rmind }
432