From f274cf125c95ffc1f4275ab5cfe2f26f24451e59 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Mon, 12 May 2008 14:38:49 +0800 Subject: [PATCH] fix G33 hardware status page in modeset We need to alloc a hw status page bo for G33 if modeset is enabled since the 2D driver can't alloc gfx memory when working in drm modeset. --- shared-core/i915_dma.c | 4 ++++ shared-core/i915_drv.h | 1 + shared-core/i915_init.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 0 deletions(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index f3a963b..8441fcc 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -997,6 +997,10 @@ static int i915_set_status_page(struct drm_device *dev, void *data, DRM_ERROR("called with no initialization\n"); return -EINVAL; } + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 2e7b6bd..10e08c5 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -124,6 +124,7 @@ struct drm_i915_private { uint32_t counter; unsigned int status_gfx_addr; drm_local_map_t hws_map; + struct drm_buffer_object *hws_bo; unsigned int cpp; int use_mi_batchbuffer_start; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index b9e7e17..7183f81 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -252,6 +252,38 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page); + } else { + size = 4 * 1024; + ret = drm_buffer_object_create(dev, size, + drm_bo_type_kernel, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, 0x1, 0, + &dev_priv->hws_bo); + if (ret < 0) { + DRM_ERROR("Unable to allocate or pin ring buffer\n"); + return -EINVAL; + } + dev_priv->status_gfx_addr = + dev_priv->hws_bo->offset & (0x1ffff << 12); + dev_priv->hws_map.offset = dev->agp->base + + dev_priv->hws_bo->offset; + dev_priv->hws_map.size = size; + dev_priv->hws_map.type = 0; + dev_priv->hws_map.flags = 0; + dev_priv->hws_map.mtrr = 0; + + drm_core_ioremap(&dev_priv->hws_map, dev); + if (dev_priv->hws_map.handle == NULL) { + dev_priv->status_gfx_addr = 0; + DRM_ERROR("can not ioremap virtual addr" + " for G33 hw status page\n"); + return -ENOMEM; + } + dev_priv->hw_status_page = dev_priv->hws_map.handle; + memset(dev_priv->hw_status_page, 0, size); + I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr); } DRM_DEBUG("Enabled hardware status page\n"); @@ -324,6 +356,7 @@ int i915_driver_unload(struct drm_device *dev) if (dev_priv->status_gfx_addr) { dev_priv->status_gfx_addr = 0; drm_core_ioremapfree(&dev_priv->hws_map, dev); + drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); } -- 1.5.0.5