aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-07-03 06:56:54 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-07-04 05:36:36 -0400
commit035dc1e0f9008b48630e02bf0eaa7cc547416d1d (patch)
tree4cfcc8ab06ef507d0f2b09e146fbc0e8fb782999 /drivers/gpu/drm/i915/intel_ringbuffer.c
parent446f8d81ca2d9cefb614e87f2fabcc996a9e4e7e (diff)
drm/i915: reinit status page registers after gpu reset
This fixes gpu reset on my gm45 - without this patch the bsd thing is forever stuck since the seqno updates never reach the status page. Tbh I have no idea how this ever worked without rewriting the hws registers after a gpu reset. To satisfy my OCD also give the functions a bit more consistent names: - Use status_page everywhere, also for the physical addressed one. - Use init for the allocation part and setup for the register setup part consistently. Long term I'd really like to share the hw init parts completely between gpu reset, resume and driver load, i.e. to call i915_gem_init_hw instead of the individual pieces we might need. v2: Add the missing paragraph to the commit message about what bug exactly this patch here fixes. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65495 Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Tested-by: lu hua <huax.lu@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index e51ab552046c..18ca76e3e5ef 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -379,6 +379,17 @@ u32 intel_ring_get_active_head(struct intel_ring_buffer *ring)
379 return I915_READ(acthd_reg); 379 return I915_READ(acthd_reg);
380} 380}
381 381
382static void ring_setup_phys_status_page(struct intel_ring_buffer *ring)
383{
384 struct drm_i915_private *dev_priv = ring->dev->dev_private;
385 u32 addr;
386
387 addr = dev_priv->status_page_dmah->busaddr;
388 if (INTEL_INFO(ring->dev)->gen >= 4)
389 addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0;
390 I915_WRITE(HWS_PGA, addr);
391}
392
382static int init_ring_common(struct intel_ring_buffer *ring) 393static int init_ring_common(struct intel_ring_buffer *ring)
383{ 394{
384 struct drm_device *dev = ring->dev; 395 struct drm_device *dev = ring->dev;
@@ -390,6 +401,11 @@ static int init_ring_common(struct intel_ring_buffer *ring)
390 if (HAS_FORCE_WAKE(dev)) 401 if (HAS_FORCE_WAKE(dev))
391 gen6_gt_force_wake_get(dev_priv); 402 gen6_gt_force_wake_get(dev_priv);
392 403
404 if (I915_NEED_GFX_HWS(dev))
405 intel_ring_setup_status_page(ring);
406 else
407 ring_setup_phys_status_page(ring);
408
393 /* Stop the ring if it's running. */ 409 /* Stop the ring if it's running. */
394 I915_WRITE_CTL(ring, 0); 410 I915_WRITE_CTL(ring, 0);
395 I915_WRITE_HEAD(ring, 0); 411 I915_WRITE_HEAD(ring, 0);
@@ -1223,7 +1239,6 @@ static int init_status_page(struct intel_ring_buffer *ring)
1223 ring->status_page.obj = obj; 1239 ring->status_page.obj = obj;
1224 memset(ring->status_page.page_addr, 0, PAGE_SIZE); 1240 memset(ring->status_page.page_addr, 0, PAGE_SIZE);
1225 1241
1226 intel_ring_setup_status_page(ring);
1227 DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", 1242 DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
1228 ring->name, ring->status_page.gfx_addr); 1243 ring->name, ring->status_page.gfx_addr);
1229 1244
@@ -1237,10 +1252,9 @@ err:
1237 return ret; 1252 return ret;
1238} 1253}
1239 1254
1240static int init_phys_hws_pga(struct intel_ring_buffer *ring) 1255static int init_phys_status_page(struct intel_ring_buffer *ring)
1241{ 1256{
1242 struct drm_i915_private *dev_priv = ring->dev->dev_private; 1257 struct drm_i915_private *dev_priv = ring->dev->dev_private;
1243 u32 addr;
1244 1258
1245 if (!dev_priv->status_page_dmah) { 1259 if (!dev_priv->status_page_dmah) {
1246 dev_priv->status_page_dmah = 1260 dev_priv->status_page_dmah =
@@ -1249,11 +1263,6 @@ static int init_phys_hws_pga(struct intel_ring_buffer *ring)
1249 return -ENOMEM; 1263 return -ENOMEM;
1250 } 1264 }
1251 1265
1252 addr = dev_priv->status_page_dmah->busaddr;
1253 if (INTEL_INFO(ring->dev)->gen >= 4)
1254 addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0;
1255 I915_WRITE(HWS_PGA, addr);
1256
1257 ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; 1266 ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr;
1258 memset(ring->status_page.page_addr, 0, PAGE_SIZE); 1267 memset(ring->status_page.page_addr, 0, PAGE_SIZE);
1259 1268
@@ -1281,7 +1290,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
1281 return ret; 1290 return ret;
1282 } else { 1291 } else {
1283 BUG_ON(ring->id != RCS); 1292 BUG_ON(ring->id != RCS);
1284 ret = init_phys_hws_pga(ring); 1293 ret = init_phys_status_page(ring);
1285 if (ret) 1294 if (ret)
1286 return ret; 1295 return ret;
1287 } 1296 }
@@ -1893,7 +1902,7 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
1893 } 1902 }
1894 1903
1895 if (!I915_NEED_GFX_HWS(dev)) { 1904 if (!I915_NEED_GFX_HWS(dev)) {
1896 ret = init_phys_hws_pga(ring); 1905 ret = init_phys_status_page(ring);
1897 if (ret) 1906 if (ret)
1898 return ret; 1907 return ret;
1899 } 1908 }