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