Hi~ 
I'm using linux in console app. in ubuntu 8.04 , intel 945
I wanna use linux console video overlay application . 
but it's not working well. 
i reference directfb , and running directfb , but it's not working. 
therefore i made sample application. 
sample app file attached. can you help me? 

cannot get mmio base address 

int driver_init_driver(I830DriverData *idrv, I830DeviceData *idev ) 
{ 

printf("[%s]enter\n", __func__); 

system_initialize(); 

idrv->mmio_base = system_map_mmio(0, 0x8000); 
//idrv->mmio_base = (volatile u8*) system_map_mmio(0, -1); 
/* !!!! ERROR cannot get mmio base address !!! */ 
if(!idrv->mmio_base){ 
printf("[%s]mmio_base ERROR\n", __func__); 
return 0; 
} 
if(i830_agp_setup(idrv, idev) == 0){ 
printf("[%s]error\n", __func__); 
return 0; 
} 
idrv->info = idev->info; 

return 1; 
printf("[%s]leave\n", __func__); 
} 

static void 
driver_term_driver(I830DriverData *idrv ) 
{ 

system_unmap_mmio(idrv->mmio_base, -1); 
system_terminate(); 
} 

int main() 
{ 

I830DriverData *idrv = malloc(sizeof(I830DriverData)); 
I830DeviceData *idev = malloc(sizeof(I830DeviceData)); 
driver_init_driver(idrv, idev); 

return 0; 
} 




Best Regards. 
>From steven

 

---------------------------------------------------------------------

153-803 서울시 금천구 가산동 550-1 롯데 IT캐슬 2동 6층

연구소 소프트웨어/선임연구원

Tel: 02-890-1661

FAX:02-890-1639

 

#ifndef __PTYPES_H__
#define __PTYPES_H__

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef int     bool;


#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif

#ifndef SIGN
#define SIGN(x)  (((x) < 0) ?  -1  :  (((x) > 0) ? 1 : 0))
#endif

#ifndef ABS
#define ABS(x)   ((x) > 0 ? (x) : -(x))
#endif

#ifndef CLAMP
#define CLAMP(x,min,max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x))
#endif

#ifndef BSWAP16
#define BSWAP16(x) (((u16)(x)>>8) | ((u16)(x)<<8))
#endif

#ifndef BSWAP32
#define BSWAP32(x) ((((u32)(x)>>24) & 0x000000ff) | (((u32)(x)>> 8) & 
0x0000ff00) | \
                    (((u32)(x)<< 8) & 0x00ff0000) | (((u32)(x)<<24) & 
0xff000000))
#endif


#define D_FLAGS_SET(flags,f)       do { (flags) |= (f); } while (0)
#define D_FLAGS_CLEAR(flags,f)     do { (flags) &= ~(f); } while (0)
#define D_FLAGS_IS_SET(flags,f)    (((flags) & (f)) != 0)
#define D_FLAGS_ARE_SET(flags,f)   (((flags) & (f)) == (f))
#define D_FLAGS_ARE_IN(flags,f)    (((flags) & ~(f)) == 0)
#define D_FLAGS_INVALID(flags,f)   (((flags) & ~(f)) != 0)



#endif


#include <fcntl.h>
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include <asm/types.h>
#include <linux/agpgart.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include "ptypes.h"
#include "i830.h"

#define TIMER_LOOP     1000000000

typedef struct _FDDEV{
        int fd;
        /* fbdev fixed screeninfo, contains infos about memory and type of card 
*/
        struct fb_fix_screeninfo fix;

        struct fb_var_screeninfo current_var;   /* fbdev variable screeninfo
                                                set by DirectFB */
        struct fb_var_screeninfo orig_var;      /* fbdev variable screeninfo
                                                before DirectFB was started */
        unsigned long            page_mask;     /* PAGE_SIZE - 1 */

        /* virtual framebuffer address */
        void                    *framebuffer_base;
}FBDEV;



FBDEV g_fbdev;
int g_nAgpGart;



/**************************************************************************************************/



static void
i830_lring_enable( I830DriverData *idrv, u32 mode )
{
     u32 tmp;

     printf("[%s]%s lp ring...\n", __func__, mode ? "Enabling" : "Disabling" );

     tmp = i830_readl(idrv->mmio_base, LP_RING + RING_LEN);
     tmp = (!mode) ? tmp & ~1 : tmp | 1;

     i830_writel( idrv->mmio_base, LP_RING + RING_LEN, tmp );
}


static inline void
i830_wait_for_blit_idle( I830DriverData *idrv,
                         I830DeviceData *idev )
{
     u32 count = 0;
     u32 head , tail;

     if (idev != NULL)
          idev->idle_calls++;
     
     head = i830_readl(idrv->mmio_base, LP_RING + RING_HEAD) & I830_HEAD_MASK;
     tail = i830_readl(idrv->mmio_base, LP_RING + RING_TAIL) & I830_TAIL_MASK;
     while ((head != tail) && (count++ < TIMER_LOOP)) {
          if (idev != NULL)
               idev->idle_waitcycles++;
          head = i830_readl(idrv->mmio_base, LP_RING + RING_HEAD) & 
I830_HEAD_MASK;
          tail = i830_readl(idrv->mmio_base, LP_RING + RING_TAIL) & 
I830_TAIL_MASK;
     }

     if (count >= TIMER_LOOP) {
          if (idev != NULL)
               idev->idle_timeoutsum++;
          printf("[%s]warning: idle timeout exceeded", __func__);
     }
}


