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