2005-09-25 08:28:13 +04:00
/**
* \ file drm_memory . c
2005-04-17 02:20:36 +04:00
* Memory management wrappers for DRM
*
* \ author Rickard E . ( Rik ) Faith < faith @ valinux . com >
* \ author Gareth Hughes < gareth @ valinux . com >
*/
2005-09-25 08:28:13 +04:00
/*
2005-04-17 02:20:36 +04:00
* Created : Thu Feb 4 14 : 00 : 34 1999 by faith @ valinux . com
*
* Copyright 1999 Precision Insight , Inc . , Cedar Park , Texas .
* Copyright 2000 VA Linux Systems , Inc . , Sunnyvale , California .
* All Rights Reserved .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* 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>
2011-08-31 02:16:33 +04:00
# include <linux/export.h>
2012-10-02 21:01:07 +04:00
# include <drm/drmP.h>
2005-04-17 02:20:36 +04:00
# if __OS_HAS_AGP
2006-04-11 10:18:27 +04:00
static void * agp_remap ( unsigned long offset , unsigned long size ,
2007-07-11 09:53:27 +04:00
struct drm_device * dev )
2006-04-07 10:55:43 +04:00
{
2009-06-12 08:11:41 +04:00
unsigned long i , num_pages =
2006-04-07 10:55:43 +04:00
PAGE_ALIGN ( size ) / PAGE_SIZE ;
struct drm_agp_mem * agpmem ;
struct page * * page_map ;
2009-06-12 08:11:41 +04:00
struct page * * phys_page_map ;
2006-04-07 10:55:43 +04:00
void * addr ;
size = PAGE_ALIGN ( size ) ;
# ifdef __alpha__
offset - = dev - > hose - > mem_space - > start ;
# endif
2007-05-25 23:01:51 +04:00
list_for_each_entry ( agpmem , & dev - > agp - > memory , head )
2006-04-07 10:55:43 +04:00
if ( agpmem - > bound < = offset
& & ( agpmem - > bound + ( agpmem - > pages < < PAGE_SHIFT ) ) > =
( offset + size ) )
break ;
2010-04-28 01:11:05 +04:00
if ( & agpmem - > head = = & dev - > agp - > memory )
2006-04-07 10:55:43 +04:00
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 ;
2009-06-12 08:11:41 +04:00
phys_page_map = ( agpmem - > memory - > pages + ( offset - agpmem - > bound ) / PAGE_SIZE ) ;
2006-04-07 10:55:43 +04:00
for ( i = 0 ; i < num_pages ; + + i )
2009-06-12 08:11:41 +04:00
page_map [ i ] = phys_page_map [ i ] ;
2006-04-07 10:55:43 +04:00
addr = vmap ( page_map , num_pages , VM_IOREMAP , PAGE_AGP ) ;
vfree ( page_map ) ;
return addr ;
}
2005-04-17 02:20:36 +04:00
/** Wrapper around agp_free_memory() */
2010-08-24 00:53:35 +04:00
void drm_free_agp ( DRM_AGP_MEM * handle , int pages )
2005-04-17 02:20:36 +04:00
{
2010-08-24 00:53:36 +04:00
agp_free_memory ( handle ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-30 23:06:12 +04:00
EXPORT_SYMBOL ( drm_free_agp ) ;
2005-09-25 08:28:13 +04:00
2005-04-17 02:20:36 +04:00
/** Wrapper around agp_bind_memory() */
2005-09-25 08:28:13 +04:00
int drm_bind_agp ( DRM_AGP_MEM * handle , unsigned int start )
2005-04-17 02:20:36 +04:00
{
2010-08-24 00:53:36 +04:00
return agp_bind_memory ( handle , start ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-25 08:28:13 +04:00
2005-04-17 02:20:36 +04:00
/** Wrapper around agp_unbind_memory() */
2005-09-25 08:28:13 +04:00
int drm_unbind_agp ( DRM_AGP_MEM * handle )
2005-04-17 02:20:36 +04:00
{
2010-08-24 00:53:36 +04:00
return agp_unbind_memory ( handle ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-30 23:06:12 +04:00
EXPORT_SYMBOL ( drm_unbind_agp ) ;
2006-04-11 10:18:27 +04:00
# else /* __OS_HAS_AGP */
static inline void * agp_remap ( unsigned long offset , unsigned long size ,
2007-07-11 09:53:27 +04:00
struct drm_device * dev )
2006-04-11 10:18:27 +04:00
{
return NULL ;
}
2005-09-25 08:28:13 +04:00
# endif /* agp */
2006-04-07 10:55:43 +04:00
2009-02-02 08:55:46 +03:00
void drm_core_ioremap ( struct drm_local_map * map , struct drm_device * dev )
2006-04-07 10:55:43 +04:00
{
2007-01-08 13:56:59 +03:00
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 ) ;
2006-04-07 10:55:43 +04:00
}
2007-01-08 13:56:59 +03:00
EXPORT_SYMBOL ( drm_core_ioremap ) ;
2006-04-07 10:55:43 +04:00
2009-02-02 08:55:46 +03:00
void drm_core_ioremap_wc ( struct drm_local_map * map , struct drm_device * dev )
2008-07-15 09:48:05 +04:00
{
2009-02-07 04:15:41 +03:00
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_wc ( map - > offset , map - > size ) ;
2008-07-15 09:48:05 +04:00
}
EXPORT_SYMBOL ( drm_core_ioremap_wc ) ;
2009-02-07 04:15:41 +03:00
2009-02-02 08:55:46 +03:00
void drm_core_ioremapfree ( struct drm_local_map * map , struct drm_device * dev )
2006-04-07 10:55:43 +04:00
{
2007-01-08 13:56:59 +03:00
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 ) ;
2006-04-07 10:55:43 +04:00
}
2007-01-08 13:56:59 +03:00
EXPORT_SYMBOL ( drm_core_ioremapfree ) ;