static void
i830_init_ringbuffer( I830DriverData *idrv,
                      I830DeviceData *idev )
{
     u32 ring_enabled;

     printf(  "[%s]Previous lp ring config: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", 
__func__, 
                 i830_readl(idrv->mmio_base, LP_RING),
                 i830_readl(idrv->mmio_base, LP_RING + RING_HEAD),
                 i830_readl(idrv->mmio_base, LP_RING + RING_START),
                 i830_readl(idrv->mmio_base, LP_RING + RING_LEN) );

     ring_enabled = i830_readl(idrv->mmio_base, LP_RING + RING_LEN) & 1;
     if (ring_enabled)
         i830_wait_for_blit_idle(idrv, idev);
     i830_lring_enable(idrv, 0);

     idev->lring1 = i830_readl(idrv->mmio_base, LP_RING);
     idev->lring2 = i830_readl(idrv->mmio_base, LP_RING + RING_HEAD);
     idev->lring3 = i830_readl(idrv->mmio_base, LP_RING + RING_START);
     idev->lring4 = i830_readl(idrv->mmio_base, LP_RING + RING_LEN);

     D_FLAGS_SET( idrv->flags, I830RES_STATE_SAVE );

     i830_writel(idrv->mmio_base, LP_RING + RING_LEN, 0);
     i830_writel(idrv->mmio_base, LP_RING + RING_HEAD, 0);
     i830_writel(idrv->mmio_base, LP_RING + RING_TAIL, 0);
     i830_writel(idrv->mmio_base, LP_RING + RING_START, 0);

     printf( "[%s]INST_DONE: 0x%04x\n", __func__, i830_readw(idrv->mmio_base, 
INST_DONE) );



     idev->lp_ring.size      = RINGBUFFER_SIZE;
     idev->lp_ring.tail_mask = idev->lp_ring.size - 1;

     i830_writel( idrv->mmio_base, LP_RING + RING_START,
                  (idev->lring_bind.pg_start * 4096) & I830_RING_START_MASK );

     i830_writel( idrv->mmio_base, LP_RING + RING_LEN,
                  (idev->lp_ring.size        - 4096) & I830_RING_NR_PAGES );

     i830_lring_enable(idrv, 1);

     printf( "[%s]Wrote lp ring config: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", 
__func__, 
                 i830_readl(idrv->mmio_base, LP_RING),
                 i830_readl(idrv->mmio_base, LP_RING + RING_HEAD),
                 i830_readl(idrv->mmio_base, LP_RING + RING_START),
                 i830_readl(idrv->mmio_base, LP_RING + RING_LEN) );
}


int
i830_wait_lp_ring( I830DriverData *idrv,
                   I830DeviceData *idev,
                   int             space )
{
     I830RingBuffer *buf = &idev->lp_ring;

     idev->waitfifo_calls++;
     idev->waitfifo_sum += space;

     printf( "[%s]Waiting for %d...\n", __func__, space );

     if (buf->space < space) {
          int head  = 0;
          int loops = 0;

          do {
               idev->fifo_waitcycles++;

               if (loops++ > 100000000) {
                    printf( "timeout waiting for ring buffer space\n" );
                    return 1;
               }

               buf->head  = i830_readl( idrv->mmio_base,
                                        LP_RING + RING_HEAD ) & I830_HEAD_MASK;
               buf->space = buf->head - (buf->tail + 8);

               if (buf->space < 0)
                    buf->space += buf->size;

               //D_DEBUG_AT( I830_Ring, "... have %d space\n", buf->space );

               if (buf->head != head)
                    loops = 0;

               head = buf->head;
          } while (buf->space < space);
     }
     else
          idev->fifo_cache_hits++;

     return 0;
}


/*
 * This is more or less the correct way to initalise, update, and shut down
 * the overlay.  Note OVERLAY_OFF should be used only after disabling the
 * overlay in OCMD and calling OVERLAY_UPDATE.
 *
 * XXX Need to make sure that the overlay engine is cleanly shutdown in
 * all modes of server exit.
 */


static void
update_overlay( I830DriverData *idrv, I830DeviceData *idev )
{
     I830RingBlock block = { NULL, 0, 0 };

     i830_begin_lp_ring( idrv, idev, 6, &block );

     i830_out_ring( &block, MI_FLUSH | MI_WRITE_DIRTY_STATE );
     i830_out_ring( &block, MI_NOOP );

     if (!idev->overlayOn) {
          //idev->overlayOn = true;
          idev->overlayOn = 1;

          i830_out_ring( &block, MI_NOOP );
          i830_out_ring( &block, MI_NOOP );
          i830_out_ring( &block, MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON );
     }
     else {
          i830_out_ring( &block, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP );
          i830_out_ring( &block, MI_NOOP );
          i830_out_ring( &block, MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE );
     }

     i830_out_ring( &block, idev->ovl_mem.physical | 1 );

     i830_advance_lp_ring( idrv, idev, &block );
}

static void disable_overlay( I830DriverData *idrv, I830DeviceData *idev )
{
     I830RingBlock block = { NULL, 0, 0 };

     if (!idev->overlayOn)
          return;

     i830_begin_lp_ring( idrv, idev, 8, &block );

     i830_out_ring( &block, MI_FLUSH | MI_WRITE_DIRTY_STATE );
     i830_out_ring( &block, MI_NOOP );
     i830_out_ring( &block, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP );
     i830_out_ring( &block, MI_NOOP );
     i830_out_ring( &block, MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF );
     i830_out_ring( &block, idev->ovl_mem.physical | 1 );
     i830_out_ring( &block, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP );
     i830_out_ring( &block, MI_NOOP );

     i830_advance_lp_ring( idrv, idev, &block );

     //idev->overlayOn = false;
     idev->overlayOn = 0;
}


void i830ovlOnOff( I830DriverData *idrv, I830DeviceData *idev, bool on )
{
     if (on)
          idrv->oregs->OCMD |= OVERLAY_ENABLE;
     else
          idrv->oregs->OCMD &= ~OVERLAY_ENABLE;

     update_overlay( idrv, idev );
     if (!on)
          disable_overlay( idrv, idev );
}

static int
ovlInitLayer(I830DriverData       *idrv,
        I830DeviceData       *idev,
        DFBDisplayLayerConfig      *config,
        DFBColorAdjustment         *adjustment
     )
{

        idrv->oregs = (I830OverlayRegs*) idrv->ovl_base;
        memset( (void*) idrv->oregs, 0, sizeof(I830OverlayRegs) );

        
        /* fill out the default configuration */
        config->flags       = DLCONF_WIDTH | DLCONF_HEIGHT |
                           DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | 
DLCONF_OPTIONS;
        config->width       = 640;
        config->height      = 480;
        config->pixelformat = DSPF_YUY2;
        config->buffermode  = DLBM_FRONTONLY;
        config->options     = DLOP_NONE;

        /* fill out default color adjustment,
        only fields set in flags will be accepted from applications */
        adjustment->flags      = DCAF_BRIGHTNESS | DCAF_CONTRAST | 
DCAF_SATURATION;
        adjustment->brightness = 0x8000;
        adjustment->contrast   = 0x8000;
        adjustment->saturation = 0x8000;


        idrv->oregs->OCLRC0 = 64 << 18;
        idrv->oregs->OCLRC1 = 0x80;
        return 0;

}

/**************************************************************************************************/


static int fbdev_open()
{
        g_fbdev.fd = open("/dev/fb0", O_RDWR);
        if( g_fbdev.fd < 0){
                printf("[%s]fd0 open ERROR\n", __func__);
                return 0;
        }
        return 1;
}

