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
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev