diff --git a/src/Makefile.am b/src/Makefile.am index 2b5799c..4e87f94 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -91,6 +91,7 @@ intel_drv_la_SOURCES = \ i830_display.c \ i830_display.h \ i830_driver.c \ + i830_drm.c \ i830_dvo.c \ i830.h \ i830_i2c.c \ diff --git a/src/i830.h b/src/i830.h index e4d5070..bb08d21 100644 --- a/src/i830.h +++ b/src/i830.h @@ -117,52 +117,9 @@ typedef CARD8(*I830ReadIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr, typedef void (*I830WriteByteFunc)(I830Ptr pI830, IOADDRESS addr, CARD8 value); typedef CARD8(*I830ReadByteFunc)(I830Ptr pI830, IOADDRESS addr); -/** Record of a linear allocation in the aperture. */ -typedef struct _i830_memory i830_memory; -struct _i830_memory { - /** Offset of the allocation in card VM */ - unsigned long offset; - /** End of the allocation in card VM */ - unsigned long end; - /** - * Requested size of the allocation: doesn't count padding. - * - * Any bound memory will cover offset to (offset + size). - */ - unsigned long size; - /** - * Physical (or more properly, bus) address of the allocation. - * Only set if requested during allocation. - */ - unsigned long bus_addr; - /** AGP memory handle */ - int key; - /** - * Whether or not the AGP memory (if any) is currently bound. - */ - Bool bound; - /** - * Offset that the AGP-allocated memory (if any) is to be bound to. - * - * This is either @offset or pI830->stolen_size - */ - unsigned long agp_offset; - - /** Description of the allocation, for logging */ - char *name; - - /** @{ - * Memory allocator linked list pointers - */ - i830_memory *next; - i830_memory *prev; - /** @} */ - -}; - typedef struct { int tail_mask; - i830_memory *mem; + drmBO *mem; unsigned char *virtual_start; int head; int tail; @@ -279,29 +236,28 @@ typedef struct _I830Rec { /* These are set in PreInit and never changed. */ long FbMapSize; - i830_memory *memory_list; /**< Linked list of video memory allocations */ long stolen_size; /**< bytes of pre-bound stolen memory */ int gtt_acquired; /**< whether we currently own the AGP */ - i830_memory *front_buffer; - i830_memory *front_buffer_2; + drmBO *front_buffer; + drmBO *front_buffer_2; /* One big buffer for all cursors for kernels that support this */ - i830_memory *cursor_mem; + drmBO *cursor_mem; /* separate small buffers for kernels that support this */ - i830_memory *cursor_mem_classic[2]; - i830_memory *cursor_mem_argb[2]; - i830_memory *xaa_scratch; - i830_memory *xaa_scratch_2; + drmBO *cursor_mem_classic[2]; + drmBO *cursor_mem_argb[2]; + drmBO *xaa_scratch; + drmBO *xaa_scratch_2; #ifdef I830_USE_EXA - i830_memory *exa_offscreen; - i830_memory *exa_965_state; + drmBO *exa_offscreen; + drmBO *exa_965_state; #endif /* Regions allocated either from the above pools, or from agpgart. */ I830RingBuffer *LpRing; #ifdef I830_XV /* For Xvideo */ - i830_memory *overlay_regs; + drmBO *overlay_regs; #endif XF86ModReqInfo shadowReq; /* to test for later libshadow */ Rotation rotation; @@ -309,17 +265,16 @@ typedef struct _I830Rec { CreateScreenResourcesProcPtr CreateScreenResources; int *used3D; - i830_memory *logical_context; + drmBO *logical_context; unsigned int front_tiled; #ifdef XF86DRI - i830_memory *back_buffer; - i830_memory *third_buffer; - i830_memory *depth_buffer; - i830_memory *textures; /**< Compatibility texture memory */ - i830_memory *memory_manager; /**< DRI memory manager aperture */ - i830_memory *hw_status; /* for G33 hw status page alloc */ + drmBO *back_buffer; + drmBO *third_buffer; + drmBO *depth_buffer; + drmBO *textures; /**< Compatibility texture memory */ + drmBO *hw_status; /* for G33 hw status page alloc */ int TexGranularity; int drmMinor; @@ -629,7 +584,7 @@ void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix); void i830_reset_allocations(ScrnInfoPtr pScrn); void i830_free_3d_memory(ScrnInfoPtr pScrn); -void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem); +void i830_free_memory(ScrnInfoPtr pScrn, drmBO *mem); extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn); diff --git a/src/i830_driver.c b/src/i830_driver.c index 3133d77..bd05be3 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2088,83 +2088,6 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn) } } -#ifdef XF86DRI_MM -#ifndef XSERVER_LIBDRM_MM - -static int -I830DrmMMInit(int drmFD, unsigned long pageOffs, unsigned long pageSize, - unsigned memType) -{ - - drm_mm_init_arg_t arg; - int ret; - - memset(&arg, 0, sizeof(arg)); - arg.req.op = mm_init; - arg.req.p_offset = pageOffs; - arg.req.p_size = pageSize; - arg.req.mem_type = memType; - - ret = ioctl(drmFD, DRM_IOCTL_MM_INIT, &arg); - - if (ret) - return -errno; - - return 0; - -} - -static int -I830DrmMMTakedown(int drmFD, unsigned memType) -{ - drm_mm_init_arg_t arg; - int ret = 0; - - memset(&arg, 0, sizeof(arg)); - arg.req.op = mm_takedown; - arg.req.mem_type = memType; - if (ioctl(drmFD, DRM_IOCTL_MM_INIT, &arg)) { - ret = -errno; - } - - return ret; -} - -static int I830DrmMMLock(int fd, unsigned memType) -{ - drm_mm_init_arg_t arg; - int ret; - - memset(&arg, 0, sizeof(arg)); - arg.req.op = mm_lock; - arg.req.mem_type = memType; - - do{ - ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg); - } while (ret && errno == EAGAIN); - - return ret; -} - -static int I830DrmMMUnlock(int fd, unsigned memType) -{ - drm_mm_init_arg_t arg; - int ret; - - memset(&arg, 0, sizeof(arg)); - arg.req.op = mm_unlock; - arg.req.mem_type = memType; - - do{ - ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg); - } while (ret && errno == EAGAIN); - - return ret; -} - -#endif -#endif /* XF86DRI_MM */ - static Bool I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { @@ -2177,12 +2100,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) int i; Bool allocation_done = FALSE; MessageType from; -#ifdef XF86DRI Bool driDisabled; -#ifdef XF86DRI_MM - unsigned long savedMMSize; -#endif -#endif pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); @@ -2334,9 +2252,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!I830CheckDRIAvailable(pScrn)) { pI830->directRenderingDisabled = TRUE; -#ifdef XF86DRI_MM - pI830->mmSize = 0; -#endif } #ifdef I830_XV @@ -2386,12 +2301,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) */ pI830->disableTiling = FALSE; -#ifdef XF86DRI_MM - savedMMSize = pI830->mmSize; -#define MM_TURNS 4 -#else #define MM_TURNS 2 -#endif for (i = 0; i < MM_TURNS; i++) { if (!tiled && i < 2) continue; @@ -2407,26 +2317,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->allowPageFlip = FALSE; } -#ifdef XF86DRI_MM - if (i & 1) { - /* For this allocation, switch to a smaller DRI memory manager - * size. - */ - pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE / KB(1); - } else { - pI830->mmSize = savedMMSize; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Attempting memory allocation with %s buffers and \n" - "\t %s DRI memory manager reservation:\n", - (i & 2) ? "untiled" : "tiled", - (i & 1) ? "small" : "large"); -#else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Attempting memory allocation with %s buffers:\n", (i & 1) ? "untiled" : "tiled"); -#endif if (i830_allocate_2d_memory(pScrn) && i830_allocate_3d_memory(pScrn)) @@ -2448,9 +2341,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (i == MM_TURNS) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Not enough video memory. Disabling DRI.\n"); -#ifdef XF86DRI_MM - pI830->mmSize = 0; -#endif pI830->directRenderingDisabled = TRUE; } } else @@ -2784,41 +2674,18 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->closing = FALSE; pI830->suspended = FALSE; -#ifdef XF86DRI_MM - if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) - { - if (pI830->memory_manager == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Too little AGP aperture space for DRM memory manager.\n" - "\tPlease increase AGP aperture size from BIOS configuration screen.\n" - "\tDisabling DRI.\n"); - pI830->directRenderingOpen = FALSE; - I830DRICloseScreen(pScreen); - pI830->directRenderingEnabled = FALSE; - } else { - unsigned long aperEnd = ROUND_DOWN_TO(pI830->memory_manager->offset + - pI830->memory_manager->size, - GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->memory_manager->offset, - GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - -#ifndef XSERVER_LIBDRM_MM - if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, - DRM_BO_MEM_TT)) { -#else - if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, - DRM_BO_MEM_TT)) { -#endif - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not initialize the DRM memory manager.\n"); - - pI830->directRenderingOpen = FALSE; - I830DRICloseScreen(pScreen); - pI830->directRenderingEnabled = FALSE; - } - } + /* FIXME: init other memory manager pools */ +#if 0 + if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, + DRM_BO_MEM_TT)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not initialize the DRM memory manager.\n"); + + pI830->directRenderingOpen = FALSE; + I830DRICloseScreen(pScreen); + pI830->directRenderingEnabled = FALSE; } -#endif /* XF86DRI_MM */ +#endif return TRUE; } @@ -2879,15 +2746,9 @@ I830LeaveVT(int scrnIndex, int flags) #ifdef XF86DRI if (pI830->directRenderingOpen) { DRILock(screenInfo.screens[pScrn->scrnIndex], 0); -#ifdef XF86DRI_MM if (pI830->mmModeFlags & I830_KERNEL_MM) { -#ifndef XSERVER_LIBDRM_MM - I830DrmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT); -#else drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT); -#endif } -#endif /* XF86DRI_MM */ I830DRISetVBlankInterrupt (pScrn, FALSE); drmCtlUninstHandler(pI830->drmSubFD); @@ -2990,11 +2851,7 @@ I830EnterVT(int scrnIndex, int flags) #ifdef XF86DRI_MM if (pI830->mmModeFlags & I830_KERNEL_MM) { -#ifndef XSERVER_LIBDRM_MM - I830DrmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT); -#else drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT); -#endif } #endif /* XF86DRI_MM */ @@ -3057,11 +2914,7 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) #endif #ifdef XF86DRI_MM if (pI830->mmModeFlags & I830_KERNEL_MM) { -#ifndef XSERVER_LIBDRM_MM - I830DrmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT); -#else drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT); -#endif } #endif /* XF86DRI_MM */ pI830->directRenderingOpen = FALSE; diff --git a/src/i830_memory.c b/src/i830_memory.c index 17d4c4e..b3cc1e7 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -146,396 +146,47 @@ i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size) } } -static Bool -i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (mem == NULL || mem->key == -1 || mem->bound || !pI830->gtt_acquired) - return TRUE; - - if (xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { - mem->bound = TRUE; - return TRUE; - } else { - return FALSE; - } - - return TRUE; -} - -static Bool -i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) -{ - if (mem == NULL || mem->key == -1 || !mem->bound) - return TRUE; - - if (xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) { - mem->bound = FALSE; - return TRUE; - } else { - return FALSE; - } -} - void -i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) -{ - if (mem == NULL) - return; - - /* Disconnect from the list of allocations */ - if (mem->prev != NULL) - mem->prev->next = mem->next; - if (mem->next != NULL) - mem->next->prev = mem->prev; - - /* Free any AGP memory. */ - i830_unbind_memory(pScrn, mem); - - if (mem->key != -1) { - xf86DeallocateGARTMemory(pScrn->scrnIndex, mem->key); - mem->key = -1; - } - - xfree(mem->name); - xfree(mem); -} - -/* Resets the state of the aperture allocator, freeing all memory that had - * been allocated. - */ -void -i830_reset_allocations(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int p; - - /* While there is any memory between the start and end markers, free it. */ - while (pI830->memory_list->next->next != NULL) - i830_free_memory(pScrn, pI830->memory_list->next); - - /* Null out the pointers for all the allocations we just freed. This is - * kind of gross, but at least it's just one place now. - */ - pI830->cursor_mem = NULL; - for (p = 0; p < 2; p++) { - pI830->cursor_mem_classic[p] = NULL; - pI830->cursor_mem_argb[p] = NULL; - } - pI830->front_buffer = NULL; - pI830->front_buffer_2 = NULL; - pI830->xaa_scratch = NULL; - pI830->xaa_scratch_2 = NULL; - pI830->exa_offscreen = NULL; - pI830->exa_965_state = NULL; - pI830->overlay_regs = NULL; - pI830->logical_context = NULL; -#ifdef XF86DRI - pI830->back_buffer = NULL; - pI830->third_buffer = NULL; - pI830->depth_buffer = NULL; - pI830->textures = NULL; - pI830->memory_manager = NULL; -#endif - pI830->LpRing->mem = NULL; - - /* Reset the fence register allocation. */ - pI830->next_fence = 0; - memset(pI830->fence, 0, sizeof(pI830->fence)); -} - -void -i830_free_3d_memory(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - -#ifdef XF86DRI - i830_free_memory(pScrn, pI830->back_buffer); - pI830->back_buffer = NULL; - i830_free_memory(pScrn, pI830->third_buffer); - pI830->third_buffer = NULL; - i830_free_memory(pScrn, pI830->depth_buffer); - pI830->depth_buffer = NULL; - i830_free_memory(pScrn, pI830->textures); - pI830->textures = NULL; - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; -#endif -} - -/** - * Initialize's the driver's video memory allocator to allocate in the - * given range. - */ -Bool -i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, - unsigned long size) -{ - I830Ptr pI830 = I830PTR(pScrn); - i830_memory *start, *end; - - start = xcalloc(1, sizeof(*start)); - if (start == NULL) - return FALSE; - start->name = xstrdup("start marker"); - if (start->name == NULL) { - xfree(start); - return FALSE; - } - end = xcalloc(1, sizeof(*end)); - if (end == NULL) { - xfree(start->name); - xfree(start); - return FALSE; - } - end->name = xstrdup("end marker"); - if (end->name == NULL) { - xfree(start->name); - xfree(start); - xfree(end); - return FALSE; - } - - start->key = -1; - start->offset = offset; - start->end = start->offset; - start->size = 0; - start->next = end; - end->key = -1; - end->offset = offset + size; - end->end = end->offset; - end->size = 0; - end->prev = start; - - pI830->memory_list = start; - - return TRUE; -} - -/** - * Reads a GTT entry for the memory at the given offset and returns the - * physical address. - * - * \return physical address if successful. - * \return (unsigned long)-1 if unsuccessful. - */ -static unsigned long -i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset) -{ - I830Ptr pI830 = I830PTR(pScrn); - CARD32 gttentry; - - /* We don't have GTTBase set up on i830 yet. */ - if (pI830->GTTBase == NULL) - return -1; - - gttentry = INGTT(offset / 1024); - - /* Mask out these reserved bits on this hardware. */ - if (!IS_I965G(pI830)) - gttentry &= ~PTE_ADDRESS_MASK_HIGH; - - /* If it's not a mapping type we know, then bail. */ - if ((gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED && - (gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_CACHED) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Unusable physical mapping type 0x%08x\n", - (unsigned int)(gttentry & PTE_MAPPING_TYPE_MASK)); - return -1; - } - /* If we can't represent the address with an unsigned long, bail. */ - if (sizeof(unsigned long) == 4 && - (gttentry & PTE_ADDRESS_MASK_HIGH) != 0) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "High memory PTE (0x%08x) on 32-bit system\n", - (unsigned int)gttentry); - return -1; - } - assert((gttentry & PTE_VALID) != 0); - - return (gttentry & PTE_ADDRESS_MASK) | - (gttentry & PTE_ADDRESS_MASK_HIGH << (32 - 4)); -} - -/** - * Reads the GTT entries for stolen memory at the given offset, returning the - * physical address. - * - * \return physical address if successful. - * \return (unsigned long)-1 if unsuccessful. - */ -static unsigned long -i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset, - unsigned long size) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned long physical, scan; - - /* Check that the requested region is within stolen memory. */ - if (offset + size >= pI830->stolen_size) - return -1; - - physical = i830_get_gtt_physical(pScrn, offset); - if (physical == -1) - return -1; - - /* Check that the following pages in our allocation follow the first page - * contiguously. - */ - for (scan = offset + 4096; scan < offset + size; scan += 4096) { - unsigned long scan_physical = i830_get_gtt_physical(pScrn, scan); - - if ((scan - offset) != (scan_physical - physical)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Non-contiguous GTT entries: (%ld,%ld) vs (%ld,%ld)\n", - scan, scan_physical, offset, physical); - return -1; - } - } - - return physical; -} - -/* Allocate aperture space for the given size and alignment, and returns the - * memory allocation. - * - * Allocations are a minimum of a page, and will be at least page-aligned. - */ -static i830_memory * -i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, - long size, unsigned long alignment, int flags) +i830_free_memory(ScrnInfoPtr pScrn, drmBO *buf) { I830Ptr pI830 = I830PTR(pScrn); - i830_memory *mem, *scan; - - mem = xcalloc(1, sizeof(*mem)); - if (mem == NULL) - return NULL; - - /* No memory allocated to back the region */ - mem->key = -1; - - mem->name = xstrdup(name); - if (mem->name == NULL) { - xfree(mem); - return NULL; - } - /* Only allocate page-sized increments. */ - size = ALIGN(size, GTT_PAGE_SIZE); - mem->size = size; - - if (alignment < GTT_PAGE_SIZE) - alignment = GTT_PAGE_SIZE; - - for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) { - mem->offset = ROUND_TO(scan->end, alignment); - if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size) { - /* If the allocation is entirely within stolen memory, and we're - * able to get the physical addresses out of the GTT and check that - * it's contiguous (it ought to be), then we can do our physical - * allocations there and not bother the kernel about it. This - * helps avoid aperture fragmentation from our physical - * allocations. - */ - mem->bus_addr = i830_get_stolen_physical(pScrn, mem->offset, - mem->size); - - if (mem->bus_addr == ((unsigned long)-1)) { - /* Move the start of the allocation to just past the end of - * stolen memory. - */ - mem->offset = ROUND_TO(pI830->stolen_size, alignment); - } - } - - mem->end = mem->offset + size; - if (flags & ALIGN_BOTH_ENDS) - mem->end = ROUND_TO(mem->end, alignment); - if (mem->end <= scan->next->offset) - break; - } - if (scan->next == NULL) { - /* Reached the end of the list, and didn't find space */ - xfree(mem->name); - xfree(mem); - return NULL; - } - /* Insert new allocation into the list */ - mem->prev = scan; - mem->next = scan->next; - scan->next = mem; - mem->next->prev = mem; - - return mem; -} - -/** - * Allocates the AGP memory necessary for the part of a memory allocation not - * already covered by the stolen memory. - * - * The memory is automatically bound if we have the VT. - */ -static Bool -i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned long size; - - if (mem->key != -1) - return TRUE; - - if (mem->offset + mem->size <= pI830->stolen_size) - return TRUE; - - if (mem->offset < pI830->stolen_size) - mem->agp_offset = pI830->stolen_size; - else - mem->agp_offset = mem->offset; - - size = mem->size - (mem->agp_offset - mem->offset); - - if (flags & NEED_PHYSICAL_ADDR) - mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, - &mem->bus_addr); - else - mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); - if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0)) - { - return FALSE; - } + int drmfd = pI830->drmSubFD; - if (!i830_bind_memory(pScrn, mem)) { - return FALSE; - } + if (!buf) + return; - return TRUE; + ret = drmBODestory(drmfd, buf); + if (ret) + ErrorF("drmBODestroy failed: %d\n"); } - /* Allocates video memory at the given size and alignment. * * The memory will be bound automatically when the driver is in control of the * VT. */ -static i830_memory * +static drmBO * i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, unsigned long size, unsigned long alignment, int flags) { - i830_memory *mem; + I830Ptr pI830 = I830PTR(pScrn); + drmBO *buf; + int drmfd = pI830->drmSubFD; - mem = i830_allocate_aperture(pScrn, name, size, alignment, flags); - if (mem == NULL) - return NULL; + buf = xcalloc(1, sizeof(*buf)); - if (!i830_allocate_agp_memory(pScrn, mem, flags)) { - i830_free_memory(pScrn, mem); + /* FIXME: correct hints (from caller?) */ + hint = DRM_BO_HINT_DONT_FENCE | DRM_BO_HINT_ALLOW_UNFENCED_MAP; + + ret = drmBOCreate(drmfd, 0, size, alignment, NULL, drm_bo_type_dc, flags, + hint, buf); + if (ret) { + ErrorF("memory allocation failed: %d\n"); + xfree(buf); return NULL; } - return mem; + return buf; } /* Allocate a tiled region with the given size and pitch. @@ -649,74 +300,6 @@ i830_describe_tiling(ScrnInfoPtr pScrn, int verbosity, const char *prefix, (tiling_mode == FENCE_LINEAR) ? "not " : ""); } -void -i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) -{ - I830Ptr pI830 = I830PTR(pScrn); - i830_memory *mem; - - if (pI830->memory_list == NULL) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sMemory allocator not initialized\n", prefix); - return; - } - - if (pI830->memory_list->next->next == NULL) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sNo memory allocations\n", prefix); - return; - } - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sMemory allocation layout:\n", prefix); - - for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) { - - if (mem->offset >= pI830->stolen_size && - mem->prev->offset < pI830->stolen_size) - { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx: end of stolen memory\n", - prefix, pI830->stolen_size); - } - - if (mem->bus_addr == 0) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix, - mem->offset, mem->end - 1, mem->name, - mem->size / 1024); - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx-0x%08lx: %s (%ld kB, 0x%08lx physical)\n", - prefix, - mem->offset, mem->end - 1, mem->name, - mem->size / 1024, mem->bus_addr); - } - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx: end of aperture\n", - prefix, pI830->FbMapSize); - - if (pI830->front_buffer != NULL) { - i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer, - pI830->front_tiled); - } -#ifdef XF86DRI - if (pI830->back_buffer != NULL) { - i830_describe_tiling(pScrn, verbosity, prefix, pI830->back_buffer, - pI830->back_tiled); - } - if (pI830->third_buffer != NULL) { - i830_describe_tiling(pScrn, verbosity, prefix, pI830->third_buffer, - pI830->third_tiled); - } - if (pI830->depth_buffer != NULL) { - i830_describe_tiling(pScrn, verbosity, prefix, pI830->depth_buffer, - pI830->depth_tiled); - } -#endif -} - static Bool i830_allocate_ringbuffer(ScrnInfoPtr pScrn) { --- /dev/null 2007-06-26 10:39:47.455826742 -0700 +++ xf86-video-intel/src/i830_drm.c 2007-06-11 17:07:16.000000000 -0700 @@ -0,0 +1,326 @@ +/** + * \file miniglx_mode.c + * \brief Mini GLX mode handling for new DRM + * \author Dave Airlie + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "xf86.h" +#include "xf86drm.h" +#include "xf86drmMode.h" + +#include "i830.h" + + +#if 0 +struct drm_output { + struct drm_output *next; + char name[32]; + int xres, yres; + int refresh; + int xoffset, yoffset; + int mode_id; + int output_id; + int crtc_id; +}; + +struct drm_output *output_list; + +void parse_output(char *opt, char *val) +{ + char *ch; + int len, count; + struct drm_output *output; + char buf[128]; + + output = calloc(sizeof(struct drm_output), 1); + if (!output) + return; + + ch = &opt[7]; + count = 0; + while(*ch!=0) { + output->name[count++] = *ch; + ch++; + } + output->name[count] = 0; + + output->xres = strtoul(val, &ch, 10); + output->yres = strtoul(ch+1, &ch, 10); + output->refresh = strtoul(ch+1, &ch, 10); + output->xoffset = strtoul(ch+1, &ch, 10); + output->yoffset = strtoul(ch+1, &ch, 10); + + if (!output_list) + output_list = output; + else { + output->next = output_list; + output_list = output; + } +} + +void drm_dump_modeinfo(DRIDriverContext *ctx) +{ + drmModeResPtr res_ptr; + drmModeCrtcPtr res_crtc; + drmModeOutputPtr res_output; + drmModeFBPtr res_fb; + int i, j; + + res_ptr = drmModeGetResources(ctx->drmFD); + + if (res_ptr) { + fprintf(stderr,"Number of fbs: %d\n", res_ptr->count_fbs); + fprintf(stderr,"Number of crtcs: %d\n", res_ptr->count_crtcs); + fprintf(stderr,"Number of outputs: %d\n", res_ptr->count_outputs); + fprintf(stderr,"Number of modes: %d\n", res_ptr->count_modes); + + for (i = 0; i < res_ptr->count_fbs; i++) + fprintf(stderr,"FB: %d id %d\n", i, res_ptr->fbs[i]); + + for (i = 0; i < res_ptr->count_crtcs; i++) + fprintf(stderr,"CRTC: %d id %d\n", i, res_ptr->crtcs[i]); + + for (i = 0; i < res_ptr->count_outputs; i++) + fprintf(stderr,"OUTPUT: %d id %d\n", i, res_ptr->outputs[i]); + + for (i = 0; i < res_ptr->count_modes; i++) { + struct drm_mode_modeinfo *m = &res_ptr->modes[i]; + fprintf(stderr,"mode %d: %d: %s: %f: %d: %d %d %d %d : %d %d %d %d\n", + i, m->id, m->name, (float)m->vrefresh/1000.0, m->clock, + m->hdisplay, m->hsync_start, m->vsync_end, m->htotal, + m->vdisplay, m->vsync_start, m->vsync_end, m->vtotal); + } + } + + for (i = 0; i < res_ptr->count_fbs; i++) { + res_fb = drmModeGetFB(ctx->drmFD, res_ptr->fbs[i]); + + if (res_fb) + fprintf(stderr,"FB %d: %dx%d %d %d %d\n", i, res_fb->width, res_fb->height, res_fb->pitch, res_fb->bpp, res_fb->depth); + drmModeFreeFB(res_fb); + } + + for (i = 0; i < res_ptr->count_crtcs; i++) { + res_crtc = drmModeGetCrtc(ctx->drmFD, res_ptr->crtcs[i]); + + if (res_crtc) + fprintf(stderr,"CRTC %d: %dx%d - mode %d - nout %d\n", i, res_crtc->x, res_crtc->y, res_crtc->mode, res_crtc->outputs); + drmModeFreeCrtc(res_crtc); + } + + for (i = 0; i < res_ptr->count_outputs; i++) { + res_output = drmModeGetOutput(ctx->drmFD, res_ptr->outputs[i]); + + if (res_output) { + fprintf(stderr,"Output %d: %s: conn:%d mm:%dx%d spixel: %d nmodes: %d: ", i, res_output->name,res_output->connection, res_output->mmWidth, res_output->mmHeight, res_output->subpixel, res_output->count_modes); + for (j = 0; j < res_output->count_modes; j++) + fprintf(stderr,"%02X ", res_output->modes[j]); + fprintf(stderr,"\n"); + + } + drmModeFreeOutput(res_output); + } + + drmModeFreeResources(res_ptr); + +} + + +static int find_mode_output(drmModeResPtr res_ptr, drmModeOutputPtr output, struct drm_output *drm_output) +{ + int i, j; + int closest_mode_id = 0; + int refresh_diff = (10*1000), diff; + int req_refresh = drm_output->refresh * 1000; + + /* Does this output match the naming */ + if (strncmp(drm_output->name, output->name, strlen(drm_output->name))) + return 0; + + if (drm_output->output_id) + return 0; + + + drm_output->mode_id = 0; + for (i = 0; i < res_ptr->count_modes; i++) { + struct drm_mode_modeinfo *m = &res_ptr->modes[i]; + + for (j = 0; j < output->count_modes; j++) { + if (output->modes[j] == m->id) { + + if (m->hdisplay == drm_output->xres && + m->vdisplay == drm_output->yres) { + /* need to fuzz refresh rate */ + if (req_refresh > m->vrefresh) + diff = req_refresh - m->vrefresh; + else + diff = m->vrefresh - req_refresh; + + if (diff < refresh_diff) { + refresh_diff = diff; + drm_output->mode_id = m->id; + } + } + } + } + } + if (drm_output->mode_id) + return 1; + return 0; +} + +int drm_set_mode(DRIDriverContext *ctx) +{ + drmModeResPtr res_ptr; + drmModeOutputPtr res_output; + struct drm_output *drm_output; + uint32_t out_array[2]; + int i; + int ret, count; + + if (!output_list) + return -1; + + res_ptr = drmModeGetResources(ctx->drmFD); + + if (!res_ptr) + return -1; + + for (i = 0; i < res_ptr->count_outputs; i++) { + res_output = drmModeGetOutput(ctx->drmFD, res_ptr->outputs[i]); + + drm_output = output_list; + while (drm_output) { + ret = find_mode_output(res_ptr, res_output, drm_output); + if (ret) { + drm_output->output_id = res_ptr->outputs[i]; + break; + } + drm_output=drm_output->next; + } + + drmModeFreeOutput(res_output); + } + + /* found and output mode - now for a CRTC */ + count = 0; + drm_output = output_list; + while(drm_output) { + if (res_ptr->crtcs[count]) + drm_output->crtc_id = res_ptr->crtcs[count]; + count++; + drm_output = drm_output->next; + } + + drm_output = output_list; + while(drm_output) { + out_array[0] = drm_output->output_id; + ret = drmModeSetCrtc(ctx->drmFD, drm_output->crtc_id, res_ptr->fbs[0], drm_output->xoffset, drm_output->yoffset, drm_output->mode_id, out_array, 1); + if (ret) { + fprintf(stderr,"Mode set failed\n"); + } + drm_output = drm_output->next; + } + drmModeFreeResources(res_ptr); + return 1; +} + +#endif + +#define KB(x) ((x) * 1024) + +static unsigned long GetBestTileAlignment(unsigned long size) +{ + unsigned long i; + + for (i = KB(512); i < size; i <<= 1) + ; + + if (i > MB(64)) + i = MB(64); + + return i; +} + +void i830_drm_init(ScrnInfoPtr pScrn) +{ + drmModeResPtr res_ptr; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long ret, size, lines, lineSize, align; + unsigned int flags, hint, fb_id; + + res_ptr = drmModeGetResources(pI830->drmSubFD); + if (!res_ptr) { + fprintf(stderr,"Unable to get DRM resources\n"); + return; + } + + if (res_ptr->count_fbs > 0) + drmModeRmFB(pI830->drmSubFD, res_ptr->fbs[0]); + + /* allocate front buffer */ + flags = DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_MEM_PRIV0 | + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_SHAREABLE | DRM_BO_FLAG_MAPPABLE; + + hint = DRM_BO_HINT_DONT_FENCE | DRM_BO_HINT_ALLOW_UNFENCED_MAP; + + memset(&(pI830->fb_obj), 0, sizeof(pI830->fb_obj)); + + align = KB(512) / getpagesize(); + + lineSize = pScrn->virtualX * pI830->cpp; + lines = (pScrn->virtualY + 15) / 16 * 16; + size = lineSize * lines; + size = ROUND_TO_PAGE(size); + + /* round size up to a fence sized alignment */ + size = GetBestTileAlignment(size); + align = size / getpagesize(); + + fprintf(stderr, "drmBOCreate(%d, %d, %ld, %lx, %p, %d, %x, %x, %p)\n"; + pI830->drmSubFD, 0, size, align, NULL, drm_bo_type_dc, flags, + hint, &pI830->fb_obj); + ret = drmBOCreate(pI830->drmSubFD, 0, size, align, NULL, drm_bo_type_dc, + flags, hint, &pI830->fb_obj); + fprintf(stderr, "returned %d, fb_obj = %p\n", ret, pI830->fb_obj); + + /* add new front buffer to our kernel mode config */ + ret = drmModeAddFB(pI830->drmSubFD, pScrn->virtualX + pScrn->virtualY, pScrn->bitsPerPixel, + pScrn->bitsPerPixel, pScrn->virtualX, + pI830->fb_obj, &fb_id); + if (ret) + fprintf(stderr,"Error adding framebuffer\n"); + + drmModeFreeResources(res_ptr); + return ; + +} + +void drm_cleanup_drmfb(DRIDriverContext *ctx) +{ + drmModeRmFB(pI830->drmSubFD, pI830->fb_id); +}