static int fbdev_close()
{
        close(g_fbdev.fd);
        
        return 1;
}

static long direct_pagesize()
{
        return sysconf( _SC_PAGESIZE );
}

static int system_initialize()
{
        long page_size;

        printf("[%s]enter\n", __func__);
        memset(&g_fbdev, 0, sizeof(FBDEV));
        if(fbdev_open() == 0){
                return 0;
        }

        page_size = direct_pagesize();
        g_fbdev.page_mask =  page_size < 0 ? 0 : (page_size - 1);


        /* Retrieve fixed informations like video ram size */
        if (ioctl( g_fbdev.fd, FBIOGET_FSCREENINFO, &g_fbdev.fix ) < 0) {
                printf( "DirectFB/FBDev: " "Could not get fixed screen 
information!\n" );
                goto error;
        }

        printf( "### fixed screen information \n" );
        printf( "mmio_len:%d\n", g_fbdev.fix.mmio_len );
        printf( "smem_len:%d\n", g_fbdev.fix.smem_len );
        printf( "############################ \n" );
        /* Map the framebuffer */
        g_fbdev.framebuffer_base = mmap( NULL, g_fbdev.fix.smem_len,
                                         PROT_READ | PROT_WRITE, MAP_SHARED,
                                         g_fbdev.fd, 0 );
        if (g_fbdev.framebuffer_base == MAP_FAILED) {
                g_fbdev.framebuffer_base = NULL;
                goto error;
        }

        
        if (ioctl( g_fbdev.fd, FBIOGET_VSCREENINFO, &g_fbdev.orig_var ) < 0) {
                printf( "DirectFB/FBDev: "
                    "Could not get variable screen information!\n" );
                goto error;
        }
        g_fbdev.current_var = g_fbdev.orig_var;
        g_fbdev.current_var.accel_flags = 0;

        if (ioctl( g_fbdev.fd, FBIOPUT_VSCREENINFO, &g_fbdev.current_var ) < 0) 
{
                printf( "DirectFB/FBDev: "
                    "Could not disable console acceleration!\n" );
                goto error;
        }

        printf("[%s]leave\n", __func__);
        return 1;
error:
        printf("[%s]ERROR\n", __func__);
        if (g_fbdev.framebuffer_base)
                munmap( g_fbdev.framebuffer_base, g_fbdev.fix.smem_len );
        if(g_fbdev.fd != -1){
                close(g_fbdev.fd);
        }
        return 0;
}

void system_terminate()
{
        munmap(g_fbdev.framebuffer_base, g_fbdev.fix.smem_len);
        fbdev_close();
}


static volatile void *
system_map_mmio(unsigned int offset, int length)
{
        void *addr;

        if (length <= 0)
                length = g_fbdev.fix.mmio_len;

        printf( "[%s]offset %d, length %d\n", __func__, offset, length );
        addr = mmap( NULL, length,  PROT_READ | PROT_WRITE, MAP_SHARED,
                        g_fbdev.fd, g_fbdev.fix.smem_len + offset);
        if(addr == MAP_FAILED){
                printf( "DirectFB/FBDev: Could not mmap MMIO region "
                     "(offset %d, length %d)!\n", offset, length );
                return NULL;
        }
        return (volatile void*) ( (unsigned char*) addr + 
(g_fbdev.fix.mmio_start& g_fbdev.page_mask) );
}

static void 
system_unmap_mmio(volatile void *addr, int length)
{
        if (length <= 0)
                length = g_fbdev.fix.mmio_len;

        if( munmap( (void*) ((unsigned char*) addr - (g_fbdev.fix.mmio_start& 
g_fbdev.page_mask)), length ) < 0){
                printf( "DirectFB/FBDev: Could not unmap MMIO region "
                     "at %p (length %d)!\n", addr, length );
        }
}

static unsigned long
system_video_memory_physical( unsigned int offset)
{
        return g_fbdev.fix.smem_start + offset;
}

static void *
system_video_memory_virtual( unsigned int offset)
{
        return (void*)( (u8*)(g_fbdev.framebuffer_base) + offset);
}


static unsigned int
system_videoram_length()
{
        return g_fbdev.fix.smem_len;
}

static void
i830_release_resource(I830DriverData *idrv, I830DeviceData *idev)
{
        agp_unbind unbind;
        if (idrv->flags & I830RES_MMAP) {
                munmap((void *) idrv->aper_base, idev->info.aper_size * 1024 * 
1024);
                idrv->flags &= ~I830RES_MMAP;

        }


        if (idrv->flags & I830RES_LRING_BIND) {
                ioctl(idrv->agpgart, AGPIOC_UNBIND, &unbind);
        }

        if (idrv->flags & I830RES_LRING_ACQ)
                ioctl(idrv->agpgart, AGPIOC_DEALLOCATE, idev->lring_mem.key);

        if (idrv->flags & I830RES_OVL_BIND) {
                unbind.key = idev->ovl_bind.key;
                ioctl(idrv->agpgart, AGPIOC_UNBIND, &unbind);
        }

        if (idrv->flags & I830RES_OVL_ACQ)
                ioctl(idrv->agpgart, AGPIOC_DEALLOCATE, idev->ovl_mem.key);

        if (idrv->flags & I830RES_GART_ACQ) {
                ioctl(idrv->agpgart, AGPIOC_RELEASE);
                idrv->flags &= ~I830RES_GART_ACQ;
        }

        if (idrv->flags & I830RES_GART) {
                close(idrv->agpgart);
                idrv->flags &= ~I830RES_GART;
        }
}

static int 
i830_agp_setup( I830DriverData *idrv, I830DeviceData *idev )
{
printf("[%s]enter\n", __func__);
        idrv->agpgart = open("/dev/agpgart", O_RDWR);
        if(g_nAgpGart == -1){
                printf("[%s]error\n", __func__);
                return 0;
        }
        D_FLAGS_SET( idrv->flags, I830RES_GART );

        if( ioctl(g_nAgpGart, AGPIOC_ACQUIRE) ){
                printf("I830/AGP: AGPIOC_ACQUIRE failed!\n" );
        }
        D_FLAGS_SET( idrv->flags, I830RES_GART_ACQ );

        if(!idev->initialized) {
                agp_setup setup;
        
                setup.agp_mode = 0;
                if (ioctl(idrv->agpgart, AGPIOC_SETUP, &setup)) {
                        printf( "I830/AGP: AGPIOC_SETUP failed!\n" );
                        return 0;
                }
     
                if (ioctl(idrv->agpgart, AGPIOC_INFO, &idev->info)) {
                        printf( "I830/AGP: AGPIOC_INFO failed!\n" );
                        return 0;
                }
        }
                


        idrv->aper_base = mmap( NULL, idev->info.aper_size * 1024 * 1024, 
PROT_WRITE,
                             MAP_SHARED, idrv->agpgart, 0 );
        if (idrv->aper_base == MAP_FAILED) {
                printf( "I830/AGP: mmap() failed!\n" );
                //i830_release_resource( idrv, idev );
                return 0;
        }       
        D_FLAGS_SET( idrv->flags, I830RES_MMAP );

        printf( "I830/AGP: mmap() aper_base 0x%x\n", idrv->aper_base );
        if(!idev->initialized) {
                u32 base;
                 /* We'll attempt to bind at fb_base + fb_len + 1 MB,
                to be safe */
                base = system_video_memory_physical(0) - idev->info.aper_base;
                base += system_videoram_length();
                base += (1024*1024);
                idev->lring_mem.pg_count = RINGBUFFER_SIZE/4096;
                idev->lring_mem.type = AGP_NORMAL_MEMORY;
                if (ioctl(idrv->agpgart, AGPIOC_ALLOCATE, &idev->lring_mem)) {
                        printf( "I830/AGP: AGPIOC_ALLOCATE failed!\n" );
                        i830_release_resource( idrv, idev );
                        return 0;
                }
                D_FLAGS_SET( idrv->flags, I830RES_LRING_ACQ );


                idev->lring_bind.key = idev->lring_mem.key;
                idev->lring_bind.pg_start = base/4096;
                if (ioctl(idrv->agpgart, AGPIOC_BIND, &idev->lring_bind)) {
                        printf( "I830/AGP: AGPIOC_BIND failed!\n" );
                        i830_release_resource( idrv, idev );
                        return 0;
                }
                D_FLAGS_SET( idrv->flags, I830RES_LRING_BIND );

                idev->ovl_mem.pg_count = 1;
                idev->ovl_mem.type = AGP_PHYSICAL_MEMORY;
                if (ioctl(idrv->agpgart, AGPIOC_ALLOCATE, &idev->ovl_mem)) {
                        printf( "I830/AGP: AGPIOC_ALLOCATE failed!\n" );
                        i830_release_resource( idrv, idev );
                        return 0;
                }
                D_FLAGS_SET( idrv->flags, I830RES_OVL_ACQ );

                     
                idev->ovl_bind.key = idev->ovl_mem.key;
                idev->ovl_bind.pg_start = (base + RINGBUFFER_SIZE)/4096;
                if (ioctl(idrv->agpgart, AGPIOC_BIND, &idev->ovl_bind)) {
                        printf( "I830/AGP: AGPIOC_BIND failed!\n" );
                        i830_release_resource( idrv, idev );
                        return 0;
                }
                D_FLAGS_SET( idrv->flags, I830RES_OVL_BIND );
        }

        if (idrv->flags & I830RES_GART_ACQ) {
                ioctl(idrv->agpgart, AGPIOC_RELEASE);
                idrv->flags &= ~I830RES_GART_ACQ;
        }

        idrv->lring_base   = idrv->aper_base + idev->lring_bind.pg_start * 4096;
        idrv->ovl_base     = idrv->aper_base + idev->ovl_bind.pg_start * 4096;
        idrv->pattern_base = idrv->ovl_base + 1024;
        
        if (!idev->initialized) {
                memset((void *) idrv->lring_base, 0x00, RINGBUFFER_SIZE);
                memset((void *) idrv->ovl_base, 0xff, 1024);
                memset((void *) idrv->pattern_base, 0xff, 4096 - 1024);
 
                idev->lring1 = 0;//i830_readl(idrv->mmio_base, LP_RING);
                idev->lring2 = 0;//i830_readl(idrv->mmio_base, LP_RING + 
RING_HEAD);
                idev->lring3 = 0;//i830_readl(idrv->mmio_base, LP_RING + 
RING_START);
                idev->lring4 = 0;//i830_readl(idrv->mmio_base, LP_RING + 
RING_LEN);
        }

        idev->initialized = 1;

        printf("[%s]leave SUCCESS\n", __func__);
        return 1;

}

