int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) { struct drm_i915_private *dev_priv; struct i915_hw_ppgtt *ppgtt; u_int first_pd_entry_in_global_pt, i; dev_priv = dev->dev_private; /* * ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 * entries. For aliasing ppgtt support we just steal them at the end for * now. */ first_pd_entry_in_global_pt = 512 * 1024 - I915_PPGTT_PD_ENTRIES; ppgtt = malloc(sizeof(*ppgtt), DRM_I915_GEM, M_WAITOK | M_ZERO); ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; ppgtt->pt_pages = malloc(sizeof(vm_page_t) * ppgtt->num_pd_entries, DRM_I915_GEM, M_WAITOK | M_ZERO); for (i = 0; i < ppgtt->num_pd_entries; i++) { ppgtt->pt_pages[i] = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO); if (ppgtt->pt_pages[i] == NULL) { dev_priv->mm.aliasing_ppgtt = ppgtt; i915_gem_cleanup_aliasing_ppgtt(dev); return (-ENOMEM); } } ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt.scratch_page_dma; i915_ppgtt_clear_range(ppgtt, 0, ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES); ppgtt->pd_offset = (first_pd_entry_in_global_pt) * sizeof(uint32_t); dev_priv->mm.aliasing_ppgtt = ppgtt; return (0); }
/** * i915_reset - reset chip after a hang * @dev: drm device to reset * * 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) { drm_i915_private_t *dev_priv = dev->dev_private; bool simulated; int ret; if (!i915_try_reset) return 0; mutex_lock(&dev->struct_mutex); i915_gem_reset(dev); simulated = dev_priv->gpu_error.stop_rings != 0; if (!simulated && get_seconds() - dev_priv->gpu_error.last_reset < 5) { DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); ret = -ENODEV; } else { ret = intel_gpu_reset(dev); /* Also reset the gpu hangman. */ if (simulated) { DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); dev_priv->gpu_error.stop_rings = 0; if (ret == -ENODEV) { DRM_ERROR("Reset not implemented, but ignoring " "error for simulated gpu hangs\n"); ret = 0; } } else dev_priv->gpu_error.last_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->ums.mm_suspended) { struct intel_ring_buffer *ring; int i; dev_priv->ums.mm_suspended = 0; i915_gem_init_swizzling(dev); for_each_ring(ring, dev_priv, i) ring->init(ring); i915_gem_context_init(dev); if (dev_priv->mm.aliasing_ppgtt) { ret = dev_priv->mm.aliasing_ppgtt->enable(dev); if (ret) i915_gem_cleanup_aliasing_ppgtt(dev); } /* * It would make sense to re-init all the other hw state, at * least the rps/rc6/emon init done within modeset_init_hw. For * some unknown reason, this blows up my ilk, so don't. */ mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); drm_irq_install(dev); intel_hpd_init(dev); } else { mutex_unlock(&dev->struct_mutex); } return 0; }
int i915_load_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; ret = intel_parse_bios(dev); if (ret) DRM_INFO("failed to find VBIOS tables\n"); #if 0 intel_register_dsm_handler(); #endif /* IIR "flip pending" bit means done if this bit is set */ if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE)) dev_priv->flip_pending_is_done = true; #ifdef notyet ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops); if (ret) goto cleanup_vga_client; /* Initialise stolen first so that we may reserve preallocated * objects for the BIOS to KMS transition. */ ret = i915_gem_init_stolen(dev); if (ret) goto cleanup_vga_switcheroo; #endif intel_modeset_init(dev); ret = i915_gem_init(dev); if (ret) goto cleanup_gem_stolen; intel_modeset_gem_init(dev); ret = drm_irq_install(dev); if (ret) goto cleanup_gem; /* Always safe in the mode setting case. */ /* FIXME: do pre/post-mode set stuff in core KMS code */ dev->vblank_disable_allowed = 1; ret = intel_fbdev_init(dev); if (ret) goto cleanup_irq; drm_kms_helper_poll_init(dev); /* We're off and running w/KMS */ dev_priv->mm.suspended = 0; return (0); cleanup_irq: drm_irq_uninstall(dev); cleanup_gem: DRM_LOCK(); i915_gem_cleanup_ringbuffer(dev); DRM_UNLOCK(); i915_gem_cleanup_aliasing_ppgtt(dev); cleanup_gem_stolen: #ifdef notyet i915_gem_cleanup_stolen(dev); #endif return (ret); }