summaryrefslogtreecommitdiffstats
path: root/sys/dev/drm2/i915/i915_drv.c
diff options
context:
space:
mode:
authordumbbell <dumbbell@FreeBSD.org>2014-09-18 20:32:40 +0000
committerdumbbell <dumbbell@FreeBSD.org>2014-09-18 20:32:40 +0000
commit58c7b08e2c4aed89b10a0d653f44f4fbbe29b2e8 (patch)
treecdf88fb9a0878567c28758edb9026a9b08489559 /sys/dev/drm2/i915/i915_drv.c
parent98e396e70c506053493336e4b4d4258832b1e3f5 (diff)
downloadFreeBSD-src-58c7b08e2c4aed89b10a0d653f44f4fbbe29b2e8.zip
FreeBSD-src-58c7b08e2c4aed89b10a0d653f44f4fbbe29b2e8.tar.gz
drm/i915: Add HW context support
This feature is required by Mesa 9.2+. Without this, a GL application crashes with the following message: # glxinfo name of display: :0.0 Gen6+ requires Kernel 3.6 or later. Assertion failed: (ctx->Version > 0), function handle_first_current, file ../../src/mesa/main/context.c, line 1498. Abort (core dumped) Now, Mesa 10.2.4 and 10.3-rc3 works fine: # glxinfo name of display: :0 display: :0 screen: 0 direct rendering: Yes ... OpenGL renderer string: Mesa DRI Intel(R) 965GM OpenGL version string: 2.1 Mesa 10.2.4 ... The code was imported from Linux 3.8.13. This an MFC of r271705. Approved by: re (glebius) Reviewed by: kib@ Tested by: kwm@, danfe@, Henry Hu, Lundberg, Johannes <johannes@brilliantservice.co.jp>, Johannes Dieterich <dieterich.joh@gmail.com>, Lutz Bichler <lutz.bichler@gmail.com>, Relnotes: yes
Diffstat (limited to 'sys/dev/drm2/i915/i915_drv.c')
-rw-r--r--sys/dev/drm2/i915/i915_drv.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/sys/dev/drm2/i915/i915_drv.c b/sys/dev/drm2/i915/i915_drv.c
index 85ac10e..2380d23 100644
--- a/sys/dev/drm2/i915/i915_drv.c
+++ b/sys/dev/drm2/i915/i915_drv.c
@@ -612,7 +612,7 @@ __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
}
static int
-i8xx_do_reset(struct drm_device *dev, u8 flags)
+i8xx_do_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int onems;
@@ -657,7 +657,7 @@ i965_reset_complete(struct drm_device *dev)
}
static int
-i965_do_reset(struct drm_device *dev, u8 flags)
+i965_do_reset(struct drm_device *dev)
{
u8 gdrst;
@@ -667,28 +667,30 @@ i965_do_reset(struct drm_device *dev, u8 flags)
* triggers the reset; when done, the hardware will clear it.
*/
gdrst = pci_read_config(dev->device, I965_GDRST, 1);
- pci_write_config(dev->device, I965_GDRST, gdrst | flags | 0x1, 1);
+ pci_write_config(dev->device, I965_GDRST,
+ gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE, 1);
return (_intel_wait_for(dev, i965_reset_complete(dev), 500, 1,
"915rst"));
}
static int
-ironlake_do_reset(struct drm_device *dev, u8 flags)
+ironlake_do_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv;
u32 gdrst;
dev_priv = dev->dev_private;
gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
- I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, gdrst | flags | 0x1);
+ I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
+ gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE);
return (_intel_wait_for(dev,
(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1) != 0,
500, 1, "915rst"));
}
static int
-gen6_do_reset(struct drm_device *dev, u8 flags)
+gen6_do_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv;
int ret;
@@ -726,8 +728,43 @@ gen6_do_reset(struct drm_device *dev, u8 flags)
return (ret);
}
+int intel_gpu_reset(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret = -ENODEV;
+
+ switch (INTEL_INFO(dev)->gen) {
+ case 7:
+ case 6:
+ ret = gen6_do_reset(dev);
+ break;
+ case 5:
+ ret = ironlake_do_reset(dev);
+ break;
+ case 4:
+ ret = i965_do_reset(dev);
+ break;
+ case 2:
+ ret = i8xx_do_reset(dev);
+ break;
+ }
+
+ /* Also reset the gpu hangman. */
+ if (dev_priv->stop_rings) {
+ DRM_DEBUG("Simulated gpu hang, resetting stop_rings\n");
+ dev_priv->stop_rings = 0;
+ if (ret == -ENODEV) {
+ DRM_ERROR("Reset not implemented, but ignoring "
+ "error for simulated gpu hangs\n");
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
int
-i915_reset(struct drm_device *dev, u8 flags)
+i915_reset(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
/*
@@ -748,23 +785,9 @@ i915_reset(struct drm_device *dev, u8 flags)
ret = -ENODEV;
if (time_second - 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;
- }
- }
+ } else
+ ret = intel_gpu_reset(dev);
+
dev_priv->last_gpu_reset = time_second;
if (ret) {
DRM_ERROR("Failed to reset chip.\n");
@@ -784,6 +807,7 @@ i915_reset(struct drm_device *dev, u8 flags)
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);
OpenPOWER on IntegriCloud