static int
driver_init_driver(I830DriverData *idrv, I830DeviceData *idev  )
{

        printf("[%s]enter\n", __func__);

        system_initialize();

        idrv->mmio_base = system_map_mmio(0, 0x8000);
        //idrv->mmio_base = (volatile u8*) system_map_mmio(0, -1);
        /* !!!! ERROR cannot get mmio base address !!! */
        if(!idrv->mmio_base){
                printf("[%s]mmio_base ERROR\n", __func__);
                return 0;
        }
        if(i830_agp_setup(idrv, idev) == 0){
                printf("[%s]error\n", __func__);
                return 0;
        }
        idrv->info = idev->info;

        return 1;
        printf("[%s]leave\n", __func__);
}

static void
driver_term_driver(I830DriverData *idrv )
{

        system_unmap_mmio(idrv->mmio_base, -1);
        system_terminate();
}

int main()
{

        I830DriverData *idrv = malloc(sizeof(I830DriverData));  
        I830DeviceData *idev = malloc(sizeof(I830DeviceData));  
        driver_init_driver(idrv, idev);

        return 0;
}



#ifndef __I830_H__
#define __I830_H__


#include <sys/types.h>
#include <linux/agpgart.h>


#define RINGBUFFER_SIZE             (128 * 1024)



/* Ring buffer registers, p277, overview p19
 */
#define LP_RING     0x2030
#define HP_RING     0x2040

#define RING_TAIL      0x00
#define TAIL_ADDR           0x000FFFF8
#define I830_TAIL_MASK      0x001FFFF8

#define RING_HEAD      0x04
#define HEAD_WRAP_COUNT     0xFFE00000
#define HEAD_WRAP_ONE       0x00200000
#define HEAD_ADDR           0x001FFFFC
#define I830_HEAD_MASK      0x001FFFFC

#define RING_START     0x08
#define START_ADDR          0x00FFFFF8
#define I830_RING_START_MASK    0xFFFFF000

#define RING_LEN       0x0C
#define RING_NR_PAGES       0x000FF000
#define I830_RING_NR_PAGES      0x001FF000
#define RING_REPORT_MASK    0x00000006
#define RING_REPORT_64K     0x00000002
#define RING_REPORT_128K    0x00000004
#define RING_NO_REPORT      0x00000000
#define RING_VALID_MASK     0x00000001
#define RING_VALID          0x00000001
#define RING_INVALID        0x00000000

