i915: Allocate and initialize the BMP.

This commit is contained in:
Michel Dänzer 2007-03-21 18:58:52 +01:00
parent a9abb4c337
commit d5f2195464
3 changed files with 97 additions and 0 deletions

View file

@ -711,13 +711,101 @@ static int i915_cmdbuffer(DRM_IOCTL_ARGS)
return 0;
}
#define BMP_SIZE PAGE_SIZE
#define BMP_POOL_SIZE ((BMP_SIZE - 32) / 4)
static int i915_bmp_alloc(drm_device_t *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int i;
u32 *ring;
dev_priv->bmp = drm_pci_alloc(dev, BMP_SIZE, PAGE_SIZE, 0xffffffff);
if (!dev_priv->bmp) {
DRM_ERROR("Failed to allocate BMP ring buffer\n");
return DRM_ERR(ENOMEM);
}
dev_priv->bmp_pool = drm_calloc(1, BMP_POOL_SIZE *
sizeof(drm_dma_handle_t*),
DRM_MEM_DRIVER);
if (!dev_priv->bmp_pool) {
DRM_ERROR("Failed to allocate BMP pool\n");
drm_pci_free(dev, dev_priv->bmp);
dev_priv->bmp = NULL;
return DRM_ERR(ENOMEM);
}
for (i = 0, ring = dev_priv->bmp->vaddr; i < BMP_POOL_SIZE; i++) {
dev_priv->bmp_pool[i] = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
0xffffffff);
if (!dev_priv->bmp_pool[i]) {
DRM_INFO("Failed to allocate page %d for BMP pool\n",
i);
break;
}
ring[i] = dev_priv->bmp_pool[i]->busaddr >> PAGE_SHIFT;
}
I915_WRITE(BMP_PUT, (i / 8) << BMP_OFFSET_SHIFT);
I915_WRITE(BMP_GET, 0 << BMP_OFFSET_SHIFT);
I915_WRITE(BMP_BUFFER, dev_priv->bmp->busaddr | BMP_PAGE_SIZE_4K |
((BMP_SIZE / PAGE_SIZE - 1) << BMP_BUFFER_SIZE_SHIFT) |
BMP_ENABLE);
return 0;
}
#define BIN_WIDTH 64
#define BIN_HEIGHT 32
static int i915_hwz_alloc(drm_device_t *dev, drm_i915_hwz_t *hwz)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int bin_h = (hwz->height + BIN_HEIGHT - 1) / BIN_HEIGHT;
if (8 * hwz->pitch / BIN_WIDTH * bin_h > PAGE_SIZE) {
DRM_ERROR("HWZ area too big\n");
return DRM_ERR(EINVAL);
}
if (!dev_priv->bmp && i915_bmp_alloc(dev)) {
DRM_ERROR("Failed to allocate BMP\n");
return DRM_ERR(ENOMEM);
}
return 0;
}
static int i915_hwz_free(drm_device_t *dev, drm_i915_hwz_t *hwz)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
if (dev_priv->bmp_pool) {
int i;
for (i = 0; i < BMP_POOL_SIZE; i++) {
if (!dev_priv->bmp_pool[i])
break;
drm_pci_free(dev, dev_priv->bmp_pool[i]);
}
drm_free(dev_priv->bmp_pool, BMP_POOL_SIZE *
sizeof(drm_dma_handle_t*), DRM_MEM_DRIVER);
dev_priv->bmp_pool = NULL;
}
if (dev_priv->bmp) {
drm_pci_free(dev, dev_priv->bmp);
dev_priv->bmp = NULL;
}
return 0;
}

View file

@ -324,6 +324,7 @@ typedef struct drm_i915_mmio {
typedef struct drm_i915_hwz {
unsigned int op;
unsigned short width, pitch, height;
} drm_i915_hwz_t;
#endif /* _I915_DRM_H_ */

View file

@ -131,6 +131,8 @@ typedef struct drm_i915_private {
spinlock_t swaps_lock;
drm_i915_vbl_swap_t vbl_swaps;
unsigned int swaps_pending;
drm_dma_handle_t *bmp, **bmp_pool;
} drm_i915_private_t;
enum intel_chip_family {
@ -320,9 +322,15 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
#define BINCTL 0x2420
#define BINSCENE 0x2428
#define BMP_BUFFER 0x2430
#define BMP_PAGE_SIZE_4K (0 << 10)
#define BMP_BUFFER_SIZE_SHIFT 1
#define BMP_ENABLE (1 << 0)
#define BMP_GET 0x2438
#define BMP_PUT 0x2440
#define BMP_OFFSET_SHIFT 5
#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
#define SC_UPDATE_SCISSOR (0x1<<1)