+++ /dev/null
-/**
- * \file server/i810_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) 2004 Dave Airlie (airlied@linux.ie)
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "driver.h"
-#include "drm.h"
-
-#include "i810.h"
-#include "i810_dri.h"
-#include "i810_reg.h"
-
-
-static int i810_pitches[] = {
- 512,
- 1024,
- 2048,
- 4096,
- 0
-};
-
-static int i810_pitch_flags[] = {
- 0x0,
- 0x1,
- 0x2,
- 0x3,
- 0
-};
-
-static unsigned int i810_drm_version = 0;
-
-static int
-I810AllocLow(I810MemRange * result, I810MemRange * pool, int size)
-{
- if (size > pool->Size)
- return 0;
-
- pool->Size -= size;
- result->Size = size;
- result->Start = pool->Start;
- result->End = pool->Start += size;
-
- return 1;
-}
-
-static int
-I810AllocHigh(I810MemRange * result, I810MemRange * pool, int size)
-{
- if (size > pool->Size)
- return 0;
-
- pool->Size -= size;
- result->Size = size;
- result->End = pool->End;
- result->Start = pool->End -= size;
-
- return 1;
-}
-
-
-/**
- * \brief Wait for free FIFO entries.
- *
- * \param ctx display handle.
- * \param entries number of free entries to wait.
- *
- * It polls the free entries from the chip until it reaches the requested value
- * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out.
- */
-static void I810WaitForFifo( const DRIDriverContext *ctx,
- int entries )
-{
-}
-
-/**
- * \brief Reset graphics card to known state.
- *
- * \param ctx display handle.
- *
- * Resets the values of several I810 registers.
- */
-static void I810EngineReset( const DRIDriverContext *ctx )
-{
- unsigned char *I810MMIO = ctx->MMIOAddress;
-}
-
-/**
- * \brief Restore the drawing engine.
- *
- * \param ctx display handle
- *
- * Resets the graphics card and sets initial values for several registers of
- * the card's drawing engine.
- *
- * Turns on the i810 command processor engine (i.e., the ringbuffer).
- */
-static int I810EngineRestore( const DRIDriverContext *ctx )
-{
- I810Ptr info = ctx->driverPrivate;
- unsigned char *I810MMIO = ctx->MMIOAddress;
-
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- return 1;
-}
-
-
-/**
- * \brief Shutdown the drawing engine.
- *
- * \param ctx display handle
- *
- * Turns off the command processor engine & restores the graphics card
- * to a state that fbdev understands.
- */
-static int I810EngineShutdown( const DRIDriverContext *ctx )
-{
- drmI810Init info;
- int ret;
-
- memset(&info, 0, sizeof(drmI810Init));
- info.func = I810_CLEANUP_DMA;
-
- ret = drmCommandWrite(ctx->drmFD, DRM_I810_INIT, &info, sizeof(drmI810Init));
- if (ret>0)
- {
- fprintf(stderr,"[dri] I810 DMA Cleanup failed\n");
- return -errno;
- }
- return 0;
-}
-
-/**
- * \brief Compute base 2 logarithm.
- *
- * \param val value.
- *
- * \return base 2 logarithm of \p val.
- */
-static int I810MinBits(int val)
-{
- int bits;
-
- if (!val) return 1;
- for (bits = 0; val; val >>= 1, ++bits);
- return bits;
-}
-
-static int I810DRIAgpPreInit( const DRIDriverContext *ctx, I810Ptr info)
-{
-
- if (drmAgpAcquire(ctx->drmFD) < 0) {
- fprintf(stderr, "[gart] AGP not available\n");
- return 0;
- }
-
-
- if (drmAgpEnable(ctx->drmFD, 0) < 0) {
- fprintf(stderr, "[gart] AGP not enabled\n");
- drmAgpRelease(ctx->drmFD);
- return 0;
- }
-}
-
-/**
- * \brief Initialize the AGP state
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * \return one on success, or zero on failure.
- *
- * Acquires and enables the AGP device. Reserves memory in the AGP space for
- * the ring buffer, vertex buffers and textures. Initialize the I810
- * registers to point to that memory and add client mappings.
- */
-static int I810DRIAgpInit( const DRIDriverContext *ctx, I810Ptr info)
-{
- unsigned char *I810MMIO = ctx->MMIOAddress;
- int ret;
- int s, l;
- unsigned long dcacheHandle;
- unsigned long agpHandle;
- int pitch_idx = 0;
- int back_size = 0;
- int sysmem_size = 0;
- int width = ctx->shared.virtualWidth * ctx->cpp;
-
-
- info->backHandle = DRM_AGP_NO_HANDLE;
- info->zHandle = DRM_AGP_NO_HANDLE;
- info->sysmemHandle = DRM_AGP_NO_HANDLE;
- info->dcacheHandle = DRM_AGP_NO_HANDLE;
-
- memset(&info->DcacheMem, 0, sizeof(I810MemRange));
- memset(&info->BackBuffer, 0, sizeof(I810MemRange));
- memset(&info->DepthBuffer, 0, sizeof(I810MemRange));
-
- drmAgpAlloc(ctx->drmFD, 4096 * 1024, 1, NULL, &dcacheHandle);
- info->dcacheHandle = dcacheHandle;
-
- fprintf(stderr, "[agp] dcacheHandle : 0x%x\n", dcacheHandle);
-
-#define Elements(x) sizeof(x)/sizeof(*x)
- for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++)
- if (width <= i810_pitches[pitch_idx])
- break;
-
- if (pitch_idx == Elements(i810_pitches)) {
- fprintf(stderr,"[dri] Couldn't find depth/back buffer pitch\n");
- exit(-1);
- }
- else
- {
- int lines = (ctx->shared.virtualWidth + 15) / 16 * 16;
- back_size = i810_pitches[pitch_idx] * lines;
- back_size = ((back_size + 4096 - 1) / 4096) * 4096;
- }
-
- sysmem_size = ctx->shared.fbSize;
- fprintf(stderr,"sysmem_size is %lu back_size is %lu\n", sysmem_size, back_size);
- if (dcacheHandle != DRM_AGP_NO_HANDLE) {
- if (back_size > 4 * 1024 * 1024) {
- fprintf(stderr,"[dri] Backsize is larger then 4 meg\n");
- sysmem_size = sysmem_size - 2 * back_size;
- drmAgpFree(ctx->drmFD, dcacheHandle);
- info->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
- } else {
- sysmem_size = sysmem_size - back_size;
- }
- } else {
- sysmem_size = sysmem_size - 2 * back_size;
- }
-
- info->SysMem.Start=0;
- info->SysMem.Size = sysmem_size;
- info->SysMem.End = sysmem_size;
-
- if (dcacheHandle != DRM_AGP_NO_HANDLE) {
- if (drmAgpBind(ctx->drmFD, dcacheHandle, info->DepthOffset) == 0) {
- memset(&info->DcacheMem, 0, sizeof(I810MemRange));
- fprintf(stderr,"[agp] GART: Found 4096K Z buffer memory\n");
- info->DcacheMem.Start = info->DepthOffset;
- info->DcacheMem.Size = 1024 * 4096;
- info->DcacheMem.End = info->DcacheMem.Start + info->DcacheMem.Size;
- } else {
- fprintf(stderr, "[agp] GART: dcache bind failed\n");
- drmAgpFree(ctx->drmFD, dcacheHandle);
- info->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
- }
- } else {
- fprintf(stderr, "[agp] GART: no dcache memory found\n");
- }
-
- drmAgpAlloc(ctx->drmFD, back_size, 0, NULL, &agpHandle);
- info->backHandle = agpHandle;
-
- if (agpHandle != DRM_AGP_NO_HANDLE) {
- if (drmAgpBind(ctx->drmFD, agpHandle, info->BackOffset) == 0) {
- fprintf(stderr, "[agp] Bound backbuffer memory\n");
-
- info->BackBuffer.Start = info->BackOffset;
- info->BackBuffer.Size = back_size;
- info->BackBuffer.End = (info->BackBuffer.Start +
- info->BackBuffer.Size);
- } else {
- fprintf(stderr,"[agp] Unable to bind backbuffer. Disabling DRI.\n");
- return 0;
- }
- } else {
- fprintf(stderr, "[dri] Unable to allocate backbuffer memory. Disabling DRI.\n");
- return 0;
- }
-
- if (dcacheHandle == DRM_AGP_NO_HANDLE) {
- drmAgpAlloc(ctx->drmFD, back_size, 0, NULL, &agpHandle);
-
- info->zHandle = agpHandle;
-
- if (agpHandle != DRM_AGP_NO_HANDLE) {
- if (drmAgpBind(ctx->drmFD, agpHandle, info->DepthOffset) == 0) {
- fprintf(stderr,"[agp] Bound depthbuffer memory\n");
- info->DepthBuffer.Start = info->DepthOffset;
- info->DepthBuffer.Size = back_size;
- info->DepthBuffer.End = (info->DepthBuffer.Start +
- info->DepthBuffer.Size);
- } else {
- fprintf(stderr,"[agp] Unable to bind depthbuffer. Disabling DRI.\n");
- return 0;
- }
- } else {
- fprintf(stderr,"[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n");
- return 0;
- }
- }
-
- /* Now allocate and bind the agp space. This memory will include the
- * regular framebuffer as well as texture memory.
- */
- drmAgpAlloc(ctx->drmFD, sysmem_size, 0, NULL, &agpHandle);
- info->sysmemHandle = agpHandle;
-
- if (agpHandle != DRM_AGP_NO_HANDLE) {
- if (drmAgpBind(ctx->drmFD, agpHandle, 0) == 0) {
- fprintf(stderr, "[agp] Bound System Texture Memory\n");
- } else {
- fprintf(stderr, "[agp] Unable to bind system texture memory. Disabling DRI.\n");
- return 0;
- }
- } else {
- fprintf(stderr, "[agp] Unable to allocate system texture memory. Disabling DRI.\n");
- return 0;
- }
-
- info->auxPitch = i810_pitches[pitch_idx];
- info->auxPitchBits = i810_pitch_flags[pitch_idx];
-
- return 1;
-}
-
-
-/**
- * \brief Initialize the kernel data structures and enable the CP engine.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * \return non-zero on success, or zero on failure.
- *
- * This function is a wrapper around the DRM_I810_CP_INIT command, passing
- * all the parameters in a drmI810Init structure.
- */
-static int I810DRIKernelInit( const DRIDriverContext *ctx,
- I810Ptr info)
-{
- int cpp = ctx->bpp / 8;
- drmI810Init drmInfo;
- int ret;
- I810RingBuffer *ring = &(info->LpRing);
-
- /* This is the struct passed to the kernel module for its initialization */
- memset(&drmInfo, 0, sizeof(drmI810Init));
-
- /* make sure we have at least 1.4 */
- drmInfo.func = I810_INIT_DMA_1_4;
-
- drmInfo.ring_start = ring->mem.Start;
- drmInfo.ring_end = ring->mem.End;
- drmInfo.ring_size = ring->mem.Size;
-
- drmInfo.mmio_offset = (unsigned int)info->regs;
- drmInfo.buffers_offset = (unsigned int)info->buffer_map;
- drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
-
- drmInfo.front_offset = 0;
- drmInfo.back_offset = info->BackBuffer.Start;
- drmInfo.depth_offset = info->DepthBuffer.Start;
-
- drmInfo.w = ctx->shared.virtualWidth;
- drmInfo.h = ctx->shared.virtualHeight;
- drmInfo.pitch = info->auxPitch;
- drmInfo.pitch_bits = info->auxPitchBits;
-
-
- ret = drmCommandWrite(ctx->drmFD, DRM_I810_INIT, &drmInfo,
- sizeof(drmI810Init));
-
- return ret >= 0;
-}
-
-
-/**
- * \brief Add a map for the vertex buffers that will be accessed by any
- * DRI-based clients.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * \return one on success, or zero on failure.
- *
- * Calls drmAddBufs() with the previously allocated vertex buffers.
- */
-static int I810DRIBufInit( const DRIDriverContext *ctx, I810Ptr info )
-{
- /* Initialize vertex buffers */
- info->bufNumBufs = drmAddBufs(ctx->drmFD,
- I810_DMA_BUF_NR,
- I810_DMA_BUF_SZ,
- DRM_AGP_BUFFER,
- info->BufferMem.Start);
-
- if (info->bufNumBufs <= 0) {
- fprintf(stderr,
- "[drm] Could not create vertex/indirect buffers list\n");
- return 0;
- }
- fprintf(stderr,
- "[drm] Added %d %d byte vertex/indirect buffers\n",
- info->bufNumBufs, I810_DMA_BUF_SZ);
-
- return 1;
-}
-
-/**
- * \brief Install an IRQ handler.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
- * IRQ-free operation on failure.
- */
-static void I810DRIIrqInit(const DRIDriverContext *ctx,
- I810Ptr info)
-{
- if (!info->irq) {
- info->irq = drmGetInterruptFromBusID(ctx->drmFD,
- ctx->pciBus,
- ctx->pciDevice,
- ctx->pciFunc);
-
- if ((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) {
- fprintf(stderr,
- "[drm] failure adding irq handler, "
- "there is a device already using that irq\n"
- "[drm] falling back to irq-free operation\n");
- info->irq = 0;
- }
- }
-
- if (info->irq)
- fprintf(stderr,
- "[drm] dma control initialized, using IRQ %d\n",
- info->irq);
-}
-
-static int I810CheckDRMVersion( const DRIDriverContext *ctx,
- I810Ptr info )
-{
- drmVersionPtr version;
-
- version = drmGetVersion(ctx->drmFD);
- if (version) {
- int req_minor, req_patch;
-
- req_minor = 4;
- req_patch = 0;
-
- i810_drm_version = (version->version_major<<16) | version->version_minor;
- 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] I810DRIScreenInit failed because of a version "
- "mismatch.\n"
- "[dri] i810.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;
- }
-
- info->drmMinor = version->version_minor;
- drmFreeVersion(version);
- }
-
- return 1;
-}
-
-static int I810MemoryInit( const DRIDriverContext *ctx, I810Ptr info )
-{
- int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
- int cpp = ctx->cpp;
- int bufferSize = (ctx->shared.virtualHeight * width_bytes);
- int depthSize = (((ctx->shared.virtualHeight+15) & ~15) * width_bytes);
- int l;
-
- if (drmAddMap(ctx->drmFD, (drm_handle_t) info->BackBuffer.Start,
- info->BackBuffer.Size, DRM_AGP, 0,
- &info->backbuffer) < 0) {
- fprintf(stderr, "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n");
- return 0;
- }
-
- if (drmAddMap(ctx->drmFD, (drm_handle_t) info->DepthBuffer.Start,
- info->DepthBuffer.Size, DRM_AGP, 0,
- &info->depthbuffer) < 0) {
- fprintf(stderr, "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n");
- return 0;
- }
-
- if (!I810AllocLow(&(info->FrontBuffer), &(info->SysMem), (((ctx->shared.virtualHeight * width_bytes) + 4095) & ~4095)))
- {
- fprintf(stderr,"Framebuffer allocation failed\n");
- return 0;
- }
- else
- fprintf(stderr,"Frame buffer at 0x%.8x (%luk, %lu bytes)\n",
- info->FrontBuffer.Start,
- info->FrontBuffer.Size / 1024, info->FrontBuffer.Size);
-
- memset(&(info->LpRing), 0, sizeof(I810RingBuffer));
- if (I810AllocLow(&(info->LpRing.mem), &(info->SysMem), 16 * 4096)) {
- fprintf(stderr,
- "Ring buffer at 0x%.8x (%luk, %lu bytes)\n",
- info->LpRing.mem.Start,
- info->LpRing.mem.Size / 1024, info->LpRing.mem.Size);
-
- info->LpRing.tail_mask = info->LpRing.mem.Size - 1;
- info->LpRing.virtual_start = info->LpRing.mem.Start;
- info->LpRing.head = 0;
- info->LpRing.tail = 0;
- info->LpRing.space = 0;
- } else {
- fprintf(stderr, "Ring buffer allocation failed\n");
- return (0);
- }
-
- /* Allocate buffer memory */
- I810AllocHigh(&(info->BufferMem), &(info->SysMem),
- I810_DMA_BUF_NR * I810_DMA_BUF_SZ);
-
-
- fprintf(stderr, "[dri] Buffer map : %lx\n",
- info->BufferMem.Start);
-
- if (info->BufferMem.Start == 0 ||
- info->BufferMem.End - info->BufferMem.Start >
- I810_DMA_BUF_NR * I810_DMA_BUF_SZ) {
- fprintf(stderr,"[dri] Not enough memory for dma buffers. Disabling DRI.\n");
- return 0;
- }
-
- if (drmAddMap(ctx->drmFD, (drm_handle_t) info->BufferMem.Start,
- info->BufferMem.Size, DRM_AGP, 0, &info->buffer_map) < 0) {
- fprintf(stderr, "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n");
- return 0;
- }
-
- if (drmAddMap(ctx->drmFD, (drm_handle_t) info->LpRing.mem.Start,
- info->LpRing.mem.Size, DRM_AGP, 0, &info->ring_map) < 0) {
- fprintf(stderr, "[drm] drmAddMap(ring_map) failed. Disabling DRI. \n");
- return 0;
- }
-
- /* Front, back and depth buffers - everything else texture??
- */
- info->textureSize = info->SysMem.Size;
-
- if (info->textureSize < 0)
- return 0;
-
-
- l = I810MinBits((info->textureSize-1) / I810_NR_TEX_REGIONS);
- if (l < I810_LOG_MIN_TEX_REGION_SIZE) l = I810_LOG_MIN_TEX_REGION_SIZE;
-
- /* Round the texture size up to the nearest whole number of
- * texture regions. Again, be greedy about this, don't
- * round down.
- */
- info->logTextureGranularity = l;
- info->textureSize = (info->textureSize >> l) << l;
-
- /* Set a minimum usable local texture heap size. This will fit
- * two 256x256x32bpp textures.
- */
- if (info->textureSize < 512 * 1024) {
- info->textureOffset = 0;
- info->textureSize = 0;
- }
-
- I810AllocLow(&(info->TexMem), &(info->SysMem), info->textureSize);
-
- if (drmAddMap(ctx->drmFD, (drm_handle_t) info->TexMem.Start,
- info->TexMem.Size, DRM_AGP, 0, &info->textures) < 0) {
- fprintf(stderr,
- "[drm] drmAddMap(textures) failed. Disabling DRI.\n");
- return 0;
- }
-
- /* Reserve space for textures */
- fprintf(stderr,
- "Will use back buffer at offset 0x%x\n",
- info->BackOffset);
- fprintf(stderr,
- "Will use depth buffer at offset 0x%x\n",
- info->DepthOffset);
- fprintf(stderr,
- "Will use %d kb for textures at offset 0x%x\n",
- info->TexMem.Size/1024, info->TexMem.Start);
-
- return 1;
-}
-
-
-
-/**
- * Called at the start of each server generation.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * \return non-zero on success, or zero on failure.
- *
- * Performs static frame buffer allocation. Opens the DRM device and add maps
- * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
- * information. Creates a \e server context to grab the lock for the
- * initialization ioctls and calls the other initilization functions in this
- * file. Starts the CP engine via the DRM_I810_CP_START command.
- *
- * Setups a I810DRIRec structure to be passed to i810_dri.so for its
- * initialization.
- */
-static int I810ScreenInit( DRIDriverContext *ctx, I810Ptr info )
-{
- I810DRIPtr pI810DRI;
- int err;
-
- usleep(100);
- /*assert(!ctx->IsClient);*/
-
- /* from XFree86 driver */
- info->DepthOffset = 0x3000000;
- info->BackOffset = 0x3800000;
- {
- int width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
- int maxy = ctx->shared.fbSize / width_bytes;
-
-
- if (maxy <= ctx->shared.virtualHeight * 3) {
- fprintf(stderr,
- "Static buffer allocation failed -- "
- "need at least %d kB video memory (have %d kB)\n",
- (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
- ctx->cpp * 3 + 1023) / 1024,
- ctx->shared.fbSize / 1024);
- return 0;
- }
- }
-
-
- info->regsSize = ctx->MMIOSize;
- ctx->shared.SAREASize = 0x2000;
-
- /* Note that drmOpen will try to load the kernel module, if needed. */
- ctx->drmFD = drmOpen("i810", 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%08lx\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%08lx 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,
- &info->regs) < 0) {
- fprintf(stderr, "[drm] drmAddMap mmio failed\n");
- return 0;
- }
- fprintf(stderr,
- "[drm] register handle = 0x%08x\n", info->regs);
-
- I810DRIAgpPreInit(ctx, info);
- /* Need to AddMap the framebuffer and mmio regions here:
- */
- if (drmAddMap( ctx->drmFD,
- (drm_handle_t)ctx->FBStart,
- ctx->FBSize,
- DRM_FRAME_BUFFER,
-#ifndef _EMBEDDED
- 0,
-#else
- DRM_READ_ONLY,
-#endif
- &ctx->shared.hFrameBuffer) < 0)
- {
- fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
- return 0;
- }
-
- fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
- ctx->shared.hFrameBuffer);
-
- /* Check the i810 DRM version */
- if (!I810CheckDRMVersion(ctx, info)) {
- return 0;
- }
-
- /* Initialize AGP */
- if (!I810DRIAgpInit(ctx, info)) {
- return 0;
- }
-
-
- /* Memory manager setup */
- if (!I810MemoryInit(ctx, info)) {
- return 0;
- }
-
- /* Initialize the SAREA private data structure */
- {
- I810SAREAPtr pSAREAPriv;
- pSAREAPriv = (I810SAREAPtr)(((char*)ctx->pSAREA) +
- sizeof(drm_sarea_t));
- memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
- // pSAREAPriv->pf_enabled=1;
- }
-
-
- /* 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 vertex buffers list */
- if (!I810DRIBufInit(ctx, info)) {
- fprintf(stderr, "I810DRIBufInit failed\n");
- DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
- return 0;
- }
-
- /* Initialize the kernel data structures */
- if (!I810DRIKernelInit(ctx, info)) {
- fprintf(stderr, "I810DRIKernelInit failed\n");
- DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
- return 0;
- }
-
- /* Initialize IRQ */
- I810DRIIrqInit(ctx, info);
-
- /* 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.
- */
-#if 0
- memset((char *)ctx->FBAddress,
- 0,
- info->auxPitch * ctx->cpp * ctx->shared.virtualHeight );
-
- memset((char *)info->backbuffer,
- 0,
- info->auxPitch * ctx->cpp * ctx->shared.virtualHeight );
-#endif
-
- /* This is the struct passed to i810_dri.so for its initialization */
- ctx->driverClientMsg = malloc(sizeof(I810DRIRec));
- ctx->driverClientMsgSize = sizeof(I810DRIRec);
- pI810DRI = (I810DRIPtr)ctx->driverClientMsg;
-
- pI810DRI->regs = info->regs;
- pI810DRI->regsSize = info->regsSize;
- // regsMap is unused
-
- pI810DRI->backbufferSize = info->BackBuffer.Size;
- pI810DRI->backbuffer = info->backbuffer;
-
- pI810DRI->depthbufferSize = info->DepthBuffer.Size;
- pI810DRI->depthbuffer = info->depthbuffer;
-
- pI810DRI->textures = info->textures;
- pI810DRI->textureSize = info->textureSize;
-
- pI810DRI->agp_buffers = info->buffer_map;
- pI810DRI->agp_buf_size = info->BufferMem.Size;
-
- pI810DRI->deviceID = info->Chipset;
- pI810DRI->width = ctx->shared.virtualWidth;
- pI810DRI->height = ctx->shared.virtualHeight;
- pI810DRI->mem = ctx->shared.fbSize;
- pI810DRI->cpp = ctx->bpp / 8;
- pI810DRI->bitsPerPixel = ctx->bpp;
- pI810DRI->fbOffset = info->FrontBuffer.Start;
- pI810DRI->fbStride = info->auxPitch;
-
- pI810DRI->backOffset = info->BackBuffer.Start;
- pI810DRI->depthOffset = info->DepthBuffer.Start;
-
- pI810DRI->auxPitch = info->auxPitch;
- pI810DRI->auxPitchBits = info->auxPitchBits;
-
- pI810DRI->logTextureGranularity = info->logTextureGranularity;
- pI810DRI->textureOffset = info->TexMem.Start;
-
- pI810DRI->ringOffset = info->LpRing.mem.Start;
- pI810DRI->ringSize = info->LpRing.mem.Size;
-
- // drmBufs looks unused
- pI810DRI->irq = info->irq;
- pI810DRI->sarea_priv_offset = sizeof(drm_sarea_t);
-
- /* Don't release the lock now - let the VT switch handler do it. */
- return 1;
-}
-
-
-/**
- * \brief Validate the fbdev mode.
- *
- * \param ctx display handle.
- *
- * \return one on success, or zero on failure.
- *
- * Saves some registers and returns 1.
- *
- * \sa i810ValidateMode().
- */
-static int i810ValidateMode( const DRIDriverContext *ctx )
-{
- unsigned char *I810MMIO = ctx->MMIOAddress;
- I810Ptr info = ctx->driverPrivate;
-
- 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 i810PostValidateMode( const DRIDriverContext *ctx )
-{
- unsigned char *I810MMIO = ctx->MMIOAddress;
- I810Ptr info = ctx->driverPrivate;
-
- 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 i810InitFBDev( DRIDriverContext *ctx )
-{
- I810Ptr info = calloc(1, sizeof(*info));
-
- {
- 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 *)info;
-
- info->Chipset = ctx->chipset;
-
- if (!I810ScreenInit( ctx, info ))
- 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 i810HaltFBDev( DRIDriverContext *ctx )
-{
- 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 = {
- i810ValidateMode,
- i810PostValidateMode,
- i810InitFBDev,
- i810HaltFBDev,
- I810EngineShutdown,
- I810EngineRestore,
-#ifndef _EMBEDDED
- 0,
-#else
- i810NotifyFocus,
-#endif
-};
+++ /dev/null
-../../intel/server/intel_dri.c
\ No newline at end of file
+++ /dev/null
-../../intel/server/intel_dri.c
\ No newline at end of file
+++ /dev/null
-/**
- * \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;
-static int nextTile = 0;
-#define xf86DrvMsg(...) do {} while(0)
-
-static const int pitches[] = {
- 128 * 8,
- 128 * 16,
- 128 * 32,
- 128 * 64,
- 0
-};
-
-static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea);
-
-static unsigned long
-GetBestTileAlignment(unsigned long size)
-{
- unsigned long i;
-
- for (i = KB(512); i < size; i <<= 1)
- ;
-
- if (i > MB(64))
- i = MB(64);
-
- return i;
-}
-
-static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- int i;
- unsigned char *MMIO = ctx->MMIOAddress;
-
- for (i = 0; i < 8; i++) {
- OUTREG(FENCE + i * 4, pI830->Fence[i]);
- // if (I810_DEBUG & DEBUG_VERBOSE_VGA)
- fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]);
- }
-}
-
-/* Tiled memory is good... really, really good...
- *
- * Need to make it less likely that we miss out on this - probably
- * need to move the frontbuffer away from the 'guarenteed' alignment
- * of the first memory segment, or perhaps allocate a discontigous
- * framebuffer to get more alignment 'sweet spots'.
- */
-static void
-SetFence(const DRIDriverContext *ctx, I830Rec *pI830,
- int nr, unsigned int start, unsigned int pitch,
- unsigned int size)
-{
- unsigned int val;
- unsigned int fence_mask = 0;
- unsigned int fence_pitch;
-
- if (nr < 0 || nr > 7) {
- fprintf(stderr,
- "SetFence: fence %d out of range\n",nr);
- return;
- }
-
- pI830->Fence[nr] = 0;
-
- if (IS_I9XX(pI830))
- fence_mask = ~I915G_FENCE_START_MASK;
- else
- fence_mask = ~I830_FENCE_START_MASK;
-
- if (start & fence_mask) {
- fprintf(stderr,
- "SetFence: %d: start (0x%08x) is not %s aligned\n",
- nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k");
- return;
- }
-
- if (start % size) {
- fprintf(stderr,
- "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n",
- nr, start, size / 1024);
- return;
- }
-
- if (pitch & 127) {
- fprintf(stderr,
- "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n",
- nr, pitch);
- return;
- }
-
- val = (start | FENCE_X_MAJOR | FENCE_VALID);
-
- if (IS_I9XX(pI830)) {
- switch (size) {
- case MB(1):
- val |= I915G_FENCE_SIZE_1M;
- break;
- case MB(2):
- val |= I915G_FENCE_SIZE_2M;
- break;
- case MB(4):
- val |= I915G_FENCE_SIZE_4M;
- break;
- case MB(8):
- val |= I915G_FENCE_SIZE_8M;
- break;
- case MB(16):
- val |= I915G_FENCE_SIZE_16M;
- break;
- case MB(32):
- val |= I915G_FENCE_SIZE_32M;
- break;
- case MB(64):
- val |= I915G_FENCE_SIZE_64M;
- break;
- default:
- fprintf(stderr,
- "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
- return;
- }
- } else {
- switch (size) {
- case KB(512):
- val |= FENCE_SIZE_512K;
- break;
- case MB(1):
- val |= FENCE_SIZE_1M;
- break;
- case MB(2):
- val |= FENCE_SIZE_2M;
- break;
- case MB(4):
- val |= FENCE_SIZE_4M;
- break;
- case MB(8):
- val |= FENCE_SIZE_8M;
- break;
- case MB(16):
- val |= FENCE_SIZE_16M;
- break;
- case MB(32):
- val |= FENCE_SIZE_32M;
- break;
- case MB(64):
- val |= FENCE_SIZE_64M;
- break;
- default:
- fprintf(stderr,
- "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
- return;
- }
- }
-
- if (IS_I9XX(pI830))
- fence_pitch = pitch / 512;
- else
- fence_pitch = pitch / 128;
-
- switch (fence_pitch) {
- case 1:
- val |= FENCE_PITCH_1;
- break;
- case 2:
- val |= FENCE_PITCH_2;
- break;
- case 4:
- val |= FENCE_PITCH_4;
- break;
- case 8:
- val |= FENCE_PITCH_8;
- break;
- case 16:
- val |= FENCE_PITCH_16;
- break;
- case 32:
- val |= FENCE_PITCH_32;
- break;
- case 64:
- val |= FENCE_PITCH_64;
- break;
- default:
- fprintf(stderr,
- "SetFence: %d: illegal pitch (%d)\n", nr, pitch);
- return;
- }
-
- pI830->Fence[nr] = val;
-}
-
-static Bool
-MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem)
-{
- int pitch, ntiles, i;
-
- pitch = pMem->Pitch * ctx->cpp;
- /*
- * Simply try to break the region up into at most four pieces of size
- * equal to the alignment.
- */
- ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment;
- if (ntiles >= 4) {
- return FALSE;
- }
-
- for (i = 0; i < ntiles; i++, nextTile++) {
- SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment,
- pitch, pMem->Alignment);
- }
- return TRUE;
-}
-
-static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- int i;
-
- /* Clear out */
- for (i = 0; i < 8; i++)
- pI830->Fence[i] = 0;
-
- nextTile = 0;
-
- if (pI830->BackBuffer.Alignment >= KB(512)) {
- if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) {
- fprintf(stderr,
- "Activating tiled memory for the back buffer.\n");
- } else {
- fprintf(stderr,
- "MakeTiles failed for the back buffer.\n");
- pI830->allowPageFlip = FALSE;
- }
- }
-
- if (pI830->DepthBuffer.Alignment >= KB(512)) {
- if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) {
- fprintf(stderr,
- "Activating tiled memory for the depth buffer.\n");
- } else {
- fprintf(stderr,
- "MakeTiles failed for the depth buffer.\n");
- }
- }
-
- return;
-}
-
-static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- struct pci_device host_bridge, ig_dev;
- uint32_t gmch_ctrl;
- int memsize = 0;
- int range;
- uint32_t aper_size;
- uint32_t membase2 = 0;
-
- memset(&host_bridge, 0, sizeof(host_bridge));
- memset(&ig_dev, 0, sizeof(ig_dev));
-
- ig_dev.dev = 2;
-
- pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL);
-
- if (IS_I830(pI830) || IS_845G(pI830)) {
- if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
- aper_size = 0x80000000;
- } else {
- aper_size = 0x40000000;
- }
- } else {
- if (IS_I9XX(pI830)) {
- int ret;
- ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18);
- if (membase2 & 0x08000000)
- aper_size = 0x8000000;
- else
- aper_size = 0x10000000;
-
- fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret);
- } else
- aper_size = 0x8000000;
- }
-
- pI830->aper_size = aper_size;
-
-
- /* 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;
-}
-
-/*
- * Allocate memory from the given pool. Grow the pool if needed and if
- * possible.
- */
-static unsigned long
-AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830,
- I830MemRange *result, I830MemPool *pool,
- long size, unsigned long alignment, int flags)
-{
- long needed, start, end;
-
- if (!result || !pool || !size)
- return 0;
-
- /* Calculate how much space is needed. */
- if (alignment <= GTT_PAGE_SIZE)
- needed = size;
- else {
- start = ROUND_TO(pool->Free.Start, alignment);
- end = ROUND_TO(start + size, alignment);
- needed = end - pool->Free.Start;
- }
- if (needed > pool->Free.Size) {
- return 0;
- }
-
- result->Start = ROUND_TO(pool->Free.Start, alignment);
- pool->Free.Start += needed;
- result->End = pool->Free.Start;
-
- pool->Free.Size = pool->Free.End - pool->Free.Start;
- result->Size = result->End - result->Start;
- result->Pool = pool;
- result->Alignment = alignment;
- return needed;
-}
-
-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;
-}
-
-unsigned long
-I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830,
- I830MemRange *result, I830MemPool *pool, long size,
- unsigned long alignment, int flags)
-{
- unsigned long ret;
-
- if (!result)
- return 0;
-
- /* Make sure these are initialised. */
- result->Size = 0;
- result->Key = -1;
-
- if (!size) {
- return 0;
- }
-
- if (pool->Free.Size < size) {
- ret = AllocFromAGP(ctx, pI830, size, alignment, result);
- }
- else {
- ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags);
- if (ret == 0)
- ret = AllocFromAGP(ctx, pI830, size, alignment, result);
- }
- return ret;
-}
-
-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 = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0);
-
- 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);
-
- align = GetBestTileAlignment(size);
-
- ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0);
- 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 = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0);
- 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 = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0);
- 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 = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0);
- if (ret < size)
- {
- fprintf(stderr,"unable to allocate context buffer %ld\n", ret);
- return FALSE;
- }
-
-#if 0
- 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;
- }
-#endif
-
- 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 0
- if (!BindAgpRange(ctx, &pI830->TexMem))
- return FALSE;
-#endif
- return TRUE;
-}
-
-static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830)
-{
- unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
- unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
-
- fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize);
- if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) {
- fprintf(stderr,
- "DRM MM Initialization Failed\n");
- } else {
- fprintf(stderr,
- "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart);
- }
-
-}
-
-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))) {
- fprintf(stderr, "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 = ctx->cpp;
-
- if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT,
- &info, sizeof(drmI830Init))) {
- fprintf(stderr,
- "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) {
- fprintf(stderr,
- "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) {
- fprintf(stderr,
- "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;
-
- SetFenceRegs(ctx, pI830);
-
- /* 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))) {
- fprintf(stderr, "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) {
- fprintf(stderr,
- "[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) {
- fprintf(stderr,
- "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n");
- return FALSE;
- }
- fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n",
- sarea->depth_handle);
-
-#if 0
- if (drmAddMap(ctx->drmFD,
- (drm_handle_t)sarea->tex_offset,
- sarea->tex_size, DRM_AGP, 0,
- &sarea->tex_handle) < 0) {
- fprintf(stderr,
- "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n");
- return FALSE;
- }
- fprintf(stderr, "[drm] textures = 0x%08x\n",
- sarea->tex_handle);
-#endif
- 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 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);
- SetupDRIMM(ctx, pI830);
-
- 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)) {
- fprintf(stderr,
- "[drm] failure adding irq handler\n");
- pI830->irq = 0;
- return FALSE;
- }
- else
- fprintf(stderr,
- "[drm] dma control initialized, using IRQ %d\n",
- pI830->irq);
- }
-
- fprintf(stderr, "[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 */
- drmAddress 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;
-
- pI830->StolenPool.Fixed = pI830->StolenMemory;
- pI830->StolenPool.Total = pI830->StolenMemory;
- pI830->StolenPool.Free = pI830->StolenPool.Total;
- pI830->FreeMemory = pI830->StolenPool.Total.Size;
-
- if (!AgpInit(ctx, pI830))
- return FALSE;
-
- if (I830AllocateMemory(ctx, pI830) == FALSE)
- {
- return FALSE;
- }
-
- if (I830BindMemory(ctx, pI830) == FALSE)
- {
- return FALSE;
- }
-
- pSAREAPriv->rotated_offset = -1;
- pSAREAPriv->rotated_size = 0;
- pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth;
-
- 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;
-#if 0
- pSAREAPriv->tex_offset = pI830->TexMem.Start;
- pSAREAPriv->tex_size = pI830->TexMem.Size;
-#endif
- 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->bitsPerPixel = ctx->bpp;
- pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t);
-
- err = I830DRIDoMappings(ctx, pI830, pSAREAPriv);
- if (err == FALSE)
- return FALSE;
-
- I830SetupMemoryTiling(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);
-
- I830SetRingRegs(ctx, pI830);
-
- 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 i;
-
- {
- 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->shared.Width = ctx->shared.virtualWidth;
- }
-
-
- for (i = 0; pitches[i] != 0; i++) {
- if (pitches[i] >= ctx->shared.virtualWidth) {
- ctx->shared.virtualWidth = pitches[i];
- break;
- }
- }
-
- 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
-};
+++ /dev/null
-
-/*
- * Copyright 2000 VA Linux Systems Inc., Fremont, California.
- * All Rights Reserved.
- *
- * 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, sublicense,
- * 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 NONINFRINGEMENT. IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS 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.
- *
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Gareth Hughes <gareth@valinux.com>
- */
-
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-
-#include "driver.h"
-#include "drm.h"
-#include "memops.h"
-
-#include "mga_reg.h"
-#include "mga.h"
-#include "mga_macros.h"
-#include "mga_dri.h"
-
-
-/* Quiescence, locking
- */
-#define MGA_TIMEOUT 2048
-
-static void MGAWaitForIdleDMA( struct DRIDriverContextRec *ctx, MGAPtr pMga )
-{
- drm_lock_t lock;
- int ret;
- int i = 0;
-
- memset( &lock, 0, sizeof(lock) );
-
- for (;;) {
- do {
- /* first ask for quiescent and flush */
- lock.flags = DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH;
- do {
- ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH,
- &lock, sizeof( lock ) );
- } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );
-
- /* if it's still busy just try quiescent */
- if ( ret == -EBUSY ) {
- lock.flags = DRM_LOCK_QUIESCENT;
- do {
- ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH,
- &lock, sizeof( lock ) );
- } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );
- }
- } while ( ( ret == -EBUSY ) && ( i++ < MGA_TIMEOUT ) );
-
- if ( ret == 0 )
- return;
-
- fprintf( stderr,
- "[dri] Idle timed out, resetting engine...\n" );
-
- drmCommandNone( ctx->drmFD, DRM_MGA_RESET );
- }
-}
-
-static unsigned int mylog2( unsigned int n )
-{
- unsigned int log2 = 1;
- while ( n > 1 ) n >>= 1, log2++;
- return log2;
-}
-
-static int MGADRIAgpInit(struct DRIDriverContextRec *ctx, MGAPtr pMga)
-{
- unsigned long mode;
- unsigned int vendor, device;
- int ret, count, i;
-
- if(pMga->agpSize < 12)pMga->agpSize = 12;
- if(pMga->agpSize > 64)pMga->agpSize = 64; /* cap */
-
- /* FIXME: Make these configurable...
- */
- pMga->agp.size = pMga->agpSize * 1024 * 1024;
-
- pMga->warp.offset = 0;
- pMga->warp.size = MGA_WARP_UCODE_SIZE;
-
- pMga->primary.offset = (pMga->warp.offset +
- pMga->warp.size);
- pMga->primary.size = 1024 * 1024;
-
- pMga->buffers.offset = (pMga->primary.offset +
- pMga->primary.size);
- pMga->buffers.size = MGA_NUM_BUFFERS * MGA_BUFFER_SIZE;
-
-
- pMga->agpTextures.offset = (pMga->buffers.offset +
- pMga->buffers.size);
-
- pMga->agpTextures.size = pMga->agp.size -
- pMga->agpTextures.offset;
-
- if ( drmAgpAcquire( ctx->drmFD ) < 0 ) {
- fprintf( stderr, "[agp] AGP not available\n" );
- return 0;
- }
-
- mode = drmAgpGetMode( ctx->drmFD ); /* Default mode */
- vendor = drmAgpVendorId( ctx->drmFD );
- device = drmAgpDeviceId( ctx->drmFD );
-
- mode &= ~MGA_AGP_MODE_MASK;
- switch ( pMga->agpMode ) {
- case 4:
- mode |= MGA_AGP_4X_MODE;
- case 2:
- mode |= MGA_AGP_2X_MODE;
- case 1:
- default:
- mode |= MGA_AGP_1X_MODE;
- }
-
-#if 0
- fprintf( stderr,
- "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
- mode, vendor, device,
- ctx->pciVendor,
- ctx->pciChipType );
-#endif
-
- if ( drmAgpEnable( ctx->drmFD, mode ) < 0 ) {
- fprintf( stderr, "[agp] AGP not enabled\n" );
- drmAgpRelease( ctx->drmFD );
- return 0;
- }
-
- if ( pMga->Chipset == PCI_CHIP_MGAG200 ) {
- switch ( pMga->agpMode ) {
- case 2:
- fprintf( stderr,
- "[drm] Enabling AGP 2x PLL encoding\n" );
- OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_ENABLE );
- break;
-
- case 1:
- default:
- fprintf( stderr,
- "[drm] Disabling AGP 2x PLL encoding\n" );
- OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_DISABLE );
- pMga->agpMode = 1;
- break;
- }
- }
-
- ret = drmAgpAlloc( ctx->drmFD, pMga->agp.size,
- 0, NULL, &pMga->agp.handle );
- if ( ret < 0 ) {
- fprintf( stderr, "[agp] Out of memory (%d)\n", ret );
- drmAgpRelease( ctx->drmFD );
- return 0;
- }
- fprintf( stderr,
- "[agp] %d kB allocated with handle 0x%08x\n",
- pMga->agp.size/1024, (unsigned int)pMga->agp.handle );
-
- if ( drmAgpBind( ctx->drmFD, pMga->agp.handle, 0 ) < 0 ) {
- fprintf( stderr, "[agp] Could not bind memory\n" );
- drmAgpFree( ctx->drmFD, pMga->agp.handle );
- drmAgpRelease( ctx->drmFD );
- return 0;
- }
-
- /* WARP microcode space
- */
- if ( drmAddMap( ctx->drmFD,
- pMga->warp.offset,
- pMga->warp.size,
- DRM_AGP, DRM_READ_ONLY,
- &pMga->warp.handle ) < 0 ) {
- fprintf( stderr,
- "[agp] Could not add WARP microcode mapping\n" );
- return 0;
- }
- fprintf( stderr,
- "[agp] WARP microcode handle = 0x%08x\n",
- pMga->warp.handle );
-
- if ( drmMap( ctx->drmFD,
- pMga->warp.handle,
- pMga->warp.size,
- &pMga->warp.map ) < 0 ) {
- fprintf( stderr,
- "[agp] Could not map WARP microcode\n" );
- return 0;
- }
- fprintf( stderr,
- "[agp] WARP microcode mapped at 0x%08lx\n",
- (unsigned long)pMga->warp.map );
-
- /* Primary DMA space
- */
- if ( drmAddMap( ctx->drmFD,
- pMga->primary.offset,
- pMga->primary.size,
- DRM_AGP, DRM_READ_ONLY,
- &pMga->primary.handle ) < 0 ) {
- fprintf( stderr,
- "[agp] Could not add primary DMA mapping\n" );
- return 0;
- }
- fprintf( stderr,
- "[agp] Primary DMA handle = 0x%08x\n",
- pMga->primary.handle );
-
- if ( drmMap( ctx->drmFD,
- pMga->primary.handle,
- pMga->primary.size,
- &pMga->primary.map ) < 0 ) {
- fprintf( stderr,
- "[agp] Could not map primary DMA\n" );
- return 0;
- }
- fprintf( stderr,
- "[agp] Primary DMA mapped at 0x%08lx\n",
- (unsigned long)pMga->primary.map );
-
- /* DMA buffers
- */
- if ( drmAddMap( ctx->drmFD,
- pMga->buffers.offset,
- pMga->buffers.size,
- DRM_AGP, 0,
- &pMga->buffers.handle ) < 0 ) {
- fprintf( stderr,
- "[agp] Could not add DMA buffers mapping\n" );
- return 0;
- }
- fprintf( stderr,
- "[agp] DMA buffers handle = 0x%08x\n",
- pMga->buffers.handle );
-
- if ( drmMap( ctx->drmFD,
- pMga->buffers.handle,
- pMga->buffers.size,
- &pMga->buffers.map ) < 0 ) {
- fprintf( stderr,
- "[agp] Could not map DMA buffers\n" );
- return 0;
- }
- fprintf( stderr,
- "[agp] DMA buffers mapped at 0x%08lx\n",
- (unsigned long)pMga->buffers.map );
-
- count = drmAddBufs( ctx->drmFD,
- MGA_NUM_BUFFERS, MGA_BUFFER_SIZE,
- DRM_AGP_BUFFER, pMga->buffers.offset );
- if ( count <= 0 ) {
- fprintf( stderr,
- "[drm] failure adding %d %d byte DMA buffers\n",
- MGA_NUM_BUFFERS, MGA_BUFFER_SIZE );
- return 0;
- }
- fprintf( stderr,
- "[drm] Added %d %d byte DMA buffers\n",
- count, MGA_BUFFER_SIZE );
-
- i = mylog2(pMga->agpTextures.size / MGA_NR_TEX_REGIONS);
- if(i < MGA_LOG_MIN_TEX_REGION_SIZE)
- i = MGA_LOG_MIN_TEX_REGION_SIZE;
- pMga->agpTextures.size = (pMga->agpTextures.size >> i) << i;
-
- if ( drmAddMap( ctx->drmFD,
- pMga->agpTextures.offset,
- pMga->agpTextures.size,
- DRM_AGP, 0,
- &pMga->agpTextures.handle ) < 0 ) {
- fprintf( stderr,
- "[agp] Could not add agpTexture mapping\n" );
- return 0;
- }
-/* should i map it ? */
- fprintf( stderr,
- "[agp] agpTexture handle = 0x%08x\n",
- pMga->agpTextures.handle );
- fprintf( stderr,
- "[agp] agpTexture size: %d kb\n", pMga->agpTextures.size/1024 );
-
- return 1;
-}
-
-static int MGADRIMapInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
-{
- pMga->registers.size = MGAIOMAPSIZE;
-
- if ( drmAddMap( ctx->drmFD,
- (drm_handle_t)pMga->IOAddress,
- pMga->registers.size,
- DRM_REGISTERS, DRM_READ_ONLY,
- &pMga->registers.handle ) < 0 ) {
- fprintf( stderr,
- "[drm] Could not add MMIO registers mapping\n" );
- return 0;
- }
- fprintf( stderr,
- "[drm] Registers handle = 0x%08lx\n",
- pMga->registers.handle );
-
- pMga->status.size = SAREA_MAX;
-
- if ( drmAddMap( ctx->drmFD, 0, pMga->status.size,
- DRM_SHM, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL,
- &pMga->status.handle ) < 0 ) {
- fprintf( stderr,
- "[drm] Could not add status page mapping\n" );
- return 0;
- }
- fprintf( stderr,
- "[drm] Status handle = 0x%08x\n",
- pMga->status.handle );
-
- if ( drmMap( ctx->drmFD,
- pMga->status.handle,
- pMga->status.size,
- &pMga->status.map ) < 0 ) {
- fprintf( stderr,
- "[agp] Could not map status page\n" );
- return 0;
- }
- fprintf( stderr,
- "[agp] Status page mapped at 0x%08lx\n",
- (unsigned long)pMga->status.map );
-
- return 1;
-}
-
-static int MGADRIKernelInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
-{
- drm_mga_init_t init;
- int ret;
-
- memset( &init, 0, sizeof(init) );
-
- init.func = MGA_INIT_DMA;
- init.sarea_priv_offset = sizeof(drm_sarea_t);
-
- switch ( pMga->Chipset ) {
- case PCI_CHIP_MGAG550:
- case PCI_CHIP_MGAG400:
- init.chipset = MGA_CARD_TYPE_G400;
- break;
- case PCI_CHIP_MGAG200:
- case PCI_CHIP_MGAG200_PCI:
- init.chipset = MGA_CARD_TYPE_G200;
- break;
- default:
- return 0;
- }
-
- init.sgram = 0; /* FIXME !pMga->HasSDRAM; */
-
-
- switch (ctx->bpp)
- {
- case 16:
- init.maccess = MGA_MACCESS_PW16;
- break;
- case 32:
- init.maccess = MGA_MACCESS_PW32;
- break;
- default:
- fprintf( stderr, "[mga] invalid bpp (%d)\n", ctx->bpp );
- return 0;
- }
-
-
- init.fb_cpp = ctx->bpp / 8;
- init.front_offset = pMga->frontOffset;
- init.front_pitch = pMga->frontPitch / init.fb_cpp;
- init.back_offset = pMga->backOffset;
- init.back_pitch = pMga->backPitch / init.fb_cpp;
-
- init.depth_cpp = ctx->bpp / 8;
- init.depth_offset = pMga->depthOffset;
- init.depth_pitch = pMga->depthPitch / init.depth_cpp;
-
- init.texture_offset[0] = pMga->textureOffset;
- init.texture_size[0] = pMga->textureSize;
-
- init.fb_offset = ctx->shared.hFrameBuffer;
- init.mmio_offset = pMga->registers.handle;
- init.status_offset = pMga->status.handle;
-
- init.warp_offset = pMga->warp.handle;
- init.primary_offset = pMga->primary.handle;
- init.buffers_offset = pMga->buffers.handle;
-
- init.texture_offset[1] = pMga->agpTextures.handle;
- init.texture_size[1] = pMga->agpTextures.size;
-
- ret = drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(init));
- if ( ret < 0 ) {
- fprintf( stderr,
- "[drm] Failed to initialize DMA! (%d)\n", ret );
- return 0;
- }
-
- return 1;
-}
-
-static void MGADRIIrqInit(struct DRIDriverContextRec *ctx, MGAPtr pMga)
-{
- if (!pMga->irq)
- {
- pMga->irq = drmGetInterruptFromBusID(ctx->drmFD,
- ctx->pciBus,
- ctx->pciDevice,
- ctx->pciFunc);
-
- fprintf(stderr, "[drm] got IRQ %d\n", pMga->irq);
-
- if((drmCtlInstHandler(ctx->drmFD, pMga->irq)) != 0)
- {
- fprintf(stderr,
- "[drm] failure adding irq handler, "
- "there is a device already using that irq\n"
- "[drm] falling back to irq-free operation\n");
- pMga->irq = 0;
- }
- else
- {
- pMga->reg_ien = INREG( MGAREG_IEN );
- }
- }
-
- if (pMga->irq)
- fprintf(stderr,
- "[drm] dma control initialized, using IRQ %d\n",
- pMga->irq);
-}
-
-static int MGADRIBuffersInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
-{
- pMga->drmBuffers = drmMapBufs( ctx->drmFD );
- if ( !pMga->drmBuffers )
- {
- fprintf( stderr,
- "[drm] Failed to map DMA buffers list\n" );
- return 0;
- }
-
- fprintf( stderr,
- "[drm] Mapped %d DMA buffers\n",
- pMga->drmBuffers->count );
-
- return 1;
-}
-
-static int MGAMemoryInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
-{
- int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
- int bufferSize = ((ctx->shared.virtualHeight * width_bytes
- + MGA_BUFFER_ALIGN)
- & ~MGA_BUFFER_ALIGN);
- int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes
- + MGA_BUFFER_ALIGN)
- & ~MGA_BUFFER_ALIGN);
- int l;
-
- pMga->frontOffset = 0;
- pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp;
-
- fprintf(stderr,
- "Using %d MB AGP aperture\n", pMga->agpSize);
- fprintf(stderr,
- "Using %d MB for vertex/indirect buffers\n", pMga->buffers.size>>20);
- fprintf(stderr,
- "Using %d MB for AGP textures\n", pMga->agpTextures.size>>20);
-
- /* Front, back and depth buffers - everything else texture??
- */
- pMga->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize;
-
- if (pMga->textureSize < 0)
- return 0;
-
- l = mylog2( pMga->textureSize / MGA_NR_TEX_REGIONS );
- if ( l < MGA_LOG_MIN_TEX_REGION_SIZE )
- l = MGA_LOG_MIN_TEX_REGION_SIZE;
-
- /* Round the texture size up to the nearest whole number of
- * texture regions. Again, be greedy about this, don't
- * round down.
- */
- pMga->logTextureGranularity = l;
- pMga->textureSize = (pMga->textureSize >> l) << l;
-
- /* Set a minimum usable local texture heap size. This will fit
- * two 256x256x32bpp textures.
- */
- if (pMga->textureSize < 512 * 1024) {
- pMga->textureOffset = 0;
- pMga->textureSize = 0;
- }
-
- /* Reserve space for textures */
- pMga->textureOffset = ((ctx->shared.fbSize - pMga->textureSize +
- MGA_BUFFER_ALIGN) &
- ~MGA_BUFFER_ALIGN);
-
- /* Reserve space for the shared depth
- * buffer.
- */
- pMga->depthOffset = ((pMga->textureOffset - depthSize +
- MGA_BUFFER_ALIGN) &
- ~MGA_BUFFER_ALIGN);
- pMga->depthPitch = ctx->shared.virtualWidth * ctx->cpp;
-
- pMga->backOffset = ((pMga->depthOffset - bufferSize +
- MGA_BUFFER_ALIGN) &
- ~MGA_BUFFER_ALIGN);
- pMga->backPitch = ctx->shared.virtualWidth * ctx->cpp;
-
-
- fprintf(stderr,
- "Will use back buffer at offset 0x%x\n",
- pMga->backOffset);
- fprintf(stderr,
- "Will use depth buffer at offset 0x%x\n",
- pMga->depthOffset);
- fprintf(stderr,
- "Will use %d kb for textures at offset 0x%x\n",
- pMga->textureSize/1024, pMga->textureOffset);
-
- return 1;
-}
-
-static int MGACheckDRMVersion( struct DRIDriverContextRec *ctx, MGAPtr pMga )
-{
- drmVersionPtr version;
-
- /* Check the MGA DRM version */
- version = drmGetVersion(ctx->drmFD);
- if ( version ) {
- if ( version->version_major != 3 ||
- version->version_minor < 0 ) {
- /* incompatible drm version */
- fprintf( stderr,
- "[dri] MGADRIScreenInit failed because of a version mismatch.\n"
- "[dri] mga.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n"
- "[dri] Disabling DRI.\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel );
- drmFreeVersion( version );
- return 0;
- }
- drmFreeVersion( version );
- }
-
- return 1;
-}
-
-static void print_client_msg( MGADRIPtr pMGADRI )
-{
- fprintf( stderr, "chipset: %d\n", pMGADRI->chipset );
-
- fprintf( stderr, "width: %d\n", pMGADRI->width );
- fprintf( stderr, "height: %d\n", pMGADRI->height );
- fprintf( stderr, "mem: %d\n", pMGADRI->mem );
- fprintf( stderr, "cpp: %d\n", pMGADRI->cpp );
-
- fprintf( stderr, "agpMode: %d\n", pMGADRI->agpMode );
-
- fprintf( stderr, "frontOffset: %d\n", pMGADRI->frontOffset );
- fprintf( stderr, "frontPitch: %d\n", pMGADRI->frontPitch );
-
- fprintf( stderr, "backOffset: %d\n", pMGADRI->backOffset );
- fprintf( stderr, "backPitch: %d\n", pMGADRI->backPitch );
-
- fprintf( stderr, "depthOffset: %d\n", pMGADRI->depthOffset );
- fprintf( stderr, "depthPitch: %d\n", pMGADRI->depthPitch );
-
- fprintf( stderr, "textureOffset: %d\n", pMGADRI->textureOffset );
- fprintf( stderr, "textureSize: %d\n", pMGADRI->textureSize );
-
- fprintf( stderr, "logTextureGranularity: %d\n", pMGADRI->logTextureGranularity );
- fprintf( stderr, "logAgpTextureGranularity: %d\n", pMGADRI->logAgpTextureGranularity );
-
- fprintf( stderr, "agpTextureHandle: %u\n", (unsigned int)pMGADRI->agpTextureOffset );
- fprintf( stderr, "agpTextureSize: %u\n", (unsigned int)pMGADRI->agpTextureSize );
-
-#if 0
- pMGADRI->registers.handle = pMga->registers.handle;
- pMGADRI->registers.size = pMga->registers.size;
- pMGADRI->status.handle = pMga->status.handle;
- pMGADRI->status.size = pMga->status.size;
- pMGADRI->primary.handle = pMga->primary.handle;
- pMGADRI->primary.size = pMga->primary.size;
- pMGADRI->buffers.handle = pMga->buffers.handle;
- pMGADRI->buffers.size = pMga->buffers.size;
- pMGADRI->sarea_priv_offset = sizeof(drm_sarea_t);
-#endif
-}
-
-static int MGAScreenInit( struct DRIDriverContextRec *ctx, MGAPtr pMga )
-{
- int i;
- int err;
- MGADRIPtr pMGADRI;
-
- usleep(100);
- /*assert(!ctx->IsClient);*/
-
- {
- int width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
- int maxy = ctx->shared.fbSize / width_bytes;
-
-
- if (maxy <= ctx->shared.virtualHeight * 3) {
- fprintf(stderr,
- "Static buffer allocation failed -- "
- "need at least %d kB video memory (have %d kB)\n",
- (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
- ctx->cpp * 3 + 1023) / 1024,
- ctx->shared.fbSize / 1024);
- return 0;
- }
- }
-
- switch(pMga->Chipset) {
- case PCI_CHIP_MGAG550:
- case PCI_CHIP_MGAG400:
- case PCI_CHIP_MGAG200:
-#if 0
- case PCI_CHIP_MGAG200_PCI:
-#endif
- break;
- default:
- fprintf(stderr, "[drm] Direct rendering only supported with G200/G400/G550 AGP\n");
- return 0;
- }
-
- fprintf( stderr,
- "[drm] bpp: %d depth: %d\n",
- ctx->bpp, ctx->bpp /* FIXME: depth */ );
-
- if ( (ctx->bpp / 8) != 2 &&
- (ctx->bpp / 8) != 4 ) {
- fprintf( stderr,
- "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" );
- return 0;
- }
-
- ctx->shared.SAREASize = SAREA_MAX;
-
-
- /* Note that drmOpen will try to load the kernel module, if needed. */
- ctx->drmFD = drmOpen("mga", 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%08lx\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%08lx to %p, size %d\n",
- ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
-
- /* Need to AddMap the framebuffer and mmio regions here:
- */
- if (drmAddMap( ctx->drmFD,
- (drm_handle_t)ctx->FBStart,
- ctx->FBSize,
- DRM_FRAME_BUFFER,
- 0,
- &ctx->shared.hFrameBuffer) < 0)
- {
- fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
- return 0;
- }
- fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
- ctx->shared.hFrameBuffer);
-
-
-#if 0 /* will be done in MGADRIMapInit */
- if (drmAddMap(ctx->drmFD,
- ctx->FixedInfo.mmio_start,
- ctx->FixedInfo.mmio_len,
- DRM_REGISTERS,
- DRM_READ_ONLY,
- &pMga->registers.handle) < 0) {
- fprintf(stderr, "[drm] drmAddMap mmio failed\n");
- return 0;
- }
- fprintf(stderr,
- "[drm] register handle = 0x%08lx\n", pMga->registers.handle);
-#endif
-
-
- /* Check the mga DRM version */
- if (!MGACheckDRMVersion(ctx, pMga)) {
- return 0;
- }
-
- if ( !MGADRIAgpInit( ctx, pMga ) ) {
- return 0;
- }
-
- if ( !MGADRIMapInit( ctx, pMga ) ) {
- return 0;
- }
-
- /* Memory manager setup */
- if (!MGAMemoryInit(ctx, pMga)) {
- return 0;
- }
-
-
- /* 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 kernel data structures */
- if (!MGADRIKernelInit(ctx, pMga)) {
- fprintf(stderr, "MGADRIKernelInit failed\n");
- DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
- return 0;
- }
-
- /* Initialize the vertex buffers list */
- if (!MGADRIBuffersInit(ctx, pMga)) {
- fprintf(stderr, "MGADRIBuffersInit failed\n");
- DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
- return 0;
- }
-
- /* Initialize IRQ */
- MGADRIIrqInit(ctx, pMga);
-
-
- /* Initialize the SAREA private data structure */
- {
- drm_mga_sarea_t *pSAREAPriv;
- pSAREAPriv = (drm_mga_sarea_t *)(((char*)ctx->pSAREA) +
- sizeof(drm_sarea_t));
- memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
- }
-
- /* 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.
- */
- drimemsetio((char *)ctx->FBAddress + pMga->frontOffset,
- 0,
- pMga->frontPitch * ctx->shared.virtualHeight );
-
- drimemsetio((char *)ctx->FBAddress + pMga->backOffset,
- 0,
- pMga->backPitch * ctx->shared.virtualHeight );
-
- /* Can release the lock now */
-/* DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);*/
-
- /* This is the struct passed to radeon_dri.so for its initialization */
- ctx->driverClientMsg = malloc(sizeof(MGADRIRec));
- ctx->driverClientMsgSize = sizeof(MGADRIRec);
-
- pMGADRI = (MGADRIPtr)ctx->driverClientMsg;
-
-
- switch(pMga->Chipset) {
- case PCI_CHIP_MGAG550:
- case PCI_CHIP_MGAG400:
- pMGADRI->chipset = MGA_CARD_TYPE_G400;
- break;
- case PCI_CHIP_MGAG200:
- case PCI_CHIP_MGAG200_PCI:
- pMGADRI->chipset = MGA_CARD_TYPE_G200;
- break;
- default:
- return 0;
- }
- pMGADRI->width = ctx->shared.virtualWidth;
- pMGADRI->height = ctx->shared.virtualHeight;
- pMGADRI->mem = ctx->shared.fbSize;
- pMGADRI->cpp = ctx->bpp / 8;
-
- pMGADRI->agpMode = pMga->agpMode;
-
- pMGADRI->frontOffset = pMga->frontOffset;
- pMGADRI->frontPitch = pMga->frontPitch;
- pMGADRI->backOffset = pMga->backOffset;
- pMGADRI->backPitch = pMga->backPitch;
- pMGADRI->depthOffset = pMga->depthOffset;
- pMGADRI->depthPitch = pMga->depthPitch;
- pMGADRI->textureOffset = pMga->textureOffset;
- pMGADRI->textureSize = pMga->textureSize;
- pMGADRI->logTextureGranularity = pMga->logTextureGranularity;
-
- i = mylog2( pMga->agpTextures.size / MGA_NR_TEX_REGIONS );
- if ( i < MGA_LOG_MIN_TEX_REGION_SIZE )
- i = MGA_LOG_MIN_TEX_REGION_SIZE;
-
- pMGADRI->logAgpTextureGranularity = i;
- pMGADRI->agpTextureOffset = (unsigned int)pMga->agpTextures.handle;
- pMGADRI->agpTextureSize = (unsigned int)pMga->agpTextures.size;
-
- pMGADRI->registers.handle = pMga->registers.handle;
- pMGADRI->registers.size = pMga->registers.size;
- pMGADRI->status.handle = pMga->status.handle;
- pMGADRI->status.size = pMga->status.size;
- pMGADRI->primary.handle = pMga->primary.handle;
- pMGADRI->primary.size = pMga->primary.size;
- pMGADRI->buffers.handle = pMga->buffers.handle;
- pMGADRI->buffers.size = pMga->buffers.size;
- pMGADRI->sarea_priv_offset = sizeof(drm_sarea_t);
-
- print_client_msg( pMGADRI );
-
- return 1;
-}
-
-
-/**
- * \brief Validate the fbdev mode.
- *
- * \param ctx display handle.
- *
- * \return one on success, or zero on failure.
- *
- * Saves some registers and returns 1.
- *
- * \sa mgaValidateMode().
- */
-static int mgaValidateMode( 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 mgaValidateMode().
- */
-static int mgaPostValidateMode( const DRIDriverContext *ctx )
-{
- 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 MGAScreenInit() for the screen initialization.
- *
- * Before exiting clears the framebuffer memomry accessing it directly.
- */
-static int mgaInitFBDev( struct DRIDriverContextRec *ctx )
-{
- MGAPtr pMga = calloc(1, sizeof(*pMga));
-
- {
- 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 *)pMga;
-
- pMga->agpMode = MGA_DEFAULT_AGP_MODE;
- pMga->agpSize = MGA_DEFAULT_AGP_SIZE;
-
- pMga->Chipset = ctx->chipset;
-
- pMga->IOAddress = ctx->MMIOStart;
- pMga->IOBase = ctx->MMIOAddress;
-
- pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp;
-
- if (!MGAScreenInit( ctx, pMga ))
- 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 mgaHaltFBDev( struct DRIDriverContextRec *ctx )
-{
- drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
- drmClose(ctx->drmFD);
-
- if (ctx->driverPrivate) {
- free(ctx->driverPrivate);
- ctx->driverPrivate = NULL;
- }
-}
-
-
-static int mgaEngineShutdown( const DRIDriverContext *ctx )
-{
- fprintf(stderr, "%s() is not yet implemented!\n", __FUNCTION__);
-
- return 1;
-}
-
-static int mgaEngineRestore( const DRIDriverContext *ctx )
-{
- fprintf(stderr, "%s() is not yet implemented!\n", __FUNCTION__);
-
- return 1;
-}
-
-/**
- * \brief Exported driver interface for Mini GLX.
- *
- * \sa DRIDriverRec.
- */
-struct DRIDriverRec __driDriver = {
- mgaValidateMode,
- mgaPostValidateMode,
- mgaInitFBDev,
- mgaHaltFBDev,
- mgaEngineShutdown,
- mgaEngineRestore,
- 0
-};
-
-
-
-
-#if 0
-void MGADRICloseScreen( ScreenPtr pScreen )
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- MGAPtr pMga = MGAPTR(pScrn);
- MGADRIServerPrivatePtr pMga = pMga->DRIServerInfo;
- drmMGAInit init;
-
- if ( pMga->drmBuffers ) {
- drmUnmapBufs( pMga->drmBuffers );
- pMga->drmBuffers = NULL;
- }
-
- if (pMga->irq) {
- drmCtlUninstHandler(ctx->drmFD);
- pMga->irq = 0;
- }
-
- /* Cleanup DMA */
- memset( &init, 0, sizeof(drmMGAInit) );
- init.func = MGA_CLEANUP_DMA;
- drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(drmMGAInit) );
-
- if ( pMga->status.map ) {
- drmUnmap( pMga->status.map, pMga->status.size );
- pMga->status.map = NULL;
- }
- if ( pMga->buffers.map ) {
- drmUnmap( pMga->buffers.map, pMga->buffers.size );
- pMga->buffers.map = NULL;
- }
- if ( pMga->primary.map ) {
- drmUnmap( pMga->primary.map, pMga->primary.size );
- pMga->primary.map = NULL;
- }
- if ( pMga->warp.map ) {
- drmUnmap( pMga->warp.map, pMga->warp.size );
- pMga->warp.map = NULL;
- }
-
- if ( pMga->agpTextures.map ) {
- drmUnmap( pMga->agpTextures.map, pMga->agpTextures.size );
- pMga->agpTextures.map = NULL;
- }
-
- if ( pMga->agp.handle ) {
- drmAgpUnbind( ctx->drmFD, pMga->agp.handle );
- drmAgpFree( ctx->drmFD, pMga->agp.handle );
- pMga->agp.handle = 0;
- drmAgpRelease( ctx->drmFD );
- }
-
- DRICloseScreen( pScreen );
-
- if ( pMga->pDRIInfo ) {
- if ( pMga->pDRIpMga->devPrivate ) {
- xfree( pMga->pDRIpMga->devPrivate );
- pMga->pDRIpMga->devPrivate = 0;
- }
- DRIDestroyInfoRec( pMga->pDRIInfo );
- pMga->pDRIInfo = 0;
- }
- if ( pMga->DRIServerInfo ) {
- xfree( pMga->DRIServerInfo );
- pMga->DRIServerInfo = 0;
- }
- if ( pMga->pVisualConfigs ) {
- xfree( pMga->pVisualConfigs );
- }
- if ( pMga->pVisualConfigsPriv ) {
- xfree( pMga->pVisualConfigsPriv );
- }
-}
-#endif
+++ /dev/null
-/*
- * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
- * Precision Insight, Inc., Cedar Park, Texas, and
- * VA Linux Systems Inc., Fremont, California.
- *
- * All Rights Reserved.
- *
- * 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 on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, 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 ATI, PRECISION INSIGHT, VA LINUX
- * SYSTEMS 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.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Rickard E. Faith <faith@valinux.com>
- * Daryll Strauss <daryll@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-// Fix this to use kernel pci_ids.h when all of these IDs make it into the kernel
-#include "pci_ids.h"
-
-#include "driver.h"
-#include "drm.h"
-#include "memops.h"
-
-#include "r128.h"
-#include "r128_dri.h"
-#include "r128_macros.h"
-#include "r128_reg.h"
-#include "r128_version.h"
-#include "r128_drm.h"
-
-static size_t r128_drm_page_size;
-
-/* Compute log base 2 of val. */
-static int R128MinBits(int val)
-{
- int bits;
-
- if (!val) return 1;
- for (bits = 0; val; val >>= 1, ++bits);
- return bits;
-}
-
-/* Initialize the AGP state. Request memory for use in AGP space, and
- initialize the Rage 128 registers to point to that memory. */
-static GLboolean R128DRIAgpInit(const DRIDriverContext *ctx)
-{
- unsigned char *R128MMIO = ctx->MMIOAddress;
- R128InfoPtr info = ctx->driverPrivate;
- unsigned long mode;
- unsigned int vendor, device;
- int ret;
- unsigned long cntl, chunk;
- int s, l;
- int flags;
- unsigned long agpBase;
-
- if (drmAgpAcquire(ctx->drmFD) < 0) {
- fprintf(stderr, "[agp] AGP not available\n");
- return GL_FALSE;
- }
-
- /* Modify the mode if the default mode is
- not appropriate for this particular
- combination of graphics card and AGP
- chipset. */
-
- mode = drmAgpGetMode(ctx->drmFD); /* Default mode */
- vendor = drmAgpVendorId(ctx->drmFD);
- device = drmAgpDeviceId(ctx->drmFD);
-
- mode &= ~R128_AGP_MODE_MASK;
- switch (info->agpMode) {
- case 4: mode |= R128_AGP_4X_MODE;
- case 2: mode |= R128_AGP_2X_MODE;
- case 1: default: mode |= R128_AGP_1X_MODE;
- }
-
- fprintf(stderr,
- "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
- mode, vendor, device,
- 0x1002,
- info->Chipset);
-
- if (drmAgpEnable(ctx->drmFD, mode) < 0) {
- fprintf(stderr, "[agp] AGP not enabled\n");
- drmAgpRelease(ctx->drmFD);
- return GL_FALSE;
- }
-
- info->agpOffset = 0;
-
- if ((ret = drmAgpAlloc(ctx->drmFD, info->agpSize*1024*1024, 0, NULL,
- &info->agpMemHandle)) < 0) {
- fprintf(stderr, "[agp] Out of memory (%d)\n", ret);
- drmAgpRelease(ctx->drmFD);
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] %d kB allocated with handle 0x%08x\n",
- info->agpSize*1024, info->agpMemHandle);
-
- if (drmAgpBind(ctx->drmFD, info->agpMemHandle, info->agpOffset) < 0) {
- fprintf(stderr, "[agp] Could not bind\n");
- drmAgpFree(ctx->drmFD, info->agpMemHandle);
- drmAgpRelease(ctx->drmFD);
- return GL_FALSE;
- }
-
- /* Initialize the CCE ring buffer data */
- info->ringStart = info->agpOffset;
- info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size;
- info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1;
-
- info->ringReadOffset = info->ringStart + info->ringMapSize;
- info->ringReadMapSize = r128_drm_page_size;
-
- /* Reserve space for vertex/indirect buffers */
- info->bufStart = info->ringReadOffset + info->ringReadMapSize;
- info->bufMapSize = info->bufSize*1024*1024;
-
- /* Reserve the rest for AGP textures */
- info->agpTexStart = info->bufStart + info->bufMapSize;
- s = (info->agpSize*1024*1024 - info->agpTexStart);
- l = R128MinBits((s-1) / R128_NR_TEX_REGIONS);
- if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
- info->agpTexMapSize = (s >> l) << l;
- info->log2AGPTexGran = l;
-
- if (info->CCESecure) flags = DRM_READ_ONLY;
- else flags = 0;
-
- if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
- DRM_AGP, flags, &info->ringHandle) < 0) {
- fprintf(stderr,
- "[agp] Could not add ring mapping\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] ring handle = 0x%08x\n", info->ringHandle);
-
- if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize,
- (drmAddressPtr)&info->ring) < 0) {
- fprintf(stderr, "[agp] Could not map ring\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] Ring mapped at 0x%08lx\n",
- (unsigned long)info->ring);
-
- if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
- DRM_AGP, flags, &info->ringReadPtrHandle) < 0) {
- fprintf(stderr,
- "[agp] Could not add ring read ptr mapping\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] ring read ptr handle = 0x%08x\n",
- info->ringReadPtrHandle);
-
- if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
- (drmAddressPtr)&info->ringReadPtr) < 0) {
- fprintf(stderr,
- "[agp] Could not map ring read ptr\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] Ring read ptr mapped at 0x%08lx\n",
- (unsigned long)info->ringReadPtr);
-
- if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
- DRM_AGP, 0, &info->bufHandle) < 0) {
- fprintf(stderr,
- "[agp] Could not add vertex/indirect buffers mapping\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] vertex/indirect buffers handle = 0x%08lx\n",
- info->bufHandle);
-
- if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize,
- (drmAddressPtr)&info->buf) < 0) {
- fprintf(stderr,
- "[agp] Could not map vertex/indirect buffers\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] Vertex/indirect buffers mapped at 0x%08lx\n",
- (unsigned long)info->buf);
-
- if (drmAddMap(ctx->drmFD, info->agpTexStart, info->agpTexMapSize,
- DRM_AGP, 0, &info->agpTexHandle) < 0) {
- fprintf(stderr,
- "[agp] Could not add AGP texture map mapping\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] AGP texture map handle = 0x%08lx\n",
- info->agpTexHandle);
-
- if (drmMap(ctx->drmFD, info->agpTexHandle, info->agpTexMapSize,
- (drmAddressPtr)&info->agpTex) < 0) {
- fprintf(stderr,
- "[agp] Could not map AGP texture map\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[agp] AGP Texture map mapped at 0x%08lx\n",
- (unsigned long)info->agpTex);
-
- /* Initialize Rage 128's AGP registers */
- cntl = INREG(R128_AGP_CNTL);
- cntl &= ~R128_AGP_APER_SIZE_MASK;
- switch (info->agpSize) {
- case 256: cntl |= R128_AGP_APER_SIZE_256MB; break;
- case 128: cntl |= R128_AGP_APER_SIZE_128MB; break;
- case 64: cntl |= R128_AGP_APER_SIZE_64MB; break;
- case 32: cntl |= R128_AGP_APER_SIZE_32MB; break;
- case 16: cntl |= R128_AGP_APER_SIZE_16MB; break;
- case 8: cntl |= R128_AGP_APER_SIZE_8MB; break;
- case 4: cntl |= R128_AGP_APER_SIZE_4MB; break;
- default:
- fprintf(stderr,
- "[agp] Illegal aperture size %d kB\n",
- info->agpSize*1024);
- return GL_FALSE;
- }
- agpBase = drmAgpBase(ctx->drmFD);
- OUTREG(R128_AGP_BASE, agpBase);
- OUTREG(R128_AGP_CNTL, cntl);
-
- /* Disable Rage 128's PCIGART registers */
- chunk = INREG(R128_BM_CHUNK_0_VAL);
- chunk &= ~(R128_BM_PTR_FORCE_TO_PCI |
- R128_BM_PM4_RD_FORCE_TO_PCI |
- R128_BM_GLOBAL_FORCE_TO_PCI);
- OUTREG(R128_BM_CHUNK_0_VAL, chunk);
-
- OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */
-
- return GL_TRUE;
-}
-
-static GLboolean R128DRIPciInit(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- unsigned char *R128MMIO = ctx->MMIOAddress;
- uint32_t chunk;
- int ret;
- int flags;
-
- info->agpOffset = 0;
-
- ret = drmScatterGatherAlloc(ctx->drmFD, info->agpSize*1024*1024,
- &info->pciMemHandle);
- if (ret < 0) {
- fprintf(stderr, "[pci] Out of memory (%d)\n", ret);
- return GL_FALSE;
- }
- fprintf(stderr,
- "[pci] %d kB allocated with handle 0x%08x\n",
- info->agpSize*1024, info->pciMemHandle);
-
- /* Initialize the CCE ring buffer data */
- info->ringStart = info->agpOffset;
- info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size;
- info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1;
-
- info->ringReadOffset = info->ringStart + info->ringMapSize;
- info->ringReadMapSize = r128_drm_page_size;
-
- /* Reserve space for vertex/indirect buffers */
- info->bufStart = info->ringReadOffset + info->ringReadMapSize;
- info->bufMapSize = info->bufSize*1024*1024;
-
- flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL;
-
- if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
- DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) {
- fprintf(stderr,
- "[pci] Could not add ring mapping\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[pci] ring handle = 0x%08lx\n", info->ringHandle);
-
- if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize,
- (drmAddressPtr)&info->ring) < 0) {
- fprintf(stderr, "[pci] Could not map ring\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[pci] Ring mapped at 0x%08lx\n",
- (unsigned long)info->ring);
- fprintf(stderr,
- "[pci] Ring contents 0x%08lx\n",
- *(unsigned long *)info->ring);
-
- if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
- DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) {
- fprintf(stderr,
- "[pci] Could not add ring read ptr mapping\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[pci] ring read ptr handle = 0x%08lx\n",
- info->ringReadPtrHandle);
-
- if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
- (drmAddressPtr)&info->ringReadPtr) < 0) {
- fprintf(stderr,
- "[pci] Could not map ring read ptr\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[pci] Ring read ptr mapped at 0x%08lx\n",
- (unsigned long)info->ringReadPtr);
- fprintf(stderr,
- "[pci] Ring read ptr contents 0x%08lx\n",
- *(unsigned long *)info->ringReadPtr);
-
- if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
- DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) {
- fprintf(stderr,
- "[pci] Could not add vertex/indirect buffers mapping\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[pci] vertex/indirect buffers handle = 0x%08lx\n",
- info->bufHandle);
-
- if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize,
- (drmAddressPtr)&info->buf) < 0) {
- fprintf(stderr,
- "[pci] Could not map vertex/indirect buffers\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[pci] Vertex/indirect buffers mapped at 0x%08lx\n",
- (unsigned long)info->buf);
- fprintf(stderr,
- "[pci] Vertex/indirect buffers contents 0x%08lx\n",
- *(unsigned long *)info->buf);
-
- if (!info->IsPCI) {
- /* This is really an AGP card, force PCI GART mode */
- chunk = INREG(R128_BM_CHUNK_0_VAL);
- chunk |= (R128_BM_PTR_FORCE_TO_PCI |
- R128_BM_PM4_RD_FORCE_TO_PCI |
- R128_BM_GLOBAL_FORCE_TO_PCI);
- OUTREG(R128_BM_CHUNK_0_VAL, chunk);
- OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */
- }
-
- return GL_TRUE;
-}
-
-/* Add a map for the MMIO registers that will be accessed by any
- DRI-based clients. */
-static GLboolean R128DRIMapInit(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- int flags;
-
- if (info->CCESecure) flags = DRM_READ_ONLY;
- else flags = 0;
-
- /* Map registers */
- if (drmAddMap(ctx->drmFD, ctx->MMIOStart, ctx->MMIOSize,
- DRM_REGISTERS, flags, &info->registerHandle) < 0) {
- return GL_FALSE;
- }
- fprintf(stderr,
- "[drm] register handle = 0x%08x\n", info->registerHandle);
-
- return GL_TRUE;
-}
-
-/* Initialize the kernel data structures. */
-static int R128DRIKernelInit(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- drm_r128_init_t drmInfo;
-
- memset( &drmInfo, 0, sizeof(&drmInfo) );
-
- drmInfo.func = R128_INIT_CCE;
- drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
- drmInfo.is_pci = info->IsPCI;
- drmInfo.cce_mode = info->CCEMode;
- drmInfo.cce_secure = info->CCESecure;
- drmInfo.ring_size = info->ringSize*1024*1024;
- drmInfo.usec_timeout = info->CCEusecTimeout;
-
- drmInfo.fb_bpp = ctx->bpp;
- drmInfo.depth_bpp = ctx->bpp;
-
- drmInfo.front_offset = info->frontOffset;
- drmInfo.front_pitch = info->frontPitch;
-
- drmInfo.back_offset = info->backOffset;
- drmInfo.back_pitch = info->backPitch;
-
- drmInfo.depth_offset = info->depthOffset;
- drmInfo.depth_pitch = info->depthPitch;
- drmInfo.span_offset = info->spanOffset;
-
- drmInfo.fb_offset = info->LinearAddr;
- drmInfo.mmio_offset = info->registerHandle;
- drmInfo.ring_offset = info->ringHandle;
- drmInfo.ring_rptr_offset = info->ringReadPtrHandle;
- drmInfo.buffers_offset = info->bufHandle;
- drmInfo.agp_textures_offset = info->agpTexHandle;
-
- if (drmCommandWrite(ctx->drmFD, DRM_R128_INIT,
- &drmInfo, sizeof(drmInfo)) < 0)
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-/* Add a map for the vertex buffers that will be accessed by any
- DRI-based clients. */
-static GLboolean R128DRIBufInit(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- /* Initialize vertex buffers */
- if (info->IsPCI) {
- info->bufNumBufs = drmAddBufs(ctx->drmFD,
- info->bufMapSize / R128_BUFFER_SIZE,
- R128_BUFFER_SIZE,
- DRM_SG_BUFFER,
- info->bufStart);
- } else {
- info->bufNumBufs = drmAddBufs(ctx->drmFD,
- info->bufMapSize / R128_BUFFER_SIZE,
- R128_BUFFER_SIZE,
- DRM_AGP_BUFFER,
- info->bufStart);
- }
- if (info->bufNumBufs <= 0) {
- fprintf(stderr,
- "[drm] Could not create vertex/indirect buffers list\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[drm] Added %d %d byte vertex/indirect buffers\n",
- info->bufNumBufs, R128_BUFFER_SIZE);
-
- if (!(info->buffers = drmMapBufs(ctx->drmFD))) {
- fprintf(stderr,
- "[drm] Failed to map vertex/indirect buffers list\n");
- return GL_FALSE;
- }
- fprintf(stderr,
- "[drm] Mapped %d vertex/indirect buffers\n",
- info->buffers->count);
-
- return GL_TRUE;
-}
-
-static void R128DRIIrqInit(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- unsigned char *R128MMIO = ctx->MMIOAddress;
-
- if (!info->irq) {
- info->irq = drmGetInterruptFromBusID(
- ctx->drmFD,
- ctx->pciBus,
- ctx->pciDevice,
- ctx->pciFunc);
-
- if((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) {
- fprintf(stderr,
- "[drm] failure adding irq handler, "
- "there is a device already using that irq\n"
- "[drm] falling back to irq-free operation\n");
- info->irq = 0;
- } else {
- info->gen_int_cntl = INREG( R128_GEN_INT_CNTL );
- }
- }
-
- if (info->irq)
- fprintf(stderr,
- "[drm] dma control initialized, using IRQ %d\n",
- info->irq);
-}
-
-static int R128CCEStop(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- drm_r128_cce_stop_t stop;
- int ret, i;
-
- stop.flush = 1;
- stop.idle = 1;
-
- ret = drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP,
- &stop, sizeof(stop) );
-
- if ( ret == 0 ) {
- return 0;
- } else if ( errno != EBUSY ) {
- return -errno;
- }
-
- stop.flush = 0;
-
- i = 0;
- do {
- ret = drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP,
- &stop, sizeof(stop) );
- } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY );
-
- if ( ret == 0 ) {
- return 0;
- } else if ( errno != EBUSY ) {
- return -errno;
- }
-
- stop.idle = 0;
-
- if ( drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP,
- &stop, sizeof(stop) )) {
- return -errno;
- } else {
- return 0;
- }
-}
-
-/* Initialize the CCE state, and start the CCE (if used by the X server) */
-static void R128DRICCEInit(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
-
- /* Turn on bus mastering */
- info->BusCntl &= ~R128_BUS_MASTER_DIS;
-
- /* CCEMode is initialized in r128_driver.c */
- switch (info->CCEMode) {
- case R128_PM4_NONPM4: info->CCEFifoSize = 0; break;
- case R128_PM4_192PIO: info->CCEFifoSize = 192; break;
- case R128_PM4_192BM: info->CCEFifoSize = 192; break;
- case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break;
- case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break;
- case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break;
- case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break;
- case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break;
- case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break;
- case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break;
- }
-
- /* Make sure the CCE is on for the X server */
- R128CCE_START(ctx, info);
-}
-
-
-static int R128MemoryInit(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
- int cpp = ctx->cpp;
- int bufferSize = ((ctx->shared.virtualHeight * width_bytes
- + R128_BUFFER_ALIGN)
- & ~R128_BUFFER_ALIGN);
- int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes
- + R128_BUFFER_ALIGN)
- & ~R128_BUFFER_ALIGN);
- int l;
-
- info->frontOffset = 0;
- info->frontPitch = ctx->shared.virtualWidth;
-
- fprintf(stderr,
- "Using %d MB AGP aperture\n", info->agpSize);
- fprintf(stderr,
- "Using %d MB for the ring buffer\n", info->ringSize);
- fprintf(stderr,
- "Using %d MB for vertex/indirect buffers\n", info->bufSize);
- fprintf(stderr,
- "Using %d MB for AGP textures\n", info->agpTexSize);
-
- /* Front, back and depth buffers - everything else texture??
- */
- info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize;
-
- if (info->textureSize < 0)
- return 0;
-
- l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS);
- if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
-
- /* Round the texture size up to the nearest whole number of
- * texture regions. Again, be greedy about this, don't
- * round down.
- */
- info->log2TexGran = l;
- info->textureSize = (info->textureSize >> l) << l;
-
- /* Set a minimum usable local texture heap size. This will fit
- * two 256x256x32bpp textures.
- */
- if (info->textureSize < 512 * 1024) {
- info->textureOffset = 0;
- info->textureSize = 0;
- }
-
- /* Reserve space for textures */
- info->textureOffset = ((ctx->shared.fbSize - info->textureSize +
- R128_BUFFER_ALIGN) &
- ~R128_BUFFER_ALIGN);
-
- /* Reserve space for the shared depth
- * buffer.
- */
- info->depthOffset = ((info->textureOffset - depthSize +
- R128_BUFFER_ALIGN) &
- ~R128_BUFFER_ALIGN);
- info->depthPitch = ctx->shared.virtualWidth;
-
- info->backOffset = ((info->depthOffset - bufferSize +
- R128_BUFFER_ALIGN) &
- ~R128_BUFFER_ALIGN);
- info->backPitch = ctx->shared.virtualWidth;
-
-
- fprintf(stderr,
- "Will use back buffer at offset 0x%x\n",
- info->backOffset);
- fprintf(stderr,
- "Will use depth buffer at offset 0x%x\n",
- info->depthOffset);
- fprintf(stderr,
- "Will use %d kb for textures at offset 0x%x\n",
- info->textureSize/1024, info->textureOffset);
-
- return 1;
-}
-
-
-/* Initialize the screen-specific data structures for the DRI and the
- Rage 128. This is the main entry point to the device-specific
- initialization code. It calls device-independent DRI functions to
- create the DRI data structures and initialize the DRI state. */
-static GLboolean R128DRIScreenInit(DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- R128DRIPtr pR128DRI;
- int err, major, minor, patch;
- drmVersionPtr version;
- drm_r128_sarea_t *pSAREAPriv;
-
- switch (ctx->bpp) {
- case 8:
- /* These modes are not supported (yet). */
- case 15:
- case 24:
- fprintf(stderr,
- "[dri] R128DRIScreenInit failed (depth %d not supported). "
- "[dri] Disabling DRI.\n", ctx->bpp);
- return GL_FALSE;
-
- /* Only 16 and 32 color depths are supports currently. */
- case 16:
- case 32:
- break;
- }
- r128_drm_page_size = getpagesize();
-
- info->registerSize = ctx->MMIOSize;
- ctx->shared.SAREASize = SAREA_MAX;
-
- /* Note that drmOpen will try to load the kernel module, if needed. */
- ctx->drmFD = drmOpen("r128", NULL );
- if (ctx->drmFD < 0) {
- fprintf(stderr, "[drm] drmOpen failed\n");
- return 0;
- }
-
- /* Check the r128 DRM version */
- version = drmGetVersion(ctx->drmFD);
- if (version) {
- if (version->version_major != 2 ||
- version->version_minor < 2) {
- /* incompatible drm version */
- fprintf(stderr,
- "[dri] R128DRIScreenInit failed because of a version mismatch.\n"
- "[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n"
- "[dri] Disabling the DRI.\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel);
- drmFreeVersion(version);
- return GL_FALSE;
- }
- info->drmMinor = version->version_minor;
- drmFreeVersion(version);
- }
-
- 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%08lx\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%08lx to %p, size %d\n",
- ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
-
- /* Need to AddMap the framebuffer and mmio regions here:
- */
- if (drmAddMap( ctx->drmFD,
- (drm_handle_t)ctx->FBStart,
- ctx->FBSize,
- DRM_FRAME_BUFFER,
- 0,
- &ctx->shared.hFrameBuffer) < 0)
- {
- fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
- return 0;
- }
-
- fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
- ctx->shared.hFrameBuffer);
-
- if (!R128MemoryInit(ctx))
- return GL_FALSE;
-
- /* Initialize AGP */
- if (!info->IsPCI && !R128DRIAgpInit(ctx)) {
- info->IsPCI = GL_TRUE;
- fprintf(stderr,
- "[agp] AGP failed to initialize -- falling back to PCI mode.\n");
- fprintf(stderr,
- "[agp] Make sure you have the agpgart kernel module loaded.\n");
- }
-
- /* Initialize PCIGART */
- if (info->IsPCI && !R128DRIPciInit(ctx)) {
- return GL_FALSE;
- }
-
- /* DRIScreenInit doesn't add all the
- common mappings. Add additional
- mappings here. */
- if (!R128DRIMapInit(ctx)) {
- return GL_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 kernel data structures */
- if (!R128DRIKernelInit(ctx)) {
- return GL_FALSE;
- }
-
- /* Initialize the vertex buffers list */
- if (!R128DRIBufInit(ctx)) {
- return GL_FALSE;
- }
-
- /* Initialize IRQ */
- R128DRIIrqInit(ctx);
-
- /* Initialize and start the CCE if required */
- R128DRICCEInit(ctx);
-
- /* 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.
- */
- drimemsetio((char *)ctx->FBAddress + info->frontOffset,
- 0,
- info->frontPitch * ctx->cpp * ctx->shared.virtualHeight );
-
- drimemsetio((char *)ctx->FBAddress + info->backOffset,
- 0,
- info->backPitch * ctx->cpp * ctx->shared.virtualHeight );
-
- pSAREAPriv = (drm_r128_sarea_t *)(((char*)ctx->pSAREA) +
- sizeof(drm_sarea_t));
- memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
-
- /* This is the struct passed to radeon_dri.so for its initialization */
- ctx->driverClientMsg = malloc(sizeof(R128DRIRec));
- ctx->driverClientMsgSize = sizeof(R128DRIRec);
-
- pR128DRI = (R128DRIPtr)ctx->driverClientMsg;
- pR128DRI->deviceID = info->Chipset;
- pR128DRI->width = ctx->shared.virtualWidth;
- pR128DRI->height = ctx->shared.virtualHeight;
- pR128DRI->depth = ctx->bpp;
- pR128DRI->bpp = ctx->bpp;
-
- pR128DRI->IsPCI = info->IsPCI;
- pR128DRI->AGPMode = info->agpMode;
-
- pR128DRI->frontOffset = info->frontOffset;
- pR128DRI->frontPitch = info->frontPitch;
- pR128DRI->backOffset = info->backOffset;
- pR128DRI->backPitch = info->backPitch;
- pR128DRI->depthOffset = info->depthOffset;
- pR128DRI->depthPitch = info->depthPitch;
- pR128DRI->spanOffset = info->spanOffset;
- pR128DRI->textureOffset = info->textureOffset;
- pR128DRI->textureSize = info->textureSize;
- pR128DRI->log2TexGran = info->log2TexGran;
-
- pR128DRI->registerHandle = info->registerHandle;
- pR128DRI->registerSize = info->registerSize;
-
- pR128DRI->agpTexHandle = info->agpTexHandle;
- pR128DRI->agpTexMapSize = info->agpTexMapSize;
- pR128DRI->log2AGPTexGran = info->log2AGPTexGran;
- pR128DRI->agpTexOffset = info->agpTexStart;
- pR128DRI->sarea_priv_offset = sizeof(drm_sarea_t);
-
- return GL_TRUE;
-}
-
-/* The screen is being closed, so clean up any state and free any
- resources used by the DRI. */
-void R128DRICloseScreen(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
- drm_r128_init_t drmInfo;
-
- /* Stop the CCE if it is still in use */
- R128CCE_STOP(ctx, info);
-
- if (info->irq) {
- drmCtlUninstHandler(ctx->drmFD);
- info->irq = 0;
- }
-
- /* De-allocate vertex buffers */
- if (info->buffers) {
- drmUnmapBufs(info->buffers);
- info->buffers = NULL;
- }
-
- /* De-allocate all kernel resources */
- memset(&drmInfo, 0, sizeof(drmInfo));
- drmInfo.func = R128_CLEANUP_CCE;
- drmCommandWrite(ctx->drmFD, DRM_R128_INIT,
- &drmInfo, sizeof(drmInfo));
-
- /* De-allocate all AGP resources */
- if (info->agpTex) {
- drmUnmap(info->agpTex, info->agpTexMapSize);
- info->agpTex = NULL;
- }
- if (info->buf) {
- drmUnmap(info->buf, info->bufMapSize);
- info->buf = NULL;
- }
- if (info->ringReadPtr) {
- drmUnmap(info->ringReadPtr, info->ringReadMapSize);
- info->ringReadPtr = NULL;
- }
- if (info->ring) {
- drmUnmap(info->ring, info->ringMapSize);
- info->ring = NULL;
- }
- if (info->agpMemHandle != DRM_AGP_NO_HANDLE) {
- drmAgpUnbind(ctx->drmFD, info->agpMemHandle);
- drmAgpFree(ctx->drmFD, info->agpMemHandle);
- info->agpMemHandle = 0;
- drmAgpRelease(ctx->drmFD);
- }
- if (info->pciMemHandle) {
- drmScatterGatherFree(ctx->drmFD, info->pciMemHandle);
- info->pciMemHandle = 0;
- }
-}
-
-static GLboolean R128PreInitDRI(const DRIDriverContext *ctx)
-{
- R128InfoPtr info = ctx->driverPrivate;
-
- /*info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;*/
- info->CCEMode = R128_DEFAULT_CCE_BM_MODE;
- info->CCESecure = GL_TRUE;
-
- info->agpMode = R128_DEFAULT_AGP_MODE;
- info->agpSize = R128_DEFAULT_AGP_SIZE;
- info->ringSize = R128_DEFAULT_RING_SIZE;
- info->bufSize = R128_DEFAULT_BUFFER_SIZE;
- info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE;
-
- info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT;
-
- return GL_TRUE;
-}
-
-/**
- * \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 R128ScreenInit() for the screen initialization.
- *
- * Before exiting clears the framebuffer memory accessing it directly.
- */
-static int R128InitFBDev( DRIDriverContext *ctx )
-{
- R128InfoPtr info = calloc(1, sizeof(*info));
-
- {
- 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 *)info;
-
- info->Chipset = ctx->chipset;
-
- switch (info->Chipset) {
- case PCI_DEVICE_ID_ATI_RAGE128_LE:
- case PCI_DEVICE_ID_ATI_RAGE128_RE:
- case PCI_DEVICE_ID_ATI_RAGE128_RK:
- case PCI_DEVICE_ID_ATI_RAGE128_PD:
- case PCI_DEVICE_ID_ATI_RAGE128_PP:
- case PCI_DEVICE_ID_ATI_RAGE128_PR:
- /* This is a PCI card */
- info->IsPCI = GL_TRUE;
- break;
- default:
- /* This is an AGP card */
- info->IsPCI = GL_FALSE;
- break;
- }
-
- info->frontPitch = ctx->shared.virtualWidth;
- info->LinearAddr = ctx->FBStart & 0xfc000000;
-
- if (!R128PreInitDRI(ctx))
- return 0;
-
- if (!R128DRIScreenInit(ctx))
- 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 R128HaltFBDev( DRIDriverContext *ctx )
-{
- drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
- drmClose(ctx->drmFD);
-
- if (ctx->driverPrivate) {
- free(ctx->driverPrivate);
- ctx->driverPrivate = 0;
- }
-}
-
-
-/**
- * \brief Validate the fbdev mode.
- *
- * \param ctx display handle.
- *
- * \return one on success, or zero on failure.
- *
- * Saves some registers and returns 1.
- *
- * \sa R128PostValidateMode().
- */
-static int R128ValidateMode( 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 R128ValidateMode().
- */
-static int R128PostValidateMode( const DRIDriverContext *ctx )
-{
- return 1;
-}
-
-
-/**
- * \brief Shutdown the drawing engine.
- *
- * \param ctx display handle
- *
- * Turns off the command processor engine & restores the graphics card
- * to a state that fbdev understands.
- */
-static int R128EngineShutdown( const DRIDriverContext *ctx )
-{
- return 1;
-}
-
-/**
- * \brief Restore the drawing engine.
- *
- * \param ctx display handle
- *
- * Resets the graphics card and sets initial values for several registers of
- * the card's drawing engine.
- *
- * Turns on the R128 command processor engine (i.e., the ringbuffer).
- */
-static int R128EngineRestore( const DRIDriverContext *ctx )
-{
- return 1;
-}
-
-
-/**
- * \brief Exported driver interface for Mini GLX.
- *
- * \sa DRIDriverRec.
- */
-const struct DRIDriverRec __driDriver = {
- R128ValidateMode,
- R128PostValidateMode,
- R128InitFBDev,
- R128HaltFBDev,
- R128EngineShutdown,
- R128EngineRestore,
- 0,
-};
+++ /dev/null
-../../radeon/server/radeon_dri.c
\ No newline at end of file
+++ /dev/null
-../../radeon/server/radeon_dri.c
\ No newline at end of file
+++ /dev/null
-../../radeon/server/radeon_dri.c
\ No newline at end of file
+++ /dev/null
-/**
- * \file server/radeon_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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "driver.h"
-#include "drm.h"
-#include "memops.h"
-
-#include "radeon.h"
-#include "radeon_dri.h"
-#include "radeon_macros.h"
-#include "radeon_reg.h"
-#include "drm_sarea.h"
-
-static size_t radeon_drm_page_size;
-
-static int RadeonSetParam(const DRIDriverContext *ctx, int param, int value)
-{
- drm_radeon_setparam_t sp;
-
- memset(&sp, 0, sizeof(sp));
- sp.param = param;
- sp.value = value;
-
- if (drmCommandWrite(ctx->drmFD, DRM_RADEON_SETPARAM, &sp, sizeof(sp))) {
- return -1;
- }
-
- return 0;
-}
-
-/**
- * \brief Wait for free FIFO entries.
- *
- * \param ctx display handle.
- * \param entries number of free entries to wait.
- *
- * It polls the free entries from the chip until it reaches the requested value
- * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out.
- */
-static void RADEONWaitForFifo( const DRIDriverContext *ctx,
- int entries )
-{
- unsigned char *RADEONMMIO = ctx->MMIOAddress;
- int i;
-
- for (i = 0; i < 3000; i++) {
- int fifo_slots =
- INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;
- if (fifo_slots >= entries) return;
- }
-
- /* There are recoveries possible, but I haven't seen them work
- * in practice:
- */
- fprintf(stderr, "FIFO timed out: %d entries, stat=0x%08x\n",
- INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
- INREG(RADEON_RBBM_STATUS));
- exit(1);
-}
-
-/**
- * \brief Read a PLL register.
- *
- * \param ctx display handle.
- * \param addr PLL register index.
- *
- * \return value of the PLL register.
- */
-static unsigned int RADEONINPLL( const DRIDriverContext *ctx, int addr)
-{
- unsigned char *RADEONMMIO = ctx->MMIOAddress;
- unsigned int data;
-
- OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);
- data = INREG(RADEON_CLOCK_CNTL_DATA);
-
- return data;
-}
-
-/**
- * \brief Reset graphics card to known state.
- *
- * \param ctx display handle.
- *
- * Resets the values of several Radeon registers.
- */
-static void RADEONEngineReset( const DRIDriverContext *ctx )
-{
- unsigned char *RADEONMMIO = ctx->MMIOAddress;
- unsigned int clock_cntl_index;
- unsigned int mclk_cntl;
- unsigned int rbbm_soft_reset;
- unsigned int host_path_cntl;
- int i;
-
- OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT,
- RADEON_RB2D_DC_FLUSH_ALL,
- ~RADEON_RB2D_DC_FLUSH_ALL);
- for (i = 0; i < 512; i++) {
- if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY))
- break;
- }
-
- clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
-
- mclk_cntl = INPLL(ctx, RADEON_MCLK_CNTL);
- OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl |
- RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_MCLKB |
- RADEON_FORCEON_YCLKA |
- RADEON_FORCEON_YCLKB |
- RADEON_FORCEON_MC |
- RADEON_FORCEON_AIC));
-
- /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
- * unexpected behaviour on some machines. Here we use
- * RADEON_HOST_PATH_CNTL to reset it.
- */
- host_path_cntl = INREG(RADEON_HOST_PATH_CNTL);
- rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
-
- OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
- RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
- RADEON_SOFT_RESET_SE |
- RADEON_SOFT_RESET_RE |
- RADEON_SOFT_RESET_PP |
- RADEON_SOFT_RESET_E2 |
- RADEON_SOFT_RESET_RB));
- INREG(RADEON_RBBM_SOFT_RESET);
- OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
- (unsigned int) ~(RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
- RADEON_SOFT_RESET_SE |
- RADEON_SOFT_RESET_RE |
- RADEON_SOFT_RESET_PP |
- RADEON_SOFT_RESET_E2 |
- RADEON_SOFT_RESET_RB)));
- INREG(RADEON_RBBM_SOFT_RESET);
-
- OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET);
- INREG(RADEON_HOST_PATH_CNTL);
- OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl);
-
- OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
-
- OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
- OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
-}
-
-/**
- * \brief Restore the drawing engine.
- *
- * \param ctx display handle
- *
- * Resets the graphics card and sets initial values for several registers of
- * the card's drawing engine.
- *
- * Turns on the radeon command processor engine (i.e., the ringbuffer).
- */
-static int RADEONEngineRestore( const DRIDriverContext *ctx )
-{
- RADEONInfoPtr info = ctx->driverPrivate;
- unsigned char *RADEONMMIO = ctx->MMIOAddress;
- int pitch64, datatype, dp_gui_master_cntl, err;
-
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- OUTREG(RADEON_RB3D_CNTL, 0);
- RADEONEngineReset( ctx );
-
- switch (ctx->bpp) {
- case 16: datatype = 4; break;
- case 32: datatype = 6; break;
- default: return 0;
- }
-
- dp_gui_master_cntl =
- ((datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
- | RADEON_GMC_CLR_CMP_CNTL_DIS);
-
- pitch64 = ((ctx->shared.virtualWidth * (ctx->bpp / 8) + 0x3f)) >> 6;
-
- RADEONWaitForFifo(ctx, 1);
- OUTREG(RADEON_DEFAULT_OFFSET, ((INREG(RADEON_DEFAULT_OFFSET) & 0xC0000000)
- | (pitch64 << 22)));
-
- RADEONWaitForFifo(ctx, 1);
- OUTREG(RADEON_SURFACE_CNTL, RADEON_SURF_TRANSLATION_DIS);
-
- RADEONWaitForFifo(ctx, 1);
- OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
- | RADEON_DEFAULT_SC_BOTTOM_MAX));
-
- RADEONWaitForFifo(ctx, 1);
- OUTREG(RADEON_DP_GUI_MASTER_CNTL, (dp_gui_master_cntl
- | RADEON_GMC_BRUSH_SOLID_COLOR
- | RADEON_GMC_SRC_DATATYPE_COLOR));
-
- RADEONWaitForFifo(ctx, 7);
- OUTREG(RADEON_DST_LINE_START, 0);
- OUTREG(RADEON_DST_LINE_END, 0);
- OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
- OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0);
- OUTREG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
- OUTREG(RADEON_DP_SRC_BKGD_CLR, 0);
- OUTREG(RADEON_DP_WRITE_MASK, 0xffffffff);
- OUTREG(RADEON_AUX_SC_CNTL, 0);
-
-/* RADEONWaitForIdleMMIO(ctx); */
- usleep(100);
-
-
- OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);
- if (info->colorTiling)
- info->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
- OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl);
-
- /* Initialize and start the CP if required */
- if ((err = drmCommandNone(ctx->drmFD, DRM_RADEON_CP_START)) != 0) {
- fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err);
- return 0;
- }
-
- return 1;
-}
-
-
-/**
- * \brief Shutdown the drawing engine.
- *
- * \param ctx display handle
- *
- * Turns off the command processor engine & restores the graphics card
- * to a state that fbdev understands.
- */
-static int RADEONEngineShutdown( const DRIDriverContext *ctx )
-{
- drm_radeon_cp_stop_t stop;
- int ret, i;
-
- stop.flush = 1;
- stop.idle = 1;
-
- ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop,
- sizeof(drm_radeon_cp_stop_t));
-
- if (ret == 0) {
- return 0;
- } else if (errno != EBUSY) {
- return -errno;
- }
-
- stop.flush = 0;
-
- i = 0;
- do {
- ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop,
- sizeof(drm_radeon_cp_stop_t));
- } while (ret && errno == EBUSY && i++ < 10);
-
- if (ret == 0) {
- return 0;
- } else if (errno != EBUSY) {
- return -errno;
- }
-
- stop.idle = 0;
-
- if (drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP,
- &stop, sizeof(drm_radeon_cp_stop_t))) {
- return -errno;
- } else {
- return 0;
- }
-}
-
-/**
- * \brief Compute base 2 logarithm.
- *
- * \param val value.
- *
- * \return base 2 logarithm of \p val.
- */
-static int RADEONMinBits(int val)
-{
- int bits;
-
- if (!val) return 1;
- for (bits = 0; val; val >>= 1, ++bits);
- return bits;
-}
-
-/**
- * \brief Initialize the AGP state
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * \return one on success, or zero on failure.
- *
- * Acquires and enables the AGP device. Reserves memory in the AGP space for
- * the ring buffer, vertex buffers and textures. Initialize the Radeon
- * registers to point to that memory and add client mappings.
- */
-static int RADEONDRIAgpInit( const DRIDriverContext *ctx, RADEONInfoPtr info)
-{
- unsigned char *RADEONMMIO = ctx->MMIOAddress;
- unsigned long mode;
- int ret;
- int s, l;
-
- if (drmAgpAcquire(ctx->drmFD) < 0) {
- fprintf(stderr, "[gart] AGP not available\n");
- return 0;
- }
-
- /* Modify the mode if the default mode is not appropriate for this
- * particular combination of graphics card and AGP chipset.
- */
- mode = drmAgpGetMode(ctx->drmFD); /* Default mode */
-
- /* Disable fast write entirely - too many lockups.
- */
- mode &= ~RADEON_AGP_MODE_MASK;
- switch (ctx->agpmode) {
- case 4: mode |= RADEON_AGP_4X_MODE;
- case 2: mode |= RADEON_AGP_2X_MODE;
- case 1: default: mode |= RADEON_AGP_1X_MODE;
- }
-
- 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);
-
- /* Workaround for some hardware bugs */
- if (info->ChipFamily < CHIP_FAMILY_R200)
- OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000);
-
- info->gartOffset = 0;
-
- if ((ret = drmAgpAlloc(ctx->drmFD, info->gartSize*1024*1024, 0, NULL,
- &info->gartMemHandle)) < 0) {
- fprintf(stderr, "[gart] Out of memory (%d)\n", ret);
- drmAgpRelease(ctx->drmFD);
- return 0;
- }
- fprintf(stderr,
- "[gart] %d kB allocated with handle 0x%08x\n",
- info->gartSize*1024, (unsigned)info->gartMemHandle);
-
- if (drmAgpBind(ctx->drmFD,
- info->gartMemHandle, info->gartOffset) < 0) {
- fprintf(stderr, "[gart] Could not bind\n");
- drmAgpFree(ctx->drmFD, info->gartMemHandle);
- drmAgpRelease(ctx->drmFD);
- return 0;
- }
-
- /* Initialize the CP ring buffer data */
- info->ringStart = info->gartOffset;
- info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size;
-
- info->ringReadOffset = info->ringStart + info->ringMapSize;
- info->ringReadMapSize = radeon_drm_page_size;
-
- /* Reserve space for vertex/indirect buffers */
- info->bufStart = info->ringReadOffset + info->ringReadMapSize;
- info->bufMapSize = info->bufSize*1024*1024;
-
- /* Reserve the rest for AGP textures */
- info->gartTexStart = info->bufStart + info->bufMapSize;
- s = (info->gartSize*1024*1024 - info->gartTexStart);
- l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
- if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
- info->gartTexMapSize = (s >> l) << l;
- info->log2GARTTexGran = l;
-
- if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
- DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) {
- fprintf(stderr, "[gart] Could not add ring mapping\n");
- return 0;
- }
- fprintf(stderr, "[gart] ring handle = 0x%08x\n", info->ringHandle);
-
-
- if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
- DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) {
- fprintf(stderr,
- "[gart] Could not add ring read ptr mapping\n");
- return 0;
- }
-
- fprintf(stderr,
- "[gart] ring read ptr handle = 0x%08lx\n",
- info->ringReadPtrHandle);
-
- if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
- DRM_AGP, 0, &info->bufHandle) < 0) {
- fprintf(stderr,
- "[gart] Could not add vertex/indirect buffers mapping\n");
- return 0;
- }
- fprintf(stderr,
- "[gart] vertex/indirect buffers handle = 0x%08x\n",
- info->bufHandle);
-
- if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize,
- DRM_AGP, 0, &info->gartTexHandle) < 0) {
- fprintf(stderr,
- "[gart] Could not add AGP texture map mapping\n");
- return 0;
- }
- fprintf(stderr,
- "[gart] AGP texture map handle = 0x%08lx\n",
- info->gartTexHandle);
-
- /* Initialize Radeon's AGP registers */
- /* Ring buffer is at AGP offset 0 */
- OUTREG(RADEON_AGP_BASE, info->ringHandle);
-
- return 1;
-}
-
-/* Initialize the PCI GART state. Request memory for use in PCI space,
- * and initialize the Radeon registers to point to that memory.
- */
-static int RADEONDRIPciInit(const DRIDriverContext *ctx, RADEONInfoPtr info)
-{
- int ret;
- int flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL;
- int s, l;
-
- ret = drmScatterGatherAlloc(ctx->drmFD, info->gartSize*1024*1024,
- &info->gartMemHandle);
- if (ret < 0) {
- fprintf(stderr, "[pci] Out of memory (%d)\n", ret);
- return 0;
- }
- fprintf(stderr,
- "[pci] %d kB allocated with handle 0x%08lx\n",
- info->gartSize*1024, info->gartMemHandle);
-
- info->gartOffset = 0;
-
- /* Initialize the CP ring buffer data */
- info->ringStart = info->gartOffset;
- info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size;
-
- info->ringReadOffset = info->ringStart + info->ringMapSize;
- info->ringReadMapSize = radeon_drm_page_size;
-
- /* Reserve space for vertex/indirect buffers */
- info->bufStart = info->ringReadOffset + info->ringReadMapSize;
- info->bufMapSize = info->bufSize*1024*1024;
-
- /* Reserve the rest for AGP textures */
- info->gartTexStart = info->bufStart + info->bufMapSize;
- s = (info->gartSize*1024*1024 - info->gartTexStart);
- l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
- if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
- info->gartTexMapSize = (s >> l) << l;
- info->log2GARTTexGran = l;
-
- if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
- DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) {
- fprintf(stderr,
- "[pci] Could not add ring mapping\n");
- return 0;
- }
- fprintf(stderr,
- "[pci] ring handle = 0x%08x\n", info->ringHandle);
-
- if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
- DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) {
- fprintf(stderr,
- "[pci] Could not add ring read ptr mapping\n");
- return 0;
- }
- fprintf(stderr,
- "[pci] ring read ptr handle = 0x%08lx\n",
- info->ringReadPtrHandle);
-
- if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
- DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) {
- fprintf(stderr,
- "[pci] Could not add vertex/indirect buffers mapping\n");
- return 0;
- }
- fprintf(stderr,
- "[pci] vertex/indirect buffers handle = 0x%08lx\n",
- info->bufHandle);
-
- if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize,
- DRM_SCATTER_GATHER, 0, &info->gartTexHandle) < 0) {
- fprintf(stderr,
- "[pci] Could not add GART texture map mapping\n");
- return 0;
- }
- fprintf(stderr,
- "[pci] GART texture map handle = 0x%08x\n",
- info->gartTexHandle);
-
- return 1;
-}
-
-
-/**
- * \brief Initialize the kernel data structures and enable the CP engine.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * \return non-zero on success, or zero on failure.
- *
- * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing
- * all the parameters in a drm_radeon_init_t structure.
- */
-static int RADEONDRIKernelInit( const DRIDriverContext *ctx,
- RADEONInfoPtr info)
-{
- int cpp = ctx->bpp / 8;
- drm_radeon_init_t drmInfo;
- int ret;
-
- memset(&drmInfo, 0, sizeof(drm_radeon_init_t));
-
- if ( (info->ChipFamily == CHIP_FAMILY_R200) ||
- (info->ChipFamily == CHIP_FAMILY_RV250) ||
- (info->ChipFamily == CHIP_FAMILY_M9) ||
- (info->ChipFamily == CHIP_FAMILY_RV280) )
- drmInfo.func = RADEON_INIT_R200_CP;
- else
- drmInfo.func = RADEON_INIT_CP;
-
- /* This is the struct passed to the kernel module for its initialization */
- drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
- drmInfo.is_pci = ctx->isPCI;
- drmInfo.cp_mode = RADEON_DEFAULT_CP_BM_MODE;
- drmInfo.gart_size = info->gartSize*1024*1024;
- drmInfo.ring_size = info->ringSize*1024*1024;
- drmInfo.usec_timeout = 1000;
- drmInfo.fb_bpp = ctx->bpp;
- drmInfo.depth_bpp = ctx->bpp;
- drmInfo.front_offset = info->frontOffset;
- drmInfo.front_pitch = info->frontPitch * cpp;
- drmInfo.back_offset = info->backOffset;
- drmInfo.back_pitch = info->backPitch * cpp;
- drmInfo.depth_offset = info->depthOffset;
- drmInfo.depth_pitch = info->depthPitch * cpp;
- drmInfo.fb_offset = info->LinearAddr;
- drmInfo.mmio_offset = info->registerHandle;
- drmInfo.ring_offset = info->ringHandle;
- drmInfo.ring_rptr_offset = info->ringReadPtrHandle;
- drmInfo.buffers_offset = info->bufHandle;
- drmInfo.gart_textures_offset = info->gartTexHandle;
-
- ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_INIT, &drmInfo,
- sizeof(drm_radeon_init_t));
-
- return ret >= 0;
-}
-
-
-/**
- * \brief Initialize the AGP heap.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing
- * all the parameters in a drm_radeon_mem_init_heap structure.
- */
-static void RADEONDRIAgpHeapInit(const DRIDriverContext *ctx,
- RADEONInfoPtr info)
-{
- drm_radeon_mem_init_heap_t drmHeap;
-
- /* Start up the simple memory manager for gart space */
- drmHeap.region = RADEON_MEM_REGION_GART;
- drmHeap.start = 0;
- drmHeap.size = info->gartTexMapSize;
-
- if (drmCommandWrite(ctx->drmFD, DRM_RADEON_INIT_HEAP,
- &drmHeap, sizeof(drmHeap))) {
- fprintf(stderr,
- "[drm] Failed to initialized gart heap manager\n");
- } else {
- fprintf(stderr,
- "[drm] Initialized kernel gart heap manager, %d\n",
- info->gartTexMapSize);
- }
-}
-
-/**
- * \brief Add a map for the vertex buffers that will be accessed by any
- * DRI-based clients.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * \return one on success, or zero on failure.
- *
- * Calls drmAddBufs() with the previously allocated vertex buffers.
- */
-static int RADEONDRIBufInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
-{
- /* Initialize vertex buffers */
- info->bufNumBufs = drmAddBufs(ctx->drmFD,
- info->bufMapSize / RADEON_BUFFER_SIZE,
- RADEON_BUFFER_SIZE,
- ctx->isPCI ? DRM_SG_BUFFER : DRM_AGP_BUFFER,
- info->bufStart);
-
- if (info->bufNumBufs <= 0) {
- fprintf(stderr,
- "[drm] Could not create vertex/indirect buffers list\n");
- return 0;
- }
- fprintf(stderr,
- "[drm] Added %d %d byte vertex/indirect buffers\n",
- info->bufNumBufs, RADEON_BUFFER_SIZE);
-
- return 1;
-}
-
-/**
- * \brief Install an IRQ handler.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
- * IRQ-free operation on failure.
- */
-static void RADEONDRIIrqInit(const DRIDriverContext *ctx,
- RADEONInfoPtr info)
-{
- if (!info->irq) {
- info->irq = drmGetInterruptFromBusID(ctx->drmFD,
- ctx->pciBus,
- ctx->pciDevice,
- ctx->pciFunc);
-
- if ((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) {
- fprintf(stderr,
- "[drm] failure adding irq handler, "
- "there is a device already using that irq\n"
- "[drm] falling back to irq-free operation\n");
- info->irq = 0;
- }
- }
-
- if (info->irq)
- fprintf(stderr,
- "[drm] dma control initialized, using IRQ %d\n",
- info->irq);
-}
-
-static int RADEONCheckDRMVersion( const DRIDriverContext *ctx,
- RADEONInfoPtr info )
-{
- drmVersionPtr version;
-
- version = drmGetVersion(ctx->drmFD);
- if (version) {
- int req_minor, req_patch;
-
- /* Need 1.8.x for proper cleanup-on-client-exit behaviour.
- */
- req_minor = 8;
- 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] RADEONDRIScreenInit failed because of a version "
- "mismatch.\n"
- "[dri] radeon.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;
- }
-
- info->drmMinor = version->version_minor;
- drmFreeVersion(version);
- }
-
- return 1;
-}
-
-static int RADEONMemoryInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
-{
- int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
- int cpp = ctx->cpp;
- int bufferSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
- int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes
- + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
- int l;
-
- info->frontOffset = 0;
- info->frontPitch = ctx->shared.virtualWidth;
-
- fprintf(stderr,
- "Using %d MB AGP aperture\n", info->gartSize);
- fprintf(stderr,
- "Using %d MB for the ring buffer\n", info->ringSize);
- fprintf(stderr,
- "Using %d MB for vertex/indirect buffers\n", info->bufSize);
- fprintf(stderr,
- "Using %d MB for AGP textures\n", info->gartTexSize);
-
- /* Front, back and depth buffers - everything else texture??
- */
- info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize;
-
- if (ctx->colorTiling==1)
- {
- info->textureSize = ctx->shared.fbSize - ((ctx->shared.fbSize - info->textureSize + width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes*16);
- }
-
- if (info->textureSize < 0)
- return 0;
-
- l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
- if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
-
- /* Round the texture size up to the nearest whole number of
- * texture regions. Again, be greedy about this, don't
- * round down.
- */
- info->log2TexGran = l;
- info->textureSize = (info->textureSize >> l) << l;
-
- /* Set a minimum usable local texture heap size. This will fit
- * two 256x256x32bpp textures.
- */
- if (info->textureSize < 512 * 1024) {
- info->textureOffset = 0;
- info->textureSize = 0;
- }
-
- /* Reserve space for textures */
- if (ctx->colorTiling==1)
- {
- info->textureOffset = ((ctx->shared.fbSize - info->textureSize) /
- (width_bytes * 16)) * (width_bytes*16);
- }
- else
- {
- info->textureOffset = ((ctx->shared.fbSize - info->textureSize +
- RADEON_BUFFER_ALIGN) &
- ~RADEON_BUFFER_ALIGN);
- }
- /* Reserve space for the shared depth
- * buffer.
- */
- info->depthOffset = ((info->textureOffset - depthSize +
- RADEON_BUFFER_ALIGN) &
- ~RADEON_BUFFER_ALIGN);
- info->depthPitch = ctx->shared.virtualWidth;
-
- info->backOffset = ((info->depthOffset - bufferSize +
- RADEON_BUFFER_ALIGN) &
- ~RADEON_BUFFER_ALIGN);
- info->backPitch = ctx->shared.virtualWidth;
-
-
- fprintf(stderr,
- "Will use back buffer at offset 0x%x\n",
- info->backOffset);
- fprintf(stderr,
- "Will use depth buffer at offset 0x%x\n",
- info->depthOffset);
- fprintf(stderr,
- "Will use %d kb for textures at offset 0x%x\n",
- info->textureSize/1024, info->textureOffset);
-
- info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
- (info->frontOffset >> 10));
-
- info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
- (info->backOffset >> 10));
-
- info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) |
- (info->depthOffset >> 10));
-
- return 1;
-}
-
-static int RADEONColorTilingInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
-{
- int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
- int bufferSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + RADEON_BUFFER_ALIGN)
- & ~RADEON_BUFFER_ALIGN);
- /* Setup color tiling */
- if (info->drmMinor<14)
- info->colorTiling=0;
-
- if (info->colorTiling)
- {
-
- int colorTilingFlag;
- drm_radeon_surface_alloc_t front,back;
-
- RadeonSetParam(ctx, RADEON_SETPARAM_SWITCH_TILING, info->colorTiling ? 1 : 0);
-
- /* Setup the surfaces */
- if (info->ChipFamily < CHIP_FAMILY_R200)
- colorTilingFlag=RADEON_SURF_TILE_COLOR_MACRO;
- else
- colorTilingFlag=R200_SURF_TILE_COLOR_MACRO;
-
- front.address = info->frontOffset;
- front.size = bufferSize;
- front.flags = (width_bytes) | colorTilingFlag;
- drmCommandWrite(ctx->drmFD, DRM_RADEON_SURF_ALLOC, &front,sizeof(front));
-
- back.address = info->backOffset;
- back.size = bufferSize;
- back.flags = (width_bytes) | colorTilingFlag;
- drmCommandWrite(ctx->drmFD, DRM_RADEON_SURF_ALLOC, &back,sizeof(back));
-
- }
- return 1;
-}
-
-
-
-/**
- * Called at the start of each server generation.
- *
- * \param ctx display handle.
- * \param info driver private data.
- *
- * \return non-zero on success, or zero on failure.
- *
- * Performs static frame buffer allocation. Opens the DRM device and add maps
- * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
- * information. Creates a \e server context to grab the lock for the
- * initialization ioctls and calls the other initilization functions in this
- * file. Starts the CP engine via the DRM_RADEON_CP_START command.
- *
- * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its
- * initialization.
- */
-static int RADEONScreenInit( DRIDriverContext *ctx, RADEONInfoPtr info )
-{
- RADEONDRIPtr pRADEONDRI;
- int err;
-
- usleep(100);
- /*assert(!ctx->IsClient);*/
-
- {
- int width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
- int maxy = ctx->shared.fbSize / width_bytes;
-
-
- if (maxy <= ctx->shared.virtualHeight * 3) {
- fprintf(stderr,
- "Static buffer allocation failed -- "
- "need at least %d kB video memory (have %d kB)\n",
- (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
- ctx->cpp * 3 + 1023) / 1024,
- ctx->shared.fbSize / 1024);
- return 0;
- }
- }
-
-
- if (info->ChipFamily >= CHIP_FAMILY_R300) {
- fprintf(stderr,
- "Direct rendering not yet supported on "
- "Radeon 9700 and newer cards\n");
- return 0;
- }
-
- radeon_drm_page_size = getpagesize();
-
- info->registerSize = ctx->MMIOSize;
- ctx->shared.SAREASize = SAREA_MAX;
-
- /* Note that drmOpen will try to load the kernel module, if needed. */
- ctx->drmFD = drmOpen("radeon", 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%08lx\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%08lx to %p, size %d\n",
- ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
-
- /* Need to AddMap the framebuffer and mmio regions here:
- */
- if (drmAddMap( ctx->drmFD,
- (drm_handle_t)ctx->FBStart,
- ctx->FBSize,
- DRM_FRAME_BUFFER,
-#ifndef _EMBEDDED
- 0,
-#else
- DRM_READ_ONLY,
-#endif
- &ctx->shared.hFrameBuffer) < 0)
- {
- fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
- return 0;
- }
-
- fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
- ctx->shared.hFrameBuffer);
-
-
-
- if (drmAddMap(ctx->drmFD,
- ctx->MMIOStart,
- ctx->MMIOSize,
- DRM_REGISTERS,
- DRM_READ_ONLY,
- &info->registerHandle) < 0) {
- fprintf(stderr, "[drm] drmAddMap mmio failed\n");
- return 0;
- }
- fprintf(stderr,
- "[drm] register handle = 0x%08lx\n", info->registerHandle);
-
- /* Check the radeon DRM version */
- if (!RADEONCheckDRMVersion(ctx, info)) {
- return 0;
- }
-
- if (ctx->isPCI) {
- /* Initialize PCI */
- if (!RADEONDRIPciInit(ctx, info))
- return 0;
- }
- else {
- /* Initialize AGP */
- if (!RADEONDRIAgpInit(ctx, info))
- return 0;
- }
-
- /* Memory manager setup */
- if (!RADEONMemoryInit(ctx, info)) {
- return 0;
- }
-
- /* 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 kernel data structures */
- if (!RADEONDRIKernelInit(ctx, info)) {
- fprintf(stderr, "RADEONDRIKernelInit failed\n");
- DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
- return 0;
- }
-
- /* Initialize the vertex buffers list */
- if (!RADEONDRIBufInit(ctx, info)) {
- fprintf(stderr, "RADEONDRIBufInit failed\n");
- DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
- return 0;
- }
-
- RADEONColorTilingInit(ctx, info);
-
- /* Initialize IRQ */
- RADEONDRIIrqInit(ctx, info);
-
- /* Initialize kernel gart memory manager */
- RADEONDRIAgpHeapInit(ctx, info);
-
- fprintf(stderr,"color tiling %sabled\n", info->colorTiling?"en":"dis");
- fprintf(stderr,"page flipping %sabled\n", info->page_flip_enable?"en":"dis");
- /* Initialize the SAREA private data structure */
- {
- drm_radeon_sarea_t *pSAREAPriv;
- pSAREAPriv = (drm_radeon_sarea_t *)(((char*)ctx->pSAREA) +
- sizeof(drm_sarea_t));
- memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
- pSAREAPriv->pfState = info->page_flip_enable;
- }
-
-
- /* 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.
- */
- drimemsetio((char *)ctx->FBAddress + info->frontOffset,
- 0,
- info->frontPitch * ctx->cpp * ctx->shared.virtualHeight );
-
- drimemsetio((char *)ctx->FBAddress + info->backOffset,
- 0,
- info->backPitch * ctx->cpp * ctx->shared.virtualHeight );
-
- /* This is the struct passed to radeon_dri.so for its initialization */
- ctx->driverClientMsg = malloc(sizeof(RADEONDRIRec));
- ctx->driverClientMsgSize = sizeof(RADEONDRIRec);
- pRADEONDRI = (RADEONDRIPtr)ctx->driverClientMsg;
- pRADEONDRI->deviceID = info->Chipset;
- pRADEONDRI->width = ctx->shared.virtualWidth;
- pRADEONDRI->height = ctx->shared.virtualHeight;
- pRADEONDRI->depth = ctx->bpp; /* XXX: depth */
- pRADEONDRI->bpp = ctx->bpp;
- pRADEONDRI->IsPCI = ctx->isPCI;
- pRADEONDRI->AGPMode = ctx->agpmode;
- pRADEONDRI->frontOffset = info->frontOffset;
- pRADEONDRI->frontPitch = info->frontPitch;
- pRADEONDRI->backOffset = info->backOffset;
- pRADEONDRI->backPitch = info->backPitch;
- pRADEONDRI->depthOffset = info->depthOffset;
- pRADEONDRI->depthPitch = info->depthPitch;
- pRADEONDRI->textureOffset = info->textureOffset;
- pRADEONDRI->textureSize = info->textureSize;
- pRADEONDRI->log2TexGran = info->log2TexGran;
- pRADEONDRI->registerHandle = info->registerHandle;
- pRADEONDRI->registerSize = info->registerSize;
- pRADEONDRI->statusHandle = info->ringReadPtrHandle;
- pRADEONDRI->statusSize = info->ringReadMapSize;
- pRADEONDRI->gartTexHandle = info->gartTexHandle;
- pRADEONDRI->gartTexMapSize = info->gartTexMapSize;
- pRADEONDRI->log2GARTTexGran = info->log2GARTTexGran;
- pRADEONDRI->gartTexOffset = info->gartTexStart;
- pRADEONDRI->sarea_priv_offset = sizeof(drm_sarea_t);
-
- /* Don't release the lock now - let the VT switch handler do it. */
-
- return 1;
-}
-
-
-/**
- * \brief Get Radeon chip family from chipset number.
- *
- * \param info driver private data.
- *
- * \return non-zero on success, or zero on failure.
- *
- * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily
- * according to the value of RADEONInfoRec::Chipset. Fails if the
- * chipset is unrecognized or not appropriate for this driver (i.e., not
- * an r100 style radeon)
- */
-static int get_chipfamily_from_chipset( RADEONInfoPtr info )
-{
- switch (info->Chipset) {
- case PCI_CHIP_RADEON_LY:
- case PCI_CHIP_RADEON_LZ:
- info->ChipFamily = CHIP_FAMILY_M6;
- break;
-
- case PCI_CHIP_RADEON_QY:
- case PCI_CHIP_RADEON_QZ:
- info->ChipFamily = CHIP_FAMILY_VE;
- break;
-
- case PCI_CHIP_R200_QL:
- case PCI_CHIP_R200_QN:
- case PCI_CHIP_R200_QO:
- case PCI_CHIP_R200_Ql:
- case PCI_CHIP_R200_BB:
- info->ChipFamily = CHIP_FAMILY_R200;
- break;
-
- case PCI_CHIP_RV200_QW: /* RV200 desktop */
- case PCI_CHIP_RV200_QX:
- info->ChipFamily = CHIP_FAMILY_RV200;
- break;
-
- case PCI_CHIP_RADEON_LW:
- case PCI_CHIP_RADEON_LX:
- info->ChipFamily = CHIP_FAMILY_M7;
- break;
-
- case PCI_CHIP_RV250_Id:
- case PCI_CHIP_RV250_Ie:
- case PCI_CHIP_RV250_If:
- case PCI_CHIP_RV250_Ig:
- info->ChipFamily = CHIP_FAMILY_RV250;
- break;
-
- case PCI_CHIP_RV250_Ld:
- case PCI_CHIP_RV250_Le:
- case PCI_CHIP_RV250_Lf:
- case PCI_CHIP_RV250_Lg:
- info->ChipFamily = CHIP_FAMILY_M9;
- break;
-
- case PCI_CHIP_RV280_Y_:
- case PCI_CHIP_RV280_Ya:
- case PCI_CHIP_RV280_Yb:
- case PCI_CHIP_RV280_Yc:
- info->ChipFamily = CHIP_FAMILY_RV280;
- break;
-
- case PCI_CHIP_R300_ND:
- case PCI_CHIP_R300_NE:
- case PCI_CHIP_R300_NF:
- case PCI_CHIP_R300_NG:
- info->ChipFamily = CHIP_FAMILY_R300;
- break;
-
- default:
- /* Original Radeon/7200 */
- info->ChipFamily = CHIP_FAMILY_RADEON;
- }
-
- return 1;
-}
-
-
-/**
- * \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 radeonValidateMode( const DRIDriverContext *ctx )
-{
- unsigned char *RADEONMMIO = ctx->MMIOAddress;
- RADEONInfoPtr info = ctx->driverPrivate;
-
- info->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
- info->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
-
- if (info->colorTiling)
- info->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
- 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 radeonValidateMode().
- */
-static int radeonPostValidateMode( const DRIDriverContext *ctx )
-{
- unsigned char *RADEONMMIO = ctx->MMIOAddress;
- RADEONInfoPtr info = ctx->driverPrivate;
-
- RADEONColorTilingInit( ctx, info);
- OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);
- if (info->colorTiling)
- info->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
- OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl);
-
- 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 RADEONScreenInit() for the screen initialization.
- *
- * Before exiting clears the framebuffer memory accessing it directly.
- */
-static int radeonInitFBDev( DRIDriverContext *ctx )
-{
- RADEONInfoPtr info = calloc(1, sizeof(*info));
-
- {
- int dummy = ctx->shared.virtualWidth;
-
- if (ctx->colorTiling==1)
- {
- switch (ctx->bpp / 8) {
- case 1: dummy = (ctx->shared.virtualWidth + 255) & ~255; break;
- case 2: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
- case 3:
- case 4: dummy = (ctx->shared.virtualWidth + 63) & ~63; break;
- }
- } else {
- 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->shared.Width = dummy;
- }
-
- fprintf(stderr,"shared virtual width is %d\n", ctx->shared.virtualWidth);
- ctx->driverPrivate = (void *)info;
-
- info->gartFastWrite = RADEON_DEFAULT_AGP_FAST_WRITE;
- info->gartSize = RADEON_DEFAULT_AGP_SIZE;
- info->gartTexSize = RADEON_DEFAULT_AGP_TEX_SIZE;
- info->bufSize = RADEON_DEFAULT_BUFFER_SIZE;
- info->ringSize = RADEON_DEFAULT_RING_SIZE;
- info->page_flip_enable = RADEON_DEFAULT_PAGE_FLIP;
- info->colorTiling = ctx->colorTiling;
-
- info->Chipset = ctx->chipset;
-
- if (!get_chipfamily_from_chipset( info )) {
- fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n");
- fprintf(stderr, "==> Verify PCI BusID is correct in miniglx.conf\n");
- return 0;
- }
-
- info->frontPitch = ctx->shared.virtualWidth;
- info->LinearAddr = ctx->FBStart & 0xfc000000;
-
-
- if (!RADEONScreenInit( ctx, info ))
- 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 radeonHaltFBDev( DRIDriverContext *ctx )
-{
- drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
- drmClose(ctx->drmFD);
-
- if (ctx->driverPrivate) {
- free(ctx->driverPrivate);
- ctx->driverPrivate = 0;
- }
-}
-
-
-extern void radeonNotifyFocus( int );
-
-/**
- * \brief Exported driver interface for Mini GLX.
- *
- * \sa DRIDriverRec.
- */
-const struct DRIDriverRec __driDriver = {
- radeonValidateMode,
- radeonPostValidateMode,
- radeonInitFBDev,
- radeonHaltFBDev,
- RADEONEngineShutdown,
- RADEONEngineRestore,
-#ifndef _EMBEDDED
- 0,
-#else
- radeonNotifyFocus,
-#endif
-};
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
- *
- * 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, sublicense,
- * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL 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.
- */
-
-/* Authors:
- * Keith Whitwell
- * Daniel Borca
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "driver.h"
-#include "drm.h"
-#include "imports.h"
-
-#include "dri_util.h"
-
-#include "tdfx_context.h"
-#include "tdfx_dri.h"
-#include "xf86drm.h"
-
-
-#define TILE_WIDTH 128
-#define TILE_HEIGHT 32
-
-#define CMDFIFO_PAGES 64
-
-
-static int
-calcBufferStride (int xres, int tiled, int cpp)
-{
- int strideInTiles;
-
- if (tiled) {
- /* Calculate tile width stuff */
- strideInTiles = (xres+TILE_WIDTH-1)/TILE_WIDTH;
-
- return strideInTiles*cpp*TILE_WIDTH;
- } else {
- return xres*cpp;
- }
-} /* calcBufferStride */
-
-
-static int
-calcBufferHeightInTiles (int yres)
-{
- int heightInTiles; /* Height of buffer in tiles */
-
- /* Calculate tile height stuff */
- heightInTiles = yres >> 5;
-
- if (yres & (TILE_HEIGHT - 1))
- heightInTiles++;
-
- return heightInTiles;
-
-} /* calcBufferHeightInTiles */
-
-
-static int
-calcBufferSize (int xres, int yres, int tiled, int cpp)
-{
- int stride, height, bufSize;
-
- if (tiled) {
- stride = calcBufferStride(xres, tiled, cpp);
- height = TILE_HEIGHT * calcBufferHeightInTiles(yres);
- } else {
- stride = xres*cpp;
- height = yres;
- }
-
- bufSize = stride * height;
-
- return bufSize;
-} /* calcBufferSize */
-
-
-static void allocateMemory (const DRIDriverContext *ctx, TDFXDRIPtr pTDFX)
-{
- int memRemaining, fifoSize, screenSizeInTiles;
- int fbSize;
- char *str;
- int pixmapCacheLinesMin;
- int cursorOffset, cursorSize;
-
- pTDFX->stride = calcBufferStride(pTDFX->width, !0, pTDFX->cpp);
-
- /* enough to do DVD */
- pixmapCacheLinesMin = ((720*480*pTDFX->cpp) +
- pTDFX->stride - 1)/pTDFX->stride;
-
- if (pTDFX->deviceID > PCI_CHIP_VOODOO3) {
- if ((pixmapCacheLinesMin + pTDFX->height) > 4095)
- pixmapCacheLinesMin = 4095 - pTDFX->height;
- } else {
- if ((pixmapCacheLinesMin + pTDFX->height) > 2047)
- pixmapCacheLinesMin = 2047 - pTDFX->height;
- }
-
- if (pTDFX->cpp!=3) {
- screenSizeInTiles=calcBufferSize(pTDFX->width, pTDFX->height,
- !0, pTDFX->cpp);
- }
- else {
- /* cpp==3 needs to bump up to 4 */
- screenSizeInTiles=calcBufferSize(pTDFX->width, pTDFX->height,
- !0, 4);
- }
-
- /*
- * Layout is:
- * cursor, fifo, fb, tex, bb, db
- */
-
- fbSize = (pTDFX->height + pixmapCacheLinesMin) * pTDFX->stride;
-
- memRemaining=(pTDFX->mem - 1) &~ 0xFFF;
- /* Note that a page is 4096 bytes, and a */
- /* tile is 32 x 128 = 4096 bytes. So, */
- /* page and tile boundaries are the same */
- /* Place the depth offset first, forcing */
- /* it to be on an *odd* page boundary. */
- pTDFX->depthOffset = (memRemaining - screenSizeInTiles) &~ 0xFFF;
- if ((pTDFX->depthOffset & (0x1 << 12)) == 0) {
- pTDFX->depthOffset -= (0x1 << 12);
- }
- /* Now, place the back buffer, forcing it */
- /* to be on an *even* page boundary. */
- pTDFX->backOffset = (pTDFX->depthOffset - screenSizeInTiles) &~ 0xFFF;
- if (pTDFX->backOffset & (0x1 << 12)) {
- pTDFX->backOffset -= (0x1 << 12);
- }
- /* Give the cmd fifo at least */
- /* CMDFIFO_PAGES pages, but no more than */
- /* 64. NOTE: Don't go higher than 64, as */
- /* there is suspect code in Glide3 ! */
- fifoSize = ((64 <= CMDFIFO_PAGES) ? 64 : CMDFIFO_PAGES) << 12;
-
- /* We give 4096 bytes to the cursor */
- cursorSize = 0/*4096*/;
- cursorOffset = 0;
-
- pTDFX->fifoOffset = cursorOffset + cursorSize;
- pTDFX->fifoSize = fifoSize;
- /* Now, place the front buffer, forcing */
- /* it to be on a page boundary too, just */
- /* for giggles. */
- pTDFX->fbOffset = pTDFX->fifoOffset + pTDFX->fifoSize;
- pTDFX->textureOffset = pTDFX->fbOffset + fbSize;
- if (pTDFX->depthOffset <= pTDFX->textureOffset ||
- pTDFX->backOffset <= pTDFX->textureOffset) {
- /*
- * pTDFX->textureSize < 0 means that the DRI is disabled. pTDFX->backOffset
- * is used to calculate the maximum amount of memory available for
- * 2D offscreen use. With DRI disabled, set this to the top of memory.
- */
-
- pTDFX->textureSize = -1;
- pTDFX->backOffset = pTDFX->mem;
- pTDFX->depthOffset = -1;
- fprintf(stderr,
- "Not enough video memory available for textures and depth buffer\n"
- "\tand/or back buffer. Disabling DRI. To use DRI try lower\n"
- "\tresolution modes and/or a smaller virtual screen size\n");
- } else {
- pTDFX->textureSize = pTDFX->backOffset - pTDFX->textureOffset;
- }
-}
-
-
-static int createScreen (DRIDriverContext *ctx, TDFXDRIPtr pTDFX)
-{
- int err;
-
- {
- int width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
- int maxy = ctx->shared.fbSize / width_bytes;
-
-
- if (maxy <= ctx->shared.virtualHeight * 3) {
- fprintf(stderr,
- "Static buffer allocation failed -- "
- "need at least %d kB video memory (have %d kB)\n",
- (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
- ctx->cpp * 3 + 1023) / 1024,
- ctx->shared.fbSize / 1024);
- return 0;
- }
- }
-
- ctx->shared.SAREASize = SAREA_MAX;
- pTDFX->regsSize = ctx->MMIOSize;
-
- /* Note that drmOpen will try to load the kernel module, if needed. */
- ctx->drmFD = drmOpen("tdfx", 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%08lx\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%08lx to %p, size %d\n",
- ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
-
- /* Need to AddMap the framebuffer and mmio regions here:
- */
- if (drmAddMap( ctx->drmFD,
- (drm_handle_t)ctx->FBStart,
- ctx->FBSize,
- DRM_FRAME_BUFFER,
-#ifndef _EMBEDDED
- 0,
-#else
- DRM_READ_ONLY,
-#endif
- &ctx->shared.hFrameBuffer) < 0)
- {
- fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
- return 0;
- }
-
- fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
- ctx->shared.hFrameBuffer);
-
-
- if (drmAddMap(ctx->drmFD,
- ctx->MMIOStart,
- ctx->MMIOSize,
- DRM_REGISTERS,
- DRM_READ_ONLY,
- &pTDFX->regs) < 0) {
- fprintf(stderr, "[drm] drmAddMap mmio failed\n");
- return 0;
- }
- fprintf(stderr,
- "[drm] register handle = 0x%08lx\n", pTDFX->regs);
-
-
- /* 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 kernel data structures */
-
- /* Initialize kernel gart memory manager */
- allocateMemory(ctx, pTDFX);
-
- /* Initialize the SAREA private data structure */
-
-
- /* 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.
- */
-
-
- /* This is the struct passed to tdfx_dri.so for its initialization */
- ctx->driverClientMsg = malloc(sizeof(TDFXDRIRec));
- ctx->driverClientMsgSize = sizeof(TDFXDRIRec);
- memcpy(ctx->driverClientMsg, pTDFX, ctx->driverClientMsgSize);
- pTDFX = (TDFXDRIPtr)ctx->driverClientMsg;
-
- /* Don't release the lock now - let the VT switch handler do it. */
-
- return 1;
-}
-
-
-/**
- * \brief Validate the fbdev mode.
- *
- * \param ctx display handle.
- *
- * \return one on success, or zero on failure.
- *
- * Saves some registers and returns 1.
- *
- * \sa tdfxValidateMode().
- */
-static int tdfxValidateMode( 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 tdfxValidateMode().
- */
-static int tdfxPostValidateMode( const DRIDriverContext *ctx )
-{
- return 1;
-}
-
-
-/**
- * \brief Initialize the framebuffer device mode
- *
- * \param ctx display handle.
- *
- * \return one on success, or zero on failure.
- *
- * Before exiting clears the framebuffer memory accessing it directly.
- */
-static int tdfxInitFBDev( DRIDriverContext *ctx )
-{
- TDFXDRIPtr pTDFX = calloc(1, sizeof(TDFXDRIRec));
-
- {
- 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 *)pTDFX;
-
- pTDFX->deviceID = ctx->chipset;
- pTDFX->width = ctx->shared.virtualWidth;
- pTDFX->height = ctx->shared.virtualHeight;
- pTDFX->cpp = ctx->cpp;
- pTDFX->mem = ctx->FBSize; /* ->shared.fbSize? mem probe? */
- pTDFX->sarea_priv_offset = sizeof(drm_sarea_t);
-
- if (!createScreen(ctx, pTDFX))
- 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 tdfxHaltFBDev( DRIDriverContext *ctx )
-{
- drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
- drmClose(ctx->drmFD);
-
- if (ctx->driverPrivate) {
- free(ctx->driverPrivate);
- ctx->driverPrivate = 0;
- }
-}
-
-
-/**
- * \brief Shutdown the drawing engine.
- *
- * \param ctx display handle
- *
- * Turns off the 3D engine & restores the graphics card
- * to a state that fbdev understands.
- */
-static int tdfxEngineShutdown( const DRIDriverContext *ctx )
-{
- fprintf(stderr, "%s: not implemented\n", __FUNCTION__);
- return 1;
-}
-
-
-/**
- * \brief Restore the drawing engine.
- *
- * \param ctx display handle
- *
- * Resets the graphics card and sets initial values for several registers of
- * the card's drawing engine.
- *
- * Turns on 3dfx
- */
-static int tdfxEngineRestore( const DRIDriverContext *ctx )
-{
- fprintf(stderr, "%s: not implemented\n", __FUNCTION__);
- return 1;
-}
-
-
-/**
- * \brief Exported driver interface for Mini GLX.
- *
- * \sa DRIDriverRec.
- */
-struct DRIDriverRec __driDriver = {
- tdfxValidateMode,
- tdfxPostValidateMode,
- tdfxInitFBDev,
- tdfxHaltFBDev,
- tdfxEngineShutdown,
- tdfxEngineRestore,
- 0
-};
+++ /dev/null
-/*
- * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
- *
- * 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
- * VIA, S3 GRAPHICS, AND/OR ITS 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 "imports.h"
-
-#include "dri_util.h"
-
-#include "via_context.h"
-#include "via_dri.h"
-#include "via_driver.h"
-#include "xf86drm.h"
-
-static void VIAEnableMMIO(DRIDriverContext * ctx);
-static void VIADisableMMIO(DRIDriverContext * ctx);
-static void VIADisableExtendedFIFO(DRIDriverContext *ctx);
-static void VIAEnableExtendedFIFO(DRIDriverContext *ctx);
-static void VIAInitialize2DEngine(DRIDriverContext *ctx);
-static void VIAInitialize3DEngine(DRIDriverContext *ctx);
-
-static int VIADRIScreenInit(DRIDriverContext * ctx);
-static void VIADRICloseScreen(DRIDriverContext * ctx);
-static int VIADRIFinishScreenInit(DRIDriverContext * ctx);
-
-/* _SOLO : missing macros normally defined by X code */
-#define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__)
-#define MMIO_IN8(base, addr) ((*(((volatile uint8_t*)base)+(addr)))+0)
-#define MMIO_OUT8(base, addr, val) ((*(((volatile uint8_t*)base)+(addr)))=((uint8_t)val))
-#define MMIO_OUT16(base, addr, val) ((*(volatile uint16_t*)(((uint8_t*)base)+(addr)))=((uint16_t)val))
-
-#define VIDEO 0
-#define AGP 1
-#define AGP_PAGE_SIZE 4096
-#define AGP_PAGES 8192
-#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)
-#define AGP_CMDBUF_PAGES 512
-#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
-
-static char VIAKernelDriverName[] = "via";
-static char VIAClientDriverName[] = "unichrome";
-
-static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia);
-static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia);
-static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia);
-static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia);
-static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia);
-
-static void VIADRIIrqInit( DRIDriverContext *ctx )
-{
- VIAPtr pVia = VIAPTR(ctx);
- VIADRIPtr pVIADRI = pVia->devPrivate;
-
- pVIADRI->irqEnabled = drmGetInterruptFromBusID(pVia->drmFD,
- ctx->pciBus,
- ctx->pciDevice,
- ctx->pciFunc);
-
- if ((drmCtlInstHandler(pVia->drmFD, pVIADRI->irqEnabled))) {
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[drm] Failure adding irq handler. "
- "Falling back to irq-free operation.\n");
- pVIADRI->irqEnabled = 0;
- }
-
- if (pVIADRI->irqEnabled)
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] Irq handler installed, using IRQ %d.\n",
- pVIADRI->irqEnabled);
-}
-
-static void VIADRIIrqExit( DRIDriverContext *ctx ) {
- VIAPtr pVia = VIAPTR(ctx);
- VIADRIPtr pVIADRI = pVia->devPrivate;
-
- if (pVIADRI->irqEnabled) {
- if (drmCtlUninstHandler(pVia->drmFD)) {
- xf86DrvMsg(pScreen-myNum, X_INFO,"[drm] Irq handler uninstalled.\n");
- } else {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] Could not uninstall irq handler.\n");
- }
- }
-}
-
-static void VIADRIRingBufferCleanup(DRIDriverContext *ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- VIADRIPtr pVIADRI = pVia->devPrivate;
- drm_via_dma_init_t ringBufInit;
-
- if (pVIADRI->ringBufActive) {
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] Cleaning up DMA ring-buffer.\n");
- ringBufInit.func = VIA_CLEANUP_DMA;
- if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,
- sizeof(ringBufInit))) {
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[drm] Failed to clean up DMA ring-buffer: %d\n", errno);
- }
- pVIADRI->ringBufActive = 0;
- }
-}
-
-static int VIADRIRingBufferInit(DRIDriverContext *ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- VIADRIPtr pVIADRI = pVia->devPrivate;
- drm_via_dma_init_t ringBufInit;
- drmVersionPtr drmVer;
-
- pVIADRI->ringBufActive = 0;
-
- if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) {
- return GL_FALSE;
- }
-
- if (((drmVer->version_major <= 1) && (drmVer->version_minor <= 3))) {
- return GL_FALSE;
- }
-
- /*
- * Info frome code-snippet on DRI-DEVEL list; Erdi Chen.
- */
-
- switch (pVia->ChipId) {
- case PCI_CHIP_VT3259:
- ringBufInit.reg_pause_addr = 0x40c;
- break;
- default:
- ringBufInit.reg_pause_addr = 0x418;
- break;
- }
-
- ringBufInit.offset = pVia->agpSize;
- ringBufInit.size = AGP_CMDBUF_SIZE;
- ringBufInit.func = VIA_INIT_DMA;
- if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,
- sizeof(ringBufInit))) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] Failed to initialize DMA ring-buffer: %d\n", errno);
- return GL_FALSE;
- }
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP offset 0x%lx.\n",
- ringBufInit.size, ringBufInit.offset);
-
- pVIADRI->ringBufActive = 1;
- return GL_TRUE;
-}
-
-static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia)
-{
- unsigned long agp_phys;
- drmAddress agpaddr;
- VIADRIPtr pVIADRI;
- pVIADRI = pVia->devPrivate;
- pVia->agpSize = 0;
-
- if (drmAgpAcquire(pVia->drmFD) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno);
- return GL_FALSE;
- }
-
- if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n");
- return GL_FALSE;
- }
-
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n");
-
- if (drmAgpAlloc(pVia->drmFD, AGP_SIZE, 0, &agp_phys, &pVia->agpHandle) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] drmAgpAlloc failed\n");
- drmAgpRelease(pVia->drmFD);
- return GL_FALSE;
- }
-
- if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] drmAgpBind failed\n");
- drmAgpFree(pVia->drmFD, pVia->agpHandle);
- drmAgpRelease(pVia->drmFD);
-
- return GL_FALSE;
- }
-
- /*
- * Place the ring-buffer last in the AGP region, and restrict the
- * public map not to include the buffer for security reasons.
- */
-
- pVia->agpSize = AGP_SIZE - AGP_CMDBUF_SIZE;
- pVia->agpAddr = drmAgpBase(pVia->drmFD);
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] agpAddr = 0x%08lx\n",pVia->agpAddr);
-
- pVIADRI->agp.size = pVia->agpSize;
- if (drmAddMap(pVia->drmFD, (drm_handle_t)0,
- pVIADRI->agp.size, DRM_AGP, 0,
- &pVIADRI->agp.handle) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] Failed to map public agp area\n");
- pVIADRI->agp.size = 0;
- return GL_FALSE;
- }
- /* Map AGP from kernel to Xserver - Not really needed */
- drmMap(pVia->drmFD, pVIADRI->agp.handle,pVIADRI->agp.size, &agpaddr);
-
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr);
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] agpSize = 0x%08lx\n", pVia->agpSize);
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] agp physical addr = 0x%08lx\n", agp_phys);
-
- {
- drm_via_agp_t agp;
- agp.offset = 0;
- agp.size = AGP_SIZE-AGP_CMDBUF_SIZE;
- if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp,
- sizeof(drm_via_agp_t)) < 0) {
- drmUnmap(&agpaddr,pVia->agpSize);
- drmRmMap(pVia->drmFD,pVIADRI->agp.handle);
- drmAgpUnbind(pVia->drmFD, pVia->agpHandle);
- drmAgpFree(pVia->drmFD, pVia->agpHandle);
- drmAgpRelease(pVia->drmFD);
- return GL_FALSE;
- }
- }
-
- return GL_TRUE;
-}
-
-static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia)
-{
- int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart;
- int FBOffset = pVia->FBFreeStart;
- VIADRIPtr pVIADRI = pVia->devPrivate;
- pVIADRI->fbOffset = FBOffset;
- pVIADRI->fbSize = pVia->videoRambytes;
-
- {
- drm_via_fb_t fb;
- fb.offset = FBOffset;
- fb.size = FBSize;
-
- if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb,
- sizeof(drm_via_fb_t)) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to init frame buffer area\n");
- return GL_FALSE;
- } else {
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x "
- "FBSize= 0x%08x\n",
- pVia->FBFreeStart, pVia->FBFreeEnd, FBSize);
- return GL_TRUE;
- }
- }
-}
-
-static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia)
-{
- return GL_TRUE;
-}
-
-static int VIADRIScreenInit(DRIDriverContext * ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- VIADRIPtr pVIADRI;
- int err;
-
-#if 0
- ctx->shared.SAREASize = ((sizeof(drm_sarea_t) + 0xfff) & 0x1000);
-#else
- if (sizeof(drm_sarea_t)+sizeof(drm_via_sarea_t) > SAREA_MAX) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Data does not fit in SAREA\n");
- return GL_FALSE;
- }
- ctx->shared.SAREASize = SAREA_MAX;
-#endif
-
- ctx->drmFD = drmOpen(VIAKernelDriverName, NULL);
- if (ctx->drmFD < 0) {
- fprintf(stderr, "[drm] drmOpen failed\n");
- return 0;
- }
- pVia->drmFD = ctx->drmFD;
-
- err = drmSetBusid(ctx->drmFD, ctx->pciBusID);
- if (err < 0) {
- fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
- ctx->drmFD, ctx->pciBusID, strerror(-err));
- return 0;
- }
-
- err = drmAddMap(ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM,
- DRM_CONTAINS_LOCK, &ctx->shared.hSAREA);
- if (err < 0) {
- fprintf(stderr, "[drm] drmAddMap failed\n");
- return 0;
- }
- fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\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%08lx to %p, size %d\n",
- ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
-
- /* Need to AddMap the framebuffer and mmio regions here:
- */
- if (drmAddMap(ctx->drmFD,
- (drm_handle_t)ctx->FBStart,
- ctx->FBSize,
- DRM_FRAME_BUFFER,
-#ifndef _EMBEDDED
- 0,
-#else
- DRM_READ_ONLY,
-#endif
- &ctx->shared.hFrameBuffer) < 0)
- {
- fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
- return 0;
- }
-
- fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
- ctx->shared.hFrameBuffer);
-
- pVIADRI = (VIADRIPtr) CALLOC(sizeof(VIADRIRec));
- if (!pVIADRI) {
- drmClose(ctx->drmFD);
- return GL_FALSE;
- }
- pVia->devPrivate = pVIADRI;
- ctx->driverClientMsg = pVIADRI;
- ctx->driverClientMsgSize = sizeof(*pVIADRI);
-
- /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */
- if (!VIADRIMapInit(ctx, pVia)) {
- VIADRICloseScreen(ctx);
- return GL_FALSE;
- }
-
- pVIADRI->regs.size = VIA_MMIO_REGSIZE;
- pVIADRI->regs.handle = pVia->registerHandle;
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n",
- pVIADRI->regs.handle);
-
- if (drmMap(pVia->drmFD,
- pVIADRI->regs.handle,
- pVIADRI->regs.size,
- (drmAddress *)&pVia->MapBase) != 0)
- {
- VIADRICloseScreen(ctx);
- return GL_FALSE;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" );
-
- VIAEnableMMIO(ctx);
-
- /* Get video memory clock. */
- VGAOUT8(0x3D4, 0x3D);
- pVia->MemClk = (VGAIN8(0x3D5) & 0xF0) >> 4;
- xf86DrvMsg(0, X_INFO, "[dri] MemClk (0x%x)\n", pVia->MemClk);
-
- /* 3D rendering has noise if not enabled. */
- VIAEnableExtendedFIFO(ctx);
-
- VIAInitialize2DEngine(ctx);
-
- /* Must disable MMIO or 3D won't work. */
- VIADisableMMIO(ctx);
-
- VIAInitialize3DEngine(ctx);
-
- pVia->IsPCI = !VIADRIAgpInit(ctx, pVia);
-
- if (pVia->IsPCI) {
- VIADRIPciInit(ctx, pVia);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use pci.\n" );
- }
- else
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use agp.\n" );
-
- if (!(VIADRIFBInit(ctx, pVia))) {
- VIADRICloseScreen(ctx);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] frame buffer initialize fail .\n" );
- return GL_FALSE;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" );
-
- return VIADRIFinishScreenInit(ctx);
-}
-
-static void
-VIADRICloseScreen(DRIDriverContext * ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- VIADRIPtr pVIADRI=(VIADRIPtr)pVia->devPrivate;
-
- VIADRIRingBufferCleanup(ctx);
-
- if (pVia->MapBase) {
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Unmapping MMIO registers\n");
- drmUnmap(pVia->MapBase, pVIADRI->regs.size);
- }
-
- if (pVia->agpSize) {
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n");
- drmAgpFree(pVia->drmFD, pVia->agpHandle);
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n");
- drmAgpRelease(pVia->drmFD);
- }
-
-#if 0
- if (pVia->DRIIrqEnable)
-#endif
- VIADRIIrqExit(ctx);
-}
-
-static int
-VIADRIFinishScreenInit(DRIDriverContext * ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- VIADRIPtr pVIADRI;
- int err;
-
- err = drmCreateContext(ctx->drmFD, &ctx->serverContext);
- if (err != 0) {
- fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
- return GL_FALSE;
- }
-
- DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
-
-
- if (!VIADRIKernelInit(ctx, pVia)) {
- VIADRICloseScreen(ctx);
- return GL_FALSE;
- }
- xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n");
-
- /* set SAREA value */
- {
- drm_via_sarea_t *saPriv;
-
- saPriv=(drm_via_sarea_t*)(((char*)ctx->pSAREA) +
- sizeof(drm_sarea_t));
- assert(saPriv);
- memset(saPriv, 0, sizeof(*saPriv));
- saPriv->ctxOwner = -1;
- }
- pVIADRI=(VIADRIPtr)pVia->devPrivate;
- pVIADRI->deviceID=pVia->Chipset;
- pVIADRI->width=ctx->shared.virtualWidth;
- pVIADRI->height=ctx->shared.virtualHeight;
- pVIADRI->mem=ctx->shared.fbSize;
- pVIADRI->bytesPerPixel= (ctx->bpp+7) / 8;
- pVIADRI->sarea_priv_offset = sizeof(drm_sarea_t);
- /* TODO */
- pVIADRI->scrnX=pVIADRI->width;
- pVIADRI->scrnY=pVIADRI->height;
-
- /* Initialize IRQ */
-#if 0
- if (pVia->DRIIrqEnable)
-#endif
- VIADRIIrqInit(ctx);
-
- pVIADRI->ringBufActive = 0;
- VIADRIRingBufferInit(ctx);
-
- return GL_TRUE;
-}
-
-/* Initialize the kernel data structures. */
-static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia)
-{
- drm_via_init_t drmInfo;
- memset(&drmInfo, 0, sizeof(drm_via_init_t));
- drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
- drmInfo.func = VIA_INIT_MAP;
- drmInfo.fb_offset = pVia->FrameBufferBase;
- drmInfo.mmio_offset = pVia->registerHandle;
- if (pVia->IsPCI)
- drmInfo.agpAddr = (uint32_t)NULL;
- else
- drmInfo.agpAddr = (uint32_t)pVia->agpAddr;
-
- if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo,
- sizeof(drm_via_init_t))) < 0)
- return GL_FALSE;
-
- return GL_TRUE;
-}
-/* Add a map for the MMIO registers */
-static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia)
-{
- int flags = 0;
-
- if (drmAddMap(pVia->drmFD, pVia->MmioBase, VIA_MMIO_REGSIZE,
- DRM_REGISTERS, flags, &pVia->registerHandle) < 0) {
- return GL_FALSE;
- }
-
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] register handle = 0x%08lx\n", pVia->registerHandle);
-
- return GL_TRUE;
-}
-
-static int viaValidateMode(const DRIDriverContext *ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
-
- return 1;
-}
-
-static int viaPostValidateMode(const DRIDriverContext *ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
-
- return 1;
-}
-
-static void VIAEnableMMIO(DRIDriverContext * ctx)
-{
- /*vgaHWPtr hwp = VGAHWPTR(ctx);*/
- VIAPtr pVia = VIAPTR(ctx);
- unsigned char val;
-
-#if 0
- if (xf86IsPrimaryPci(pVia->PciInfo)) {
- /* If we are primary card, we still use std vga port. If we use
- * MMIO, system will hang in vgaHWSave when our card used in
- * PLE and KLE (integrated Trident MVP4)
- */
- vgaHWSetStdFuncs(hwp);
- }
- else {
- vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
- }
-#endif
-
- val = VGAIN8(0x3c3);
- VGAOUT8(0x3c3, val | 0x01);
- val = VGAIN8(0x3cc);
- VGAOUT8(0x3c2, val | 0x01);
-
- /* Unlock Extended IO Space */
- VGAOUT8(0x3c4, 0x10);
- VGAOUT8(0x3c5, 0x01);
-
- /* Enable MMIO */
- if(!pVia->IsSecondary) {
- VGAOUT8(0x3c4, 0x1a);
- val = VGAIN8(0x3c5);
-#ifdef DEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "primary val = %x\n", val);
-#endif
- VGAOUT8(0x3c5, val | 0x68);
- }
- else {
- VGAOUT8(0x3c4, 0x1a);
- val = VGAIN8(0x3c5);
-#ifdef DEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "secondary val = %x\n", val);
-#endif
- VGAOUT8(0x3c5, val | 0x38);
- }
-
- /* Unlock CRTC registers */
- VGAOUT8(0x3d4, 0x47);
- VGAOUT8(0x3d5, 0x00);
-
- return;
-}
-
-static void VIADisableMMIO(DRIDriverContext * ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- unsigned char val;
-
- VGAOUT8(0x3c4, 0x1a);
- val = VGAIN8(0x3c5);
- VGAOUT8(0x3c5, val & 0x97);
-
- return;
-}
-
-static void VIADisableExtendedFIFO(DRIDriverContext *ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- uint32_t dwGE230, dwGE298;
-
- /* Cause of exit XWindow will dump back register value, others chipset no
- * need to set extended fifo value */
- if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15 &&
- (ctx->shared.virtualWidth > 1024 || pVia->HasSecondary)) {
- /* Turn off Extend FIFO */
- /* 0x298[29] */
- dwGE298 = VIAGETREG(0x298);
- VIASETREG(0x298, dwGE298 | 0x20000000);
- /* 0x230[21] */
- dwGE230 = VIAGETREG(0x230);
- VIASETREG(0x230, dwGE230 & ~0x00200000);
- /* 0x298[29] */
- dwGE298 = VIAGETREG(0x298);
- VIASETREG(0x298, dwGE298 & ~0x20000000);
- }
-}
-
-static void VIAEnableExtendedFIFO(DRIDriverContext *ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- uint8_t bRegTemp;
- uint32_t dwGE230, dwGE298;
-
- switch (pVia->Chipset) {
- case VIA_CLE266:
- if (pVia->ChipRev > 14) { /* For 3123Cx */
- if (pVia->HasSecondary) { /* SAMM or DuoView case */
- if (ctx->shared.virtualWidth >= 1024)
- {
- /* 3c5.16[0:5] */
- VGAOUT8(0x3C4, 0x16);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp |= 0x1C;
- VGAOUT8(0x3C5, bRegTemp);
- /* 3c5.17[0:6] */
- VGAOUT8(0x3C4, 0x17);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x7F;
- bRegTemp |= 0x3F;
- VGAOUT8(0x3C5, bRegTemp);
- pVia->EnableExtendedFIFO = GL_TRUE;
- }
- }
- else /* Single view or Simultaneoue case */
- {
- if (ctx->shared.virtualWidth > 1024)
- {
- /* 3c5.16[0:5] */
- VGAOUT8(0x3C4, 0x16);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp |= 0x17;
- VGAOUT8(0x3C5, bRegTemp);
- /* 3c5.17[0:6] */
- VGAOUT8(0x3C4, 0x17);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x7F;
- bRegTemp |= 0x2F;
- VGAOUT8(0x3C5, bRegTemp);
- pVia->EnableExtendedFIFO = GL_TRUE;
- }
- }
- /* 3c5.18[0:5] */
- VGAOUT8(0x3C4, 0x18);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp |= 0x17;
- bRegTemp |= 0x40; /* force the preq always higher than treq */
- VGAOUT8(0x3C5, bRegTemp);
- }
- else { /* for 3123Ax */
- if (ctx->shared.virtualWidth > 1024 || pVia->HasSecondary) {
- /* Turn on Extend FIFO */
- /* 0x298[29] */
- dwGE298 = VIAGETREG(0x298);
- VIASETREG(0x298, dwGE298 | 0x20000000);
- /* 0x230[21] */
- dwGE230 = VIAGETREG(0x230);
- VIASETREG(0x230, dwGE230 | 0x00200000);
- /* 0x298[29] */
- dwGE298 = VIAGETREG(0x298);
- VIASETREG(0x298, dwGE298 & ~0x20000000);
-
- /* 3c5.16[0:5] */
- VGAOUT8(0x3C4, 0x16);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp |= 0x17;
- /* bRegTemp |= 0x10; */
- VGAOUT8(0x3C5, bRegTemp);
- /* 3c5.17[0:6] */
- VGAOUT8(0x3C4, 0x17);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x7F;
- bRegTemp |= 0x2F;
- /*bRegTemp |= 0x1F;*/
- VGAOUT8(0x3C5, bRegTemp);
- /* 3c5.18[0:5] */
- VGAOUT8(0x3C4, 0x18);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp |= 0x17;
- bRegTemp |= 0x40; /* force the preq always higher than treq */
- VGAOUT8(0x3C5, bRegTemp);
- pVia->EnableExtendedFIFO = GL_TRUE;
- }
- }
- break;
- case VIA_KM400:
- if (pVia->HasSecondary) { /* SAMM or DuoView case */
- if ((ctx->shared.virtualWidth >= 1600) &&
- (pVia->MemClk <= VIA_MEM_DDR200)) {
- /* enable CRT extendded FIFO */
- VGAOUT8(0x3C4, 0x17);
- VGAOUT8(0x3C5, 0x1C);
- /* revise second display queue depth and read threshold */
- VGAOUT8(0x3C4, 0x16);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp = (bRegTemp) | (0x09);
- VGAOUT8(0x3C5, bRegTemp);
- }
- else {
- /* enable CRT extendded FIFO */
- VGAOUT8(0x3C4, 0x17);
- VGAOUT8(0x3C5,0x3F);
- /* revise second display queue depth and read threshold */
- VGAOUT8(0x3C4, 0x16);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp = (bRegTemp) | (0x1C);
- VGAOUT8(0x3C5, bRegTemp);
- }
- /* 3c5.18[0:5] */
- VGAOUT8(0x3C4, 0x18);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp |= 0x17;
- bRegTemp |= 0x40; /* force the preq always higher than treq */
- VGAOUT8(0x3C5, bRegTemp);
- pVia->EnableExtendedFIFO = GL_TRUE;
- }
- else {
- if ( (ctx->shared.virtualWidth > 1024) && (ctx->shared.virtualWidth <= 1280) )
- {
- /* enable CRT extendded FIFO */
- VGAOUT8(0x3C4, 0x17);
- VGAOUT8(0x3C5, 0x3F);
- /* revise second display queue depth and read threshold */
- VGAOUT8(0x3C4, 0x16);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp = (bRegTemp) | (0x17);
- VGAOUT8(0x3C5, bRegTemp);
- pVia->EnableExtendedFIFO = GL_TRUE;
- }
- else if ((ctx->shared.virtualWidth > 1280))
- {
- /* enable CRT extendded FIFO */
- VGAOUT8(0x3C4, 0x17);
- VGAOUT8(0x3C5, 0x3F);
- /* revise second display queue depth and read threshold */
- VGAOUT8(0x3C4, 0x16);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp = (bRegTemp) | (0x1C);
- VGAOUT8(0x3C5, bRegTemp);
- pVia->EnableExtendedFIFO = GL_TRUE;
- }
- else
- {
- /* enable CRT extendded FIFO */
- VGAOUT8(0x3C4, 0x17);
- VGAOUT8(0x3C5, 0x3F);
- /* revise second display queue depth and read threshold */
- VGAOUT8(0x3C4, 0x16);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp = (bRegTemp) | (0x10);
- VGAOUT8(0x3C5, bRegTemp);
- }
- /* 3c5.18[0:5] */
- VGAOUT8(0x3C4, 0x18);
- bRegTemp = VGAIN8(0x3C5);
- bRegTemp &= ~0x3F;
- bRegTemp |= 0x17;
- bRegTemp |= 0x40; /* force the preq always higher than treq */
- VGAOUT8(0x3C5, bRegTemp);
- }
- break;
- case VIA_K8M800:
- /*=* R1 Display FIFO depth (384 /8 -1 -> 0xbf) SR17[7:0] (8bits) *=*/
- VGAOUT8(0x3c4, 0x17);
- VGAOUT8(0x3c5, 0xbf);
-
- /*=* R2 Display fetch datum threshold value (328/4 -> 0x52)
- SR16[5:0], SR16[7] (7bits) *=*/
- VGAOUT8(0x3c4, 0x16);
- bRegTemp = VGAIN8(0x3c5) & ~0xBF;
- bRegTemp |= (0x52 & 0x3F);
- bRegTemp |= ((0x52 & 0x40) << 1);
- VGAOUT8(0x3c5, bRegTemp);
-
- /*=* R3 Switch to the highest agent threshold value (74 -> 0x4a)
- SR18[5:0], SR18[7] (7bits) *=*/
- VGAOUT8(0x3c4, 0x18);
- bRegTemp = VGAIN8(0x3c5) & ~0xBF;
- bRegTemp |= (0x4a & 0x3F);
- bRegTemp |= ((0x4a & 0x40) << 1);
- VGAOUT8(0x3c5, bRegTemp);
-#if 0
- /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
- SR1C[7:0], SR1D[1:0] (10bits) *=*/
- wRegTemp = (pBIOSInfo->offsetWidthByQWord >> 1) + 4;
- VGAOUT8(0x3c4, 0x1c);
- VGAOUT8(0x3c5, (uint8_t)(wRegTemp & 0xFF));
- VGAOUT8(0x3c4, 0x1d);
- bRegTemp = VGAIN8(0x3c5) & ~0x03;
- VGAOUT8(0x3c5, bRegTemp | ((wRegTemp & 0x300) >> 8));
-#endif
- if (ctx->shared.virtualWidth >= 1400 && ctx->bpp == 32)
- {
- /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
- VGAOUT8(0x3c4, 0x22);
- bRegTemp = VGAIN8(0x3c5) & ~0x1F;
- VGAOUT8(0x3c5, bRegTemp | 0x10);
- }
- else
- {
- /*=* Max. length for a request SR22[4:0]
- (128/4 -> over flow 0x0) *=*/
- VGAOUT8(0x3c4, 0x22);
- bRegTemp = VGAIN8(0x3c5) & ~0x1F;
- VGAOUT8(0x3c5, bRegTemp);
- }
- break;
- case VIA_PM800:
- /*=* R1 Display FIFO depth (96-1 -> 0x5f) SR17[7:0] (8bits) *=*/
- VGAOUT8(0x3c4, 0x17);
- VGAOUT8(0x3c5, 0x5f);
-
- /*=* R2 Display fetch datum threshold value (32 -> 0x20)
- SR16[5:0], SR16[7] (7bits) *=*/
- VGAOUT8(0x3c4, 0x16);
- bRegTemp = VGAIN8(0x3c5) & ~0xBF;
- bRegTemp |= (0x20 & 0x3F);
- bRegTemp |= ((0x20 & 0x40) << 1);
- VGAOUT8(0x3c5, bRegTemp);
-
- /*=* R3 Switch to the highest agent threshold value (16 -> 0x10)
- SR18[5:0], SR18[7] (7bits) *=*/
- VGAOUT8(0x3c4, 0x18);
- bRegTemp = VGAIN8(0x3c5) & ~0xBF;
- bRegTemp |= (0x10 & 0x3F);
- bRegTemp |= ((0x10 & 0x40) << 1);
- VGAOUT8(0x3c5, bRegTemp);
-#if 0
- /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
- SR1C[7:0], SR1D[1:0] (10bits) *=*/
- wRegTemp = (pBIOSInfo->offsetWidthByQWord >> 1) + 4;
- VGAOUT8(0x3c4, 0x1c);
- VGAOUT8(0x3c5, (uint8_t)(wRegTemp & 0xFF));
- VGAOUT8(0x3c4, 0x1d);
- bRegTemp = VGAIN8(0x3c5) & ~0x03;
- VGAOUT8(0x3c5, bRegTemp | ((wRegTemp & 0x300) >> 8));
-#endif
- if (ctx->shared.virtualWidth >= 1400 && ctx->bpp == 32)
- {
- /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
- VGAOUT8(0x3c4, 0x22);
- bRegTemp = VGAIN8(0x3c5) & ~0x1F;
- VGAOUT8(0x3c5, bRegTemp | 0x10);
- }
- else
- {
- /*=* Max. length for a request SR22[4:0] (0x1F) *=*/
- VGAOUT8(0x3c4, 0x22);
- bRegTemp = VGAIN8(0x3c5) & ~0x1F;
- VGAOUT8(0x3c5, bRegTemp | 0x1F);
- }
- break;
- default:
- break;
- }
-}
-
-static void VIAInitialize2DEngine(DRIDriverContext *ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- uint32_t dwVQStartAddr, dwVQEndAddr;
- uint32_t dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
- uint32_t dwGEMode;
-
- /* init 2D engine regs to reset 2D engine */
- VIASETREG(0x04, 0x0);
- VIASETREG(0x08, 0x0);
- VIASETREG(0x0c, 0x0);
- VIASETREG(0x10, 0x0);
- VIASETREG(0x14, 0x0);
- VIASETREG(0x18, 0x0);
- VIASETREG(0x1c, 0x0);
- VIASETREG(0x20, 0x0);
- VIASETREG(0x24, 0x0);
- VIASETREG(0x28, 0x0);
- VIASETREG(0x2c, 0x0);
- VIASETREG(0x30, 0x0);
- VIASETREG(0x34, 0x0);
- VIASETREG(0x38, 0x0);
- VIASETREG(0x3c, 0x0);
- VIASETREG(0x40, 0x0);
-
- VIADisableMMIO(ctx);
-
- /* Init AGP and VQ regs */
- VIASETREG(0x43c, 0x00100000);
- VIASETREG(0x440, 0x00000000);
- VIASETREG(0x440, 0x00333004);
- VIASETREG(0x440, 0x60000000);
- VIASETREG(0x440, 0x61000000);
- VIASETREG(0x440, 0x62000000);
- VIASETREG(0x440, 0x63000000);
- VIASETREG(0x440, 0x64000000);
- VIASETREG(0x440, 0x7D000000);
-
- VIASETREG(0x43c, 0xfe020000);
- VIASETREG(0x440, 0x00000000);
-
- if (pVia->VQStart != 0) {
- /* Enable VQ */
- dwVQStartAddr = pVia->VQStart;
- dwVQEndAddr = pVia->VQEnd;
- dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
- dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
- dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) |
- ((dwVQEndAddr & 0xFF000000) >> 16);
- dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
-
- VIASETREG(0x43c, 0x00fe0000);
- VIASETREG(0x440, 0x080003fe);
- VIASETREG(0x440, 0x0a00027c);
- VIASETREG(0x440, 0x0b000260);
- VIASETREG(0x440, 0x0c000274);
- VIASETREG(0x440, 0x0d000264);
- VIASETREG(0x440, 0x0e000000);
- VIASETREG(0x440, 0x0f000020);
- VIASETREG(0x440, 0x1000027e);
- VIASETREG(0x440, 0x110002fe);
- VIASETREG(0x440, 0x200f0060);
-
- VIASETREG(0x440, 0x00000006);
- VIASETREG(0x440, 0x40008c0f);
- VIASETREG(0x440, 0x44000000);
- VIASETREG(0x440, 0x45080c04);
- VIASETREG(0x440, 0x46800408);
-
- VIASETREG(0x440, dwVQStartEndH);
- VIASETREG(0x440, dwVQStartL);
- VIASETREG(0x440, dwVQEndL);
- VIASETREG(0x440, dwVQLen);
- }
- else {
- /* Diable VQ */
- VIASETREG(0x43c, 0x00fe0000);
- VIASETREG(0x440, 0x00000004);
- VIASETREG(0x440, 0x40008c0f);
- VIASETREG(0x440, 0x44000000);
- VIASETREG(0x440, 0x45080c04);
- VIASETREG(0x440, 0x46800408);
- }
-
- dwGEMode = 0;
-
- switch (ctx->bpp) {
- case 16:
- dwGEMode |= VIA_GEM_16bpp;
- break;
- case 32:
- dwGEMode |= VIA_GEM_32bpp;
- break;
- default:
- dwGEMode |= VIA_GEM_8bpp;
- break;
- }
-
-#if 0
- switch (ctx->shared.virtualWidth) {
- case 800:
- dwGEMode |= VIA_GEM_800;
- break;
- case 1024:
- dwGEMode |= VIA_GEM_1024;
- break;
- case 1280:
- dwGEMode |= VIA_GEM_1280;
- break;
- case 1600:
- dwGEMode |= VIA_GEM_1600;
- break;
- case 2048:
- dwGEMode |= VIA_GEM_2048;
- break;
- default:
- dwGEMode |= VIA_GEM_640;
- break;
- }
-#endif
-
- VIAEnableMMIO(ctx);
-
- /* Set BPP and Pitch */
- VIASETREG(VIA_REG_GEMODE, dwGEMode);
-
- /* Set Src and Dst base address and pitch, pitch is qword */
- VIASETREG(VIA_REG_SRCBASE, 0x0);
- VIASETREG(VIA_REG_DSTBASE, 0x0);
- VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) |
- (((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) << 16));
-}
-
-static int b3DRegsInitialized = 0;
-
-static void VIAInitialize3DEngine(DRIDriverContext *ctx)
-{
- VIAPtr pVia = VIAPTR(ctx);
- int i;
-
- if (!b3DRegsInitialized)
- {
-
- VIASETREG(0x43C, 0x00010000);
-
- for (i = 0; i <= 0x7D; i++)
- {
- VIASETREG(0x440, (uint32_t) i << 24);
- }
-
- VIASETREG(0x43C, 0x00020000);
-
- for (i = 0; i <= 0x94; i++)
- {
- VIASETREG(0x440, (uint32_t) i << 24);
- }
-
- VIASETREG(0x440, 0x82400000);
-
- VIASETREG(0x43C, 0x01020000);
-
-
- for (i = 0; i <= 0x94; i++)
- {
- VIASETREG(0x440, (uint32_t) i << 24);
- }
-
- VIASETREG(0x440, 0x82400000);
- VIASETREG(0x43C, 0xfe020000);
-
- for (i = 0; i <= 0x03; i++)
- {
- VIASETREG(0x440, (uint32_t) i << 24);
- }
-
- VIASETREG(0x43C, 0x00030000);
-
- for (i = 0; i <= 0xff; i++)
- {
- VIASETREG(0x440, 0);
- }
- VIASETREG(0x43C, 0x00100000);
- VIASETREG(0x440, 0x00333004);
- VIASETREG(0x440, 0x10000002);
- VIASETREG(0x440, 0x60000000);
- VIASETREG(0x440, 0x61000000);
- VIASETREG(0x440, 0x62000000);
- VIASETREG(0x440, 0x63000000);
- VIASETREG(0x440, 0x64000000);
-
- VIASETREG(0x43C, 0x00fe0000);
-
- if (pVia->ChipRev >= 3 )
- VIASETREG(0x440,0x40008c0f);
- else
- VIASETREG(0x440,0x4000800f);
-
- VIASETREG(0x440,0x44000000);
- VIASETREG(0x440,0x45080C04);
- VIASETREG(0x440,0x46800408);
- VIASETREG(0x440,0x50000000);
- VIASETREG(0x440,0x51000000);
- VIASETREG(0x440,0x52000000);
- VIASETREG(0x440,0x53000000);
-
- b3DRegsInitialized = 1;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "3D Engine has been initialized.\n");
- }
-
- VIASETREG(0x43C,0x00fe0000);
- VIASETREG(0x440,0x08000001);
- VIASETREG(0x440,0x0A000183);
- VIASETREG(0x440,0x0B00019F);
- VIASETREG(0x440,0x0C00018B);
- VIASETREG(0x440,0x0D00019B);
- VIASETREG(0x440,0x0E000000);
- VIASETREG(0x440,0x0F000000);
- VIASETREG(0x440,0x10000000);
- VIASETREG(0x440,0x11000000);
- VIASETREG(0x440,0x20000000);
-}
-
-static int
-WaitIdleCLE266(VIAPtr pVia)
-{
- int loop = 0;
-
- /*mem_barrier();*/
-
- while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
- ;
-
- while ((VIAGETREG(VIA_REG_STATUS) &
- (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
- (loop++ < MAXLOOP))
- ;
-
- return loop >= MAXLOOP;
-}
-
-static int viaInitFBDev(DRIDriverContext *ctx)
-{
- VIAPtr pVia = CALLOC(sizeof(*pVia));
-
- ctx->driverPrivate = (void *)pVia;
-
- switch (ctx->chipset) {
- case PCI_CHIP_CLE3122:
- case PCI_CHIP_CLE3022:
- pVia->Chipset = VIA_CLE266;
- break;
- case PCI_CHIP_VT7205:
- case PCI_CHIP_VT3205:
- pVia->Chipset = VIA_KM400;
- break;
- case PCI_CHIP_VT3204:
- case PCI_CHIP_VT3344:
- pVia->Chipset = VIA_K8M800;
- break;
- case PCI_CHIP_VT3259:
- pVia->Chipset = VIA_PM800;
- break;
- default:
- xf86DrvMsg(0, X_ERROR, "VIA: Unknown device ID (0x%x)\n", ctx->chipset);
- }
-
- /* _SOLO TODO XXX need to read ChipRev too */
- pVia->ChipRev = 0;
-
- pVia->videoRambytes = ctx->shared.fbSize;
- pVia->MmioBase = ctx->MMIOStart;
- pVia->FrameBufferBase = ctx->FBStart & 0xfc000000;
-
- pVia->FBFreeStart = ctx->shared.virtualWidth * ctx->cpp *
- ctx->shared.virtualHeight;
-
-#if 1
- /* Alloc a second framebuffer for the second head */
- pVia->FBFreeStart += ctx->shared.virtualWidth * ctx->cpp *
- ctx->shared.virtualHeight;
-#endif
-
- pVia->VQStart = pVia->FBFreeStart;
- pVia->VQEnd = pVia->FBFreeStart + VIA_VQ_SIZE - 1;
-
- pVia->FBFreeStart += VIA_VQ_SIZE;
-
- pVia->FBFreeEnd = pVia->videoRambytes;
-
- if (!VIADRIScreenInit(ctx))
- return 0;
-
- return 1;
-}
-
-static void viaHaltFBDev(DRIDriverContext *ctx)
-{
- drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
- drmClose(ctx->drmFD);
-
- if (ctx->driverPrivate) {
- free(ctx->driverPrivate);
- ctx->driverPrivate = 0;
- }
-}
-
-static int viaEngineShutdown(const DRIDriverContext *ctx)
-{
- return 1;
-}
-
-static int viaEngineRestore(const DRIDriverContext *ctx)
-{
- return 1;
-}
-
-const struct DRIDriverRec __driDriver =
-{
- viaValidateMode,
- viaPostValidateMode,
- viaInitFBDev,
- viaHaltFBDev,
- viaEngineShutdown,
- viaEngineRestore,
- 0,
-};
-