/* Overlay Flip */
#define MI_OVERLAY_FLIP                 (0x11<<23)
#define MI_OVERLAY_FLIP_CONTINUE        (0<<21)
#define MI_OVERLAY_FLIP_ON              (1<<21)
#define MI_OVERLAY_FLIP_OFF             (2<<21)

/* Wait for Events */
#define MI_WAIT_FOR_EVENT               (0x03<<23)
#define MI_WAIT_FOR_OVERLAY_FLIP        (1<<16)

/* Flush */
#define MI_FLUSH                        (0x04<<23)
#define MI_WRITE_DIRTY_STATE            (1<<4)
#define MI_END_SCENE                    (1<<3)
#define MI_INHIBIT_RENDER_CACHE_FLUSH   (1<<2)
#define MI_INVALIDATE_MAP_CACHE         (1<<0)

/* Noop */
#define MI_NOOP                         0x00
#define MI_NOOP_WRITE_ID                (1<<22)
#define MI_NOOP_ID_MASK                 (1<<22 - 1)


/* Instruction Parser Mode Register
 *    - p281
 *    - 2 new bits.
 */
#define INST_PM                  0x20c0
#define AGP_SYNC_PACKET_FLUSH_ENABLE 0x20 /* reserved */
#define SYNC_PACKET_FLUSH_ENABLE     0x10
#define TWO_D_INST_DISABLE           0x08
#define THREE_D_INST_DISABLE         0x04
#define STATE_VAR_UPDATE_DISABLE     0x02
#define PAL_STIP_DISABLE             0x01

#define INST_DONE                0x2090
#define INST_PS                  0x20c4

#define MEMMODE                  0x20dc



#define I830RES_GART                1
#define I830RES_LRING_ACQ           2
#define I830RES_LRING_BIND          4
#define I830RES_OVL_ACQ             8
#define I830RES_OVL_BIND           16
#define I830RES_GART_ACQ           32
#define I830RES_MMAP               64
#define I830RES_STATE_SAVE        128

#ifndef AGP_NORMAL_MEMORY
#define AGP_NORMAL_MEMORY 0
#endif

#ifndef AGP_PHYSICAL_MEMORY
#define AGP_PHYSICAL_MEMORY 2
#endif



/*
 * OCMD - Overlay Command Register
 */
#define MIRROR_MODE             (0x3<<17)
#define MIRROR_HORIZONTAL       (0x1<<17)
#define MIRROR_VERTICAL         (0x2<<17)
#define MIRROR_BOTH             (0x3<<17)
#define OV_BYTE_ORDER           (0x3<<14)
#define UV_SWAP                 (0x1<<14)
#define Y_SWAP                  (0x2<<14)
#define Y_AND_UV_SWAP           (0x3<<14)
#define SOURCE_FORMAT           (0xf<<10)
#define RGB_888                 (0x1<<10)
#define RGB_555                 (0x2<<10)
#define RGB_565                 (0x3<<10)
#define YUV_422                 (0x8<<10)
#define YUV_411                 (0x9<<10)
#define YUV_420                 (0xc<<10)
#define YUV_422_PLANAR          (0xd<<10)
#define YUV_410                 (0xe<<10)
#define TVSYNC_FLIP_PARITY      (0x1<<9)
#define TVSYNC_FLIP_ENABLE      (0x1<<7)
#define BUF_TYPE                (0x1<<5)
#define BUF_TYPE_FRAME          (0x0<<5)
#define BUF_TYPE_FIELD          (0x1<<5)
#define TEST_MODE               (0x1<<4)
#define BUFFER_SELECT           (0x3<<2)
#define BUFFER0                 (0x0<<2)
#define BUFFER1                 (0x1<<2)
#define FIELD_SELECT            (0x1<<1)
#define FIELD0                  (0x0<<1)
#define FIELD1                  (0x1<<1)
#define OVERLAY_ENABLE          0x1


/* OCONFIG register */
#define CC_OUT_8BIT             (0x1<<3)
#define OVERLAY_PIPE_MASK       (0x1<<18)
#define OVERLAY_PIPE_A          (0x0<<18)
#define OVERLAY_PIPE_B          (0x1<<18)

/* DCLRKM register */
#define DEST_KEY_ENABLE         (0x1<<31)

/* Polyphase filter coefficients */
#define N_HORIZ_Y_TAPS          5
#define N_VERT_Y_TAPS           3
#define N_HORIZ_UV_TAPS         3
#define N_VERT_UV_TAPS          3
#define N_PHASES                17
#define MAX_TAPS                5

/* Filter cutoff frequency limits. */
#define MIN_CUTOFF_FREQ         1.0
#define MAX_CUTOFF_FREQ         3.0




/*
 * Used to enable some capabilities like flicker filtering or colorkeying.
 */
typedef enum {
     DLOP_NONE                = 0x00000000,  /* None of these. */
     DLOP_ALPHACHANNEL        = 0x00000001,  /* Make usage of alpha channel
                                                for blending on a pixel per
                                                pixel basis. */
     DLOP_FLICKER_FILTERING   = 0x00000002,  /* Enable flicker filtering. */
     DLOP_DEINTERLACING       = 0x00000004,  /* Enable deinterlacing of an
                                                interlaced (video) source. */
     DLOP_SRC_COLORKEY        = 0x00000008,  /* Enable source color key. */
     DLOP_DST_COLORKEY        = 0x00000010,  /* Enable dest. color key. */
     DLOP_OPACITY             = 0x00000020,  /* Make usage of the global alpha
                                                factor set by SetOpacity. */
     DLOP_FIELD_PARITY        = 0x00000040   /* Set field parity */
} DFBDisplayLayerOptions;


/*
 * Layer Buffer Mode.
 */
typedef enum {
     DLBM_UNKNOWN    = 0x00000000,

     DLBM_FRONTONLY  = 0x00000001,      /* no backbuffer */
     DLBM_BACKVIDEO  = 0x00000002,      /* backbuffer in video memory */
     DLBM_BACKSYSTEM = 0x00000004,      /* backbuffer in system memory */
     DLBM_TRIPLE     = 0x00000008,      /* triple buffering */
     DLBM_WINDOWS    = 0x00000010       /* no layer buffers at all,
                                           using buffer of each window */
} DFBDisplayLayerBufferMode;

/*
 * Layer configuration flags
 */
