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