mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 08:58:02 +02:00
add initial miniglx files for i915, not integrated yet
This commit is contained in:
parent
e43edd3c70
commit
8b186e3695
2 changed files with 1251 additions and 0 deletions
294
src/mesa/drivers/dri/i915/server/intel.h
Normal file
294
src/mesa/drivers/dri/i915/server/intel.h
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
#ifndef _INTEL_H_
|
||||
#define _INTEL_H_
|
||||
|
||||
#include "xf86drm.h" /* drm_handle_t, etc */
|
||||
|
||||
/* Intel */
|
||||
#ifndef PCI_CHIP_I810
|
||||
#define PCI_CHIP_I810 0x7121
|
||||
#define PCI_CHIP_I810_DC100 0x7123
|
||||
#define PCI_CHIP_I810_E 0x7125
|
||||
#define PCI_CHIP_I815 0x1132
|
||||
#define PCI_CHIP_I810_BRIDGE 0x7120
|
||||
#define PCI_CHIP_I810_DC100_BRIDGE 0x7122
|
||||
#define PCI_CHIP_I810_E_BRIDGE 0x7124
|
||||
#define PCI_CHIP_I815_BRIDGE 0x1130
|
||||
#endif
|
||||
|
||||
#define PCI_CHIP_845_G 0x2562
|
||||
#define PCI_CHIP_I830_M 0x3577
|
||||
|
||||
#ifndef PCI_CHIP_I855_GM
|
||||
#define PCI_CHIP_I855_GM 0x3582
|
||||
#define PCI_CHIP_I855_GM_BRIDGE 0x3580
|
||||
#endif
|
||||
|
||||
#ifndef PCI_CHIP_I865_G
|
||||
#define PCI_CHIP_I865_G 0x2572
|
||||
#define PCI_CHIP_I865_G_BRIDGE 0x2570
|
||||
#endif
|
||||
|
||||
#ifndef PCI_CHIP_I915_G
|
||||
#define PCI_CHIP_I915_G 0x2582
|
||||
#define PCI_CHIP_I915_G_BRIDGE 0x2580
|
||||
#endif
|
||||
|
||||
#ifndef PCI_CHIP_I915_GM
|
||||
#define PCI_CHIP_I915_GM 0x2592
|
||||
#define PCI_CHIP_I915_GM_BRIDGE 0x2590
|
||||
#endif
|
||||
|
||||
#ifndef PCI_CHIP_E7221_G
|
||||
#define PCI_CHIP_E7221_G 0x258A
|
||||
/* Same as I915_G_BRIDGE */
|
||||
#define PCI_CHIP_E7221_G_BRIDGE 0x2580
|
||||
#endif
|
||||
|
||||
#ifndef PCI_CHIP_I945_G
|
||||
#define PCI_CHIP_I945_G 0x2772
|
||||
#define PCI_CHIP_I945_G_BRIDGE 0x2770
|
||||
#endif
|
||||
|
||||
#ifndef PCI_CHIP_I945_GM
|
||||
#define PCI_CHIP_I945_GM 0x27A2
|
||||
#define PCI_CHIP_I945_GM_BRIDGE 0x27A0
|
||||
#endif
|
||||
|
||||
#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \
|
||||
pI810->Chipset == PCI_CHIP_I810_DC100 || \
|
||||
pI810->Chipset == PCI_CHIP_I810_E)
|
||||
#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815)
|
||||
#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M)
|
||||
#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G)
|
||||
#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM)
|
||||
#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME))
|
||||
#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME))
|
||||
#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G)
|
||||
|
||||
#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G)
|
||||
#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM)
|
||||
#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G)
|
||||
#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM)
|
||||
#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810))
|
||||
|
||||
#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810))
|
||||
|
||||
#define I830_GMCH_CTRL 0x52
|
||||
|
||||
|
||||
#define I830_GMCH_GMS_MASK 0x70
|
||||
#define I830_GMCH_GMS_DISABLED 0x00
|
||||
#define I830_GMCH_GMS_LOCAL 0x10
|
||||
#define I830_GMCH_GMS_STOLEN_512 0x20
|
||||
#define I830_GMCH_GMS_STOLEN_1024 0x30
|
||||
#define I830_GMCH_GMS_STOLEN_8192 0x40
|
||||
|
||||
#define I855_GMCH_GMS_MASK (0x7 << 4)
|
||||
#define I855_GMCH_GMS_DISABLED 0x00
|
||||
#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
|
||||
#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)
|
||||
#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4)
|
||||
#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4)
|
||||
#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4)
|
||||
#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
|
||||
#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
|
||||
|
||||
typedef unsigned char Bool;
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define PIPE_NONE 0<<0
|
||||
#define PIPE_CRT 1<<0
|
||||
#define PIPE_TV 1<<1
|
||||
#define PIPE_DFP 1<<2
|
||||
#define PIPE_LFP 1<<3
|
||||
#define PIPE_CRT2 1<<4
|
||||
#define PIPE_TV2 1<<5
|
||||
#define PIPE_DFP2 1<<6
|
||||
#define PIPE_LFP2 1<<7
|
||||
|
||||
typedef struct _I830MemPool *I830MemPoolPtr;
|
||||
typedef struct _I830MemRange *I830MemRangePtr;
|
||||
typedef struct _I830MemRange {
|
||||
long Start;
|
||||
long End;
|
||||
long Size;
|
||||
unsigned long Physical;
|
||||
unsigned long Offset; /* Offset of AGP-allocated portion */
|
||||
unsigned long Alignment;
|
||||
drm_handle_t Key;
|
||||
unsigned long Pitch; // add pitch
|
||||
I830MemPoolPtr Pool;
|
||||
} I830MemRange;
|
||||
|
||||
typedef struct _I830MemPool {
|
||||
I830MemRange Total;
|
||||
I830MemRange Free;
|
||||
I830MemRange Fixed;
|
||||
I830MemRange Allocated;
|
||||
} I830MemPool;
|
||||
|
||||
typedef struct {
|
||||
int tail_mask;
|
||||
I830MemRange mem;
|
||||
unsigned char *virtual_start;
|
||||
int head;
|
||||
int tail;
|
||||
int space;
|
||||
} I830RingBuffer;
|
||||
|
||||
typedef struct {
|
||||
unsigned int Fence[8];
|
||||
} I830RegRec, *I830RegPtr;
|
||||
|
||||
|
||||
typedef struct _I830Rec {
|
||||
unsigned char *MMIOBase;
|
||||
unsigned char *FbBase;
|
||||
int cpp;
|
||||
|
||||
unsigned int bios_version;
|
||||
|
||||
/* These are set in PreInit and never changed. */
|
||||
long FbMapSize;
|
||||
long TotalVideoRam;
|
||||
I830MemRange StolenMemory; /* pre-allocated memory */
|
||||
long BIOSMemorySize; /* min stolen pool size */
|
||||
int BIOSMemSizeLoc;
|
||||
|
||||
/* These change according to what has been allocated. */
|
||||
long FreeMemory;
|
||||
I830MemRange MemoryAperture;
|
||||
I830MemPool StolenPool;
|
||||
long allocatedMemory;
|
||||
|
||||
/* Regions allocated either from the above pools, or from agpgart. */
|
||||
/* for single and dual head configurations */
|
||||
I830MemRange FrontBuffer;
|
||||
I830MemRange FrontBuffer2;
|
||||
I830MemRange Scratch;
|
||||
I830MemRange Scratch2;
|
||||
|
||||
I830RingBuffer *LpRing;
|
||||
|
||||
I830MemRange BackBuffer;
|
||||
I830MemRange DepthBuffer;
|
||||
I830MemRange TexMem;
|
||||
int TexGranularity;
|
||||
I830MemRange ContextMem;
|
||||
int drmMinor;
|
||||
Bool have3DWindows;
|
||||
|
||||
Bool NeedRingBufferLow;
|
||||
Bool allowPageFlip;
|
||||
Bool disableTiling;
|
||||
|
||||
int Chipset;
|
||||
unsigned long LinearAddr;
|
||||
unsigned long MMIOAddr;
|
||||
|
||||
drmSize registerSize; /**< \brief MMIO register map size */
|
||||
drm_handle_t registerHandle; /**< \brief MMIO register map handle */
|
||||
// IOADDRESS ioBase;
|
||||
int irq; /**< \brief IRQ number */
|
||||
int GttBound;
|
||||
|
||||
drm_handle_t ring_map;
|
||||
|
||||
} I830Rec;
|
||||
|
||||
/*
|
||||
* 12288 is set as the maximum, chosen because it is enough for
|
||||
* 1920x1440@32bpp with a 2048 pixel line pitch with some to spare.
|
||||
*/
|
||||
#define I830_MAXIMUM_VBIOS_MEM 12288
|
||||
#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024)
|
||||
#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024)
|
||||
|
||||
/* Flags for memory allocation function */
|
||||
#define FROM_ANYWHERE 0x00000000
|
||||
#define FROM_POOL_ONLY 0x00000001
|
||||
#define FROM_NEW_ONLY 0x00000002
|
||||
#define FROM_MASK 0x0000000f
|
||||
|
||||
#define ALLOCATE_AT_TOP 0x00000010
|
||||
#define ALLOCATE_AT_BOTTOM 0x00000020
|
||||
#define FORCE_GAPS 0x00000040
|
||||
|
||||
#define NEED_PHYSICAL_ADDR 0x00000100
|
||||
#define ALIGN_BOTH_ENDS 0x00000200
|
||||
#define FORCE_LOW 0x00000400
|
||||
|
||||
#define ALLOC_NO_TILING 0x00001000
|
||||
#define ALLOC_INITIAL 0x00002000
|
||||
|
||||
#define ALLOCATE_DRY_RUN 0x80000000
|
||||
|
||||
/* Chipset registers for VIDEO BIOS memory RW access */
|
||||
#define _855_DRAM_RW_CONTROL 0x58
|
||||
#define _845_DRAM_RW_CONTROL 0x90
|
||||
#define DRAM_WRITE 0x33330000
|
||||
|
||||
#define KB(x) ((x) * 1024)
|
||||
#define MB(x) ((x) * KB(1024))
|
||||
|
||||
#define GTT_PAGE_SIZE KB(4)
|
||||
#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y))
|
||||
#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y))
|
||||
#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE)
|
||||
#define ROUND_TO_MB(x) ROUND_TO((x), MB(1))
|
||||
#define PRIMARY_RINGBUFFER_SIZE KB(128)
|
||||
|
||||
|
||||
/* Ring buffer registers, p277, overview p19
|
||||
*/
|
||||
#define LP_RING 0x2030
|
||||
#define HP_RING 0x2040
|
||||
|
||||
#define RING_TAIL 0x00
|
||||
#define TAIL_ADDR 0x000FFFF8
|
||||
#define I830_TAIL_MASK 0x001FFFF8
|
||||
|
||||
#define RING_HEAD 0x04
|
||||
#define HEAD_WRAP_COUNT 0xFFE00000
|
||||
#define HEAD_WRAP_ONE 0x00200000
|
||||
#define HEAD_ADDR 0x001FFFFC
|
||||
#define I830_HEAD_MASK 0x001FFFFC
|
||||
|
||||
#define RING_START 0x08
|
||||
#define START_ADDR 0x03FFFFF8
|
||||
#define I830_RING_START_MASK 0xFFFFF000
|
||||
|
||||
#define RING_LEN 0x0C
|
||||
#define RING_NR_PAGES 0x001FF000
|
||||
#define I830_RING_NR_PAGES 0x001FF000
|
||||
#define RING_REPORT_MASK 0x00000006
|
||||
#define RING_REPORT_64K 0x00000002
|
||||
#define RING_REPORT_128K 0x00000004
|
||||
#define RING_NO_REPORT 0x00000000
|
||||
#define RING_VALID_MASK 0x00000001
|
||||
#define RING_VALID 0x00000001
|
||||
#define RING_INVALID 0x00000000
|
||||
|
||||
|
||||
#include <mmio.h>
|
||||
|
||||
# define MMIO_IN8(base, offset) \
|
||||
*(volatile unsigned char *)(((unsigned char*)(base)) + (offset))
|
||||
# define MMIO_IN32(base, offset) \
|
||||
read_MMIO_LE32(base, offset)
|
||||
# define MMIO_OUT8(base, offset, val) \
|
||||
*(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val)
|
||||
# define MMIO_OUT32(base, offset, val) \
|
||||
*(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val)
|
||||
|
||||
|
||||
/* Memory mapped register access macros */
|
||||
#define INREG8(addr) MMIO_IN8(MMIO, addr)
|
||||
#define INREG(addr) MMIO_IN32(MMIO, addr)
|
||||
#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val)
|
||||
#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val)
|
||||
|
||||
#define DSPABASE 0x70184
|
||||
|
||||
#endif
|
||||
957
src/mesa/drivers/dri/i915/server/intel_dri.c
Normal file
957
src/mesa/drivers/dri/i915/server/intel_dri.c
Normal file
|
|
@ -0,0 +1,957 @@
|
|||
/**
|
||||
* \file server/intel_dri.c
|
||||
* \brief File to perform the device-specific initialization tasks typically
|
||||
* done in the X server.
|
||||
*
|
||||
* Here they are converted to run in the client (or perhaps a standalone
|
||||
* process), and to work with the frame buffer device rather than the X
|
||||
* server infrastructure.
|
||||
*
|
||||
* Copyright (C) 2006 Dave Airlie (airlied@linux.ie)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sub license, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "driver.h"
|
||||
#include "drm.h"
|
||||
|
||||
#include "intel.h"
|
||||
#include "i830_dri.h"
|
||||
|
||||
#include "memops.h"
|
||||
#include "pciaccess.h"
|
||||
|
||||
static size_t drm_page_size;
|
||||
#define xf86DrvMsg(...) do {} while(0)
|
||||
|
||||
static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea);
|
||||
|
||||
static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830)
|
||||
{
|
||||
struct pci_device host_bridge;
|
||||
uint32_t gmch_ctrl;
|
||||
int memsize = 0;
|
||||
int range;
|
||||
|
||||
memset(&host_bridge, 0, sizeof(host_bridge));
|
||||
|
||||
pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL);
|
||||
|
||||
/* We need to reduce the stolen size, by the GTT and the popup.
|
||||
* The GTT varying according the the FbMapSize and the popup is 4KB */
|
||||
range = (ctx->shared.fbSize / (1024*1024)) + 4;
|
||||
|
||||
if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
|
||||
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
|
||||
case I855_GMCH_GMS_STOLEN_1M:
|
||||
memsize = MB(1) - KB(range);
|
||||
break;
|
||||
case I855_GMCH_GMS_STOLEN_4M:
|
||||
memsize = MB(4) - KB(range);
|
||||
break;
|
||||
case I855_GMCH_GMS_STOLEN_8M:
|
||||
memsize = MB(8) - KB(range);
|
||||
break;
|
||||
case I855_GMCH_GMS_STOLEN_16M:
|
||||
memsize = MB(16) - KB(range);
|
||||
break;
|
||||
case I855_GMCH_GMS_STOLEN_32M:
|
||||
memsize = MB(32) - KB(range);
|
||||
break;
|
||||
case I915G_GMCH_GMS_STOLEN_48M:
|
||||
if (IS_I9XX(pI830))
|
||||
memsize = MB(48) - KB(range);
|
||||
break;
|
||||
case I915G_GMCH_GMS_STOLEN_64M:
|
||||
if (IS_I9XX(pI830))
|
||||
memsize = MB(64) - KB(range);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
|
||||
case I830_GMCH_GMS_STOLEN_512:
|
||||
memsize = KB(512) - KB(range);
|
||||
break;
|
||||
case I830_GMCH_GMS_STOLEN_1024:
|
||||
memsize = MB(1) - KB(range);
|
||||
break;
|
||||
case I830_GMCH_GMS_STOLEN_8192:
|
||||
memsize = MB(8) - KB(range);
|
||||
break;
|
||||
case I830_GMCH_GMS_LOCAL:
|
||||
memsize = 0;
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
|
||||
"Local memory found, but won't be used.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (memsize > 0) {
|
||||
fprintf(stderr,
|
||||
"detected %d kB stolen memory.\n", memsize / 1024);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"no video memory detected.\n");
|
||||
}
|
||||
return memsize;
|
||||
}
|
||||
|
||||
static int AgpInit(const DRIDriverContext *ctx, I830Rec *info)
|
||||
{
|
||||
unsigned long mode = 0x4;
|
||||
|
||||
if (drmAgpAcquire(ctx->drmFD) < 0) {
|
||||
fprintf(stderr, "[gart] AGP not available\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (drmAgpEnable(ctx->drmFD, mode) < 0) {
|
||||
fprintf(stderr, "[gart] AGP not enabled\n");
|
||||
drmAgpRelease(ctx->drmFD);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result)
|
||||
{
|
||||
unsigned long start, end;
|
||||
unsigned long newApStart, newApEnd;
|
||||
int ret;
|
||||
if (!result || !size)
|
||||
return 0;
|
||||
|
||||
if (!alignment)
|
||||
alignment = 4;
|
||||
|
||||
start = ROUND_TO(pI830->MemoryAperture.Start, alignment);
|
||||
end = ROUND_TO(start + size, alignment);
|
||||
newApStart = end;
|
||||
newApEnd = pI830->MemoryAperture.End;
|
||||
|
||||
ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key));
|
||||
|
||||
if (ret)
|
||||
{
|
||||
fprintf(stderr,"drmAgpAlloc failed %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
pI830->allocatedMemory += size;
|
||||
pI830->MemoryAperture.Start = newApStart;
|
||||
pI830->MemoryAperture.End = newApEnd;
|
||||
pI830->MemoryAperture.Size = newApEnd - newApStart;
|
||||
pI830->FreeMemory -= size;
|
||||
result->Start = start;
|
||||
result->End = start + size;
|
||||
result->Size = size;
|
||||
result->Offset = start;
|
||||
result->Alignment = alignment;
|
||||
result->Pool = NULL;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem)
|
||||
{
|
||||
if (!mem)
|
||||
return FALSE;
|
||||
|
||||
if (mem->Key == -1)
|
||||
return TRUE;
|
||||
|
||||
return drmAgpBind(ctx->drmFD, mem->Key, mem->Offset);
|
||||
}
|
||||
|
||||
/* simple memory allocation routines needed */
|
||||
/* put ring buffer in low memory */
|
||||
/* need to allocate front, back, depth buffers aligned correctly,
|
||||
allocate ring buffer,
|
||||
*/
|
||||
|
||||
/* */
|
||||
static Bool
|
||||
I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
|
||||
{
|
||||
unsigned long size, ret;
|
||||
unsigned long lines, lineSize, align;
|
||||
|
||||
/* allocate ring buffer */
|
||||
memset(pI830->LpRing, 0, sizeof(I830RingBuffer));
|
||||
pI830->LpRing->mem.Key = -1;
|
||||
|
||||
size = PRIMARY_RINGBUFFER_SIZE;
|
||||
|
||||
ret = AllocFromAGP(ctx, pI830, size, 0x1000, &pI830->LpRing->mem);
|
||||
|
||||
if (ret != size)
|
||||
{
|
||||
fprintf(stderr,"unable to allocate ring buffer %ld\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1;
|
||||
|
||||
|
||||
/* allocate front buffer */
|
||||
memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
|
||||
pI830->FrontBuffer.Key = -1;
|
||||
pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth;
|
||||
|
||||
align = KB(512);
|
||||
|
||||
lineSize = ctx->shared.virtualWidth * ctx->cpp;
|
||||
lines = (ctx->shared.virtualHeight + 15) / 16 * 16;
|
||||
size = lineSize * lines;
|
||||
size = ROUND_TO_PAGE(size);
|
||||
|
||||
ret = AllocFromAGP(ctx, pI830, size, align, &pI830->FrontBuffer);
|
||||
if (ret != size)
|
||||
{
|
||||
fprintf(stderr,"unable to allocate front buffer %ld\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer));
|
||||
pI830->BackBuffer.Key = -1;
|
||||
pI830->BackBuffer.Pitch = ctx->shared.virtualWidth;
|
||||
|
||||
ret = AllocFromAGP(ctx, pI830, size, align, &pI830->BackBuffer);
|
||||
if (ret != size)
|
||||
{
|
||||
fprintf(stderr,"unable to allocate back buffer %ld\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer));
|
||||
pI830->DepthBuffer.Key = -1;
|
||||
pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth;
|
||||
|
||||
ret = AllocFromAGP(ctx, pI830, size, align, &pI830->DepthBuffer);
|
||||
if (ret != size)
|
||||
{
|
||||
fprintf(stderr,"unable to allocate depth buffer %ld\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem));
|
||||
pI830->ContextMem.Key = -1;
|
||||
size = KB(32);
|
||||
|
||||
ret = AllocFromAGP(ctx, pI830, size, align, &pI830->ContextMem);
|
||||
if (ret != size)
|
||||
{
|
||||
fprintf(stderr,"unable to allocate back buffer %ld\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem));
|
||||
pI830->TexMem.Key = -1;
|
||||
|
||||
size = 32768 * 1024;
|
||||
ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem);
|
||||
if (ret != size)
|
||||
{
|
||||
fprintf(stderr,"unable to allocate texture memory %ld\n", ret);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830)
|
||||
{
|
||||
if (BindAgpRange(ctx, &pI830->LpRing->mem))
|
||||
return FALSE;
|
||||
if (BindAgpRange(ctx, &pI830->FrontBuffer))
|
||||
return FALSE;
|
||||
if (BindAgpRange(ctx, &pI830->BackBuffer))
|
||||
return FALSE;
|
||||
if (BindAgpRange(ctx, &pI830->DepthBuffer))
|
||||
return FALSE;
|
||||
if (BindAgpRange(ctx, &pI830->ContextMem))
|
||||
return FALSE;
|
||||
if (BindAgpRange(ctx, &pI830->TexMem))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830CleanupDma(const DRIDriverContext *ctx)
|
||||
{
|
||||
drmI830Init info;
|
||||
|
||||
memset(&info, 0, sizeof(drmI830Init));
|
||||
info.func = I830_CLEANUP_DMA;
|
||||
|
||||
if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
|
||||
&info, sizeof(drmI830Init))) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Dma Cleanup Failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830)
|
||||
{
|
||||
I830RingBuffer *ring = pI830->LpRing;
|
||||
drmI830Init info;
|
||||
|
||||
memset(&info, 0, sizeof(drmI830Init));
|
||||
info.func = I830_INIT_DMA;
|
||||
|
||||
info.ring_start = ring->mem.Start + pI830->LinearAddr;
|
||||
info.ring_end = ring->mem.End + pI830->LinearAddr;
|
||||
info.ring_size = ring->mem.Size;
|
||||
|
||||
info.mmio_offset = (unsigned int)ctx->MMIOStart;
|
||||
|
||||
info.sarea_priv_offset = sizeof(drm_sarea_t);
|
||||
|
||||
info.front_offset = pI830->FrontBuffer.Start;
|
||||
info.back_offset = pI830->BackBuffer.Start;
|
||||
info.depth_offset = pI830->DepthBuffer.Start;
|
||||
info.w = ctx->shared.virtualWidth;
|
||||
info.h = ctx->shared.virtualHeight;
|
||||
info.pitch = ctx->shared.virtualWidth;
|
||||
info.back_pitch = pI830->BackBuffer.Pitch;
|
||||
info.depth_pitch = pI830->DepthBuffer.Pitch;
|
||||
info.cpp = pI830->cpp;
|
||||
|
||||
if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
|
||||
&info, sizeof(drmI830Init))) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"I830 Dma Initialization Failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int I830CheckDRMVersion( const DRIDriverContext *ctx,
|
||||
I830Rec *pI830 )
|
||||
{
|
||||
drmVersionPtr version;
|
||||
|
||||
version = drmGetVersion(ctx->drmFD);
|
||||
|
||||
if (version) {
|
||||
int req_minor, req_patch;
|
||||
|
||||
req_minor = 4;
|
||||
req_patch = 0;
|
||||
|
||||
if (version->version_major != 1 ||
|
||||
version->version_minor < req_minor ||
|
||||
(version->version_minor == req_minor &&
|
||||
version->version_patchlevel < req_patch)) {
|
||||
/* Incompatible drm version */
|
||||
fprintf(stderr,
|
||||
"[dri] I830DRIScreenInit failed because of a version "
|
||||
"mismatch.\n"
|
||||
"[dri] i915.o kernel module version is %d.%d.%d "
|
||||
"but version 1.%d.%d or newer is needed.\n"
|
||||
"[dri] Disabling DRI.\n",
|
||||
version->version_major,
|
||||
version->version_minor,
|
||||
version->version_patchlevel,
|
||||
req_minor,
|
||||
req_patch);
|
||||
drmFreeVersion(version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pI830->drmMinor = version->version_minor;
|
||||
drmFreeVersion(version);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830)
|
||||
{
|
||||
unsigned int itemp;
|
||||
unsigned char *MMIO = ctx->MMIOAddress;
|
||||
|
||||
OUTREG(LP_RING + RING_LEN, 0);
|
||||
OUTREG(LP_RING + RING_TAIL, 0);
|
||||
OUTREG(LP_RING + RING_HEAD, 0);
|
||||
|
||||
if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) !=
|
||||
pI830->LpRing->mem.Start) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"I830SetRingRegs: Ring buffer start (%lx) violates its "
|
||||
"mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK);
|
||||
}
|
||||
/* Don't care about the old value. Reserved bits must be zero anyway. */
|
||||
itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK;
|
||||
OUTREG(LP_RING + RING_START, itemp);
|
||||
|
||||
if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) !=
|
||||
pI830->LpRing->mem.Size - 4096) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
|
||||
"mask (%x)\n", pI830->LpRing->mem.Size - 4096,
|
||||
I830_RING_NR_PAGES);
|
||||
}
|
||||
/* Don't care about the old value. Reserved bits must be zero anyway. */
|
||||
itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES;
|
||||
itemp |= (RING_NO_REPORT | RING_VALID);
|
||||
OUTREG(LP_RING + RING_LEN, itemp);
|
||||
|
||||
pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
|
||||
pI830->LpRing->tail = INREG(LP_RING + RING_TAIL);
|
||||
pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
|
||||
if (pI830->LpRing->space < 0)
|
||||
pI830->LpRing->space += pI830->LpRing->mem.Size;
|
||||
|
||||
/* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky
|
||||
hacky hacky */
|
||||
OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr);
|
||||
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830SetParam(const DRIDriverContext *ctx, int param, int value)
|
||||
{
|
||||
drmI830SetParam sp;
|
||||
|
||||
memset(&sp, 0, sizeof(sp));
|
||||
sp.param = param;
|
||||
sp.value = value;
|
||||
|
||||
if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 SetParam Failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[drm] Mapping front buffer\n");
|
||||
|
||||
if (drmAddMap(ctx->drmFD,
|
||||
(drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
|
||||
sarea->front_size,
|
||||
DRM_FRAME_BUFFER, /*DRM_AGP,*/
|
||||
0,
|
||||
&sarea->front_handle) < 0) {
|
||||
fprintf(stderr,
|
||||
"[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
|
||||
return FALSE;
|
||||
}
|
||||
ctx->shared.hFrameBuffer = sarea->front_handle;
|
||||
ctx->shared.fbSize = sarea->front_size;
|
||||
fprintf(stderr, "[drm] Front Buffer = 0x%08x\n",
|
||||
sarea->front_handle);
|
||||
|
||||
if (drmAddMap(ctx->drmFD,
|
||||
(drm_handle_t)(sarea->back_offset),
|
||||
sarea->back_size, DRM_AGP, 0,
|
||||
&sarea->back_handle) < 0) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"[drm] drmAddMap(back_handle) failed. Disabling DRI\n");
|
||||
return FALSE;
|
||||
}
|
||||
fprintf(stderr, "[drm] Back Buffer = 0x%08x\n",
|
||||
sarea->back_handle);
|
||||
|
||||
if (drmAddMap(ctx->drmFD,
|
||||
(drm_handle_t)sarea->depth_offset,
|
||||
sarea->depth_size, DRM_AGP, 0,
|
||||
&sarea->depth_handle) < 0) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"[drm] drmAddMap(depth_handle) failed. Disabling DRI\n");
|
||||
return FALSE;
|
||||
}
|
||||
fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n",
|
||||
sarea->depth_handle);
|
||||
|
||||
if (drmAddMap(ctx->drmFD,
|
||||
(drm_handle_t)sarea->tex_offset,
|
||||
sarea->tex_size, DRM_AGP, 0,
|
||||
&sarea->tex_handle) < 0) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"[drm] drmAddMap(tex_handle) failed. Disabling DRI\n");
|
||||
return FALSE;
|
||||
}
|
||||
fprintf(stderr, "[drm] textures = 0x%08x\n",
|
||||
sarea->tex_handle);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
|
||||
{
|
||||
#if 1
|
||||
if (sarea->front_handle) {
|
||||
drmRmMap(ctx->drmFD, sarea->front_handle);
|
||||
sarea->front_handle = 0;
|
||||
}
|
||||
#endif
|
||||
if (sarea->back_handle) {
|
||||
drmRmMap(ctx->drmFD, sarea->back_handle);
|
||||
sarea->back_handle = 0;
|
||||
}
|
||||
if (sarea->depth_handle) {
|
||||
drmRmMap(ctx->drmFD, sarea->depth_handle);
|
||||
sarea->depth_handle = 0;
|
||||
}
|
||||
if (sarea->tex_handle) {
|
||||
drmRmMap(ctx->drmFD, sarea->tex_handle);
|
||||
sarea->tex_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
|
||||
{
|
||||
/* Start up the simple memory manager for agp space */
|
||||
drmI830MemInitHeap drmHeap;
|
||||
drmHeap.region = I830_MEM_REGION_AGP;
|
||||
drmHeap.start = 0;
|
||||
drmHeap.size = sarea->tex_size;
|
||||
|
||||
if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT_HEAP,
|
||||
&drmHeap, sizeof(drmHeap))) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"[drm] Failed to initialized agp heap manager\n");
|
||||
} else {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"[drm] Initialized kernel agp heap manager, %d\n",
|
||||
sarea->tex_size);
|
||||
|
||||
I830SetParam(ctx, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY,
|
||||
sarea->log_tex_granularity);
|
||||
}
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
|
||||
{
|
||||
if (drmAddMap(ctx->drmFD,
|
||||
(drm_handle_t)pI830->LpRing->mem.Start,
|
||||
pI830->LpRing->mem.Size, DRM_AGP, 0,
|
||||
&pI830->ring_map) < 0) {
|
||||
fprintf(stderr,
|
||||
"[drm] drmAddMap(ring_map) failed. Disabling DRI\n");
|
||||
return FALSE;
|
||||
}
|
||||
fprintf(stderr, "[drm] ring buffer = 0x%08x\n",
|
||||
pI830->ring_map);
|
||||
|
||||
if (I830InitDma(ctx, pI830) == FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* init to zero to be safe */
|
||||
|
||||
I830DRIMapScreenRegions(ctx, pI830, sarea);
|
||||
I830InitTextureHeap(ctx, pI830, sarea);
|
||||
|
||||
if (ctx->pciDevice != PCI_CHIP_845_G &&
|
||||
ctx->pciDevice != PCI_CHIP_I830_M) {
|
||||
I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 );
|
||||
}
|
||||
|
||||
/* Okay now initialize the dma engine */
|
||||
{
|
||||
pI830->irq = drmGetInterruptFromBusID(ctx->drmFD,
|
||||
ctx->pciBus,
|
||||
ctx->pciDevice,
|
||||
ctx->pciFunc);
|
||||
|
||||
if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"[drm] failure adding irq handler\n");
|
||||
pI830->irq = 0;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"[drm] dma control initialized, using IRQ %d\n",
|
||||
pI830DRI->irq);
|
||||
}
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
|
||||
{
|
||||
/* need to drmMap front and back buffers and zero them */
|
||||
drmAddressPtr map_addr;
|
||||
int ret;
|
||||
|
||||
ret = drmMap(ctx->drmFD,
|
||||
sarea->front_handle,
|
||||
sarea->front_size,
|
||||
map_addr);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
fprintf(stderr, "Unable to map front buffer\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
drimemsetio((char *)map_addr,
|
||||
0,
|
||||
sarea->front_size);
|
||||
drmUnmap(map_addr, sarea->front_size);
|
||||
|
||||
|
||||
ret = drmMap(ctx->drmFD,
|
||||
sarea->back_handle,
|
||||
sarea->back_size,
|
||||
map_addr);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
fprintf(stderr, "Unable to map back buffer\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
drimemsetio((char *)map_addr,
|
||||
0,
|
||||
sarea->back_size);
|
||||
drmUnmap(map_addr, sarea->back_size);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
|
||||
|
||||
{
|
||||
I830DRIPtr pI830DRI;
|
||||
drmI830Sarea *pSAREAPriv;
|
||||
int err;
|
||||
|
||||
|
||||
drm_page_size = getpagesize();
|
||||
|
||||
pI830->registerSize = ctx->MMIOSize;
|
||||
/* This is a hack for now. We have to have more than a 4k page here
|
||||
* because of the size of the state. However, the state should be
|
||||
* in a per-context mapping. This will be added in the Mesa 3.5 port
|
||||
* of the I830 driver.
|
||||
*/
|
||||
ctx->shared.SAREASize = SAREA_MAX;
|
||||
|
||||
/* Note that drmOpen will try to load the kernel module, if needed. */
|
||||
ctx->drmFD = drmOpen("i915", NULL );
|
||||
if (ctx->drmFD < 0) {
|
||||
fprintf(stderr, "[drm] drmOpen failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
|
||||
fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
|
||||
ctx->drmFD, ctx->pciBusID, strerror(-err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (drmAddMap( ctx->drmFD,
|
||||
0,
|
||||
ctx->shared.SAREASize,
|
||||
DRM_SHM,
|
||||
DRM_CONTAINS_LOCK,
|
||||
&ctx->shared.hSAREA) < 0)
|
||||
{
|
||||
fprintf(stderr, "[drm] drmAddMap failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n",
|
||||
ctx->shared.SAREASize, ctx->shared.hSAREA);
|
||||
|
||||
if (drmMap( ctx->drmFD,
|
||||
ctx->shared.hSAREA,
|
||||
ctx->shared.SAREASize,
|
||||
(drmAddressPtr)(&ctx->pSAREA)) < 0)
|
||||
{
|
||||
fprintf(stderr, "[drm] drmMap failed\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
|
||||
fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n",
|
||||
ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
|
||||
|
||||
|
||||
if (drmAddMap(ctx->drmFD,
|
||||
ctx->MMIOStart,
|
||||
ctx->MMIOSize,
|
||||
DRM_REGISTERS,
|
||||
DRM_READ_ONLY,
|
||||
&pI830->registerHandle) < 0) {
|
||||
fprintf(stderr, "[drm] drmAddMap mmio failed\n");
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"[drm] register handle = 0x%08x\n", pI830->registerHandle);
|
||||
|
||||
|
||||
if (!I830CheckDRMVersion(ctx, pI830)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create a 'server' context so we can grab the lock for
|
||||
* initialization ioctls.
|
||||
*/
|
||||
if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
|
||||
fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
|
||||
|
||||
/* Initialize the SAREA private data structure */
|
||||
pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) +
|
||||
sizeof(drm_sarea_t));
|
||||
memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
|
||||
|
||||
pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830);
|
||||
pI830->StolenMemory.Start = 0;
|
||||
pI830->StolenMemory.End = pI830->StolenMemory.Size;
|
||||
|
||||
pI830->MemoryAperture.Start = pI830->StolenMemory.End;
|
||||
pI830->MemoryAperture.End = KB(40000);
|
||||
pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start;
|
||||
|
||||
if (!AgpInit(ctx, pI830))
|
||||
return FALSE;
|
||||
|
||||
if (I830AllocateMemory(ctx, pI830) == FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (I830BindMemory(ctx, pI830) == FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pSAREAPriv->front_offset = pI830->FrontBuffer.Start;
|
||||
pSAREAPriv->front_size = pI830->FrontBuffer.Size;
|
||||
pSAREAPriv->width = ctx->shared.virtualWidth;
|
||||
pSAREAPriv->height = ctx->shared.virtualHeight;
|
||||
pSAREAPriv->pitch = ctx->shared.virtualWidth;
|
||||
pSAREAPriv->virtualX = ctx->shared.virtualWidth;
|
||||
pSAREAPriv->virtualY = ctx->shared.virtualHeight;
|
||||
pSAREAPriv->back_offset = pI830->BackBuffer.Start;
|
||||
pSAREAPriv->back_size = pI830->BackBuffer.Size;
|
||||
pSAREAPriv->depth_offset = pI830->DepthBuffer.Start;
|
||||
pSAREAPriv->depth_size = pI830->DepthBuffer.Size;
|
||||
pSAREAPriv->tex_offset = pI830->TexMem.Start;
|
||||
pSAREAPriv->tex_size = pI830->TexMem.Size;
|
||||
pSAREAPriv->log_tex_granularity = pI830->TexGranularity;
|
||||
|
||||
ctx->driverClientMsg = malloc(sizeof(I830DRIRec));
|
||||
ctx->driverClientMsgSize = sizeof(I830DRIRec);
|
||||
pI830DRI = (I830DRIPtr)ctx->driverClientMsg;
|
||||
pI830DRI->deviceID = pI830->Chipset;
|
||||
pI830DRI->regsSize = I830_REG_SIZE;
|
||||
pI830DRI->width = ctx->shared.virtualWidth;
|
||||
pI830DRI->height = ctx->shared.virtualHeight;
|
||||
pI830DRI->mem = ctx->shared.fbSize;
|
||||
pI830DRI->cpp = ctx->cpp;
|
||||
pI830DRI->backOffset = pI830->BackBuffer.Start;
|
||||
pI830DRI->backPitch = pI830->BackBuffer.Pitch;
|
||||
|
||||
pI830DRI->depthOffset = pI830->DepthBuffer.Start;
|
||||
pI830DRI->depthPitch = pI830->DepthBuffer.Pitch;
|
||||
|
||||
pI830DRI->fbOffset = pI830->FrontBuffer.Start;
|
||||
pI830DRI->fbStride = pI830->FrontBuffer.Pitch;
|
||||
|
||||
pI830DRI->bitsPerPixel = ctx->bpp;
|
||||
pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t);
|
||||
|
||||
err = I830DRIDoMappings(ctx, pI830, pSAREAPriv);
|
||||
if (err == FALSE)
|
||||
return FALSE;
|
||||
|
||||
I830SetRingRegs(ctx, pI830);
|
||||
|
||||
/* Quick hack to clear the front & back buffers. Could also use
|
||||
* the clear ioctl to do this, but would need to setup hw state
|
||||
* first.
|
||||
*/
|
||||
I830ClearScreen(ctx, pI830, pSAREAPriv);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Validate the fbdev mode.
|
||||
*
|
||||
* \param ctx display handle.
|
||||
*
|
||||
* \return one on success, or zero on failure.
|
||||
*
|
||||
* Saves some registers and returns 1.
|
||||
*
|
||||
* \sa radeonValidateMode().
|
||||
*/
|
||||
static int i830ValidateMode( const DRIDriverContext *ctx )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Examine mode returned by fbdev.
|
||||
*
|
||||
* \param ctx display handle.
|
||||
*
|
||||
* \return one on success, or zero on failure.
|
||||
*
|
||||
* Restores registers that fbdev has clobbered and returns 1.
|
||||
*
|
||||
* \sa i810ValidateMode().
|
||||
*/
|
||||
static int i830PostValidateMode( const DRIDriverContext *ctx )
|
||||
{
|
||||
I830Rec *pI830 = ctx->driverPrivate;
|
||||
|
||||
I830SetRingRegs(ctx, pI830);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize the framebuffer device mode
|
||||
*
|
||||
* \param ctx display handle.
|
||||
*
|
||||
* \return one on success, or zero on failure.
|
||||
*
|
||||
* Fills in \p info with some default values and some information from \p ctx
|
||||
* and then calls I810ScreenInit() for the screen initialization.
|
||||
*
|
||||
* Before exiting clears the framebuffer memory accessing it directly.
|
||||
*/
|
||||
static int i830InitFBDev( DRIDriverContext *ctx )
|
||||
{
|
||||
I830Rec *pI830 = calloc(1, sizeof(I830Rec));
|
||||
|
||||
{
|
||||
int dummy = ctx->shared.virtualWidth;
|
||||
|
||||
switch (ctx->bpp / 8) {
|
||||
case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
|
||||
case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break;
|
||||
case 3:
|
||||
case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break;
|
||||
}
|
||||
|
||||
ctx->shared.virtualWidth = dummy;
|
||||
}
|
||||
|
||||
ctx->driverPrivate = (void *)pI830;
|
||||
|
||||
pI830->LpRing = calloc(1, sizeof(I830RingBuffer));
|
||||
pI830->Chipset = ctx->chipset;
|
||||
pI830->LinearAddr = ctx->FBStart;
|
||||
|
||||
if (!I830ScreenInit( ctx, pI830 ))
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief The screen is being closed, so clean up any state and free any
|
||||
* resources used by the DRI.
|
||||
*
|
||||
* \param ctx display handle.
|
||||
*
|
||||
* Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
|
||||
* private data.
|
||||
*/
|
||||
static void i830HaltFBDev( DRIDriverContext *ctx )
|
||||
{
|
||||
drmI830Sarea *pSAREAPriv;
|
||||
I830Rec *pI830 = ctx->driverPrivate;
|
||||
|
||||
if (pI830->irq) {
|
||||
drmCtlUninstHandler(ctx->drmFD);
|
||||
pI830->irq = 0; }
|
||||
|
||||
I830CleanupDma(ctx);
|
||||
|
||||
pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) +
|
||||
sizeof(drm_sarea_t));
|
||||
|
||||
I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv);
|
||||
drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
|
||||
drmClose(ctx->drmFD);
|
||||
|
||||
if (ctx->driverPrivate) {
|
||||
free(ctx->driverPrivate);
|
||||
ctx->driverPrivate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern void i810NotifyFocus( int );
|
||||
|
||||
/**
|
||||
* \brief Exported driver interface for Mini GLX.
|
||||
*
|
||||
* \sa DRIDriverRec.
|
||||
*/
|
||||
const struct DRIDriverRec __driDriver = {
|
||||
i830ValidateMode,
|
||||
i830PostValidateMode,
|
||||
i830InitFBDev,
|
||||
i830HaltFBDev,
|
||||
NULL,//I830EngineShutdown,
|
||||
NULL, //I830EngineRestore,
|
||||
#ifndef _EMBEDDED
|
||||
0,
|
||||
#else
|
||||
i810NotifyFocus,
|
||||
#endif
|
||||
};
|
||||
Loading…
Add table
Reference in a new issue