typedef enum {
     DLCONF_NONE              = 0x00000000,

     DLCONF_WIDTH             = 0x00000001,
     DLCONF_HEIGHT            = 0x00000002,
     DLCONF_PIXELFORMAT       = 0x00000004,
     DLCONF_BUFFERMODE        = 0x00000008,
     DLCONF_OPTIONS           = 0x00000010,
     DLCONF_SOURCE            = 0x00000020,
     DLCONF_SURFACE_CAPS      = 0x00000040,

     DLCONF_ALL               = 0x0000007F
} DFBDisplayLayerConfigFlags;



/*
 * Flags defining which fields of a DFBColorAdjustment are valid.
 */
typedef enum {
     DCAF_NONE         = 0x00000000,  /* none of these              */
     DCAF_BRIGHTNESS   = 0x00000001,  /* brightness field is valid  */
     DCAF_CONTRAST     = 0x00000002,  /* contrast field is valid    */
     DCAF_HUE          = 0x00000004,  /* hue field is valid         */
     DCAF_SATURATION   = 0x00000008,  /* saturation field is valid  */
     DCAF_ALL          = 0x0000000F   /* all of these               */
} DFBColorAdjustmentFlags;




/*
 * @internal
 *
 * Encodes format constants in the following way (bit 31 - 0):
 *
 * lkjj:hhgg | gfff:eeed | cccc:bbbb | baaa:aaaa
 *
 * a) pixelformat index<br>
 * b) effective color (or index) bits per pixel of format<br>
 * c) effective alpha bits per pixel of format<br>
 * d) alpha channel present<br>
 * e) bytes per "pixel in a row" (1/8 fragment, i.e. bits)<br>
 * f) bytes per "pixel in a row" (decimal part, i.e. bytes)<br>
 * g) smallest number of pixels aligned to byte boundary (minus one)<br>
 * h) multiplier for planes minus one (1/4 fragment)<br>
 * j) multiplier for planes minus one (decimal part)<br>
 * k) color and/or alpha lookup table present<br>
 * l) alpha channel is inverted
 */
#define DFB_SURFACE_PIXELFORMAT( index, color_bits, alpha_bits, has_alpha,     \
                                 row_bits, row_bytes, align, mul_f, mul_d,     \
                                 has_lut, inv_alpha )                          \
     ( (((index     ) & 0x7F)      ) |                                         \
       (((color_bits) & 0x1F) <<  7) |                                         \
       (((alpha_bits) & 0x0F) << 12) |                                         \
       (((has_alpha ) ? 1 :0) << 16) |                                         \
       (((row_bits  ) & 0x07) << 17) |                                         \
       (((row_bytes ) & 0x07) << 20) |                                         \
       (((align     ) & 0x07) << 23) |                                         \
       (((mul_f     ) & 0x03) << 26) |                                         \
       (((mul_d     ) & 0x03) << 28) |                                         \
       (((has_lut   ) ? 1 :0) << 30) |                                         \
       (((inv_alpha ) ? 1 :0) << 31) )


/*
 * Pixel format of a surface.
 */
