igma.c revision 1.4 1 /* $NetBSD: igma.c,v 1.4 2019/12/22 23:23:32 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 2014 Michael van Elst
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /*
20 * Intel Graphic Media Accelerator
21 */
22
23 #include <sys/cdefs.h>
24 __KERNEL_RCSID(0, "$NetBSD: igma.c,v 1.4 2019/12/22 23:23:32 thorpej Exp $");
25
26 #include "vga.h"
27
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/device.h>
31 #include <sys/bus.h>
32
33 #include <dev/pci/pcireg.h>
34 #include <dev/pci/pcivar.h>
35 #include <dev/pci/pcidevs.h>
36 #include <dev/pci/pciio.h>
37
38 #include <dev/i2c/i2cvar.h>
39 #include <dev/i2c/i2c_bitbang.h>
40 #include <dev/i2c/ddcvar.h>
41
42 #include <dev/videomode/videomode.h>
43 #include <dev/videomode/edidvar.h>
44
45 #include <dev/wscons/wsdisplayvar.h>
46
47 #if NVGA > 0
48 #include <dev/ic/mc6845reg.h>
49 #include <dev/ic/pcdisplayvar.h>
50 #include <dev/ic/vgareg.h>
51 #include <dev/ic/vgavar.h>
52 #endif
53
54 #include <dev/pci/igmareg.h>
55 #include <dev/pci/igmavar.h>
56
57 #include "igmafb.h"
58
59 struct igma_softc;
60 struct igma_i2c {
61 struct igma_softc *ii_sc;
62 bus_addr_t ii_reg;
63 struct i2c_controller ii_i2c;
64 const char *ii_name;
65 u_int32_t ii_dir;
66 };
67
68 struct igma_softc {
69 device_t sc_dev;
70 struct igma_chip sc_chip;
71 struct igma_i2c sc_ii[GMBUS_NUM_PORTS];
72 };
73
74 static int igma_match(device_t, cfdata_t, void *);
75 static void igma_attach(device_t, device_t, void *);
76 static int igma_print(void *, const char *);
77
78 static void igma_i2c_attach(struct igma_softc *);
79
80 CFATTACH_DECL_NEW(igma, sizeof(struct igma_softc),
81 igma_match, igma_attach, NULL, NULL);
82
83 static int igma_i2c_acquire_bus(void *, int);
84 static void igma_i2c_release_bus(void *, int);
85 static int igma_i2c_send_start(void *, int);
86 static int igma_i2c_send_stop(void *, int);
87 static int igma_i2c_initiate_xfer(void *, i2c_addr_t, int);
88 static int igma_i2c_read_byte(void *, uint8_t *, int);
89 static int igma_i2c_write_byte(void *, uint8_t, int);
90 static void igma_i2cbb_set_bits(void *, uint32_t);
91 static void igma_i2cbb_set_dir(void *, uint32_t);
92 static uint32_t igma_i2cbb_read(void *);
93
94 static void igma_reg_barrier(const struct igma_chip *, int);
95 static u_int32_t igma_reg_read(const struct igma_chip *, int);
96 static void igma_reg_write(const struct igma_chip *, int, u_int32_t);
97 static u_int8_t igma_vga_read(const struct igma_chip *, int);
98 static void igma_vga_write(const struct igma_chip *, int , u_int8_t);
99 #if 0
100 static u_int8_t igma_crtc_read(const struct igma_chip *, int);
101 static void igma_crtc_write(const struct igma_chip *, int, u_int8_t);
102 #endif
103
104 static const struct i2c_bitbang_ops igma_i2cbb_ops = {
105 igma_i2cbb_set_bits,
106 igma_i2cbb_set_dir,
107 igma_i2cbb_read,
108 { 1, 2, 0, 1 }
109 };
110
111 static const struct igma_chip_ops igma_bus_ops = {
112 igma_reg_barrier,
113 igma_reg_read,
114 igma_reg_write,
115 igma_vga_read,
116 igma_vga_write,
117 #if 0
118 igma_crtc_read,
119 igma_crtc_write,
120 #endif
121 };
122
123 static struct igma_product {
124 u_int16_t product;
125 int gentype;
126 int num_pipes;
127 } const igma_products[] = {
128 /* i830 */
129 { PCI_PRODUCT_INTEL_82830MP_IV, 200,2 },
130 /* i845g */
131 { PCI_PRODUCT_INTEL_82845G_IGD, 200,2 },
132 /* i85x */
133 { PCI_PRODUCT_INTEL_82855GM_IGD, 200,2 },
134 // 0x358e ?
135 /* i865g */
136 { PCI_PRODUCT_INTEL_82865_IGD, 200,2 },
137 /* i915g */
138 { PCI_PRODUCT_INTEL_82915G_IGD, 200,2 },
139 { PCI_PRODUCT_INTEL_E7221_IGD, 200,2 },
140 /* i915gm */
141 { PCI_PRODUCT_INTEL_82915GM_IGD, 300,2 },
142 /* i945g */
143 { PCI_PRODUCT_INTEL_82945P_IGD, 300,2 },
144 /* i945gm */
145 { PCI_PRODUCT_INTEL_82945GM_IGD, 300,2 },
146 { PCI_PRODUCT_INTEL_82945GM_IGD_1, 300,2 },
147 { PCI_PRODUCT_INTEL_82945GME_IGD, 300,2 },
148 /* i965g */
149 { PCI_PRODUCT_INTEL_82946GZ_IGD, 300,2 },
150 { PCI_PRODUCT_INTEL_82G35_IGD, 300,2 },
151 { PCI_PRODUCT_INTEL_82G35_IGD_1, 300,2 },
152 { PCI_PRODUCT_INTEL_82965Q_IGD, 300,2 },
153 { PCI_PRODUCT_INTEL_82965Q_IGD_1, 300,2 },
154 { PCI_PRODUCT_INTEL_82965G_IGD, 300,2 },
155 { PCI_PRODUCT_INTEL_82965G_IGD_1, 300,2 },
156 /* g33 */
157 { PCI_PRODUCT_INTEL_82G33_IGD, 300,2 },
158 { PCI_PRODUCT_INTEL_82G33_IGD_1, 300,2 },
159 { PCI_PRODUCT_INTEL_82Q33_IGD, 300,2 },
160 { PCI_PRODUCT_INTEL_82Q33_IGD_1, 300,2 },
161 { PCI_PRODUCT_INTEL_82Q35_IGD, 300,2 },
162 { PCI_PRODUCT_INTEL_82Q35_IGD_1, 300,2 },
163 /* pineview */
164 { PCI_PRODUCT_INTEL_PINEVIEW_IGD, 350,2 },
165 { PCI_PRODUCT_INTEL_PINEVIEW_M_IGD, 350,2 },
166 /* i965gm */
167 { PCI_PRODUCT_INTEL_82965PM_IGD, 400,2 },
168 { PCI_PRODUCT_INTEL_82965PM_IGD_1, 400,2 },
169 { PCI_PRODUCT_INTEL_82965GME_IGD, 400,2 },
170 /* gm45 */
171 { PCI_PRODUCT_INTEL_82GM45_IGD, 450,2 },
172 { PCI_PRODUCT_INTEL_82GM45_IGD_1, 450,2 },
173 /* g45 */
174 { PCI_PRODUCT_INTEL_82IGD_E_IGD, 450,2 },
175 { PCI_PRODUCT_INTEL_82Q45_IGD, 450,2 },
176 { PCI_PRODUCT_INTEL_82G45_IGD, 450,2 },
177 { PCI_PRODUCT_INTEL_82G41_IGD, 450,2 },
178 { PCI_PRODUCT_INTEL_82B43_IGD, 450,2 },
179 // 0x2e92 ?
180 /* ironlake d */
181 { PCI_PRODUCT_INTEL_IRONLAKE_D_IGD, 500,2 },
182 /* ironlake m */
183 { PCI_PRODUCT_INTEL_IRONLAKE_M_IGD, 500,2 },
184 /* sandy bridge */
185 { PCI_PRODUCT_INTEL_SANDYBRIDGE_IGD, 600,2 },
186 { PCI_PRODUCT_INTEL_SANDYBRIDGE_IGD_1, 600,2 },
187 { PCI_PRODUCT_INTEL_SANDYBRIDGE_IGD_2, 600,2 },
188 /* sandy bridge m */
189 { PCI_PRODUCT_INTEL_SANDYBRIDGE_M_IGD, 600,2 },
190 { PCI_PRODUCT_INTEL_SANDYBRIDGE_M_IGD_1, 600,2 },
191 { PCI_PRODUCT_INTEL_SANDYBRIDGE_M_IGD_2, 600,2 },
192 /* sandy bridge s */
193 { PCI_PRODUCT_INTEL_SANDYBRIDGE_S_IGD, 600,2 },
194 /* ivy bridge */
195 { PCI_PRODUCT_INTEL_IVYBRIDGE_IGD, 700,3 },
196 { PCI_PRODUCT_INTEL_IVYBRIDGE_IGD_1, 700,3 },
197 /* ivy bridge m */
198 { PCI_PRODUCT_INTEL_IVYBRIDGE_M_IGD, 700,3 },
199 { PCI_PRODUCT_INTEL_IVYBRIDGE_M_IGD_1, 700,3 },
200 /* ivy bridge s */
201 { PCI_PRODUCT_INTEL_IVYBRIDGE_S_IGD, 700,3 },
202 { PCI_PRODUCT_INTEL_IVYBRIDGE_S_IGD_1, 700,3 },
203 #if 0
204 /* valleyview d */
205 /* valleyview m */
206 { PCI_PRODUCT_INTEL_HASWELL_IGD_1, 800,3 },
207 /* haswell d */
208 { PCI_PRODUCT_INTEL_HASWELL_IGD, 800,3 },
209 { PCI_PRODUCT_INTEL_HASWELL_IGD_1, 800,3 },
210 /* haswell m */
211 /* broadwell d */
212 /* broadwell m */
213 #endif
214 };
215
216 static int
217 igma_newpch_match(const struct pci_attach_args *pa)
218 {
219 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
220 return 0;
221 switch (0xff00 & PCI_PRODUCT(pa->pa_id)) {
222 case 0x3b00: /* ibex peak */
223 case 0x1c00: /* cougar point */
224 case 0x1e00: /* panther point */
225 case 0x8c00: /* lynx point */
226 case 0x9c00: /* lynx point lp */
227 return 1;
228 }
229
230 return 0;
231 }
232
233 static const struct igma_product *
234 igma_lookup(const struct pci_attach_args *pa)
235 {
236 const struct igma_product *ip;
237 int i;
238
239 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
240 return NULL;
241 for (i=0; i < __arraycount(igma_products); ++i) {
242 ip = &igma_products[i];
243 if (PCI_PRODUCT(pa->pa_id) == ip->product)
244 return ip;
245 }
246 return NULL;
247 }
248
249 static void
250 igma_product_to_chip(const struct pci_attach_args *pa, struct igma_chip *cd)
251 {
252 const struct igma_product *ip;
253 struct pci_attach_args PA;
254
255 ip = igma_lookup(pa);
256 KASSERT(ip != NULL);
257
258 cd->ops = &igma_bus_ops;
259 cd->num_gmbus = 6;
260 cd->num_pipes = ip->num_pipes;
261 cd->quirks = 0;
262 cd->backlight_factor = 1;
263
264 cd->gpio_offset = OLD_GPIOA;
265 cd->vga_cntrl = PCH_VGA_CNTRL;
266 cd->backlight_cntrl = OLD_BLC_PWM_CTL;
267 cd->backlight_cntrl2 = OLD_BLC_PWM_CTL2;
268
269 PA = *pa;
270 if (pci_find_device(&PA, igma_newpch_match)) {
271 cd->gpio_offset = PCH_GPIOA;
272 cd->vga_cntrl = CPU_VGA_CNTRL;
273 cd->backlight_cntrl = CPU_BLC_PWM_CTL;
274 cd->backlight_cntrl2 = CPU_BLC_PWM_CTL2;
275 }
276
277 switch (ip->gentype) {
278 case 200:
279 cd->backlight_factor = 2;
280 break;
281 case 300:
282 case 350:
283 cd->backlight_factor = 2;
284 cd->quirks |= IGMA_PFITDISABLE_QUIRK;
285 break;
286 case 450:
287 cd->pri_cntrl = PRI_CTRL_NOTRICKLE;
288 cd->quirks |= IGMA_PLANESTART_QUIRK;
289 break;
290 default:
291 cd->pri_cntrl = 0;
292 break;
293 }
294 }
295
296 static void
297 igma_adjust_chip(struct igma_softc *sc, struct igma_chip *cd)
298 {
299 const struct igma_chip_ops *co = cd->ops;
300 u_int32_t reg;
301
302 reg = co->read_reg(cd, cd->vga_cntrl);
303 if (reg & VGA_PIPE_B_SELECT)
304 cd->use_pipe = 1;
305 }
306
307 static int
308 igma_print(void *aux, const char *pnp)
309 {
310 if (pnp)
311 aprint_normal("drm at %s", pnp);
312 return (UNCONF);
313 }
314
315 static int
316 igma_match(device_t parent, cfdata_t match, void *aux)
317 {
318 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
319 const struct igma_product *ip;
320
321 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
322 return 0;
323
324 ip = igma_lookup(pa);
325 if (ip != NULL)
326 return 100;
327
328 return 0;
329 }
330
331 static void
332 igma_attach(device_t parent, device_t self, void *aux)
333 {
334 struct igma_softc *sc = device_private(self);
335 const struct pci_attach_args *pa = (struct pci_attach_args *)aux;
336 struct igma_attach_args iaa;
337 bus_space_tag_t gttmmt, gmt, regt;
338 bus_space_handle_t gttmmh, gmh, regh;
339 bus_addr_t gttmmb, gmb;
340
341 pci_aprint_devinfo(pa, NULL);
342
343 sc->sc_dev = self;
344
345 /* Initialize according to chip type */
346 igma_product_to_chip(pa, &sc->sc_chip);
347
348 if (pci_mapreg_map(pa, PCI_BAR0, PCI_MAPREG_TYPE_MEM,
349 BUS_SPACE_MAP_LINEAR,
350 >tmmt, >tmmh, >tmmb, NULL)) {
351 aprint_error_dev(sc->sc_dev, "unable to map GTTMM\n");
352 return;
353 }
354 sc->sc_chip.mmiot = gttmmt;
355 if (bus_space_subregion(gttmmt, gttmmh, 0, 2*1024*1024,
356 &sc->sc_chip.mmioh)) {
357 aprint_error_dev(sc->sc_dev, "unable to submap MMIO\n");
358 return;
359 }
360 sc->sc_chip.gttt = gttmmt;
361 if (bus_space_subregion(gttmmt, gttmmh, 2*1024*1024, 2*1024*1024,
362 &sc->sc_chip.gtth)) {
363 aprint_error_dev(sc->sc_dev, "unable to submap GTT\n");
364 return;
365 }
366
367 if (pci_mapreg_map(pa, PCI_BAR2, PCI_MAPREG_TYPE_MEM,
368 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE,
369 &gmt, &gmh, &gmb, NULL)) {
370 aprint_error_dev(sc->sc_dev, "unable to map aperture\n");
371 return;
372 }
373 sc->sc_chip.gmt = gmt;
374 sc->sc_chip.gmh = gmh;
375 sc->sc_chip.gmb = gmb;
376
377 if (pci_mapreg_map(pa, PCI_BAR4, PCI_MAPREG_TYPE_IO, 0,
378 ®t, ®h, NULL, NULL)) {
379 aprint_error_dev(sc->sc_dev, "unable to map IO registers\n");
380 return;
381 }
382
383 #if NVGA > 0
384 iaa.iaa_console = vga_cndetach() ? true : false;
385 #else
386 iaa.iaa_console = 0;
387 #endif
388 sc->sc_chip.vgat = regt;
389 if (bus_space_map(regt, 0x3c0, 0x10, 0, &sc->sc_chip.vgah)) {
390 aprint_error_dev(sc->sc_dev, "unable to map VGA registers\n");
391 return;
392 }
393
394 /* Check hardware for more information */
395 igma_adjust_chip(sc, &sc->sc_chip);
396
397 aprint_normal("%s: VGA_CNTRL: 0x%x\n",device_xname(sc->sc_dev),
398 sc->sc_chip.vga_cntrl);
399 aprint_normal("%s: GPIO_OFFSET: 0x%x\n",device_xname(sc->sc_dev),
400 sc->sc_chip.gpio_offset);
401 aprint_normal("%s: BACKLIGHT_CTRL: 0x%x\n",device_xname(sc->sc_dev),
402 sc->sc_chip.backlight_cntrl);
403 aprint_normal("%s: BACKLIGHT_CTRL2: 0x%x\n",device_xname(sc->sc_dev),
404 sc->sc_chip.backlight_cntrl2);
405
406 #if NIGMAFB > 0
407 strcpy(iaa.iaa_name, "igmafb");
408 iaa.iaa_chip = sc->sc_chip;
409 config_found_ia(sc->sc_dev, "igmabus", &iaa, igma_print);
410 #endif
411
412 igma_i2c_attach(sc);
413 }
414
415 static void
416 igma_i2c_attach(struct igma_softc *sc)
417 {
418 struct igma_i2c *ii;
419 int i;
420 #if 0
421 struct i2cbus_attach_args iba;
422 #endif
423
424 for (i=0; i<sc->sc_chip.num_gmbus; ++i) {
425 ii = &sc->sc_ii[i];
426 ii->ii_sc = sc;
427
428 /* XXX */
429 ii->ii_reg = sc->sc_chip.gpio_offset - PCH_GPIOA;
430 switch (i) {
431 case 0:
432 ii->ii_reg += PCH_GPIOB;
433 ii->ii_name = "ssc";
434 break;
435 case 1:
436 ii->ii_reg += PCH_GPIOA;
437 ii->ii_name = "vga";
438 break;
439 case 2:
440 ii->ii_reg += PCH_GPIOC;
441 ii->ii_name = "panel";
442 break;
443 case 3:
444 ii->ii_reg += PCH_GPIOD;
445 ii->ii_name = "dpc";
446 break;
447 case 4:
448 ii->ii_reg += PCH_GPIOE;
449 ii->ii_name = "dpb";
450 break;
451 case 5:
452 ii->ii_reg += PCH_GPIOF;
453 ii->ii_name = "dpd";
454 break;
455 default:
456 panic("don't know GMBUS %d\n",i);
457 }
458
459 iic_tag_init(&ii->ii_i2c);
460 ii->ii_i2c.ic_cookie = ii;
461 ii->ii_i2c.ic_send_start = igma_i2c_send_start;
462 ii->ii_i2c.ic_send_stop = igma_i2c_send_stop;
463 ii->ii_i2c.ic_initiate_xfer = igma_i2c_initiate_xfer;
464 ii->ii_i2c.ic_read_byte = igma_i2c_read_byte;
465 ii->ii_i2c.ic_write_byte = igma_i2c_write_byte;
466
467 #if 0
468 memset(&iba, 0, sizeof(iba));
469 iba.iba_tag = &ii->ii_i2c;
470 config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
471 #endif
472 }
473 }
474
475 /*
476 * I2C interface
477 */
478
479 static int
480 igma_i2c_send_start(void *cookie, int flags)
481 {
482 return i2c_bitbang_send_start(cookie, flags, &igma_i2cbb_ops);
483 }
484
485 static int
486 igma_i2c_send_stop(void *cookie, int flags)
487 {
488 return i2c_bitbang_send_stop(cookie, flags, &igma_i2cbb_ops);
489 }
490
491 static int
492 igma_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
493 {
494 return i2c_bitbang_initiate_xfer(cookie, addr, flags, &igma_i2cbb_ops);
495 }
496
497 static int
498 igma_i2c_read_byte(void *cookie, uint8_t *valp, int flags)
499 {
500 return i2c_bitbang_read_byte(cookie, valp, flags, &igma_i2cbb_ops);
501 }
502
503 static int
504 igma_i2c_write_byte(void *cookie, uint8_t val, int flags)
505 {
506 return i2c_bitbang_write_byte(cookie, val, flags, &igma_i2cbb_ops);
507 }
508
509 static void
510 igma_i2cbb_set_bits(void *cookie, uint32_t bits)
511 {
512 struct igma_i2c *ii = cookie;
513 struct igma_softc *sc = ii->ii_sc;
514 const struct igma_chip *cd = &sc->sc_chip;
515 const struct igma_chip_ops *co = cd->ops;
516 uint32_t reg;
517
518 reg = co->read_reg(cd, ii->ii_reg);
519 reg &= GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE;
520
521 if ((bits | ii->ii_dir) & 1)
522 /* make data input, signal is pulled high */
523 reg |= GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
524 else
525 /* make data output, signal is driven low */
526 reg |= GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK
527 | GPIO_DATA_VAL_MASK;
528
529 if (bits & 2)
530 /* make clock input, signal is pulled high */
531 reg |= GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
532 else
533 /* make clock output, signal is driven low */
534 reg |= GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK
535 | GPIO_CLOCK_VAL_MASK;
536
537 co->write_reg(cd, ii->ii_reg, reg);
538 #if 1
539 reg = co->read_reg(cd, ii->ii_reg);
540 #else
541 co->barrier(cd, ii->ii_reg);
542 #endif
543 }
544
545 static void
546 igma_i2cbb_set_dir(void *cookie, uint32_t bits)
547 {
548 struct igma_i2c *ii = cookie;
549
550 ii->ii_dir = bits;
551 }
552
553 static uint32_t
554 igma_i2cbb_read(void *cookie)
555 {
556 struct igma_i2c *ii = cookie;
557 struct igma_softc *sc = ii->ii_sc;
558 const struct igma_chip *cd = &sc->sc_chip;
559 const struct igma_chip_ops *co = cd->ops;
560 uint32_t reg;
561 int sda, scl;
562
563 reg = co->read_reg(cd, ii->ii_reg);
564
565 sda = reg & GPIO_DATA_VAL_IN;
566 scl = reg & GPIO_CLOCK_VAL_IN;
567
568 reg = (sda ? 1 : 0) | (scl ? 2 : 0);
569 return reg;
570 }
571
572 static void
573 igma_reg_barrier(const struct igma_chip *cd, int r)
574 {
575 bus_space_barrier(cd->mmiot, cd->mmioh, r, sizeof(u_int32_t),
576 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
577 }
578
579 static u_int32_t
580 igma_reg_read(const struct igma_chip *cd, int r)
581 {
582 return bus_space_read_4(cd->mmiot, cd->mmioh, r);
583 }
584
585 static void
586 igma_reg_write(const struct igma_chip *cd, int r, u_int32_t v)
587 {
588 bus_space_write_4(cd->mmiot, cd->mmioh, r, v);
589 }
590
591 static u_int8_t
592 igma_vga_read(const struct igma_chip *cd, int r)
593 {
594 bus_space_write_1(cd->vgat, cd->vgah, 0x4, r | 0x20);
595 return bus_space_read_1(cd->vgat, cd->vgah, 0x5);
596 }
597
598 static void
599 igma_vga_write(const struct igma_chip *cd, int r, u_int8_t v)
600 {
601 bus_space_write_1(cd->vgat, cd->vgah, 0x4, r | 0x20);
602 bus_space_write_1(cd->vgat, cd->vgah, 0x5, v);
603 }
604
605 #if 0
606 static u_int8_t
607 igma_crtc_read(const struct igma_chip *cd, int r)
608 {
609 bus_space_write_1(cd->crtct, cd->crtch, 0x4, r);
610 return bus_space_read_1(cd->crtct, cd->crtch, 0x5);
611 }
612
613 static void
614 igma_crtc_write(const struct igma_chip *cd, int r, u_int8_t v)
615 {
616 bus_space_write_1(cd->crtct, cd->crtch, 0x4, r);
617 bus_space_write_1(cd->crtct, cd->crtch, 0x5, v);
618 }
619 #endif
620