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