typedef enum {
     DSPF_UNKNOWN   = 0x00000000,  /* unknown or unspecified format */

     /* 16 bit  ARGB (2 byte, alpha [EMAIL PROTECTED], red [EMAIL PROTECTED], 
green [EMAIL PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_ARGB1555  = DFB_SURFACE_PIXELFORMAT(  0, 15, 1, 1, 0, 2, 0, 0, 0, 0, 
0 ),

     /* 16 bit   RGB (2 byte, red [EMAIL PROTECTED], green [EMAIL PROTECTED], 
blue [EMAIL PROTECTED]) */
     DSPF_RGB16     = DFB_SURFACE_PIXELFORMAT(  1, 16, 0, 0, 0, 2, 0, 0, 0, 0, 
0 ),

     /* 24 bit   RGB (3 byte, red [EMAIL PROTECTED], green [EMAIL PROTECTED], 
blue [EMAIL PROTECTED]) */
     DSPF_RGB24     = DFB_SURFACE_PIXELFORMAT(  2, 24, 0, 0, 0, 3, 0, 0, 0, 0, 
0 ),

     /* 24 bit   RGB (4 byte, [EMAIL PROTECTED], red [EMAIL PROTECTED], green 
[EMAIL PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_RGB32     = DFB_SURFACE_PIXELFORMAT(  3, 24, 0, 0, 0, 4, 0, 0, 0, 0, 
0 ),

     /* 32 bit  ARGB (4 byte, alpha [EMAIL PROTECTED], red [EMAIL PROTECTED], 
green [EMAIL PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_ARGB      = DFB_SURFACE_PIXELFORMAT(  4, 24, 8, 1, 0, 4, 0, 0, 0, 0, 
0 ),

     /*  8 bit alpha (1 byte, alpha [EMAIL PROTECTED]), e.g. anti-aliased 
glyphs */
     DSPF_A8        = DFB_SURFACE_PIXELFORMAT(  5,  0, 8, 1, 0, 1, 0, 0, 0, 0, 
0 ),

     /* 16 bit   YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */
     DSPF_YUY2      = DFB_SURFACE_PIXELFORMAT(  6, 16, 0, 0, 0, 2, 0, 0, 0, 0, 
0 ),

     /*  8 bit   RGB (1 byte, red [EMAIL PROTECTED], green [EMAIL PROTECTED], 
blue [EMAIL PROTECTED]) */
     DSPF_RGB332    = DFB_SURFACE_PIXELFORMAT(  7,  8, 0, 0, 0, 1, 0, 0, 0, 0, 
0 ),

     /* 16 bit   YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */
     DSPF_UYVY      = DFB_SURFACE_PIXELFORMAT(  8, 16, 0, 0, 0, 2, 0, 0, 0, 0, 
0 ),

     /* 12 bit   YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) 
*/
     DSPF_I420      = DFB_SURFACE_PIXELFORMAT(  9, 12, 0, 0, 0, 1, 0, 2, 0, 0, 
0 ),

     /* 12 bit   YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) 
*/
     DSPF_YV12      = DFB_SURFACE_PIXELFORMAT( 10, 12, 0, 0, 0, 1, 0, 2, 0, 0, 
0 ),

     /*  8 bit   LUT (8 bit color and alpha lookup from palette) */
     DSPF_LUT8      = DFB_SURFACE_PIXELFORMAT( 11,  8, 0, 1, 0, 1, 0, 0, 0, 1, 
0 ),

     /*  8 bit  ALUT (1 byte, alpha [EMAIL PROTECTED], color lookup [EMAIL 
PROTECTED]) */
     DSPF_ALUT44    = DFB_SURFACE_PIXELFORMAT( 12,  4, 4, 1, 0, 1, 0, 0, 0, 1, 
0 ),

     /* 32 bit  ARGB (4 byte, inv. alpha [EMAIL PROTECTED], red [EMAIL 
PROTECTED], green [EMAIL PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_AiRGB     = DFB_SURFACE_PIXELFORMAT( 13, 24, 8, 1, 0, 4, 0, 0, 0, 0, 
1 ),

     /*  1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */
     DSPF_A1        = DFB_SURFACE_PIXELFORMAT( 14,  0, 1, 1, 1, 0, 7, 0, 0, 0, 
0 ),

     /* 12 bit   YUV (8 bit Y plane followed by one 16 bit quarter size Cb|Cr 
[7:0|7:0] plane) */
     DSPF_NV12      = DFB_SURFACE_PIXELFORMAT( 15, 12, 0, 0, 0, 1, 0, 2, 0, 0, 
0 ),

     /* 16 bit   YUV (8 bit Y plane followed by one 16 bit half width Cb|Cr 
[7:0|7:0] plane) */
     DSPF_NV16      = DFB_SURFACE_PIXELFORMAT( 16, 24, 0, 0, 0, 1, 0, 0, 1, 0, 
0 ),

     /* 16 bit  ARGB (2 byte, alpha [EMAIL PROTECTED], red [EMAIL PROTECTED], 
green [EMAIL PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_ARGB2554  = DFB_SURFACE_PIXELFORMAT( 17, 14, 2, 1, 0, 2, 0, 0, 0, 0, 
0 ),

     /* 16 bit  ARGB (2 byte, alpha [EMAIL PROTECTED], red [EMAIL PROTECTED], 
green [EMAIL PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_ARGB4444  = DFB_SURFACE_PIXELFORMAT( 18, 12, 4, 1, 0, 2, 0, 0, 0, 0, 
0 ),

     /* 16 bit  RGBA (2 byte, red [EMAIL PROTECTED], green [EMAIL PROTECTED], 
blue [EMAIL PROTECTED], alpha [EMAIL PROTECTED]) */
     DSPF_RGBA4444  = DFB_SURFACE_PIXELFORMAT( 19, 12, 4, 1, 0, 2, 0, 0, 0, 0, 
0 ),

     /* 12 bit   YUV (8 bit Y plane followed by one 16 bit quarter size Cr|Cb 
[7:0|7:0] plane) */
     DSPF_NV21      = DFB_SURFACE_PIXELFORMAT( 20, 12, 0, 0, 0, 1, 0, 2, 0, 0, 
0 ),

     /* 32 bit  AYUV (4 byte, alpha [EMAIL PROTECTED], Y [EMAIL PROTECTED], Cb 
[EMAIL PROTECTED], Cr [EMAIL PROTECTED]) */
     DSPF_AYUV      = DFB_SURFACE_PIXELFORMAT( 21, 24, 8, 1, 0, 4, 0, 0, 0, 0, 
0 ),

     /*  4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */
     DSPF_A4        = DFB_SURFACE_PIXELFORMAT( 22,  0, 4, 1, 4, 0, 1, 0, 0, 0, 
0 ),

     /*  1 bit alpha (3 byte/  alpha [EMAIL PROTECTED], red [EMAIL PROTECTED], 
green [EMAIL PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_ARGB1666  = DFB_SURFACE_PIXELFORMAT( 23, 18, 1, 1, 0, 3, 0, 0, 0, 0, 
0 ),

     /*  6 bit alpha (3 byte/  alpha [EMAIL PROTECTED], red [EMAIL PROTECTED], 
green [EMAIL PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_ARGB6666  = DFB_SURFACE_PIXELFORMAT( 24, 18, 6, 1, 0, 3, 0, 0, 0, 0, 
0 ),

     /*  6 bit   RGB (3 byte/   red [EMAIL PROTECTED], green [EMAIL PROTECTED], 
blue [EMAIL PROTECTED]) */
     DSPF_RGB18     = DFB_SURFACE_PIXELFORMAT( 25, 18, 0, 0, 0, 3, 0, 0, 0, 0, 
0 ),

     /*  2 bit   LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from 
palette) */
     DSPF_LUT2      = DFB_SURFACE_PIXELFORMAT( 26,  2, 0, 1, 2, 0, 3, 0, 0, 1, 
0 ),

     /* 16 bit   RGB (2 byte, nothing @12, red [EMAIL PROTECTED], green [EMAIL 
PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_RGB444    = DFB_SURFACE_PIXELFORMAT( 27, 12, 0, 0, 0, 2, 0, 0, 0, 0, 
0 ),

     /* 16 bit   RGB (2 byte, nothing @15, red [EMAIL PROTECTED], green [EMAIL 
PROTECTED], blue [EMAIL PROTECTED]) */
     DSPF_RGB555    = DFB_SURFACE_PIXELFORMAT( 28, 15, 0, 0, 0, 2, 0, 0, 0, 0, 
0 ),

     /* 16 bit   BGR (2 byte, nothing @15, blue [EMAIL PROTECTED], green [EMAIL 
PROTECTED], red [EMAIL PROTECTED]) */
     DSPF_BGR555    = DFB_SURFACE_PIXELFORMAT( 29, 15, 0, 0, 0, 2, 0, 0, 0, 0, 
0 )

} DFBSurfacePixelFormat;


/*
 * Color Adjustment used to adjust video colors.
 *
 * All fields are in the range 0x0 to 0xFFFF with
 * 0x8000 as the default value (no adjustment).
 */
typedef struct {
     DFBColorAdjustmentFlags  flags;

     u16                      brightness;
     u16                      contrast;
     u16                      hue;
     u16                      saturation;
} DFBColorAdjustment;

/*
 * Layer configuration
 */
typedef struct {
     DFBDisplayLayerConfigFlags    flags;         /* Which fields of the 
configuration are set */

     int                           width;         /* Pixel width */
     int                           height;        /* Pixel height */
     DFBSurfacePixelFormat         pixelformat;   /* Pixel format */
     DFBDisplayLayerBufferMode     buffermode;    /* Buffer mode */
     DFBDisplayLayerOptions        options;       /* Enable capabilities */
     //DFBDisplayLayerSourceID       source;        /* Selected layer source */

     //DFBSurfaceCapabilities        surface_caps;  /* Choose surface 
capabilities, available:
                       //                              INTERLACED, SEPARATED, 
PREMULTIPLIED. */
} DFBDisplayLayerConfig;


