static int i915_resume(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret = 0; pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); if (pci_enable_device(dev->pdev)) return -1; pci_set_master(dev->pdev); i915_restore_state(dev); intel_opregion_init(dev, 1); /* KMS EnterVT equivalent */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { mutex_lock(&dev->struct_mutex); dev_priv->mm.suspended = 0; ret = i915_gem_init_ringbuffer(dev); if (ret != 0) ret = -1; mutex_unlock(&dev->struct_mutex); drm_irq_install(dev); } if (drm_core_check_feature(dev, DRIVER_MODESET)) { /* Resume the modeset for every activated CRTC */ drm_helper_resume_force_mode(dev); } return ret; }
static int i915_drm_thaw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int error = 0; i915_restore_state(dev); intel_opregion_init(dev, 1); /* KMS EnterVT equivalent */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { mutex_lock(&dev->struct_mutex); dev_priv->mm.suspended = 0; error = i915_gem_init_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); drm_irq_install(dev); /* Resume the modeset for every activated CRTC */ drm_helper_resume_force_mode(dev); } dev_priv->modeset_on_lid = 0; return error; }
static int vbox_drm_thaw(struct drm_device *dev) { struct vbox_private *vbox = dev->dev_private; drm_mode_config_reset(dev); drm_helper_resume_force_mode(dev); drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, false); return 0; }
static int vbox_drm_thaw(struct drm_device *dev) { int error = 0; drm_mode_config_reset(dev); drm_helper_resume_force_mode(dev); console_lock(); vbox_fbdev_set_suspend(dev, 0); console_unlock(); return error; }
static int bochs_pm_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct bochs_device *bochs = drm_dev->dev_private; drm_helper_resume_force_mode(drm_dev); drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 0); drm_kms_helper_poll_enable(drm_dev); return 0; }
static int ast_drm_thaw(struct drm_device *dev) { int error = 0; ast_post_gpu(dev); drm_mode_config_reset(dev); drm_modeset_lock_all(dev); drm_helper_resume_force_mode(dev); drm_modeset_unlock_all(dev); console_lock(); ast_fbdev_set_suspend(dev, 0); console_unlock(); return error; }
static int cirrus_pm_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct cirrus_device *cdev = drm_dev->dev_private; drm_helper_resume_force_mode(drm_dev); if (cdev->mode_info.gfbdev) { console_lock(); fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0); console_unlock(); } drm_kms_helper_poll_enable(drm_dev); return 0; }
static int i915_drm_thaw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int error = 0; if (drm_core_check_feature(dev, DRIVER_MODESET)) { mutex_lock(&dev->struct_mutex); i915_gem_restore_gtt_mappings(dev); mutex_unlock(&dev->struct_mutex); } i915_restore_state(dev); intel_opregion_setup(dev); /* KMS EnterVT equivalent */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { mutex_lock(&dev->struct_mutex); dev_priv->mm.suspended = 0; error = i915_gem_init_hw(dev); mutex_unlock(&dev->struct_mutex); if (HAS_PCH_SPLIT(dev)) ironlake_init_pch_refclk(dev); drm_mode_config_reset(dev); drm_irq_install(dev); /* Resume the modeset for every activated CRTC */ mutex_lock(&dev->mode_config.mutex); drm_helper_resume_force_mode(dev); mutex_unlock(&dev->mode_config.mutex); if (IS_IRONLAKE_M(dev)) ironlake_enable_rc6(dev); } intel_opregion_init(dev); dev_priv->modeset_on_lid = 0; console_lock(); intel_fbdev_set_suspend(dev, 0); console_unlock(); return error; }
static int bochs_pm_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct bochs_device *bochs = drm_dev->dev_private; drm_helper_resume_force_mode(drm_dev); if (bochs->fb.initialized) { console_lock(); fb_set_suspend(bochs->fb.helper.fbdev, 0); console_unlock(); } drm_kms_helper_poll_enable(drm_dev); return 0; }
static int i915_drm_thaw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int error = 0; DRM_LOCK(dev); if (drm_core_check_feature(dev, DRIVER_MODESET)) { i915_gem_restore_gtt_mappings(dev); } i915_restore_state(dev); intel_opregion_setup(dev); /* KMS EnterVT equivalent */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { dev_priv->mm.suspended = 0; error = i915_gem_init_hw(dev); if (HAS_PCH_SPLIT(dev)) ironlake_init_pch_refclk(dev); DRM_UNLOCK(dev); lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE); drm_mode_config_reset(dev); lockmgr(&dev->mode_config.mutex, LK_RELEASE); drm_irq_install(dev); lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE); /* Resume the modeset for every activated CRTC */ drm_helper_resume_force_mode(dev); lockmgr(&dev->mode_config.mutex, LK_RELEASE); if (IS_IRONLAKE_M(dev)) ironlake_enable_rc6(dev); DRM_LOCK(dev); } intel_opregion_init(dev); dev_priv->modeset_on_lid = 0; DRM_UNLOCK(dev); return error; }
/** * i965_reset - reset chip after a hang * @dev: drm device to reset * @flags: reset domains * * Reset the chip. Useful if a hang is detected. Returns zero on successful * reset or otherwise an error code. * * Procedure is fairly simple: * - reset the chip using the reset reg * - re-init context state * - re-init hardware status page * - re-init ring buffer * - re-init interrupt state * - re-init display */ int i915_reset(struct drm_device *dev, u8 flags) { drm_i915_private_t *dev_priv = dev->dev_private; /* * We really should only reset the display subsystem if we actually * need to */ bool need_display = true; int ret; if (!i915_try_reset) return 0; if (!mutex_trylock(&dev->struct_mutex)) return -EBUSY; i915_gem_reset(dev); ret = -ENODEV; if (get_seconds() - dev_priv->last_gpu_reset < 5) { DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); } else switch (INTEL_INFO(dev)->gen) { case 7: case 6: ret = gen6_do_reset(dev, flags); break; case 5: ret = ironlake_do_reset(dev, flags); break; case 4: ret = i965_do_reset(dev, flags); break; case 2: ret = i8xx_do_reset(dev, flags); break; } dev_priv->last_gpu_reset = get_seconds(); if (ret) { DRM_ERROR("Failed to reset chip.\n"); mutex_unlock(&dev->struct_mutex); return ret; } /* Ok, now get things going again... */ /* * Everything depends on having the GTT running, so we need to start * there. Fortunately we don't need to do this unless we reset the * chip at a PCI level. * * Next we need to restore the context, but we don't use those * yet either... * * Ring buffer needs to be re-initialized in the KMS case, or if X * was running at the time of the reset (i.e. we weren't VT * switched away). */ if (drm_core_check_feature(dev, DRIVER_MODESET) || !dev_priv->mm.suspended) { dev_priv->mm.suspended = 0; dev_priv->ring[RCS].init(&dev_priv->ring[RCS]); if (HAS_BSD(dev)) dev_priv->ring[VCS].init(&dev_priv->ring[VCS]); if (HAS_BLT(dev)) dev_priv->ring[BCS].init(&dev_priv->ring[BCS]); mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); drm_mode_config_reset(dev); drm_irq_install(dev); mutex_lock(&dev->struct_mutex); } mutex_unlock(&dev->struct_mutex); /* * Perform a full modeset as on later generations, e.g. Ironlake, we may * need to retrain the display link and cannot just restore the register * values. */ if (need_display) { mutex_lock(&dev->mode_config.mutex); drm_helper_resume_force_mode(dev); mutex_unlock(&dev->mode_config.mutex); } return 0; }
int evdi_painter_connect(struct evdi_device *evdi, void const __user *edid_data, unsigned int edid_length, struct drm_file *file, int dev_index) { struct evdi_painter *painter = evdi->painter; struct edid *new_edid = NULL; int expected_edid_size = 0; EVDI_CHECKPT(); if (edid_length < sizeof(struct edid)) { EVDI_ERROR("Edid length too small\n"); return -EINVAL; } if (edid_length > MAX_EDID_SIZE) { EVDI_ERROR("Edid length too large\n"); return -EINVAL; } new_edid = kzalloc(edid_length, GFP_KERNEL); if (!new_edid) return -ENOMEM; if (copy_from_user(new_edid, edid_data, edid_length)) { EVDI_ERROR("(dev=%d) LSP Failed to read edid\n", dev_index); kfree(new_edid); return -EFAULT; } expected_edid_size = sizeof(struct edid) + new_edid->extensions * EDID_EXT_BLOCK_SIZE; if (expected_edid_size != edid_length) { EVDI_ERROR("Wrong edid size. Expected %d but is %d\n", expected_edid_size, edid_length); kfree(new_edid); return -EINVAL; } if (painter->drm_filp) EVDI_WARN("(dev=%d) Double connect - replacing %p with %p\n", dev_index, painter->drm_filp, file); EVDI_DEBUG("(dev=%d) Connected with %p\n", evdi->dev_index, painter->drm_filp); painter_lock(painter); evdi->dev_index = dev_index; painter->drm_filp = file; kfree(painter->edid); painter->edid_length = edid_length; painter->edid = new_edid; painter->is_connected = true; painter_unlock(painter); drm_helper_hpd_irq_event(evdi->ddev); drm_helper_resume_force_mode(evdi->ddev); return 0; }
int i915_reset(struct drm_device *dev, u8 flags) { drm_i915_private_t *dev_priv = dev->dev_private; bool need_display = true; int ret; if (!i915_try_reset) return 0; if (!mutex_trylock(&dev->struct_mutex)) return -EBUSY; i915_gem_reset(dev); ret = -ENODEV; if (get_seconds() - dev_priv->last_gpu_reset < 5) { DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); } else switch (INTEL_INFO(dev)->gen) { case 7: case 6: ret = gen6_do_reset(dev, flags); break; case 5: ret = ironlake_do_reset(dev, flags); break; case 4: ret = i965_do_reset(dev, flags); break; case 2: ret = i8xx_do_reset(dev, flags); break; } dev_priv->last_gpu_reset = get_seconds(); if (ret) { DRM_ERROR("Failed to reset chip.\n"); mutex_unlock(&dev->struct_mutex); return ret; } if (drm_core_check_feature(dev, DRIVER_MODESET) || !dev_priv->mm.suspended) { dev_priv->mm.suspended = 0; i915_gem_init_swizzling(dev); dev_priv->ring[RCS].init(&dev_priv->ring[RCS]); if (HAS_BSD(dev)) dev_priv->ring[VCS].init(&dev_priv->ring[VCS]); if (HAS_BLT(dev)) dev_priv->ring[BCS].init(&dev_priv->ring[BCS]); i915_gem_init_ppgtt(dev); mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); drm_mode_config_reset(dev); drm_irq_install(dev); mutex_lock(&dev->struct_mutex); } mutex_unlock(&dev->struct_mutex); if (need_display) { mutex_lock(&dev->mode_config.mutex); drm_helper_resume_force_mode(dev); mutex_unlock(&dev->mode_config.mutex); } return 0; }
int i915_reset(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; /* * We really should only reset the display subsystem if we actually * need to */ bool need_display = true; int ret; if (!i915_try_reset) return (0); if (!sx_try_xlock(&dev->dev_struct_lock)) return (-EBUSY); i915_gem_reset(dev); ret = -ENODEV; if (time_second - dev_priv->last_gpu_reset < 5) { DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); } else ret = intel_gpu_reset(dev); dev_priv->last_gpu_reset = time_second; if (ret) { DRM_ERROR("Failed to reset chip.\n"); DRM_UNLOCK(dev); return (ret); } if (drm_core_check_feature(dev, DRIVER_MODESET) || !dev_priv->mm.suspended) { dev_priv->mm.suspended = 0; i915_gem_init_swizzling(dev); dev_priv->rings[RCS].init(&dev_priv->rings[RCS]); if (HAS_BSD(dev)) dev_priv->rings[VCS].init(&dev_priv->rings[VCS]); if (HAS_BLT(dev)) dev_priv->rings[BCS].init(&dev_priv->rings[BCS]); i915_gem_context_init(dev); i915_gem_init_ppgtt(dev); drm_irq_uninstall(dev); drm_mode_config_reset(dev); DRM_UNLOCK(dev); drm_irq_install(dev); DRM_LOCK(dev); } DRM_UNLOCK(dev); if (need_display) { sx_xlock(&dev->mode_config.mutex); drm_helper_resume_force_mode(dev); sx_xunlock(&dev->mode_config.mutex); } return (0); }
/** * cdv_restore_display_registers - restore lost register state * @dev: our DRM device * * Restore register state that was lost during suspend and resume. * * FIXME: review */ static int cdv_restore_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct psb_save_area *regs = &dev_priv->regs; struct drm_connector *connector; u32 temp; pci_write_config_byte(dev->pdev, 0xF4, regs->cdv.saveLBB); REG_WRITE(DSPCLK_GATE_D, regs->cdv.saveDSPCLK_GATE_D); REG_WRITE(RAMCLK_GATE_D, regs->cdv.saveRAMCLK_GATE_D); /* BIOS does below anyway */ REG_WRITE(DPIO_CFG, 0); REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N); temp = REG_READ(DPLL_A); if ((temp & DPLL_SYNCLOCK_ENABLE) == 0) { REG_WRITE(DPLL_A, temp | DPLL_SYNCLOCK_ENABLE); REG_READ(DPLL_A); } temp = REG_READ(DPLL_B); if ((temp & DPLL_SYNCLOCK_ENABLE) == 0) { REG_WRITE(DPLL_B, temp | DPLL_SYNCLOCK_ENABLE); REG_READ(DPLL_B); } udelay(500); REG_WRITE(DSPFW1, regs->cdv.saveDSPFW[0]); REG_WRITE(DSPFW2, regs->cdv.saveDSPFW[1]); REG_WRITE(DSPFW3, regs->cdv.saveDSPFW[2]); REG_WRITE(DSPFW4, regs->cdv.saveDSPFW[3]); REG_WRITE(DSPFW5, regs->cdv.saveDSPFW[4]); REG_WRITE(DSPFW6, regs->cdv.saveDSPFW[5]); REG_WRITE(DSPARB, regs->cdv.saveDSPARB); REG_WRITE(ADPA, regs->cdv.saveADPA); REG_WRITE(BLC_PWM_CTL2, regs->saveBLC_PWM_CTL2); REG_WRITE(LVDS, regs->cdv.saveLVDS); REG_WRITE(PFIT_CONTROL, regs->cdv.savePFIT_CONTROL); REG_WRITE(PFIT_PGM_RATIOS, regs->cdv.savePFIT_PGM_RATIOS); REG_WRITE(BLC_PWM_CTL, regs->saveBLC_PWM_CTL); REG_WRITE(PP_ON_DELAYS, regs->cdv.savePP_ON_DELAYS); REG_WRITE(PP_OFF_DELAYS, regs->cdv.savePP_OFF_DELAYS); REG_WRITE(PP_CYCLE, regs->cdv.savePP_CYCLE); REG_WRITE(PP_CONTROL, regs->cdv.savePP_CONTROL); REG_WRITE(VGACNTRL, regs->cdv.saveVGACNTRL); REG_WRITE(PSB_INT_ENABLE_R, regs->cdv.saveIER); REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR); /* Fix arbitration bug */ cdv_errata(dev); drm_mode_config_reset(dev); list_for_each_entry(connector, &dev->mode_config.connector_list, head) connector->funcs->dpms(connector, DRM_MODE_DPMS_ON); /* Resume the modeset for every activated CRTC */ drm_helper_resume_force_mode(dev); return 0; }
int i915_restore_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int i; pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); /* Render Standby */ if (IS_I965G(dev) && IS_MOBILE(dev)) I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); /* Hardware status page */ I915_WRITE(HWS_PGA, dev_priv->saveHWS); /* Display arbitration */ I915_WRITE(DSPARB, dev_priv->saveDSPARB); /* Fences */ if (IS_I965G(dev)) { for (i = 0; i < 16; i++) I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); } else { for (i = 0; i < 8; i++) I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) for (i = 0; i < 8; i++) I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); } /* Display port ratios (must be done before clock is set) */ if (SUPPORTS_INTEGRATED_DP(dev)) { I915_WRITE(PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); I915_WRITE(PIPEB_GMCH_DATA_M, dev_priv->savePIPEB_GMCH_DATA_M); I915_WRITE(PIPEA_GMCH_DATA_N, dev_priv->savePIPEA_GMCH_DATA_N); I915_WRITE(PIPEB_GMCH_DATA_N, dev_priv->savePIPEB_GMCH_DATA_N); I915_WRITE(PIPEA_DP_LINK_M, dev_priv->savePIPEA_DP_LINK_M); I915_WRITE(PIPEB_DP_LINK_M, dev_priv->savePIPEB_DP_LINK_M); I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); } /* This is only meaningful in non-KMS mode */ /* Don't restore them in KMS mode */ i915_restore_modeset_reg(dev); /* Cursor state */ I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); I915_WRITE(CURABASE, dev_priv->saveCURABASE); I915_WRITE(CURBPOS, dev_priv->saveCURBPOS); I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR); I915_WRITE(CURBBASE, dev_priv->saveCURBBASE); if (!IS_I9XX(dev)) I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); /* CRT state */ I915_WRITE(ADPA, dev_priv->saveADPA); /* LVDS state */ if (IS_I965G(dev)) I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); if (IS_MOBILE(dev) && !IS_I830(dev)) I915_WRITE(LVDS, dev_priv->saveLVDS); if (!IS_I830(dev) && !IS_845G(dev)) I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); /* Display Port state */ if (SUPPORTS_INTEGRATED_DP(dev)) { I915_WRITE(DP_B, dev_priv->saveDP_B); I915_WRITE(DP_C, dev_priv->saveDP_C); I915_WRITE(DP_D, dev_priv->saveDP_D); } /* FIXME: restore TV & SDVO state */ /* FBC info */ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); /* VGA state */ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); I915_WRITE(VGA0, dev_priv->saveVGA0); I915_WRITE(VGA1, dev_priv->saveVGA1); I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); DRM_UDELAY(150); /* Clock gating state */ I915_WRITE (D_STATE, dev_priv->saveD_STATE); I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); /* Cache mode state */ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); /* Memory arbitration state */ I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); for (i = 0; i < 16; i++) { I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i]); } for (i = 0; i < 3; i++) I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); i915_restore_vga(dev); if (drm_core_check_feature(dev, DRIVER_MODESET)) drm_helper_resume_force_mode(dev); return 0; }