Index: i915_drv.c =================================================================== --- i915_drv.c (revision 287201) +++ i915_drv.c (working copy) @@ -308,6 +308,7 @@ INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */ INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */ INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ + INTEL_VGA_DEVICE(0x1616, &intel_haswell_m_info), /* something */ INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), @@ -316,6 +317,55 @@ static int i915_enable_unsupported; +#define PCI_VENDOR_INTEL 0x8086 +#define INTEL_PCH_DEVICE_ID_MASK 0xff00 +#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 +#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 +#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 +#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 + +void intel_detect_pch(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + device_t pch; + + /* + * The reason to probe ISA bridge instead of Dev31:Fun0 is to + * make graphics device passthrough work easy for VMM, that only + * need to expose ISA bridge to let driver know the real hardware + * underneath. This is a requirement from virtualization team. + */ + pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA); + if (pch) { + if (pci_get_vendor(pch) == PCI_VENDOR_ID_INTEL) { + int id; + id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK; + + if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_IBX; + dev_priv->num_pch_pll = 2; + DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); + } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_CPT; + dev_priv->num_pch_pll = 2; + DRM_DEBUG_KMS("Found CougarPoint PCH\n"); + } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { + /* PantherPoint is CPT compatible */ + dev_priv->pch_type = PCH_CPT; + dev_priv->num_pch_pll = 2; + DRM_DEBUG_KMS("Found PatherPoint PCH\n"); + } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_LPT; + dev_priv->num_pch_pll = 0; + DRM_DEBUG_KMS("Found LynxPoint PCH\n"); + } + KASSERT(dev_priv->num_pch_pll <= I915_NUM_PLLS, + ("num_pch_pll %d\n", dev_priv->num_pch_pll)); + } + } else + DRM_DEBUG_KMS("No Intel PCI-ISA bridge found\n"); +} + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -384,7 +434,7 @@ /* KMS EnterVT equivalent */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { - if (HAS_PCH_SPLIT(dev)) + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) ironlake_init_pch_refclk(dev); DRM_LOCK(dev); @@ -486,11 +536,14 @@ { const struct intel_gfx_device_id *did; + printf("loading\n"); for (did = &pciidlist[0]; did->device != 0; did++) { if (did->device != device) continue; + printf("ici\n"); if (did->info->not_supported && !i915_enable_unsupported) return (NULL); + printf("la\n"); return (did->info); } return (NULL); @@ -562,48 +615,6 @@ TUNABLE_INT("drm.i915.enable_hangcheck", &i915_enable_hangcheck); TUNABLE_INT("drm.i915.enable_unsupported", &i915_enable_unsupported); -#define PCI_VENDOR_INTEL 0x8086 -#define INTEL_PCH_DEVICE_ID_MASK 0xff00 -#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 -#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 -#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 -#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 - -void intel_detect_pch(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv; - device_t pch; - uint32_t id; - - dev_priv = dev->dev_private; - pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA); - if (pch != NULL && pci_get_vendor(pch) == PCI_VENDOR_INTEL) { - id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK; - if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { - dev_priv->pch_type = PCH_IBX; - dev_priv->num_pch_pll = 2; - DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); - } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { - dev_priv->pch_type = PCH_CPT; - dev_priv->num_pch_pll = 2; - DRM_DEBUG_KMS("Found CougarPoint PCH\n"); - } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { - /* PantherPoint is CPT compatible */ - dev_priv->pch_type = PCH_CPT; - dev_priv->num_pch_pll = 2; - DRM_DEBUG_KMS("Found PatherPoint PCH\n"); - } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { - dev_priv->pch_type = PCH_LPT; - dev_priv->num_pch_pll = 0; - DRM_DEBUG_KMS("Found LynxPoint PCH\n"); - } else - DRM_DEBUG_KMS("No PCH detected\n"); - KASSERT(dev_priv->num_pch_pll <= I915_NUM_PLLS, - ("num_pch_pll %d\n", dev_priv->num_pch_pll)); - } else - DRM_DEBUG_KMS("No Intel PCI-ISA bridge found\n"); -} - bool i915_semaphore_is_enabled(struct drm_device *dev) { if (INTEL_INFO(dev)->gen < 6) @@ -1008,10 +1019,115 @@ ((reg) < 0x40000) && \ ((reg) != FORCEWAKE)) && \ (!IS_VALLEYVIEW((dev_priv)->dev)) +static bool IS_DISPLAYREG(u32 reg) +{ + /* + * This should make it easier to transition modules over to the + * new register block scheme, since we can do it incrementally. + */ + if (reg >= VLV_DISPLAY_BASE) + return false; + if (reg >= RENDER_RING_BASE && + reg < RENDER_RING_BASE + 0xff) + return false; + if (reg >= GEN6_BSD_RING_BASE && + reg < GEN6_BSD_RING_BASE + 0xff) + return false; + if (reg >= BLT_RING_BASE && + reg < BLT_RING_BASE + 0xff) + return false; + + if (reg == PGTBL_ER) + return false; + + if (reg >= IPEIR_I965 && + reg < HWSTAM) + return false; + + if (reg == MI_MODE) + return false; + + if (reg == GFX_MODE_GEN7) + return false; + + if (reg == RENDER_HWS_PGA_GEN7 || + reg == BSD_HWS_PGA_GEN7 || + reg == BLT_HWS_PGA_GEN7) + return false; + + if (reg == GEN6_BSD_SLEEP_PSMI_CONTROL || + reg == GEN6_BSD_RNCID) + return false; + + if (reg == GEN6_BLITTER_ECOSKPD) + return false; + + if (reg >= 0x4000c && + reg <= 0x4002c) + return false; + + if (reg >= 0x4f000 && + reg <= 0x4f08f) + return false; + + if (reg >= 0x4f100 && + reg <= 0x4f11f) + return false; + + if (reg >= VLV_MASTER_IER && + reg <= GEN6_PMIER) + return false; + + if (reg >= FENCE_REG_SANDYBRIDGE_0 && + reg < (FENCE_REG_SANDYBRIDGE_0 + (16*8))) + return false; + + if (reg >= VLV_IIR_RW && + reg <= VLV_ISR) + return false; + + if (reg == FORCEWAKE_VLV || + reg == FORCEWAKE_ACK_VLV) + return false; + + if (reg == GEN6_GDRST) + return false; + + switch (reg) { + case _3D_CHICKEN3: + case IVB_CHICKEN3: + case GEN7_COMMON_SLICE_CHICKEN1: + case GEN7_L3CNTLREG1: + case GEN7_L3_CHICKEN_MODE_REGISTER: + case GEN7_ROW_CHICKEN2: + case GEN7_L3SQCREG4: + case GEN7_SQ_CHICKEN_MBCUNIT_CONFIG: + case GEN7_HALF_SLICE_CHICKEN1: + case GEN6_MBCTL: + case GEN6_UCGCTL2: + return false; + default: + break; + } + + return true; +} + +static void +ilk_dummy_write(struct drm_i915_private *dev_priv) +{ + /* WaIssueDummyWriteToWakeupFromRC6: Issue a dummy write to wake up the + * chip from rc6 before touching it for real. MI_MODE is masked, hence + * harmless to write 0 into. */ + I915_WRITE_NOTRACE(MI_MODE, 0); +} + #define __i915_read(x, y) \ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ u##x val = 0; \ + if (IS_GEN5(dev_priv->dev)) \ + ilk_dummy_write(dev_priv); \ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ mtx_lock(&dev_priv->gt_lock); \ if (dev_priv->forcewake_count == 0) \ @@ -1020,6 +1136,8 @@ if (dev_priv->forcewake_count == 0) \ dev_priv->display.force_wake_put(dev_priv); \ mtx_unlock(&dev_priv->gt_lock); \ + } else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ + val = DRM_READ##y(dev_priv->mmio_map, reg + 0x180000); \ } else { \ val = DRM_READ##y(dev_priv->mmio_map, reg); \ } \ @@ -1040,10 +1158,24 @@ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ } \ - DRM_WRITE##y(dev_priv->mmio_map, reg, val); \ + if (IS_GEN5(dev_priv->dev)) \ + ilk_dummy_write(dev_priv); \ + if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ + DRM_ERROR("Unknown unclaimed register before writing to %x\n", reg); \ + I915_WRITE_NOTRACE(GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ + } \ + if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ + DRM_WRITE##y(dev_priv->mmio_map, reg + 0x180000, val); \ + } else { \ + DRM_WRITE##y(dev_priv->mmio_map, reg, val); \ + } \ if (__predict_false(__fifo_ret)) { \ gen6_gt_check_fifodbg(dev_priv); \ } \ + if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ + DRM_ERROR("Unclaimed write to %x\n", reg); \ + writel(dev_priv->mmio_map + GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ + } \ } __i915_write(8, 8) __i915_write(16, 16) Index: i915_drv.h =================================================================== --- i915_drv.h (revision 287201) +++ i915_drv.h (working copy) @@ -57,8 +57,15 @@ I915_MAX_PIPES }; #define pipe_name(p) ((p) + 'A') -#define I915_NUM_PIPE 2 +enum transcoder { + TRANSCODER_A = 0, + TRANSCODER_B, + TRANSCODER_C, + TRANSCODER_EDP = 0xF, +}; +#define transcoder_name(t) ((t) + 'A') + enum plane { PLANE_A = 0, PLANE_B, @@ -78,9 +85,12 @@ #define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) - #define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++) +#define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ + list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ + if ((intel_encoder)->base.crtc == (__crtc)) + struct intel_pch_pll { int refcount; /* count of number of CRTCs sharing this PLL */ int active; /* count of number of active CRTCs (i.e. DPMS on) */ @@ -91,6 +101,12 @@ }; #define I915_NUM_PLLS 2 +struct intel_ddi_plls { + int spll_refcount; + int wrpll1_refcount; + int wrpll2_refcount; +}; + /* Interface history: * * 1.1: Original. @@ -697,6 +713,7 @@ /* wait_queue_head_t pending_flip_queue; XXXKIB */ struct intel_pch_pll pch_plls[I915_NUM_PLLS]; + struct intel_ddi_plls ddi_plls; /* Reclocking support */ bool render_reclock_avail; Index: i915_gem.c =================================================================== --- i915_gem.c (revision 287201) +++ i915_gem.c (working copy) @@ -122,6 +122,26 @@ return obj->pin_display; } + +static inline int +__copy_to_user_inatomic(void __user *to, const void *from, unsigned n) +{ + return (copyout_nofault(from, to, n) != 0 ? n : 0); +} +static inline unsigned long +__copy_from_user_inatomic_nocache(void *to, const void __user *from, + unsigned long n) +{ + + /* + * XXXKIB. Equivalent Linux function is implemented using + * MOVNTI for aligned moves. For unaligned head and tail, + * normal move is performed. As such, it is not incorrect, if + * only somewhat slower, to use normal copyin. All uses + * except shmem_pwrite_fast() have the destination mapped WC. + */ + return ((copyin_nofault(__DECONST(void *, from), to, n) != 0 ? n : 0)); +} static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) { if (obj->tiling_mode) @@ -341,79 +361,6 @@ } static inline int -__copy_to_user_inatomic(void __user *to, const void *from, unsigned n) -{ - return (copyout_nofault(from, to, n) != 0 ? n : 0); -} -static inline unsigned long -__copy_from_user_inatomic_nocache(void *to, const void __user *from, - unsigned long n) -{ - - /* - * XXXKIB. Equivalent Linux function is implemented using - * MOVNTI for aligned moves. For unaligned head and tail, - * normal move is performed. As such, it is not incorrect, if - * only somewhat slower, to use normal copyin. All uses - * except shmem_pwrite_fast() have the destination mapped WC. - */ - return ((copyin_nofault(__DECONST(void *, from), to, n) != 0 ? n : 0)); -} -static inline int -fault_in_multipages_readable(const char __user *uaddr, int size) -{ - char c; - int ret = 0; - const char __user *end = uaddr + size - 1; - - if (unlikely(size == 0)) - return ret; - - while (uaddr <= end) { - ret = -copyin(uaddr, &c, 1); - if (ret != 0) - return -EFAULT; - uaddr += PAGE_SIZE; - } - - /* Check whether the range spilled into the next page. */ - if (((unsigned long)uaddr & ~PAGE_MASK) == - ((unsigned long)end & ~PAGE_MASK)) { - ret = -copyin(end, &c, 1); - } - - return ret; -} - -static inline int -fault_in_multipages_writeable(char __user *uaddr, int size) -{ - int ret = 0; - char __user *end = uaddr + size - 1; - - if (unlikely(size == 0)) - return ret; - - /* - * Writing zeroes into userspace here is OK, because we know that if - * the zero gets there, we'll be overwriting it. - */ - while (uaddr <= end) { - ret = subyte(uaddr, 0); - if (ret != 0) - return -EFAULT; - uaddr += PAGE_SIZE; - } - - /* Check whether the range spilled into the next page. */ - if (((unsigned long)uaddr & ~PAGE_MASK) == - ((unsigned long)end & ~PAGE_MASK)) - ret = subyte(end, 0); - - return ret; -} - -static inline int __copy_to_user_swizzled(char __user *cpu_vaddr, const char *gpu_vaddr, int gpu_offset, int length) @@ -552,6 +499,60 @@ return ret ? - EFAULT : 0; } +static inline int +fault_in_multipages_readable(const char __user *uaddr, int size) +{ + char c; + int ret = 0; + const char __user *end = uaddr + size - 1; + + if (unlikely(size == 0)) + return ret; + + while (uaddr <= end) { + ret = -copyin(uaddr, &c, 1); + if (ret != 0) + return -EFAULT; + uaddr += PAGE_SIZE; + } + + /* Check whether the range spilled into the next page. */ + if (((unsigned long)uaddr & ~PAGE_MASK) == + ((unsigned long)end & ~PAGE_MASK)) { + ret = -copyin(end, &c, 1); + } + + return ret; +} + +static inline int +fault_in_multipages_writeable(char __user *uaddr, int size) +{ + int ret = 0; + char __user *end = uaddr + size - 1; + + if (unlikely(size == 0)) + return ret; + + /* + * Writing zeroes into userspace here is OK, because we know that if + * the zero gets there, we'll be overwriting it. + */ + while (uaddr <= end) { + ret = subyte(uaddr, 0); + if (ret != 0) + return -EFAULT; + uaddr += PAGE_SIZE; + } + + /* Check whether the range spilled into the next page. */ + if (((unsigned long)uaddr & ~PAGE_MASK) == + ((unsigned long)end & ~PAGE_MASK)) + ret = subyte(end, 0); + + return ret; +} + static int i915_gem_shmem_pread(struct drm_device *dev, struct drm_i915_gem_object *obj, @@ -3870,6 +3871,9 @@ drm_i915_private_t *dev_priv = dev->dev_private; int ret; + if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) + I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000); + i915_gem_init_swizzling(dev); ret = intel_init_render_ring_buffer(dev); Index: i915_gem_context.c =================================================================== --- i915_gem_context.c (revision 287201) +++ i915_gem_context.c (working copy) @@ -115,11 +115,9 @@ break; case 7: reg = I915_READ(GEN7_CXT_SIZE); -#ifdef FREEBSD_WIP if (IS_HASWELL(dev)) ret = HSW_CXT_TOTAL_SIZE(reg) * 64; else -#endif ret = GEN7_CXT_TOTAL_SIZE(reg) * 64; break; default: Index: i915_gem_gtt.c =================================================================== --- i915_gem_gtt.c (revision 287201) +++ i915_gem_gtt.c (working copy) @@ -24,6 +24,7 @@ #include __FBSDID("$FreeBSD$"); +#define HSW_PTE_UNCACHED (0) #include #include @@ -163,13 +164,20 @@ switch (cache_level) { case I915_CACHE_LLC_MLC: - pte_flags |= GEN6_PTE_CACHE_LLC_MLC; + /* Haswell doesn't set L3 this way */ + if (IS_HASWELL(dev)) + pte_flags |= GEN6_PTE_CACHE_LLC; + else + pte_flags |= GEN6_PTE_CACHE_LLC_MLC; break; case I915_CACHE_LLC: pte_flags |= GEN6_PTE_CACHE_LLC; break; case I915_CACHE_NONE: - pte_flags |= GEN6_PTE_UNCACHED; + if (IS_HASWELL(dev)) + pte_flags |= HSW_PTE_UNCACHED; + else + pte_flags |= GEN6_PTE_UNCACHED; break; default: panic("cache mode"); Index: i915_irq.c =================================================================== --- i915_irq.c (revision 287201) +++ i915_irq.c (working copy) @@ -2161,84 +2161,6 @@ I915_WRITE(IIR, I915_READ(IIR)); } -void intel_irq_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - TASK_INIT(&dev_priv->hotplug_task, 0, i915_hotplug_work_func, - dev->dev_private); - TASK_INIT(&dev_priv->error_task, 0, i915_error_work_func, - dev->dev_private); - TASK_INIT(&dev_priv->rps_task, 0, gen6_pm_rps_work_func, - dev->dev_private); - - dev->driver->get_vblank_counter = i915_get_vblank_counter; - dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { - dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ - dev->driver->get_vblank_counter = gm45_get_vblank_counter; - } - if (drm_core_check_feature(dev, DRIVER_MODESET)) - dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; - else - dev->driver->get_vblank_timestamp = NULL; - dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; - - if (IS_VALLEYVIEW(dev)) { - dev->driver->irq_handler = valleyview_irq_handler; - dev->driver->irq_preinstall = valleyview_irq_preinstall; - dev->driver->irq_postinstall = valleyview_irq_postinstall; - dev->driver->irq_uninstall = valleyview_irq_uninstall; - dev->driver->enable_vblank = valleyview_enable_vblank; - dev->driver->disable_vblank = valleyview_disable_vblank; - } else if (IS_IVYBRIDGE(dev)) { - /* Share pre & uninstall handlers with ILK/SNB */ - dev->driver->irq_handler = ivybridge_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->driver->irq_postinstall = ivybridge_irq_postinstall; - dev->driver->irq_uninstall = ironlake_irq_uninstall; - dev->driver->enable_vblank = ivybridge_enable_vblank; - dev->driver->disable_vblank = ivybridge_disable_vblank; - } else if (IS_HASWELL(dev)) { - /* Share interrupts handling with IVB */ - dev->driver->irq_handler = ivybridge_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->driver->irq_postinstall = ivybridge_irq_postinstall; - dev->driver->irq_uninstall = ironlake_irq_uninstall; - dev->driver->enable_vblank = ivybridge_enable_vblank; - dev->driver->disable_vblank = ivybridge_disable_vblank; - } else if (HAS_PCH_SPLIT(dev)) { - dev->driver->irq_handler = ironlake_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->driver->irq_postinstall = ironlake_irq_postinstall; - dev->driver->irq_uninstall = ironlake_irq_uninstall; - dev->driver->enable_vblank = ironlake_enable_vblank; - dev->driver->disable_vblank = ironlake_disable_vblank; - } else { - if (INTEL_INFO(dev)->gen == 2) { - dev->driver->irq_preinstall = i8xx_irq_preinstall; - dev->driver->irq_postinstall = i8xx_irq_postinstall; - dev->driver->irq_handler = i8xx_irq_handler; - dev->driver->irq_uninstall = i8xx_irq_uninstall; - } else if (INTEL_INFO(dev)->gen == 3) { - /* IIR "flip pending" means done if this bit is set */ - I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); - - dev->driver->irq_preinstall = i915_irq_preinstall; - dev->driver->irq_postinstall = i915_irq_postinstall; - dev->driver->irq_uninstall = i915_irq_uninstall; - dev->driver->irq_handler = i915_irq_handler; - } else { - dev->driver->irq_preinstall = i965_irq_preinstall; - dev->driver->irq_postinstall = i965_irq_postinstall; - dev->driver->irq_uninstall = i965_irq_uninstall; - dev->driver->irq_handler = i965_irq_handler; - } - dev->driver->enable_vblank = i915_enable_vblank; - dev->driver->disable_vblank = i915_disable_vblank; - } -} - static struct drm_i915_error_object * i915_error_object_create(struct drm_i915_private *dev_priv, struct drm_i915_gem_object *src) @@ -2659,3 +2581,82 @@ if (error != NULL && refcount_release(&error->ref)) i915_error_state_free(error); } + +void intel_irq_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + TASK_INIT(&dev_priv->hotplug_task, 0, i915_hotplug_work_func, + dev->dev_private); + TASK_INIT(&dev_priv->error_task, 0, i915_error_work_func, + dev->dev_private); + TASK_INIT(&dev_priv->rps_task, 0, gen6_pm_rps_work_func, + dev->dev_private); + + dev->driver->get_vblank_counter = i915_get_vblank_counter; + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ + if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { + dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ + dev->driver->get_vblank_counter = gm45_get_vblank_counter; + } + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; + else + dev->driver->get_vblank_timestamp = NULL; + dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; + + if (IS_VALLEYVIEW(dev)) { + dev->driver->irq_handler = valleyview_irq_handler; + dev->driver->irq_preinstall = valleyview_irq_preinstall; + dev->driver->irq_postinstall = valleyview_irq_postinstall; + dev->driver->irq_uninstall = valleyview_irq_uninstall; + dev->driver->enable_vblank = valleyview_enable_vblank; + dev->driver->disable_vblank = valleyview_disable_vblank; + } else if (IS_IVYBRIDGE(dev)) { + /* Share pre & uninstall handlers with ILK/SNB */ + dev->driver->irq_handler = ivybridge_irq_handler; + dev->driver->irq_preinstall = ironlake_irq_preinstall; + dev->driver->irq_postinstall = ivybridge_irq_postinstall; + dev->driver->irq_uninstall = ironlake_irq_uninstall; + dev->driver->enable_vblank = ivybridge_enable_vblank; + dev->driver->disable_vblank = ivybridge_disable_vblank; + } else if (IS_HASWELL(dev)) { + /* Share interrupts handling with IVB */ + dev->driver->irq_handler = ivybridge_irq_handler; + dev->driver->irq_preinstall = ironlake_irq_preinstall; + dev->driver->irq_postinstall = ivybridge_irq_postinstall; + dev->driver->irq_uninstall = ironlake_irq_uninstall; + dev->driver->enable_vblank = ivybridge_enable_vblank; + dev->driver->disable_vblank = ivybridge_disable_vblank; + } else if (HAS_PCH_SPLIT(dev)) { + dev->driver->irq_handler = ironlake_irq_handler; + dev->driver->irq_preinstall = ironlake_irq_preinstall; + dev->driver->irq_postinstall = ironlake_irq_postinstall; + dev->driver->irq_uninstall = ironlake_irq_uninstall; + dev->driver->enable_vblank = ironlake_enable_vblank; + dev->driver->disable_vblank = ironlake_disable_vblank; + } else { + if (INTEL_INFO(dev)->gen == 2) { + dev->driver->irq_preinstall = i8xx_irq_preinstall; + dev->driver->irq_postinstall = i8xx_irq_postinstall; + dev->driver->irq_handler = i8xx_irq_handler; + dev->driver->irq_uninstall = i8xx_irq_uninstall; + } else if (INTEL_INFO(dev)->gen == 3) { + /* IIR "flip pending" means done if this bit is set */ + I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); + + dev->driver->irq_preinstall = i915_irq_preinstall; + dev->driver->irq_postinstall = i915_irq_postinstall; + dev->driver->irq_uninstall = i915_irq_uninstall; + dev->driver->irq_handler = i915_irq_handler; + } else { + dev->driver->irq_preinstall = i965_irq_preinstall; + dev->driver->irq_postinstall = i965_irq_postinstall; + dev->driver->irq_uninstall = i965_irq_uninstall; + dev->driver->irq_handler = i965_irq_handler; + } + dev->driver->enable_vblank = i915_enable_vblank; + dev->driver->disable_vblank = i915_disable_vblank; + } +} Index: intel_display.c =================================================================== --- intel_display.c (revision 287201) +++ intel_display.c (working copy) @@ -37,8 +37,6 @@ #include #include -#define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) - bool intel_pipe_has_type(struct drm_crtc *crtc, int type); static void intel_increase_pllclock(struct drm_crtc *crtc); static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); @@ -1174,6 +1172,24 @@ pipe_name(pipe)); } +static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, + enum pipe pipe, u32 port_sel, u32 val) +{ + if ((val & DP_PORT_EN) == 0) + return false; + + if (HAS_PCH_CPT(dev_priv->dev)) { + u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe); + u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg); + if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel) + return false; + } else { + if ((val & DP_PIPE_MASK) != (pipe << 30)) + return false; + } + return true; +} + static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv, enum pipe pipe, u32 val) { @@ -1221,24 +1237,6 @@ return true; } -static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe, u32 port_sel, u32 val) -{ - if ((val & DP_PORT_EN) == 0) - return false; - - if (HAS_PCH_CPT(dev_priv->dev)) { - u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe); - u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg); - if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel) - return false; - } else { - if ((val & DP_PIPE_MASK) != (pipe << 30)) - return false; - } - return true; -} - static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 port_sel) { @@ -1252,7 +1250,7 @@ enum pipe pipe, int reg) { u32 val = I915_READ(reg); - if (hdmi_pipe_enabled(dev_priv, val, pipe)) + if (hdmi_pipe_enabled(dev_priv, pipe, val)) printf("PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", reg, pipe_name(pipe)); } @@ -1269,13 +1267,13 @@ reg = PCH_ADPA; val = I915_READ(reg); - if (adpa_pipe_enabled(dev_priv, val, pipe)) + if (adpa_pipe_enabled(dev_priv, pipe, val)) printf("PCH VGA enabled on transcoder %c, should be disabled\n", pipe_name(pipe)); reg = PCH_LVDS; val = I915_READ(reg); - if (lvds_pipe_enabled(dev_priv, val, pipe)) + if (lvds_pipe_enabled(dev_priv, pipe, val)) printf("PCH LVDS enabled on transcoder %c, should be disabled\n", pipe_name(pipe)); @@ -1499,7 +1497,7 @@ /* Make sure transcoder isn't still depending on us */ assert_transcoder_disabled(dev_priv, intel_crtc->pipe); - + reg = pll->pll_reg; val = I915_READ(reg); val &= ~DPLL_VCO_ENABLE; @@ -1741,7 +1739,7 @@ enum pipe pipe, int reg) { u32 val = I915_READ(reg); - if (hdmi_pipe_enabled(dev_priv, val, pipe)) { + if (hdmi_pipe_enabled(dev_priv, pipe, val)) { DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", reg, pipe); I915_WRITE(reg, val & ~PORT_ENABLE); @@ -1763,12 +1761,12 @@ reg = PCH_ADPA; val = I915_READ(reg); - if (adpa_pipe_enabled(dev_priv, val, pipe)) + if (adpa_pipe_enabled(dev_priv, pipe, val)) I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); reg = PCH_LVDS; val = I915_READ(reg); - if (lvds_pipe_enabled(dev_priv, val, pipe)) { + if (lvds_pipe_enabled(dev_priv, pipe, val)) { DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); I915_WRITE(reg, val & ~LVDS_PORT_EN); POSTING_READ(reg); @@ -3060,7 +3058,8 @@ /* Enable panel fitting for LVDS */ if (dev_priv->pch_pf_size && - (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP)) { + (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { /* Force use of hard-coded filter coefficients * as some pre-programmed values are broken, * e.g. x201. @@ -4207,6 +4206,7 @@ /* We need to take the global config into account */ list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { + DRM_DEBUG_KMS("ici %d\n", encoder->type); switch (encoder->type) { case INTEL_OUTPUT_LVDS: has_panel = true; @@ -4219,6 +4219,9 @@ else has_cpu_edp = true; break; + default: + DRM_DEBUG_KMS("la\n"); + break; } } @@ -6577,7 +6580,7 @@ if (I915_READ(HDMIC) & PORT_DETECTED) intel_hdmi_init(dev, HDMIC); - if (I915_READ(HDMID) & PORT_DETECTED) + if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED) intel_hdmi_init(dev, HDMID); if (I915_READ(PCH_DP_C) & DP_DETECTED) @@ -6647,7 +6650,7 @@ /* disable all the possible outputs/crtcs before entering KMS mode */ drm_helper_disable_unused_functions(dev); - if (HAS_PCH_SPLIT(dev)) + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) ironlake_init_pch_refclk(dev); } @@ -6942,7 +6945,7 @@ #endif outb(VGA_SR_INDEX, SR01); sr1 = inb(VGA_SR_DATA); - outb(VGA_SR_DATA, sr1 | 1 << 5); + outb(VGA_SR_DATA, sr1 | 1<<5); #if 0 vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); #endif Index: intel_dp.c =================================================================== --- intel_dp.c (revision 287201) +++ intel_dp.c (working copy) @@ -379,7 +379,9 @@ * clock divider. */ if (is_cpu_edp(intel_dp)) { - if (IS_GEN6(dev) || IS_GEN7(dev)) + if (IS_VALLEYVIEW(dev)) + aux_clock_divider = 100; + else if (IS_GEN6(dev) || IS_GEN7(dev)) aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */ else aux_clock_divider = 225; /* eDP input clock at 450Mhz */ Index: intel_pm.c =================================================================== --- intel_pm.c (revision 287201) +++ intel_pm.c (working copy) @@ -3613,9 +3613,6 @@ } } -printf("XXXKIB HACK: HSW RC OFF\n"); - I915_WRITE(GEN6_RC_STATE, 0); - I915_WRITE(GEN6_RC_CONTROL, 0); DRM_UNLOCK(dev); }