typedef volatile struct {
     u32 OBUF_0Y;
     u32 OBUF_1Y;
     u32 OBUF_0U;
     u32 OBUF_0V;
     u32 OBUF_1U;
     u32 OBUF_1V;
     u32 OSTRIDE;
     u32 YRGB_VPH;
     u32 UV_VPH;
     u32 HORZ_PH;
     u32 INIT_PHS;
     u32 DWINPOS;
     u32 DWINSZ;
     u32 SWIDTH;
     u32 SWIDTHSW;
     u32 SHEIGHT;
     u32 YRGBSCALE;
     u32 UVSCALE;
     u32 OCLRC0;
     u32 OCLRC1;
     u32 DCLRKV;
     u32 DCLRKM;
     u32 SCLRKVH;
     u32 SCLRKVL;
     u32 SCLRKEN;
     u32 OCONFIG;
     u32 OCMD;
     u32 RESERVED1;           /* 0x6C */
     u32 AWINPOS;
     u32 AWINSZ;
     u32 RESERVED2;           /* 0x78 */
     u32 RESERVED3;           /* 0x7C */
     u32 RESERVED4;           /* 0x80 */
     u32 RESERVED5;           /* 0x84 */
     u32 RESERVED6;           /* 0x88 */
     u32 RESERVED7;           /* 0x8C */
     u32 RESERVED8;           /* 0x90 */
     u32 RESERVED9;           /* 0x94 */
     u32 RESERVEDA;           /* 0x98 */
     u32 RESERVEDB;           /* 0x9C */
     u32 FASTHSCALE;               /* 0xA0 */
     u32 UVSCALEV;            /* 0xA4 */

     u32 RESERVEDC[(0x200 - 0xA8) / 4];         /* 0xA8 - 0x1FC */
     u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES];         /* 0x200 */
     u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
     u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES];             /* 0x300 */
     u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
     u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES];            /* 0x500 */
     u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
     u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES];      /* 0x600 */
     u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
} I830OverlayRegs;




typedef struct {
     unsigned int   tail_mask;

     int            size;
     int            head;
     int            tail;
     int            space;
} I830RingBuffer;


typedef struct {
     volatile void *virt;
     unsigned int   tail_mask;
     unsigned int   outring;
} I830RingBlock;

typedef struct {
     bool                  initialized;

     I830RingBuffer        lp_ring;

     bool                  overlayOn;
     //I830OverlayLayerData *iovl;

     agp_info              info;
     agp_allocate          lring_mem;
     agp_allocate          ovl_mem;
     agp_bind              lring_bind;
     agp_bind              ovl_bind;

     u32                   pattern;
     u32                   lring1;
     u32                   lring2;
     u32                   lring3;
     u32                   lring4;

     /* benchmarking */
     u32                   waitfifo_sum;
     u32                   waitfifo_calls;
     u32                   idle_calls;
     u32                   fifo_waitcycles;
     u32                   idle_waitcycles;
     u32                   fifo_cache_hits;
     u32                   fifo_timeoutsum;
     u32                   idle_timeoutsum;
} I830DeviceData;

typedef struct {
     //I830DeviceData     *idev;

     I830OverlayRegs    *oregs;

     u32                 flags;
     int                 agpgart;
     agp_info            info;
     volatile u8        *aper_base;
     volatile u8        *lring_base;
     volatile u8        *ovl_base;
     volatile u8        *mmio_base;
     volatile u8        *pattern_base;
} I830DriverData;



#define i830_readb(mmio_base, where)                     \
        *((volatile u8 *) (mmio_base + where))           \

#define i830_readw(mmio_base, where)                     \
       *((volatile u16 *) (mmio_base + where))           \

#define i830_readl(mmio_base, where)                     \
       *((volatile u32 *) (mmio_base + where))           \

#define i830_writeb(mmio_base, where, val)                              \
        *((volatile u8 *) (mmio_base + where)) = (volatile u8) val      \

#define i830_writew(mmio_base, where, val)                              \
        *((volatile u16 *) (mmio_base + where)) = (volatile u16) val    \

#define i830_writel(mmio_base, where, val)                              \
        *((volatile u32 *) (mmio_base + where)) = (volatile u32) val    \


int i830_wait_lp_ring( I830DriverData *idrv, I830DeviceData *idev, int space );

static inline int i830_begin_lp_ring( I830DriverData *idrv, I830DeviceData 
*idev, int needed, I830RingBlock  *ret_block )
{
     int ret;
     I830RingBuffer *buf = &idev->lp_ring;

     printf(  "begin_lp_ring( %d ) <- head 0x%08x\n", needed, i830_readl( 
idrv->mmio_base, LP_RING + RING_HEAD ) );

     if (needed & 1)
          printf( "i830_begin_ring called with odd argument: %d\n", needed);
          //D_ERROR( "i830_begin_ring called with odd argument: %d\n", needed);

     needed *= 4;

     if (buf->space < needed) {
          ret = i830_wait_lp_ring( idrv, idev, needed );
          if (ret)
               return ret;
     }

     buf->space -= needed;

     ret_block->virt      = idrv->lring_base;
     ret_block->tail_mask = buf->tail_mask;
     ret_block->outring   = buf->tail;

     return 1;
}


static inline void
i830_out_ring( I830RingBlock *block,
               u32            value )
{
     //D_DEBUG_AT( I830_Ring, "out_ring( 0x%08x, 0x%08x )\n", block->outring, 
value );
     printf( "out_ring( 0x%08x, 0x%08x )\n", block->outring, value );

     *(volatile u32*)(block->virt + block->outring) = value;

     block->outring = (block->outring + 4) & block->tail_mask;
}


static inline void
i830_advance_lp_ring( I830DriverData      *idrv,
                      I830DeviceData      *idev,
                      const I830RingBlock *block )
{
     //D_DEBUG_AT( I830_Ring, "advance_lp_ring( 0x%08x )\n", block->outring );
     printf(  "advance_lp_ring( 0x%08x )\n", block->outring );

     idev->lp_ring.tail = block->outring;

     if (block->outring & 0x07){
          //D_ERROR( "i830_advance_lp_ring: " "outring (0x%x) isn't on a QWord 
boundary", block->outring );
          printf( "i830_advance_lp_ring: " "outring (0x%x) isn't on a QWord 
boundary", block->outring );
     }
     i830_writel( idrv->mmio_base, LP_RING + RING_TAIL, block->outring );
}



#endif /* __I830_H__ */
_______________________________________________
directfb-dev mailing list
directfb-dev@directfb.org
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to