summaryrefslogtreecommitdiff
path: root/shared-core/drm.h
AgeCommit message (Collapse)Author
2001-06-14First pass of 4.1.0 merge.David Dawes
2001-05-17Make the SiS module work again. At least glxinfo reports it's working, yetAlan Hourihane
trying to run the simple apps return 'out of video memory'
2001-05-03Make SiS driver compile with the new templated format. Not tested. minorAlan Hourihane
cleanups
2001-04-05Merged ati-pcigart-1-0-0Kevin E Martin
2001-03-21Move #include <linux/config.h> inside the __linux__ #ifdef, so that itDavid Dawes
doesn't break non-Linux builds.
2001-03-14Merged sarea-1-0-0Kevin E Martin
2001-03-06Merge tdfx-3-1-0 branch.Gareth Hughes
2001-02-28Implement drmOpen* without /proc dependence (Fallback to /proc is includedRik Faith
for backward compatibility.) Move statistic-gathering drm* calls from dristat.c to xf86drm.c
2001-02-15Merge mga-1-0-0-branch into trunk.Gareth Hughes
2001-01-05Merged ati-5-0-0Kevin E Martin
2001-01-04Sync with Linux 2.4.0-prereleaseRik Faith
2000-12-30add blit ioctl, fix plnwt handlingKeith Whitwell
2000-12-02Merged ati-4-1-1-branch into trunk.Gareth Hughes
2000-11-08merge with 4.0.1dDavid Dawes
2000-09-29More changes for sync with Linux 2.4.0-test9-pre7Rik Faith
2000-09-29Audit calls to schedule() Remove tags from files shared with Linux kernelRik Faith
tree Remove debugging statements to make debugging more useful Other minor cleanups in preparation for sync with Linux 2.4.0-test9-pre7
2000-09-24commit xfree86 4.0.1d-pre updateAlan Hourihane
2000-07-13applied Jeff's xf86cvs-I810copy.patchBrian Paul
2000-06-13Merged bsd-1-0-1Doug Rabson
2000-06-13Unify code with kernel: Change some spacing in comments Add #includeRik Faith
<linux/config.h> to all *_drv.c files
2000-06-12Merging the ati-4-1-0 branch onto the trunk.Gareth Hughes
2000-06-08Merged glxmisc-3-0-0Brian Paul
2000-05-30Merged bsd-1-0-0Doug Rabson
2000-05-25Merged mga-0-0-3-branchKeith Whitwell
- New security model for i810 - Enable i810 dri by default - New indexed vertex path for mga - Mga kernel driver rework - Removed dead files in i810 driver
2000-05-18Merged ati-4-0-1Kevin E Martin
2000-04-04Merged mga branch with trunkJeff Hartmann
2000-03-16Merge with 4.0Jeff Hartmann
2000-02-22Import of XFree86 3.9.18Kevin E Martin
2000-01-06Import of XFree86 3.9.17Rik Faith
1999-12-07Move Mesa to xc/extras Update to the latest Mesa 3.2 code Fix the Q3DemoDaryll Strauss
bugs (white railgun and texture mapping) Simplify driver texture mapping routines Fix device driver for 2.3 kernels Improve performance
1999-12-05First DRI release of 3dfx driver.Daryll Strauss
, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include <linux/highmem.h> #include "drmP.h" static struct { spinlock_t lock; uint64_t cur_used; uint64_t low_threshold; uint64_t high_threshold; } drm_memctl = { .lock = SPIN_LOCK_UNLOCKED }; static inline size_t drm_size_align(size_t size) { size_t tmpSize = 4; if (size > PAGE_SIZE) return PAGE_ALIGN(size); while (tmpSize < size) tmpSize <<= 1; return (size_t) tmpSize; } int drm_alloc_memctl(size_t size) { int ret; unsigned long a_size = drm_size_align(size); spin_lock(&drm_memctl.lock); ret = ((drm_memctl.cur_used + a_size) > drm_memctl.high_threshold) ? -ENOMEM : 0; if (!ret) drm_memctl.cur_used += a_size; spin_unlock(&drm_memctl.lock); return ret; } EXPORT_SYMBOL(drm_alloc_memctl); void drm_free_memctl(size_t size) { unsigned long a_size = drm_size_align(size); spin_lock(&drm_memctl.lock); drm_memctl.cur_used -= a_size; spin_unlock(&drm_memctl.lock); } EXPORT_SYMBOL(drm_free_memctl); void drm_query_memctl(uint64_t *cur_used, uint64_t *low_threshold, uint64_t *high_threshold) { spin_lock(&drm_memctl.lock); *cur_used = drm_memctl.cur_used; *low_threshold = drm_memctl.low_threshold; *high_threshold = drm_memctl.high_threshold; spin_unlock(&drm_memctl.lock); } EXPORT_SYMBOL(drm_query_memctl); void drm_init_memctl(size_t p_low_threshold, size_t p_high_threshold, size_t unit_size) { spin_lock(&drm_memctl.lock); drm_memctl.cur_used = 0; drm_memctl.low_threshold = p_low_threshold * unit_size; drm_memctl.high_threshold = p_high_threshold * unit_size; spin_unlock(&drm_memctl.lock); } #ifndef DEBUG_MEMORY /** No-op. */ void drm_mem_init(void) { } /** * Called when "/proc/dri/%dev%/mem" is read. * * \param buf output buffer. * \param start start of output data. * \param offset requested start offset. * \param len requested number of bytes. * \param eof whether there is no more data to return. * \param data private data. * \return number of written bytes. * * No-op. */ int drm_mem_info(char *buf, char **start, off_t offset, int len, int *eof, void *data) { return 0; } /** Wrapper around kmalloc() */ void *drm_calloc(size_t nmemb, size_t size, int area) { return kcalloc(nmemb, size, GFP_KERNEL); } EXPORT_SYMBOL(drm_calloc); /** Wrapper around kmalloc() and kfree() */ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) { void *pt; if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL; if (oldpt && oldsize) { memcpy(pt, oldpt, oldsize); kfree(oldpt); } return pt; } /** * Allocate pages. * * \param order size order. * \param area memory area. (Not used.) * \return page address on success, or zero on failure. * * Allocate and reserve free pages. */ unsigned long drm_alloc_pages(int order, int area) { unsigned long address; unsigned long bytes = PAGE_SIZE << order; unsigned long addr; unsigned int sz; address = __get_free_pages(GFP_KERNEL, order); if (!address) return 0; /* Zero */ memset((void *)address, 0, bytes); /* Reserve */ for (addr = address, sz = bytes; sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { SetPageReserved(virt_to_page(addr)); } return address; } /** * Free pages. * * \param address address of the pages to free. * \param order size order. * \param area memory area. (Not used.) * * Unreserve and free pages allocated by alloc_pages(). */ void drm_free_pages(unsigned long address, int order, int area) { unsigned long bytes = PAGE_SIZE << order; unsigned long addr; unsigned int sz; if (!address) return; /* Unreserve */ for (addr = address, sz = bytes; sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); } free_pages(address, order); } #if __OS_HAS_AGP static void *agp_remap(unsigned long offset, unsigned long size, struct drm_device * dev) { unsigned long *phys_addr_map, i, num_pages = PAGE_ALIGN(size) / PAGE_SIZE; struct drm_agp_mem *agpmem; struct page **page_map; void *addr; size = PAGE_ALIGN(size); #ifdef __alpha__ offset -= dev->hose->mem_space->start; #endif list_for_each_entry(agpmem, &dev->agp->memory, head) if (agpmem->bound <= offset && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= (offset + size)) break; if (!agpmem) return NULL; /* * OK, we're mapping AGP space on a chipset/platform on which memory accesses by * the CPU do not get remapped by the GART. We fix this by using the kernel's * page-table instead (that's probably faster anyhow...). */ /* note: use vmalloc() because num_pages could be large... */ page_map = vmalloc(num_pages * sizeof(struct page *)); if (!page_map) return NULL; phys_addr_map = agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE; for (i = 0; i < num_pages; ++i) page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT); addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP); vfree(page_map); return addr; } /** Wrapper around agp_allocate_memory() */ #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11) DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type) { return drm_agp_allocate_memory(pages, type); } #else DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type) { return drm_agp_allocate_memory(dev->agp->bridge, pages, type); } #endif /** Wrapper around agp_free_memory() */ int drm_free_agp(DRM_AGP_MEM * handle, int pages) { return drm_agp_free_memory(handle) ? 0 : -EINVAL; } /** Wrapper around agp_bind_memory() */ int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) { return drm_agp_bind_memory(handle, start); } /** Wrapper around agp_unbind_memory() */ int drm_unbind_agp(DRM_AGP_MEM * handle) { return drm_agp_unbind_memory(handle); } #else /* __OS_HAS_AGP*/ static void *agp_remap(unsigned long offset, unsigned long size, struct drm_device * dev) { return NULL; } #endif /* agp */ #endif /* debug_memory */ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) { if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) map->handle = agp_remap(map->offset, map->size, dev); else map->handle = ioremap(map->offset, map->size); } EXPORT_SYMBOL_GPL(drm_core_ioremap); void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) { if (!map->handle || !map->size) return; if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) vunmap(map->handle); else iounmap(map->handle); } EXPORT_SYMBOL_GPL(drm_core_ioremapfree);