diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/pkgdefs/SUNWagp/postinstall | 8 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWdrmr/postinstall | 4 | ||||
-rw-r--r-- | usr/src/uts/common/io/drm/drm_gem.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/agp/agpdefs.h | 11 | ||||
-rw-r--r-- | usr/src/uts/intel/io/agpgart/agpgart.c | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/io/agpgart/agptarget.c | 244 | ||||
-rw-r--r-- | usr/src/uts/intel/io/agpmaster/agpmaster.c | 2 | ||||
-rw-r--r-- | usr/src/uts/intel/io/drm/drm_pciids.h | 2 | ||||
-rw-r--r-- | usr/src/uts/intel/io/drm/i915_dma.c | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/io/drm/i915_drv.c | 8 | ||||
-rw-r--r-- | usr/src/uts/intel/io/drm/i915_drv.h | 475 | ||||
-rw-r--r-- | usr/src/uts/intel/io/drm/i915_gem.c | 14 | ||||
-rw-r--r-- | usr/src/uts/intel/io/drm/i915_gem_tiling.c | 6 | ||||
-rw-r--r-- | usr/src/uts/intel/io/drm/i915_irq.c | 266 |
14 files changed, 936 insertions, 116 deletions
diff --git a/usr/src/pkgdefs/SUNWagp/postinstall b/usr/src/pkgdefs/SUNWagp/postinstall index e231ccdb54..a9090a6e1b 100644 --- a/usr/src/pkgdefs/SUNWagp/postinstall +++ b/usr/src/pkgdefs/SUNWagp/postinstall @@ -21,7 +21,7 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # SUNWagp postinstall script @@ -55,6 +55,12 @@ BRALIAS="\ \"pci8086,2e00\" \ \"pci8086,2e10\" \ \"pci8086,2e20\" \ + \"pci8086,2e30\" \ + \"pci8086,2e40\" \ + \"pci8086,40\" \ + \"pci8086,44\" \ + \"pci8086,62\" \ + \"pci8086,6a\" \ \"pci8086,1130\" \ " CPUGART='"pci1022,1103"' diff --git a/usr/src/pkgdefs/SUNWdrmr/postinstall b/usr/src/pkgdefs/SUNWdrmr/postinstall index 2bb7740f2f..c835549e6b 100644 --- a/usr/src/pkgdefs/SUNWdrmr/postinstall +++ b/usr/src/pkgdefs/SUNWdrmr/postinstall @@ -51,6 +51,10 @@ IGFX_ALIAS="\ \"pci8086,2e02.8086.2e02\" \ \"pci8086,2e12\" \ \"pci8086,2e22\" \ + \"pci8086,2e32\" \ + \"pci8086,2e42\" \ + \"pci8086,42\" \ + \"pci8086,46\" \ " DRVPERM='* 0644 root sys' diff --git a/usr/src/uts/common/io/drm/drm_gem.c b/usr/src/uts/common/io/drm/drm_gem.c index 9805ae7b62..69c5fc1c46 100644 --- a/usr/src/uts/common/io/drm/drm_gem.c +++ b/usr/src/uts/common/io/drm/drm_gem.c @@ -80,7 +80,7 @@ idr_list_init(struct idr_list *head) struct idr_list *entry; /* HASH for accelerate */ entry = kmem_zalloc(DRM_GEM_OBJIDR_HASHNODE - * sizeof (struct idr_list), KM_NOSLEEP); + * sizeof (struct idr_list), KM_SLEEP); head->next = entry; for (int i = 0; i < DRM_GEM_OBJIDR_HASHNODE; i++) { INIT_LIST_HEAD(&entry[i]); @@ -94,7 +94,7 @@ idr_list_get_new_above(struct idr_list *head, { struct idr_list *entry; int key; - entry = kmem_zalloc(sizeof (*entry), KM_NOSLEEP); + entry = kmem_zalloc(sizeof (*entry), KM_SLEEP); key = obj->name % DRM_GEM_OBJIDR_HASHNODE; list_add(entry, &head->next[key], NULL); entry->obj = obj; diff --git a/usr/src/uts/common/sys/agp/agpdefs.h b/usr/src/uts/common/sys/agp/agpdefs.h index 5ed32cb122..adda870efd 100644 --- a/usr/src/uts/common/sys/agp/agpdefs.h +++ b/usr/src/uts/common/sys/agp/agpdefs.h @@ -108,6 +108,10 @@ extern "C" { #define INTEL_BR_Q45 0x2e108086 #define INTEL_BR_G45 0x2e208086 #define INTEL_BR_G41 0x2e308086 +#define INTEL_BR_IGDNG_D 0x00408086 +#define INTEL_BR_IGDNG_M 0x00448086 +#define INTEL_BR_IGDNG_MA 0x00628086 +#define INTEL_BR_IGDNG_MC2 0x006a8086 #define INTEL_BR_B43 0x2e408086 /* AGP common register offset in pci configuration space */ @@ -178,6 +182,8 @@ extern "C" { #define INTEL_IGD_Q45 0x2e128086 #define INTEL_IGD_G45 0x2e228086 #define INTEL_IGD_G41 0x2e328086 +#define INTEL_IGD_IGDNG_D 0x00428086 +#define INTEL_IGD_IGDNG_M 0x00468086 #define INTEL_IGD_B43 0x2e428086 /* Intel 915 and 945 series */ @@ -202,11 +208,16 @@ extern "C" { (device == INTEL_IGD_G33) || \ (device == INTEL_IGD_Q33)) +/* IGDNG */ +#define IS_IGDNG(device) ((device == INTEL_IGD_IGDNG_D) || \ + (device == INTEL_IGD_IGDNG_M)) + /* Intel G4X series */ #define IS_INTEL_G4X(device) ((device == INTEL_IGD_EL) || \ (device == INTEL_IGD_Q45) || \ (device == INTEL_IGD_G45) || \ (device == INTEL_IGD_G41) || \ + IS_IGDNG(device) || \ (device == INTEL_IGD_B43)) /* register offsets in PCI config space */ diff --git a/usr/src/uts/intel/io/agpgart/agpgart.c b/usr/src/uts/intel/io/agpgart/agpgart.c index 0f7ce74458..7df05184e3 100644 --- a/usr/src/uts/intel/io/agpgart/agpgart.c +++ b/usr/src/uts/intel/io/agpgart/agpgart.c @@ -71,7 +71,7 @@ list_head_init(struct list_head *head) { struct list_head *entry, *tmp; /* HASH for accelerate */ entry = kmem_zalloc(AGP_HASH_NODE * - sizeof (struct list_head), KM_NOSLEEP); + sizeof (struct list_head), KM_SLEEP); head->next = entry; for (int i = 0; i < AGP_HASH_NODE; i++) { tmp = &entry[i]; @@ -87,7 +87,7 @@ list_head_add_new(struct list_head *head, { struct list_head *entry, *tmp; int key; - entry = kmem_zalloc(sizeof (*entry), KM_NOSLEEP); + entry = kmem_zalloc(sizeof (*entry), KM_SLEEP); key = gttseg->igs_pgstart % AGP_HASH_NODE; tmp = &head->next[key]; tmp->next->prev = entry; diff --git a/usr/src/uts/intel/io/agpgart/agptarget.c b/usr/src/uts/intel/io/agpgart/agptarget.c index f0c1808abb..c963bcf970 100644 --- a/usr/src/uts/intel/io/agpgart/agptarget.c +++ b/usr/src/uts/intel/io/agpgart/agptarget.c @@ -62,7 +62,8 @@ static struct _i9xx_private_compat { uint_t regnum; /* register number */ caddr_t flush_page; /* kernel virtual address */ ddi_acc_handle_t handle; /* data access handle */ -} i9xx_private; + uint_t ra_alloced; +} i9xx_private = {0, 0, 0, 0, 0, 0}; #define I915_IFPADDR 0x60 #define I965_IFPADDR 0x70 @@ -414,6 +415,14 @@ static gms_mode_t gms_modes[] = { GMS_SIZE(gms_G4X), gms_G4X}, {INTEL_BR_G41, I8XX_CONF_GC, I8XX_GC_MODE_MASK, GMS_SIZE(gms_G4X), gms_G4X}, + {INTEL_BR_IGDNG_D, I8XX_CONF_GC, I8XX_GC_MODE_MASK, + GMS_SIZE(gms_G4X), gms_G4X}, + {INTEL_BR_IGDNG_M, I8XX_CONF_GC, I8XX_GC_MODE_MASK, + GMS_SIZE(gms_G4X), gms_G4X}, + {INTEL_BR_IGDNG_MA, I8XX_CONF_GC, I8XX_GC_MODE_MASK, + GMS_SIZE(gms_G4X), gms_G4X}, + {INTEL_BR_IGDNG_MC2, I8XX_CONF_GC, I8XX_GC_MODE_MASK, + GMS_SIZE(gms_G4X), gms_G4X}, {INTEL_BR_B43, I8XX_CONF_GC, I8XX_GC_MODE_MASK, GMS_SIZE(gms_G4X), gms_G4X} }; @@ -530,141 +539,192 @@ intel_br_suspend(agp_target_softstate_t *softstate) static void intel_chipset_flush_setup(dev_info_t *dip, - ddi_acc_handle_t pci_acc_hdl, int gms_off) + ddi_acc_handle_t pci_acc_hdl, int gms_off) { uint32_t temp_hi, temp_lo; - ndi_ra_request_t request; - uint64_t answer; - uint64_t alen; - pci_regspec_t *regs, *regs2; - int n_reg, length; - uint32_t i, regnum, ret; - ddi_acc_handle_t conf_hdl = pci_acc_hdl; + uint64_t phys_base, phys_len; uint32_t phys_hi_mask = 0; + pci_regspec_t *old_regs = NULL, *new_regs = NULL; + int old_len = 0, new_len = 0; + uint32_t old_regnum, new_regnum; + int circular = 0, prop_updated = 0; + int ret; - bzero((caddr_t)&request, sizeof (ndi_ra_request_t)); - request.ra_flags |= NDI_RA_ALIGN_SIZE | NDI_RA_ALLOC_BOUNDED; - request.ra_boundbase = 0; - request.ra_boundlen = 0xffffffff; - request.ra_len = AGP_PAGE_SIZE; + if (i9xx_private.handle) + return; /* IS_I965 || IS_G33 || IS_G4X */ if (gms_off > 11) { - temp_hi = pci_config_get32(conf_hdl, I965_IFPADDR + 4); - temp_lo = pci_config_get32(conf_hdl, I965_IFPADDR); + temp_hi = pci_config_get32(pci_acc_hdl, I965_IFPADDR + 4); + temp_lo = pci_config_get32(pci_acc_hdl, I965_IFPADDR); phys_hi_mask |= PCI_ADDR_MEM64 | I965_IFPADDR; } else { - temp_lo = pci_config_get32(conf_hdl, I915_IFPADDR); + temp_lo = pci_config_get32(pci_acc_hdl, I915_IFPADDR); phys_hi_mask |= PCI_ADDR_MEM32 | I915_IFPADDR; } if (!(temp_lo & 0x1)) { + ndi_ra_request_t request; + + bzero((caddr_t)&request, sizeof (ndi_ra_request_t)); + request.ra_flags |= NDI_RA_ALIGN_SIZE | NDI_RA_ALLOC_BOUNDED; + request.ra_boundbase = 0; + request.ra_boundlen = 0xffffffff; + request.ra_len = AGP_PAGE_SIZE; + /* allocate space from the allocator */ - if (ndi_ra_alloc(ddi_get_parent(dip), - &request, &answer, &alen, - NDI_RA_TYPE_MEM, NDI_RA_PASS) - != NDI_SUCCESS) { - return; + ndi_devi_enter(ddi_get_parent(dip), &circular); + if (ndi_ra_alloc(ddi_get_parent(dip), &request, &phys_base, + &phys_len, NDI_RA_TYPE_MEM, NDI_RA_PASS) != NDI_SUCCESS) { + TARGETDB_PRINT2((CE_WARN, + "intel_chipset_flush_setup: " + "ndi_ra_alloc failed!")); + ndi_devi_exit(ddi_get_parent(dip), circular); + goto error; } - TARGETDB_PRINT2((CE_WARN, "addr = 0x%x.0x%x len [0x%x]\n", - HIADDR(answer), - LOADDR(answer), - (uint32_t)alen)); + ndi_devi_exit(ddi_get_parent(dip), circular); + i9xx_private.ra_alloced = 1; + + TARGETDB_PRINT2((CE_WARN, + "intel_chipset_flush_setup: " + "addr = 0x%x.0x%x len [0x%x]\n", + HIADDR(phys_base), LOADDR(phys_base), + (uint32_t)phys_len)); if (gms_off > 11) { - pci_config_put32(conf_hdl, I965_IFPADDR + 4, - HIADDR(answer)); - pci_config_put32(conf_hdl, I965_IFPADDR, - LOADDR(answer) | 0x1); + pci_config_put32(pci_acc_hdl, I965_IFPADDR + 4, + HIADDR(phys_base)); + pci_config_put32(pci_acc_hdl, I965_IFPADDR, + LOADDR(phys_base) | 0x1); } else { - pci_config_put32(conf_hdl, I915_IFPADDR, - LOADDR(answer) | 0x1); + pci_config_put32(pci_acc_hdl, I915_IFPADDR, + LOADDR(phys_base) | 0x1); } - } - else - { + } else { temp_lo &= ~0x1; - answer = ((uint64_t)temp_hi << 32) | temp_lo; + phys_base = ((uint64_t)temp_hi << 32) | temp_lo; } - temp_hi = pci_config_get32(conf_hdl, I965_IFPADDR + 4); - temp_lo = pci_config_get32(conf_hdl, I965_IFPADDR); + temp_hi = pci_config_get32(pci_acc_hdl, I965_IFPADDR + 4); + temp_lo = pci_config_get32(pci_acc_hdl, I965_IFPADDR); /* set pci props */ - if (ddi_dev_nregs(dip, &n_reg) == DDI_FAILURE) { - TARGETDB_PRINT2((CE_WARN, "init_chipset_flush failed")); - n_reg = 0; - return; - } - if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "reg", (caddr_t)®s, &length) != - DDI_PROP_SUCCESS) { - TARGETDB_PRINT2((CE_WARN, "init_chipset_flush failed!")); - return; + "reg", (caddr_t)&old_regs, &old_len) != DDI_PROP_SUCCESS) { + TARGETDB_PRINT2((CE_WARN, + "intel_chipset_flush_setup: " + "ddi_getlongprop(1) failed!")); + goto error; } - regnum = length / sizeof (pci_regspec_t); - - TARGETDB_PRINT2((CE_WARN, "reg regnum %d", regnum)); - - regs2 = kmem_alloc((regnum + 1) * sizeof (pci_regspec_t), KM_SLEEP); - if (regs2 == NULL) { + old_regnum = old_len / sizeof (pci_regspec_t); + TARGETDB_PRINT2((CE_WARN, + "intel_chipset_flush_setup: old_regnum = %d", old_regnum)); - TARGETDB_PRINT2((CE_WARN, "init_chipset_flush failed")); - goto error; - } - if (memcpy(regs2, regs, (size_t)length) == NULL) { - TARGETDB_PRINT2((CE_WARN, "init_chipset_flush failed")); - kmem_free(regs2, (regnum + 1) * sizeof (pci_regspec_t)); + new_regnum = old_regnum + 1; + new_len = new_regnum * sizeof (pci_regspec_t); + new_regs = kmem_zalloc(new_len, KM_SLEEP); + if (memcpy(new_regs, old_regs, (size_t)old_len) == NULL) { + TARGETDB_PRINT2((CE_WARN, + "intel_chipset_flush_setup: memcpy failed")); goto error; } /* Bus=0, Dev=0, Func=0 0x82001000 */ - regs2[regnum].pci_phys_hi = PCI_REG_REL_M | phys_hi_mask; - regs2[regnum].pci_phys_mid = HIADDR(answer); - regs2[regnum].pci_phys_low = LOADDR(answer); - regs2[regnum].pci_size_hi = 0x00000000; - regs2[regnum].pci_size_low = AGP_PAGE_SIZE; - kmem_free(regs, (size_t)length); - regs = regs2; - - i = ndi_prop_update_int_array(DDI_DEV_T_NONE, - dip, "reg", (int *)regs, (uint_t)5 * (regnum + 1)); - if (i != DDI_PROP_SUCCESS) { - TARGETDB_PRINT2((CE_WARN, "Failed to update reg %d", i)); - kmem_free(regs2, (regnum + 1) * sizeof (pci_regspec_t)); - return; + new_regs[old_regnum].pci_phys_hi = PCI_REG_REL_M | phys_hi_mask; + new_regs[old_regnum].pci_phys_mid = HIADDR(phys_base); + new_regs[old_regnum].pci_phys_low = LOADDR(phys_base); + new_regs[old_regnum].pci_size_hi = 0x00000000; + new_regs[old_regnum].pci_size_low = AGP_PAGE_SIZE; + + ret = ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, + "reg", (int *)new_regs, (uint_t)5 * new_regnum); + if (ret != DDI_PROP_SUCCESS) { + TARGETDB_PRINT2((CE_WARN, + "intel_chipset_flush_setup: " + "ndi_prop_update_int_array failed %d", ret)); + goto error; } - kmem_free(regs2, (regnum + 1) * sizeof (pci_regspec_t)); - regs = NULL; + kmem_free(new_regs, (size_t)new_len); + new_regs = NULL; + + prop_updated = 1; if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "reg", (caddr_t)®s, &length) != - DDI_PROP_SUCCESS) { - TARGETDB_PRINT2((CE_WARN, "init_chipset_flush: failed1!")); + "reg", (caddr_t)&new_regs, &new_len) != DDI_PROP_SUCCESS) { + TARGETDB_PRINT2((CE_WARN, + "intel_chipset_flush_setup: " + "ddi_getlongprop(2) failed")); goto error; } - regnum = length / sizeof (pci_regspec_t); - kmem_free(regs, (size_t)length); + kmem_free(new_regs, (size_t)new_len); + new_regs = NULL; - i9xx_private.physical = answer; + new_regnum = new_len / sizeof (pci_regspec_t); + + i9xx_private.physical = phys_base; i9xx_private.size = AGP_PAGE_SIZE; - i9xx_private.regnum = regnum - 1; + i9xx_private.regnum = new_regnum - 1; + ret = ddi_regs_map_setup(dip, i9xx_private.regnum, (caddr_t *)&(i9xx_private.flush_page), 0, - i9xx_private.size, &dev_attr, - (ddi_acc_handle_t *)&i9xx_private.handle); - + i9xx_private.size, &dev_attr, &i9xx_private.handle); if (ret != DDI_SUCCESS) { - TARGETDB_PRINT2((CE_WARN, "chipset_flush do_ioremap failed ")); + TARGETDB_PRINT2((CE_WARN, + "intel_chipset_flush_setup: ddi_regs_map_setup failed")); i9xx_private.handle = NULL; - return; + goto error; } + + kmem_free(old_regs, (size_t)old_len); return; error: + if (prop_updated) + (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, + "reg", (int *)old_regs, (uint_t)5 * old_regnum); + if (new_regs) + kmem_free(new_regs, (size_t)new_len); + if (old_regs) + kmem_free(old_regs, (size_t)old_len); + if (i9xx_private.ra_alloced) { + ndi_devi_enter(ddi_get_parent(dip), &circular); + (void) ndi_ra_free(ddi_get_parent(dip), + phys_base, phys_len, NDI_RA_TYPE_MEM, NDI_RA_PASS); + ndi_devi_exit(ddi_get_parent(dip), circular); + i9xx_private.ra_alloced = 0; + } +} + +static void +intel_chipset_flush_free(dev_info_t *dip) +{ + pci_regspec_t *regs = NULL; + int len = 0, regnum; + int circular = 0; + + if (i9xx_private.handle == NULL) + return; + + ddi_regs_map_free(&i9xx_private.handle); + i9xx_private.handle = NULL; + + if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, + "reg", (caddr_t)®s, &len) == DDI_PROP_SUCCESS) { + regnum = len / sizeof (pci_regspec_t) - 1; + (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, + "reg", (int *)regs, (uint_t)5 * regnum); + } if (regs) - kmem_free(regs, (size_t)length); + kmem_free(regs, (size_t)len); + + if (i9xx_private.ra_alloced) { + ndi_devi_enter(ddi_get_parent(dip), &circular); + (void) ndi_ra_free(ddi_get_parent(dip), + i9xx_private.physical, i9xx_private.size, + NDI_RA_TYPE_MEM, NDI_RA_PASS); + ndi_devi_exit(ddi_get_parent(dip), circular); + i9xx_private.ra_alloced = 0; + } } static int @@ -989,11 +1049,7 @@ agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode, } case INTEL_CHIPSET_FLUSH_FREE: { - if (i9xx_private.handle != NULL) { - ddi_regs_map_free( - (ddi_acc_handle_t *)&i9xx_private.handle); - i9xx_private.handle = NULL; - } + intel_chipset_flush_free(st->tsoft_dip); break; } default: diff --git a/usr/src/uts/intel/io/agpmaster/agpmaster.c b/usr/src/uts/intel/io/agpmaster/agpmaster.c index 24b77a4201..9e71b3cf41 100644 --- a/usr/src/uts/intel/io/agpmaster/agpmaster.c +++ b/usr/src/uts/intel/io/agpmaster/agpmaster.c @@ -626,6 +626,8 @@ detect_i8xx_device(agp_master_softc_t *master_softc) case INTEL_IGD_Q45: case INTEL_IGD_G45: case INTEL_IGD_G41: + case INTEL_IGD_IGDNG_D: + case INTEL_IGD_IGDNG_M: case INTEL_IGD_B43: master_softc->agpm_dev_type = DEVICE_IS_I830; break; diff --git a/usr/src/uts/intel/io/drm/drm_pciids.h b/usr/src/uts/intel/io/drm/drm_pciids.h index 16de72ca61..18176edce5 100644 --- a/usr/src/uts/intel/io/drm/drm_pciids.h +++ b/usr/src/uts/intel/io/drm/drm_pciids.h @@ -207,6 +207,8 @@ extern "C" { {0x8086, 0x2E12, CHIP_I9XX|CHIP_I965, "Intel Q45"}, \ {0x8086, 0x2E22, CHIP_I9XX|CHIP_I965, "Intel G45"}, \ {0x8086, 0x2E32, CHIP_I9XX|CHIP_I965, "Intel G41"}, \ + {0x8086, 0x42, CHIP_I9XX|CHIP_I965, "Intel IGDNG_D"}, \ + {0x8086, 0x46, CHIP_I9XX|CHIP_I965, "Intel IGDNG_M"}, \ {0x8086, 0x2E42, CHIP_I9XX|CHIP_I965, "Intel B43"}, \ {0, 0, 0, NULL} diff --git a/usr/src/uts/intel/io/drm/i915_dma.c b/usr/src/uts/intel/io/drm/i915_dma.c index f737a1c38d..851c68fb97 100644 --- a/usr/src/uts/intel/io/drm/i915_dma.c +++ b/usr/src/uts/intel/io/drm/i915_dma.c @@ -951,9 +951,9 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) dev->driver->get_vblank_counter = i915_get_vblank_counter; dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ #if defined(__i386) - if (IS_G4X(dev) || IS_GM45(dev)) + if (IS_G4X(dev) || IS_IGDNG(dev) || IS_GM45(dev)) #else - if (IS_G4X(dev)) + if (IS_G4X(dev) || IS_IGDNG(dev)) #endif { dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ diff --git a/usr/src/uts/intel/io/drm/i915_drv.c b/usr/src/uts/intel/io/drm/i915_drv.c index d8eaf8c60a..4e7ce559e8 100644 --- a/usr/src/uts/intel/io/drm/i915_drv.c +++ b/usr/src/uts/intel/io/drm/i915_drv.c @@ -713,10 +713,7 @@ i915_resume(struct drm_device *dev) for (i = 0; i < 3; i++) S3_WRITE(SWF30 + (i << 2), s3_priv->saveSWF2[i]); - if (IS_I965GM(dev)) { - S3_WRITE(I915REG_PGTBL_CTRL, s3_priv->pgtbl_ctl); - (void) S3_READ(I915REG_PGTBL_CTRL); - } + S3_WRITE(I915REG_PGTBL_CTRL, s3_priv->pgtbl_ctl); (void) pci_config_teardown(&conf_hdl); @@ -777,8 +774,7 @@ i915_suspend(struct drm_device *dev) /* * Save page table control register */ - if (IS_I965GM(dev)) - s3_priv->pgtbl_ctl = S3_READ(I915REG_PGTBL_CTRL); + s3_priv->pgtbl_ctl = S3_READ(I915REG_PGTBL_CTRL); (void) pci_config_teardown(&conf_hdl); diff --git a/usr/src/uts/intel/io/drm/i915_drv.h b/usr/src/uts/intel/io/drm/i915_drv.h index e96840064e..ccf4bd66e4 100644 --- a/usr/src/uts/intel/io/drm/i915_drv.h +++ b/usr/src/uts/intel/io/drm/i915_drv.h @@ -245,6 +245,11 @@ typedef struct drm_i915_private { /** Cached value of IMR to avoid reads in updating the bitfield */ int irq_mask_reg; uint32_t pipestat[2]; + /** splitted irq regs for graphics and display engine on IGDNG, + irq_mask_reg is still used for display irq. */ + u32 gt_irq_mask_reg; + u32 gt_irq_enable_reg; + u32 de_irq_enable_reg; int tex_lru_log_granularity; int allow_batchbuffer; @@ -758,6 +763,11 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define I915_ERROR_MEMORY_REFRESH (1<<1) #define I915_ERROR_INSTRUCTION (1<<0) +#define PIPEA_FRMCOUNT_GM45 0x70040 +#define PIPEA_FLIPCOUNT_GM45 0x70044 +#define PIPEB_FRMCOUNT_GM45 0x71040 +#define PIPEB_FLIPCOUNT_GM45 0x71044 + #define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) #define I915_VBLANK_CLEAR (1UL<<1) @@ -916,6 +926,14 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); # define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) # define PLL_REF_INPUT_MASK (3 << 13) # define PLL_LOAD_PULSE_PHASE_SHIFT 9 + +/* IGDNG */ +#define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT 9 +#define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK (7 << 9) +#define PLL_REF_SDVO_HDMI_MULTIPLIER(x) (((x)-1) << 9) +#define DPLL_FPA1_P1_POST_DIV_SHIFT 0 +#define DPLL_FPA1_P1_POST_DIV_MASK 0xff + /* * Parallel to Serial Load Pulse phase selection. * Selects the phase for the 10X DPLL clock for the PCIe @@ -1288,6 +1306,446 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define SWF30 0x72414 +/* IGDNG */ + +#define CPU_VGACNTRL 0x41000 + +#define DIGITAL_PORT_HOTPLUG_CNTRL 0x44030 +#define DIGITAL_PORTA_HOTPLUG_ENABLE (1 << 4) +#define DIGITAL_PORTA_SHORT_PULSE_2MS (0 << 2) +#define DIGITAL_PORTA_SHORT_PULSE_4_5MS (1 << 2) +#define DIGITAL_PORTA_SHORT_PULSE_6MS (2 << 2) +#define DIGITAL_PORTA_SHORT_PULSE_100MS (3 << 2) +#define DIGITAL_PORTA_NO_DETECT (0 << 0) +#define DIGITAL_PORTA_LONG_PULSE_DETECT_MASK (1 << 1) +#define DIGITAL_PORTA_SHORT_PULSE_DETECT_MASK (1 << 0) + +/* refresh rate hardware control */ +#define RR_HW_CTL 0x45300 +#define RR_HW_LOW_POWER_FRAMES_MASK 0xff +#define RR_HW_HIGH_POWER_FRAMES_MASK 0xff00 + +#define FDI_PLL_BIOS_0 0x46000 +#define FDI_PLL_BIOS_1 0x46004 +#define FDI_PLL_BIOS_2 0x46008 +#define DISPLAY_PORT_PLL_BIOS_0 0x4600c +#define DISPLAY_PORT_PLL_BIOS_1 0x46010 +#define DISPLAY_PORT_PLL_BIOS_2 0x46014 + +#define FDI_PLL_FREQ_CTL 0x46030 +#define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) +#define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 +#define FDI_PLL_FREQ_DISABLE_COUNT_LIMIT_MASK 0xff + + +#define PIPEA_DATA_M1 0x60030 +#define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */ +#define TU_SIZE_MASK 0x7e000000 +#define PIPEA_DATA_M1_OFFSET 0 +#define PIPEA_DATA_N1 0x60034 +#define PIPEA_DATA_N1_OFFSET 0 + +#define PIPEA_DATA_M2 0x60038 +#define PIPEA_DATA_M2_OFFSET 0 +#define PIPEA_DATA_N2 0x6003c +#define PIPEA_DATA_N2_OFFSET 0 + +#define PIPEA_LINK_M1 0x60040 +#define PIPEA_LINK_M1_OFFSET 0 +#define PIPEA_LINK_N1 0x60044 +#define PIPEA_LINK_N1_OFFSET 0 + +#define PIPEA_LINK_M2 0x60048 +#define PIPEA_LINK_M2_OFFSET 0 +#define PIPEA_LINK_N2 0x6004c +#define PIPEA_LINK_N2_OFFSET 0 + +/* PIPEB timing regs are same start from 0x61000 */ + +#define PIPEB_DATA_M1 0x61030 +#define PIPEB_DATA_M1_OFFSET 0 +#define PIPEB_DATA_N1 0x61034 +#define PIPEB_DATA_N1_OFFSET 0 + +#define PIPEB_DATA_M2 0x61038 +#define PIPEB_DATA_M2_OFFSET 0 +#define PIPEB_DATA_N2 0x6103c +#define PIPEB_DATA_N2_OFFSET 0 + +#define PIPEB_LINK_M1 0x61040 +#define PIPEB_LINK_M1_OFFSET 0 +#define PIPEB_LINK_N1 0x61044 +#define PIPEB_LINK_N1_OFFSET 0 + +#define PIPEB_LINK_M2 0x61048 +#define PIPEB_LINK_M2_OFFSET 0 +#define PIPEB_LINK_N2 0x6104c +#define PIPEB_LINK_N2_OFFSET 0 + +/* CPU panel fitter */ +#define PFA_CTL_1 0x68080 +#define PFB_CTL_1 0x68880 +#define PF_ENABLE (1<<31) + +/* legacy palette */ +#define LGC_PALETTE_A 0x4a000 +#define LGC_PALETTE_B 0x4a800 + +/* interrupts */ +#define DE_MASTER_IRQ_CONTROL (0x80000000) +#define DE_SPRITEB_FLIP_DONE (1 << 29) +#define DE_SPRITEA_FLIP_DONE (1 << 28) +#define DE_PLANEB_FLIP_DONE (1 << 27) +#define DE_PLANEA_FLIP_DONE (1 << 26) +#define DE_PCU_EVENT (1 << 25) +#define DE_GTT_FAULT (1 << 24) +#define DE_POISON (1 << 23) +#define DE_PERFORM_COUNTER (1 << 22) +#define DE_PCH_EVENT (1 << 21) +#define DE_AUX_CHANNEL_A (1 << 20) +#define DE_DP_A_HOTPLUG (1 << 19) +#define DE_GSE (1 << 18) +#define DE_PIPEB_VBLANK (1 << 15) +#define DE_PIPEB_EVEN_FIELD (1 << 14) +#define DE_PIPEB_ODD_FIELD (1 << 13) +#define DE_PIPEB_LINE_COMPARE (1 << 12) +#define DE_PIPEB_VSYNC (1 << 11) +#define DE_PIPEB_FIFO_UNDERRUN (1 << 8) +#define DE_PIPEA_VBLANK (1 << 7) +#define DE_PIPEA_EVEN_FIELD (1 << 6) +#define DE_PIPEA_ODD_FIELD (1 << 5) +#define DE_PIPEA_LINE_COMPARE (1 << 4) +#define DE_PIPEA_VSYNC (1 << 3) +#define DE_PIPEA_FIFO_UNDERRUN (1 << 0) + +#define DEISR 0x44000 +#define DEIMR 0x44004 +#define DEIIR 0x44008 +#define DEIER 0x4400c + +/* GT interrupt */ +#define GT_SYNC_STATUS (1 << 2) +#define GT_USER_INTERRUPT (1 << 0) + +#define GTISR 0x44010 +#define GTIMR 0x44014 +#define GTIIR 0x44018 +#define GTIER 0x4401c + +/* PCH */ + +/* south display engine interrupt */ +#define SDE_CRT_HOTPLUG (1 << 11) +#define SDE_PORTD_HOTPLUG (1 << 10) +#define SDE_PORTC_HOTPLUG (1 << 9) +#define SDE_PORTB_HOTPLUG (1 << 8) +#define SDE_SDVOB_HOTPLUG (1 << 6) + +#define SDEISR 0xc4000 +#define SDEIMR 0xc4004 +#define SDEIIR 0xc4008 +#define SDEIER 0xc400c + +/* digital port hotplug */ +#define PCH_PORT_HOTPLUG 0xc4030 +#define PORTD_HOTPLUG_ENABLE (1 << 20) +#define PORTD_PULSE_DURATION_2ms (0) +#define PORTD_PULSE_DURATION_4_5ms (1 << 18) +#define PORTD_PULSE_DURATION_6ms (2 << 18) +#define PORTD_PULSE_DURATION_100ms (3 << 18) +#define PORTD_HOTPLUG_NO_DETECT (0) +#define PORTD_HOTPLUG_SHORT_DETECT (1 << 16) +#define PORTD_HOTPLUG_LONG_DETECT (1 << 17) +#define PORTC_HOTPLUG_ENABLE (1 << 12) +#define PORTC_PULSE_DURATION_2ms (0) +#define PORTC_PULSE_DURATION_4_5ms (1 << 10) +#define PORTC_PULSE_DURATION_6ms (2 << 10) +#define PORTC_PULSE_DURATION_100ms (3 << 10) +#define PORTC_HOTPLUG_NO_DETECT (0) +#define PORTC_HOTPLUG_SHORT_DETECT (1 << 8) +#define PORTC_HOTPLUG_LONG_DETECT (1 << 9) +#define PORTB_HOTPLUG_ENABLE (1 << 4) +#define PORTB_PULSE_DURATION_2ms (0) +#define PORTB_PULSE_DURATION_4_5ms (1 << 2) +#define PORTB_PULSE_DURATION_6ms (2 << 2) +#define PORTB_PULSE_DURATION_100ms (3 << 2) +#define PORTB_HOTPLUG_NO_DETECT (0) +#define PORTB_HOTPLUG_SHORT_DETECT (1 << 0) +#define PORTB_HOTPLUG_LONG_DETECT (1 << 1) + +#define PCH_GPIOA 0xc5010 +#define PCH_GPIOB 0xc5014 +#define PCH_GPIOC 0xc5018 +#define PCH_GPIOD 0xc501c +#define PCH_GPIOE 0xc5020 +#define PCH_GPIOF 0xc5024 + +#define PCH_DPLL_A 0xc6014 +#define PCH_DPLL_B 0xc6018 + +#define PCH_FPA0 0xc6040 +#define PCH_FPA1 0xc6044 +#define PCH_FPB0 0xc6048 +#define PCH_FPB1 0xc604c + +#define PCH_DPLL_TEST 0xc606c + +#define PCH_DREF_CONTROL 0xC6200 +#define DREF_CONTROL_MASK 0x7fc3 +#define DREF_CPU_SOURCE_OUTPUT_DISABLE (0<<13) +#define DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD (2<<13) +#define DREF_CPU_SOURCE_OUTPUT_NONSPREAD (3<<13) +#define DREF_CPU_SOURCE_OUTPUT_MASK (3<<13) +#define DREF_SSC_SOURCE_DISABLE (0<<11) +#define DREF_SSC_SOURCE_ENABLE (2<<11) +#define DREF_SSC_SOURCE_MASK (2<<11) +#define DREF_NONSPREAD_SOURCE_DISABLE (0<<9) +#define DREF_NONSPREAD_CK505_ENABLE (1<<9) +#define DREF_NONSPREAD_SOURCE_ENABLE (2<<9) +#define DREF_NONSPREAD_SOURCE_MASK (2<<9) +#define DREF_SUPERSPREAD_SOURCE_DISABLE (0<<7) +#define DREF_SUPERSPREAD_SOURCE_ENABLE (2<<7) +#define DREF_SSC4_DOWNSPREAD (0<<6) +#define DREF_SSC4_CENTERSPREAD (1<<6) +#define DREF_SSC1_DISABLE (0<<1) +#define DREF_SSC1_ENABLE (1<<1) +#define DREF_SSC4_DISABLE (0) +#define DREF_SSC4_ENABLE (1) + +#define PCH_RAWCLK_FREQ 0xc6204 +#define FDL_TP1_TIMER_SHIFT 12 +#define FDL_TP1_TIMER_MASK (3<<12) +#define FDL_TP2_TIMER_SHIFT 10 +#define FDL_TP2_TIMER_MASK (3<<10) +#define RAWCLK_FREQ_MASK 0x3ff + +#define PCH_DPLL_TMR_CFG 0xc6208 + +#define PCH_SSC4_PARMS 0xc6210 +#define PCH_SSC4_AUX_PARMS 0xc6214 + +/* transcoder */ + +#define TRANS_HTOTAL_A 0xe0000 +#define TRANS_HTOTAL_SHIFT 16 +#define TRANS_HACTIVE_SHIFT 0 +#define TRANS_HBLANK_A 0xe0004 +#define TRANS_HBLANK_END_SHIFT 16 +#define TRANS_HBLANK_START_SHIFT 0 +#define TRANS_HSYNC_A 0xe0008 +#define TRANS_HSYNC_END_SHIFT 16 +#define TRANS_HSYNC_START_SHIFT 0 +#define TRANS_VTOTAL_A 0xe000c +#define TRANS_VTOTAL_SHIFT 16 +#define TRANS_VACTIVE_SHIFT 0 +#define TRANS_VBLANK_A 0xe0010 +#define TRANS_VBLANK_END_SHIFT 16 +#define TRANS_VBLANK_START_SHIFT 0 +#define TRANS_VSYNC_A 0xe0014 +#define TRANS_VSYNC_END_SHIFT 16 +#define TRANS_VSYNC_START_SHIFT 0 + +#define TRANSA_DATA_M1 0xe0030 +#define TRANSA_DATA_N1 0xe0034 +#define TRANSA_DATA_M2 0xe0038 +#define TRANSA_DATA_N2 0xe003c +#define TRANSA_DP_LINK_M1 0xe0040 +#define TRANSA_DP_LINK_N1 0xe0044 +#define TRANSA_DP_LINK_M2 0xe0048 +#define TRANSA_DP_LINK_N2 0xe004c + +#define TRANS_HTOTAL_B 0xe1000 +#define TRANS_HBLANK_B 0xe1004 +#define TRANS_HSYNC_B 0xe1008 +#define TRANS_VTOTAL_B 0xe100c +#define TRANS_VBLANK_B 0xe1010 +#define TRANS_VSYNC_B 0xe1014 + +#define TRANSB_DATA_M1 0xe1030 +#define TRANSB_DATA_N1 0xe1034 +#define TRANSB_DATA_M2 0xe1038 +#define TRANSB_DATA_N2 0xe103c +#define TRANSB_DP_LINK_M1 0xe1040 +#define TRANSB_DP_LINK_N1 0xe1044 +#define TRANSB_DP_LINK_M2 0xe1048 +#define TRANSB_DP_LINK_N2 0xe104c + +#define TRANSACONF 0xf0008 +#define TRANSBCONF 0xf1008 +#define TRANS_DISABLE (0<<31) +#define TRANS_ENABLE (1<<31) +#define TRANS_STATE_MASK (1<<30) +#define TRANS_STATE_DISABLE (0<<30) +#define TRANS_STATE_ENABLE (1<<30) +#define TRANS_FSYNC_DELAY_HB1 (0<<27) +#define TRANS_FSYNC_DELAY_HB2 (1<<27) +#define TRANS_FSYNC_DELAY_HB3 (2<<27) +#define TRANS_FSYNC_DELAY_HB4 (3<<27) +#define TRANS_DP_AUDIO_ONLY (1<<26) +#define TRANS_DP_VIDEO_AUDIO (0<<26) +#define TRANS_PROGRESSIVE (0<<21) +#define TRANS_8BPC (0<<5) +#define TRANS_10BPC (1<<5) +#define TRANS_6BPC (2<<5) +#define TRANS_12BPC (3<<5) + +#define FDI_RXA_CHICKEN 0xc200c +#define FDI_RXB_CHICKEN 0xc2010 +#define FDI_RX_PHASE_SYNC_POINTER_ENABLE (1) + +/* CPU: FDI_TX */ +#define FDI_TXA_CTL 0x60100 +#define FDI_TXB_CTL 0x61100 +#define FDI_TX_DISABLE (0<<31) +#define FDI_TX_ENABLE (1<<31) +#define FDI_LINK_TRAIN_PATTERN_1 (0<<28) +#define FDI_LINK_TRAIN_PATTERN_2 (1<<28) +#define FDI_LINK_TRAIN_PATTERN_IDLE (2<<28) +#define FDI_LINK_TRAIN_NONE (3<<28) +#define FDI_LINK_TRAIN_VOLTAGE_0_4V (0<<25) +#define FDI_LINK_TRAIN_VOLTAGE_0_6V (1<<25) +#define FDI_LINK_TRAIN_VOLTAGE_0_8V (2<<25) +#define FDI_LINK_TRAIN_VOLTAGE_1_2V (3<<25) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0<<22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1<<22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2<<22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3<<22) +#define FDI_DP_PORT_WIDTH_X1 (0<<19) +#define FDI_DP_PORT_WIDTH_X2 (1<<19) +#define FDI_DP_PORT_WIDTH_X3 (2<<19) +#define FDI_DP_PORT_WIDTH_X4 (3<<19) +#define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18) +/* IGDNG: hardwired to 1 */ +#define FDI_TX_PLL_ENABLE (1<<14) +/* both Tx and Rx */ +#define FDI_SCRAMBLING_ENABLE (0<<7) +#define FDI_SCRAMBLING_DISABLE (1<<7) + +/* FDI_RX, FDI_X is hard-wired to Transcoder_X */ +#define FDI_RXA_CTL 0xf000c +#define FDI_RXB_CTL 0xf100c +#define FDI_RX_ENABLE (1<<31) +#define FDI_RX_DISABLE (0<<31) +/* train, dp width same as FDI_TX */ +#define FDI_DP_PORT_WIDTH_X8 (7<<19) +#define FDI_8BPC (0<<16) +#define FDI_10BPC (1<<16) +#define FDI_6BPC (2<<16) +#define FDI_12BPC (3<<16) +#define FDI_LINK_REVERSE_OVERWRITE (1<<15) +#define FDI_DMI_LINK_REVERSE_MASK (1<<14) +#define FDI_RX_PLL_ENABLE (1<<13) +#define FDI_FS_ERR_CORRECT_ENABLE (1<<11) +#define FDI_FE_ERR_CORRECT_ENABLE (1<<10) +#define FDI_FS_ERR_REPORT_ENABLE (1<<9) +#define FDI_FE_ERR_REPORT_ENABLE (1<<8) +#define FDI_RX_ENHANCE_FRAME_ENABLE (1<<6) +#define FDI_SEL_RAWCLK (0<<4) +#define FDI_SEL_PCDCLK (1<<4) + +#define FDI_RXA_MISC 0xf0010 +#define FDI_RXB_MISC 0xf1010 +#define FDI_RXA_TUSIZE1 0xf0030 +#define FDI_RXA_TUSIZE2 0xf0038 +#define FDI_RXB_TUSIZE1 0xf1030 +#define FDI_RXB_TUSIZE2 0xf1038 + +/* FDI_RX interrupt register format */ +#define FDI_RX_INTER_LANE_ALIGN (1<<10) +#define FDI_RX_SYMBOL_LOCK (1<<9) /* train 2 */ +#define FDI_RX_BIT_LOCK (1<<8) /* train 1 */ +#define FDI_RX_TRAIN_PATTERN_2_FAIL (1<<7) +#define FDI_RX_FS_CODE_ERR (1<<6) +#define FDI_RX_FE_CODE_ERR (1<<5) +#define FDI_RX_SYMBOL_ERR_RATE_ABOVE (1<<4) +#define FDI_RX_HDCP_LINK_FAIL (1<<3) +#define FDI_RX_PIXEL_FIFO_OVERFLOW (1<<2) +#define FDI_RX_CROSS_CLOCK_OVERFLOW (1<<1) +#define FDI_RX_SYMBOL_QUEUE_OVERFLOW (1<<0) + +#define FDI_RXA_IIR 0xf0014 +#define FDI_RXA_IMR 0xf0018 +#define FDI_RXB_IIR 0xf1014 +#define FDI_RXB_IMR 0xf1018 + +#define FDI_PLL_CTL_1 0xfe000 +#define FDI_PLL_CTL_2 0xfe004 + +/* CRT */ +#define PCH_ADPA 0xe1100 +#define ADPA_TRANS_SELECT_MASK (1<<30) +#define ADPA_TRANS_A_SELECT 0 +#define ADPA_TRANS_B_SELECT (1<<30) +#define ADPA_CRT_HOTPLUG_MASK 0x03ff0000 /* bit 25-16 */ +#define ADPA_CRT_HOTPLUG_MONITOR_NONE (0<<24) +#define ADPA_CRT_HOTPLUG_MONITOR_MASK (3<<24) +#define ADPA_CRT_HOTPLUG_MONITOR_COLOR (3<<24) +#define ADPA_CRT_HOTPLUG_MONITOR_MONO (2<<24) +#define ADPA_CRT_HOTPLUG_ENABLE (1<<23) +#define ADPA_CRT_HOTPLUG_PERIOD_64 (0<<22) +#define ADPA_CRT_HOTPLUG_PERIOD_128 (1<<22) +#define ADPA_CRT_HOTPLUG_WARMUP_5MS (0<<21) +#define ADPA_CRT_HOTPLUG_WARMUP_10MS (1<<21) +#define ADPA_CRT_HOTPLUG_SAMPLE_2S (0<<20) +#define ADPA_CRT_HOTPLUG_SAMPLE_4S (1<<20) +#define ADPA_CRT_HOTPLUG_VOLTAGE_40 (0<<18) +#define ADPA_CRT_HOTPLUG_VOLTAGE_50 (1<<18) +#define ADPA_CRT_HOTPLUG_VOLTAGE_60 (2<<18) +#define ADPA_CRT_HOTPLUG_VOLTAGE_70 (3<<18) +#define ADPA_CRT_HOTPLUG_VOLREF_325MV (0<<17) +#define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17) +#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) + +/* or SDVOB */ +#define HDMIB 0xe1140 +#define PORT_ENABLE (1 << 31) +#define TRANSCODER_A (0) +#define TRANSCODER_B (1 << 30) +#define COLOR_FORMAT_8bpc (0) +#define COLOR_FORMAT_12bpc (3 << 26) +#define SDVOB_HOTPLUG_ENABLE (1 << 23) +#define SDVO_ENCODING (0) +#define TMDS_ENCODING (2 << 10) +#define NULL_PACKET_VSYNC_ENABLE (1 << 9) +#define SDVOB_BORDER_ENABLE (1 << 7) +#define AUDIO_ENABLE (1 << 6) +#define VSYNC_ACTIVE_HIGH (1 << 4) +#define HSYNC_ACTIVE_HIGH (1 << 3) +#define PORT_DETECTED (1 << 2) + +#define HDMIC 0xe1150 +#define HDMID 0xe1160 + +#define PCH_LVDS 0xe1180 +#define LVDS_DETECTED (1 << 1) + +#define BLC_PWM_CPU_CTL2 0x48250 +#define PWM_ENABLE (1 << 31) +#define PWM_PIPE_A (0 << 29) +#define PWM_PIPE_B (1 << 29) +#define BLC_PWM_CPU_CTL 0x48254 + +#define BLC_PWM_PCH_CTL1 0xc8250 +#define PWM_PCH_ENABLE (1 << 31) +#define PWM_POLARITY_ACTIVE_LOW (1 << 29) +#define PWM_POLARITY_ACTIVE_HIGH (0 << 29) +#define PWM_POLARITY_ACTIVE_LOW2 (1 << 28) +#define PWM_POLARITY_ACTIVE_HIGH2 (0 << 28) + +#define BLC_PWM_PCH_CTL2 0xc8254 + +#define PCH_PP_STATUS 0xc7200 +#define PCH_PP_CONTROL 0xc7204 +#define EDP_FORCE_VDD (1 << 3) +#define EDP_BLC_ENABLE (1 << 2) +#define PANEL_POWER_RESET (1 << 1) +#define PANEL_POWER_OFF (0 << 0) +#define PANEL_POWER_ON (1 << 0) +#define PCH_PP_ON_DELAYS 0xc7208 +#define EDP_PANEL (1 << 30) +#define PCH_PP_OFF_DELAYS 0xc720c +#define PCH_PP_DIVISOR 0xc7210 + #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 #define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562 #define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582 @@ -1311,6 +1769,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define PCI_DEVICE_ID_INTEL_82Q45_IG 0x2e12 #define PCI_DEVICE_ID_INTEL_82G45_IG 0x2e22 #define PCI_DEVICE_ID_INTEL_82G41_IG 0x2e32 +#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x42 +#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x46 #define PCI_DEVICE_ID_INTEL_82B43_IG 0x2e42 @@ -1326,6 +1786,10 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG || \ (dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GME_IG) +#define IS_IGDNG_D(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_IGDNG_D_IG) +#define IS_IGDNG_M(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_IGDNG_M_IG) +#define IS_IGDNG(dev) (IS_IGDNG_D(dev) || IS_IGDNG_M(dev)) + #define IS_I965G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82946_GZ || \ (dev)->pci_device == PCI_DEVICE_ID_INTEL_82G35_IG || \ (dev)->pci_device == PCI_DEVICE_ID_INTEL_82Q963_IG || \ @@ -1337,6 +1801,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); (dev)->pci_device == PCI_DEVICE_ID_INTEL_82Q45_IG || \ (dev)->pci_device == PCI_DEVICE_ID_INTEL_82G45_IG || \ (dev)->pci_device == PCI_DEVICE_ID_INTEL_82B43_IG || \ + (dev)->pci_device == PCI_DEVICE_ID_INTEL_IGDNG_D_IG || \ + (dev)->pci_device == PCI_DEVICE_ID_INTEL_IGDNG_M_IG || \ (dev)->pci_device == PCI_DEVICE_ID_INTEL_82G41_IG) #define IS_I965GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_GM965_IG) @@ -1354,16 +1820,19 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); (dev)->pci_device == PCI_DEVICE_ID_INTEL_82Q33_IG) #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ - IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) + IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \ + IS_IGDNG(dev)) #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ - IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) + IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \ + IS_IGDNG_M(dev)) #define IS_IGDG(dev) ((dev)->pci_device == 0xa001) #define IS_IGDGM(dev) ((dev)->pci_device == 0xa011) #define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev)) -#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) +#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev) || \ + IS_IGDNG(dev)) /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte * rows, which changed the alignment requirements and fence programming. */ diff --git a/usr/src/uts/intel/io/drm/i915_gem.c b/usr/src/uts/intel/io/drm/i915_gem.c index 28a534f406..2e4c13448e 100644 --- a/usr/src/uts/intel/io/drm/i915_gem.c +++ b/usr/src/uts/intel/io/drm/i915_gem.c @@ -674,7 +674,7 @@ i915_retire_commands(struct drm_device *dev) /* The sampler always gets flushed on i965 (sigh) */ if (IS_I965G(dev)) flush_domains |= I915_GEM_DOMAIN_SAMPLER; - BEGIN_LP_RING(3); + BEGIN_LP_RING(2); OUT_RING(cmd); OUT_RING(0); /* noop */ ADVANCE_LP_RING(); @@ -886,11 +886,23 @@ int i915_wait_request(struct drm_device *dev, uint32_t seqno) { drm_i915_private_t *dev_priv = dev->dev_private; + u32 ier; int ret = 0; ASSERT(seqno != 0); if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { + if (IS_IGDNG(dev)) + ier = I915_READ(DEIER) | I915_READ(GTIER); + else + ier = I915_READ(IER); + if (!ier) { + DRM_ERROR("something (likely vbetool) disabled " + "interrupts, re-enabling\n"); + (void) i915_driver_irq_preinstall(dev); + i915_driver_irq_postinstall(dev); + } + dev_priv->mm.waiting_gem_seqno = seqno; i915_user_irq_on(dev); DRM_WAIT(ret, &dev_priv->irq_queue, diff --git a/usr/src/uts/intel/io/drm/i915_gem_tiling.c b/usr/src/uts/intel/io/drm/i915_gem_tiling.c index 9978463c24..987d56710c 100644 --- a/usr/src/uts/intel/io/drm/i915_gem_tiling.c +++ b/usr/src/uts/intel/io/drm/i915_gem_tiling.c @@ -177,6 +177,12 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) } } + /* FIXME: check with memory config on IGDNG */ + if (IS_IGDNG(dev)) { + swizzle_x = I915_BIT_6_SWIZZLE_9_10; + swizzle_y = I915_BIT_6_SWIZZLE_9; + } + dev_priv->mm.bit_6_swizzle_x = swizzle_x; dev_priv->mm.bit_6_swizzle_y = swizzle_y; } diff --git a/usr/src/uts/intel/io/drm/i915_irq.c b/usr/src/uts/intel/io/drm/i915_irq.c index 6596fdd094..d4023b5560 100644 --- a/usr/src/uts/intel/io/drm/i915_irq.c +++ b/usr/src/uts/intel/io/drm/i915_irq.c @@ -62,6 +62,58 @@ #define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \ I915_INTERRUPT_ENABLE_VAR) +void +igdng_enable_irq(drm_i915_private_t *dev_priv, u32 mask, int gfx_irq) +{ + if (gfx_irq && ((dev_priv->gt_irq_mask_reg & mask) != 0)) { + dev_priv->gt_irq_mask_reg &= ~mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); + (void) I915_READ(GTIMR); + } else if ((dev_priv->irq_mask_reg & mask) != 0) { + dev_priv->irq_mask_reg &= ~mask; + I915_WRITE(DEIMR, dev_priv->irq_mask_reg); + (void) I915_READ(DEIMR); + + } +} + +static inline void +igdng_disable_irq(drm_i915_private_t *dev_priv, u32 mask, int gfx_irq) +{ + if (gfx_irq && ((dev_priv->gt_irq_mask_reg & mask) != mask)) { + dev_priv->gt_irq_mask_reg |= mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); + (void) I915_READ(GTIMR); + } else if ((dev_priv->irq_mask_reg & mask) != mask) { + dev_priv->irq_mask_reg |= mask; + I915_WRITE(DEIMR, dev_priv->irq_mask_reg); + (void) I915_READ(DEIMR); + } +} + +/* For display hotplug interrupt */ +void +igdng_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) +{ + if ((dev_priv->irq_mask_reg & mask) != 0) { + dev_priv->irq_mask_reg &= ~mask; + I915_WRITE(DEIMR, dev_priv->irq_mask_reg); + (void) I915_READ(DEIMR); + } +} + +#if 0 +static inline void +igdng_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) +{ + if ((dev_priv->irq_mask_reg & mask) != mask) { + dev_priv->irq_mask_reg |= mask; + I915_WRITE(DEIMR, dev_priv->irq_mask_reg); + (void) I915_READ(DEIMR); + } +} +#endif + static inline void i915_enable_irq(drm_i915_private_t *dev_priv, uint32_t mask) { @@ -374,6 +426,62 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) return I915_READ(reg); } +irqreturn_t igdng_irq_handler(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + int ret = IRQ_NONE; + u32 de_iir, gt_iir, de_ier; + u32 new_de_iir, new_gt_iir; + int vblank = 0; + + /* disable master interrupt before clearing iir */ + de_ier = I915_READ(DEIER); + I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); + (void)I915_READ(DEIER); + + de_iir = I915_READ(DEIIR); + gt_iir = I915_READ(GTIIR); + + for (;;) { + if (de_iir == 0 && gt_iir == 0) + break; + + ret = IRQ_HANDLED; + + I915_WRITE(DEIIR, de_iir); + new_de_iir = I915_READ(DEIIR); + I915_WRITE(GTIIR, gt_iir); + new_gt_iir = I915_READ(GTIIR); + + if (dev_priv->sarea_priv) { + dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + + } + + if (gt_iir & GT_USER_INTERRUPT) { + dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); + DRM_WAKEUP(&dev_priv->irq_queue); + } + if (de_iir & DE_PIPEA_VBLANK) { + vblank++; + drm_handle_vblank(dev, 0); + } + + if (de_iir & DE_PIPEB_VBLANK) { + vblank++; + drm_handle_vblank(dev, 1); + } + + de_iir = new_de_iir; + gt_iir = new_gt_iir; + } + + I915_WRITE(DEIER, de_ier); + (void)I915_READ(DEIER); + + return ret; +} + irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) (void *) arg; @@ -382,6 +490,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) u32 pipea_stats = 0, pipeb_stats = 0; int vblank = 0; + if (IS_IGDNG(dev)) + return igdng_irq_handler(dev); + iir = I915_READ(IIR); if (iir == 0) { @@ -485,9 +596,9 @@ int i915_emit_irq(drm_device_t * dev) #endif /* __i386 */ #if defined(__i386) - if (IS_I965GM(dev) || IS_GM45(dev)) + if (IS_I965GM(dev) || IS_IGDNG(dev) || IS_GM45(dev)) #else - if (IS_I965GM(dev)) + if (IS_I965GM(dev) || IS_IGDNG(dev)) #endif /* __i386 */ { (void) READ_BREADCRUMB(dev_priv); @@ -506,7 +617,10 @@ void i915_user_irq_on(struct drm_device *dev) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; spin_lock(&dev_priv->user_irq_lock); if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ - i915_enable_irq(dev_priv, I915_USER_INTERRUPT); + if (IS_IGDNG(dev)) + igdng_enable_irq(dev_priv, GT_USER_INTERRUPT, 1); + else + i915_enable_irq(dev_priv, I915_USER_INTERRUPT); } spin_unlock(&dev_priv->user_irq_lock); @@ -517,7 +631,10 @@ void i915_user_irq_off(struct drm_device *dev) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; spin_lock(&dev_priv->user_irq_lock); if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { - i915_disable_irq(dev_priv, I915_USER_INTERRUPT); + if (IS_IGDNG(dev)) + igdng_disable_irq(dev_priv, GT_USER_INTERRUPT, 1); + else + i915_disable_irq(dev_priv, I915_USER_INTERRUPT); } spin_unlock(&dev_priv->user_irq_lock); } @@ -527,12 +644,15 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = 0; + int wait_time = 0; if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } +waitmore: + wait_time++; if (READ_BREADCRUMB(dev_priv) >= irq_nr) { if (dev_priv->sarea_priv) { dev_priv->sarea_priv->last_dispatch = @@ -547,14 +667,26 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) i915_user_irq_off(dev); if (ret == EBUSY) { + if (wait_time > 5) { DRM_DEBUG("%d: EBUSY -- rec: %d emitted: %d\n", ret, READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); + return ret; + } + goto waitmore; } if (dev_priv->sarea_priv) dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + if (ret == EINTR) { + if (wait_time > 5) { + DRM_DEBUG("EINTR wait %d now %d", dev_priv->counter, READ_BREADCRUMB(dev_priv)); + return ret; + } + goto waitmore; + } + return ret; } @@ -620,6 +752,42 @@ int i915_irq_wait(DRM_IOCTL_ARGS) return i915_wait_irq(dev, irqwait.irq_seq); } +static void igdng_enable_vblank(struct drm_device *dev, int pipe) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 vblank; + + if (pipe == 0) + vblank = DE_PIPEA_VBLANK; + else + vblank = DE_PIPEB_VBLANK; + + if ((dev_priv->de_irq_enable_reg & vblank) == 0) { + igdng_enable_irq(dev_priv, vblank, 0); + dev_priv->de_irq_enable_reg |= vblank; + I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); + (void) I915_READ(DEIER); + } +} + +static void igdng_disable_vblank(struct drm_device *dev, int pipe) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 vblank; + + if (pipe == 0) + vblank = DE_PIPEA_VBLANK; + else + vblank = DE_PIPEB_VBLANK; + + if ((dev_priv->de_irq_enable_reg & vblank) != 0) { + igdng_disable_irq(dev_priv, vblank, 0); + dev_priv->de_irq_enable_reg &= ~vblank; + I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); + (void) I915_READ(DEIER); + } +} + int i915_enable_vblank(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -631,7 +799,9 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) return -EINVAL; spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - if (IS_I965G(dev)) + if (IS_IGDNG(dev)) + igdng_enable_vblank(dev, pipe); + else if (IS_I965G(dev)) i915_enable_pipestat(dev_priv, pipe, PIPE_START_VBLANK_INTERRUPT_ENABLE); else @@ -647,6 +817,9 @@ void i915_disable_vblank(struct drm_device *dev, int pipe) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); + if (IS_IGDNG(dev)) + igdng_disable_vblank(dev, pipe); + else i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE | PIPE_START_VBLANK_INTERRUPT_ENABLE); @@ -714,6 +887,69 @@ int i915_vblank_swap(DRM_IOCTL_ARGS) /* drm_dma.h hooks */ + +static void igdng_irq_preinstall(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + + I915_WRITE(HWSTAM, 0xeffe); + + /* XXX hotplug from PCH */ + + I915_WRITE(DEIMR, 0xffffffff); + I915_WRITE(DEIER, 0x0); + (void) I915_READ(DEIER); + + /* and GT */ + I915_WRITE(GTIMR, 0xffffffff); + I915_WRITE(GTIER, 0x0); + (void) I915_READ(GTIER); +} + +static int igdng_irq_postinstall(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + /* enable kind of interrupts always enabled */ + u32 display_mask = DE_MASTER_IRQ_CONTROL /*| DE_PCH_EVENT */; + u32 render_mask = GT_USER_INTERRUPT; + + dev_priv->irq_mask_reg = ~display_mask; + dev_priv->de_irq_enable_reg = display_mask; + + /* should always can generate irq */ + I915_WRITE(DEIIR, I915_READ(DEIIR)); + (void) I915_READ(DEIIR); + I915_WRITE(DEIMR, dev_priv->irq_mask_reg); + I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); + (void) I915_READ(DEIER); + + /* user interrupt should be enabled, but masked initial */ + dev_priv->gt_irq_mask_reg = 0xffffffff; + dev_priv->gt_irq_enable_reg = render_mask; + + I915_WRITE(GTIIR, I915_READ(GTIIR)); + (void) I915_READ(GTIIR); + I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); + I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); + (void) I915_READ(GTIER); + + return 0; +} + +static void igdng_irq_uninstall(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + I915_WRITE(HWSTAM, 0xffffffff); + + I915_WRITE(DEIMR, 0xffffffff); + I915_WRITE(DEIER, 0x0); + I915_WRITE(DEIIR, I915_READ(DEIIR)); + + I915_WRITE(GTIMR, 0xffffffff); + I915_WRITE(GTIER, 0x0); + I915_WRITE(GTIIR, I915_READ(GTIIR)); +} + int i915_driver_irq_preinstall(drm_device_t * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -721,6 +957,11 @@ int i915_driver_irq_preinstall(drm_device_t * dev) if (!dev_priv->mmio_map) return -EINVAL; + if (IS_IGDNG(dev)) { + igdng_irq_preinstall(dev); + return 0; + } + I915_WRITE16(HWSTAM, 0xeffe); I915_WRITE(PIPEASTAT, 0); I915_WRITE(PIPEBSTAT, 0); @@ -738,6 +979,12 @@ void i915_driver_irq_postinstall(drm_device_t * dev) dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; + if (IS_IGDNG(dev)) { + (void) igdng_irq_postinstall(dev); + DRM_INIT_WAITQUEUE(&dev_priv->irq_queue, DRM_INTR_PRI(dev)); + return; + } + /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX; @@ -762,9 +1009,12 @@ void i915_driver_irq_postinstall(drm_device_t * dev) /* Disable pipe interrupt enables, clear pending pipe status */ I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); + (void) I915_READ(PIPEASTAT); + (void) I915_READ(PIPEBSTAT); /* Clear pending interrupt status */ I915_WRITE(IIR, I915_READ(IIR)); + (void) I915_READ(IIR); I915_WRITE(IMR, dev_priv->irq_mask_reg); I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); (void) I915_READ(IER); @@ -782,6 +1032,12 @@ void i915_driver_irq_uninstall(drm_device_t * dev) dev_priv->vblank_pipe = 0; + if (IS_IGDNG(dev)) { + igdng_irq_uninstall(dev); + DRM_FINI_WAITQUEUE(&dev_priv->irq_queue); + return; + } + I915_WRITE(HWSTAM, 0xffffffff); I915_WRITE(PIPEASTAT, 0); I915_WRITE(PIPEBSTAT, 0); |