diff options
Diffstat (limited to 'kernel/drivers/gpu/drm/i915/i915_drv.c')
-rw-r--r-- | kernel/drivers/gpu/drm/i915/i915_drv.c | 252 |
1 files changed, 179 insertions, 73 deletions
diff --git a/kernel/drivers/gpu/drm/i915/i915_drv.c b/kernel/drivers/gpu/drm/i915/i915_drv.c index fb91df163..a6ad938f4 100644 --- a/kernel/drivers/gpu/drm/i915/i915_drv.c +++ b/kernel/drivers/gpu/drm/i915/i915_drv.c @@ -356,26 +356,39 @@ static const struct intel_device_info intel_cherryview_info = { }; static const struct intel_device_info intel_skylake_info = { - .is_preliminary = 1, .is_skylake = 1, .gen = 9, .num_pipes = 3, .need_gfx_hws = 1, .has_hotplug = 1, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, .has_llc = 1, .has_ddi = 1, + .has_fpga_dbg = 1, .has_fbc = 1, GEN_DEFAULT_PIPEOFFSETS, IVB_CURSOR_OFFSETS, }; static const struct intel_device_info intel_skylake_gt3_info = { - .is_preliminary = 1, .is_skylake = 1, .gen = 9, .num_pipes = 3, .need_gfx_hws = 1, .has_hotplug = 1, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, .has_llc = 1, .has_ddi = 1, + .has_fpga_dbg = 1, + .has_fbc = 1, + GEN_DEFAULT_PIPEOFFSETS, + IVB_CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_broxton_info = { + .is_preliminary = 1, + .gen = 9, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, + .num_pipes = 3, + .has_ddi = 1, + .has_fpga_dbg = 1, .has_fbc = 1, GEN_DEFAULT_PIPEOFFSETS, IVB_CURSOR_OFFSETS, @@ -420,16 +433,43 @@ static const struct intel_device_info intel_skylake_gt3_info = { INTEL_CHV_IDS(&intel_cherryview_info), \ INTEL_SKL_GT1_IDS(&intel_skylake_info), \ INTEL_SKL_GT2_IDS(&intel_skylake_info), \ - INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info) \ + INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info), \ + INTEL_BXT_IDS(&intel_broxton_info) static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_PCI_IDS, {0, 0, 0} }; -#if defined(CONFIG_DRM_I915_KMS) MODULE_DEVICE_TABLE(pci, pciidlist); -#endif + +static enum intel_pch intel_virt_detect_pch(struct drm_device *dev) +{ + enum intel_pch ret = PCH_NOP; + + /* + * In a virtualized passthrough environment we can be in a + * setup where the ISA bridge is not able to be passed through. + * In this case, a south bridge can be emulated and we have to + * make an educated guess as to which PCH is really there. + */ + + if (IS_GEN5(dev)) { + ret = PCH_IBX; + DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n"); + } else if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { + ret = PCH_CPT; + DRM_DEBUG_KMS("Assuming CouarPoint PCH\n"); + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + ret = PCH_LPT; + DRM_DEBUG_KMS("Assuming LynxPoint PCH\n"); + } else if (IS_SKYLAKE(dev)) { + ret = PCH_SPT; + DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n"); + } + + return ret; +} void intel_detect_pch(struct drm_device *dev) { @@ -491,6 +531,11 @@ void intel_detect_pch(struct drm_device *dev) dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); WARN_ON(!IS_SKYLAKE(dev)); + } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) || + ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) && + pch->subsystem_vendor == 0x1af4 && + pch->subsystem_device == 0x1100)) { + dev_priv->pch_type = intel_virt_detect_pch(dev); } else continue; @@ -528,19 +573,24 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return true; } -void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) +void i915_firmware_load_error_print(const char *fw_path, int err) { - spin_lock_irq(&dev_priv->irq_lock); + DRM_ERROR("failed to load firmware %s (%d)\n", fw_path, err); - dev_priv->long_hpd_port_mask = 0; - dev_priv->short_hpd_port_mask = 0; - dev_priv->hpd_event_bits = 0; + /* + * If the reason is not known assume -ENOENT since that's the most + * usual failure mode. + */ + if (!err) + err = -ENOENT; - spin_unlock_irq(&dev_priv->irq_lock); + if (!(IS_BUILTIN(CONFIG_DRM_I915) && err == -ENOENT)) + return; - cancel_work_sync(&dev_priv->dig_port_work); - cancel_work_sync(&dev_priv->hotplug_work); - cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work); + DRM_ERROR( + "The driver is built-in, so to load the firmware you need to\n" + "include it either in the kernel (see CONFIG_EXTRA_FIRMWARE) or\n" + "in your initrd/initramfs image.\n"); } static void intel_suspend_encoders(struct drm_i915_private *dev_priv) @@ -561,11 +611,13 @@ static void intel_suspend_encoders(struct drm_i915_private *dev_priv) static int intel_suspend_complete(struct drm_i915_private *dev_priv); static int vlv_resume_prepare(struct drm_i915_private *dev_priv, bool rpm_resume); +static int skl_resume_prepare(struct drm_i915_private *dev_priv); +static int bxt_resume_prepare(struct drm_i915_private *dev_priv); + static int i915_drm_suspend(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; pci_power_t opregion_target_state; int error; @@ -589,6 +641,8 @@ static int i915_drm_suspend(struct drm_device *dev) return error; } + intel_guc_suspend(dev); + intel_suspend_gt_powersave(dev); /* @@ -596,8 +650,7 @@ static int i915_drm_suspend(struct drm_device *dev) * for _thaw. Also, power gate the CRTC power wells. */ drm_modeset_lock_all(dev); - for_each_crtc(dev, crtc) - intel_crtc_control(crtc, false); + intel_display_suspend(dev); drm_modeset_unlock_all(dev); intel_dp_mst_suspend(dev); @@ -664,7 +717,7 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation) return 0; } -int i915_suspend_legacy(struct drm_device *dev, pm_message_t state) +int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state) { int error; @@ -715,10 +768,12 @@ static int i915_drm_resume(struct drm_device *dev) mutex_lock(&dev->struct_mutex); if (i915_gem_init_hw(dev)) { DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); - atomic_set_mask(I915_WEDGED, &dev_priv->gpu_error.reset_counter); + atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter); } mutex_unlock(&dev->struct_mutex); + intel_guc_resume(dev); + intel_modeset_init_hw(dev); spin_lock_irq(&dev_priv->irq_lock); @@ -727,7 +782,7 @@ static int i915_drm_resume(struct drm_device *dev) spin_unlock_irq(&dev_priv->irq_lock); drm_modeset_lock_all(dev); - intel_modeset_setup_hw_state(dev, true); + intel_display_resume(dev); drm_modeset_unlock_all(dev); intel_dp_mst_resume(dev); @@ -779,11 +834,16 @@ static int i915_drm_resume_early(struct drm_device *dev) if (IS_VALLEYVIEW(dev_priv)) ret = vlv_resume_prepare(dev_priv, false); if (ret) - DRM_ERROR("Resume prepare failed: %d,Continuing resume\n", ret); + DRM_ERROR("Resume prepare failed: %d, continuing anyway\n", + ret); intel_uncore_early_sanitize(dev, true); - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + if (IS_BROXTON(dev)) + ret = bxt_resume_prepare(dev_priv); + else if (IS_SKYLAKE(dev_priv)) + ret = skl_resume_prepare(dev_priv); + else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) hsw_disable_pc8(dev_priv); intel_uncore_sanitize(dev); @@ -792,7 +852,7 @@ static int i915_drm_resume_early(struct drm_device *dev) return ret; } -int i915_resume_legacy(struct drm_device *dev) +int i915_resume_switcheroo(struct drm_device *dev) { int ret; @@ -827,9 +887,6 @@ int i915_reset(struct drm_device *dev) bool simulated; int ret; - if (!i915.reset) - return 0; - intel_reset_gt_powersave(dev); mutex_lock(&dev->struct_mutex); @@ -921,8 +978,6 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (PCI_FUNC(pdev->devfn)) return -ENODEV; - driver.driver_features &= ~(DRIVER_USE_AGP); - return drm_get_pci_dev(pdev, ent, &driver); } @@ -955,7 +1010,7 @@ static int i915_pm_suspend_late(struct device *dev) struct drm_device *drm_dev = dev_to_i915(dev)->dev; /* - * We have a suspedn ordering issue with the snd-hda driver also + * We have a suspend ordering issue with the snd-hda driver also * requiring our device to be power up. Due to the lack of a * parent/child relationship we currently solve this with an late * suspend hook. @@ -999,6 +1054,15 @@ static int i915_pm_resume(struct device *dev) return i915_drm_resume(drm_dev); } +static int skl_suspend_complete(struct drm_i915_private *dev_priv) +{ + /* Enabling DC6 is not a hard requirement to enter runtime D3 */ + + skl_uninit_cdclk(dev_priv); + + return 0; +} + static int hsw_suspend_complete(struct drm_i915_private *dev_priv) { hsw_enable_pc8(dev_priv); @@ -1006,6 +1070,48 @@ static int hsw_suspend_complete(struct drm_i915_private *dev_priv) return 0; } +static int bxt_suspend_complete(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + /* TODO: when DC5 support is added disable DC5 here. */ + + broxton_ddi_phy_uninit(dev); + broxton_uninit_cdclk(dev); + bxt_enable_dc9(dev_priv); + + return 0; +} + +static int bxt_resume_prepare(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + /* TODO: when CSR FW support is added make sure the FW is loaded */ + + bxt_disable_dc9(dev_priv); + + /* + * TODO: when DC5 support is added enable DC5 here if the CSR FW + * is available. + */ + broxton_init_cdclk(dev); + broxton_ddi_phy_init(dev); + intel_prepare_ddi(dev); + + return 0; +} + +static int skl_resume_prepare(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + skl_init_cdclk(dev_priv); + intel_csr_load_program(dev); + + return 0; +} + /* * Save all Gunit registers that may be lost after a D3 and a subsequent * S0i[R123] transition. The list of registers needing a save/restore is @@ -1045,7 +1151,7 @@ static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv) s->gfx_pend_tlb1 = I915_READ(GEN7_GFX_PEND_TLB1); for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++) - s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS_BASE + i * 4); + s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS(i)); s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); s->gfx_max_req_count = I915_READ(GEN7_GFX_MAX_REQ_COUNT); @@ -1089,7 +1195,7 @@ static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv) s->pm_ier = I915_READ(GEN6_PMIER); for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++) - s->gt_scratch[i] = I915_READ(GEN7_GT_SCRATCH_BASE + i * 4); + s->gt_scratch[i] = I915_READ(GEN7_GT_SCRATCH(i)); /* GT SA CZ domain, 0x100000-0x138124 */ s->tilectl = I915_READ(TILECTL); @@ -1127,7 +1233,7 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv) I915_WRITE(GEN7_GFX_PEND_TLB1, s->gfx_pend_tlb1); for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++) - I915_WRITE(GEN7_LRA_LIMITS_BASE + i * 4, s->lra_limits[i]); + I915_WRITE(GEN7_LRA_LIMITS(i), s->lra_limits[i]); I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count); I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count); @@ -1171,7 +1277,7 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_PMIER, s->pm_ier); for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++) - I915_WRITE(GEN7_GT_SCRATCH_BASE + i * 4, s->gt_scratch[i]); + I915_WRITE(GEN7_GT_SCRATCH(i), s->gt_scratch[i]); /* GT SA CZ domain, 0x100000-0x138124 */ I915_WRITE(TILECTL, s->tilectl); @@ -1401,6 +1507,8 @@ static int intel_runtime_suspend(struct device *device) i915_gem_release_all_mmaps(dev_priv); mutex_unlock(&dev->struct_mutex); + intel_guc_suspend(dev); + intel_suspend_gt_powersave(dev); intel_runtime_pm_disable_interrupts(dev_priv); @@ -1420,7 +1528,15 @@ static int intel_runtime_suspend(struct device *device) * FIXME: We really should find a document that references the arguments * used below! */ - if (IS_HASWELL(dev)) { + if (IS_BROADWELL(dev)) { + /* + * On Broadwell, if we use PCI_D1 the PCH DDI ports will stop + * being detected, and the call we do at intel_runtime_resume() + * won't be able to restore them. Since PCI_D3hot matches the + * actual specification and appears to be working, use it. + */ + intel_opregion_notify_adapter(dev, PCI_D3hot); + } else { /* * current versions of firmware which depend on this opregion * notification have repurposed the D1 definition to mean @@ -1429,16 +1545,6 @@ static int intel_runtime_suspend(struct device *device) * the suspend path. */ intel_opregion_notify_adapter(dev, PCI_D1); - } else { - /* - * On Broadwell, if we use PCI_D1 the PCH DDI ports will stop - * being detected, and the call we do at intel_runtime_resume() - * won't be able to restore them. Since PCI_D3hot matches the - * actual specification and appears to be working, use it. Let's - * assume the other non-Haswell platforms will stay the same as - * Broadwell. - */ - intel_opregion_notify_adapter(dev, PCI_D3hot); } assert_forcewakes_inactive(dev_priv); @@ -1462,8 +1568,15 @@ static int intel_runtime_resume(struct device *device) intel_opregion_notify_adapter(dev, PCI_D0); dev_priv->pm.suspended = false; + intel_guc_resume(dev); + if (IS_GEN6(dev_priv)) intel_init_pch_refclk(dev); + + if (IS_BROXTON(dev)) + ret = bxt_resume_prepare(dev_priv); + else if (IS_SKYLAKE(dev)) + ret = skl_resume_prepare(dev_priv); else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) hsw_disable_pc8(dev_priv); else if (IS_VALLEYVIEW(dev_priv)) @@ -1477,6 +1590,15 @@ static int intel_runtime_resume(struct device *device) gen6_update_ring_freq(dev); intel_runtime_pm_enable_interrupts(dev_priv); + + /* + * On VLV/CHV display interrupts are part of the display + * power well, so hpd is reinitialized from there. For + * everyone else do it here. + */ + if (!IS_VALLEYVIEW(dev_priv)) + intel_hpd_init(dev_priv); + intel_enable_gt_powersave(dev); if (ret) @@ -1493,12 +1615,15 @@ static int intel_runtime_resume(struct device *device) */ static int intel_suspend_complete(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; int ret; - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + if (IS_BROXTON(dev_priv)) + ret = bxt_suspend_complete(dev_priv); + else if (IS_SKYLAKE(dev_priv)) + ret = skl_suspend_complete(dev_priv); + else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) ret = hsw_suspend_complete(dev_priv); - else if (IS_VALLEYVIEW(dev)) + else if (IS_VALLEYVIEW(dev_priv)) ret = vlv_suspend_complete(dev_priv); else ret = 0; @@ -1570,9 +1695,8 @@ static struct drm_driver driver = { * deal with them for Intel hardware. */ .driver_features = - DRIVER_USE_AGP | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | - DRIVER_RENDER, + DRIVER_RENDER | DRIVER_MODESET, .load = i915_driver_load, .unload = i915_driver_unload, .open = i915_driver_open, @@ -1581,11 +1705,6 @@ static struct drm_driver driver = { .postclose = i915_driver_postclose, .set_busid = drm_pci_set_busid, - /* Used in place of i915_pm_ops for non-DRIVER_MODESET */ - .suspend = i915_suspend_legacy, - .resume = i915_resume_legacy, - - .device_is_agp = i915_driver_device_is_agp, #if defined(CONFIG_DEBUG_FS) .debugfs_init = i915_debugfs_init, .debugfs_cleanup = i915_debugfs_cleanup, @@ -1624,20 +1743,13 @@ static int __init i915_init(void) driver.num_ioctls = i915_max_ioctl; /* - * If CONFIG_DRM_I915_KMS is set, default to KMS unless - * explicitly disabled with the module pararmeter. - * - * Otherwise, just follow the parameter (defaulting to off). - * - * Allow optional vga_text_mode_force boot option to override - * the default behavior. + * Enable KMS by default, unless explicitly overriden by + * either the i915.modeset prarameter or by the + * vga_text_mode_force boot option. */ -#if defined(CONFIG_DRM_I915_KMS) - if (i915.modeset != 0) - driver.driver_features |= DRIVER_MODESET; -#endif - if (i915.modeset == 1) - driver.driver_features |= DRIVER_MODESET; + + if (i915.modeset == 0) + driver.driver_features &= ~DRIVER_MODESET; #ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && i915.modeset == -1) @@ -1645,17 +1757,11 @@ static int __init i915_init(void) #endif if (!(driver.driver_features & DRIVER_MODESET)) { - driver.get_vblank_timestamp = NULL; /* Silently fail loading to not upset userspace. */ DRM_DEBUG_DRIVER("KMS and UMS disabled.\n"); return 0; } - /* - * FIXME: Note that we're lying to the DRM core here so that we can get access - * to the atomic ioctl and the atomic properties. Only plane operations on - * a single CRTC will actually work. - */ if (i915.nuclear_pageflip) driver.driver_features |= DRIVER_ATOMIC; |