2009-12-11 12:24:15 +03:00
# include "drmP.h"
# include "drm.h"
# include "nouveau_drv.h"
2010-09-01 09:24:34 +04:00
# include "nouveau_ramht.h"
2009-12-11 12:24:15 +03:00
/* returns the size of fifo context */
static int
nouveau_fifo_ctx_size ( struct drm_device * dev )
{
struct drm_nouveau_private * dev_priv = dev - > dev_private ;
if ( dev_priv - > chipset > = 0x40 )
return 128 ;
else
if ( dev_priv - > chipset > = 0x17 )
return 64 ;
return 32 ;
}
int nv04_instmem_init ( struct drm_device * dev )
{
struct drm_nouveau_private * dev_priv = dev - > dev_private ;
2010-09-01 09:24:34 +04:00
struct nouveau_gpuobj * ramht = NULL ;
2010-09-01 09:24:35 +04:00
u32 offset , length ;
2010-06-01 09:32:24 +04:00
int ret ;
2009-12-11 12:24:15 +03:00
2010-09-06 22:25:28 +04:00
/* RAMIN always available */
dev_priv - > ramin_available = true ;
2010-09-01 09:24:34 +04:00
/* Setup shared RAMHT */
2010-09-01 09:24:35 +04:00
ret = nouveau_gpuobj_new_fake ( dev , 0x10000 , ~ 0 , 4096 ,
2010-09-01 09:24:34 +04:00
NVOBJ_FLAG_ZERO_ALLOC , & ramht ) ;
if ( ret )
return ret ;
ret = nouveau_ramht_new ( dev , ramht , & dev_priv - > ramht ) ;
nouveau_gpuobj_ref ( NULL , & ramht ) ;
if ( ret )
return ret ;
2010-09-01 09:24:35 +04:00
/* And RAMRO */
ret = nouveau_gpuobj_new_fake ( dev , 0x11200 , ~ 0 , 512 ,
NVOBJ_FLAG_ZERO_ALLOC , & dev_priv - > ramro ) ;
if ( ret )
return ret ;
/* And RAMFC */
length = dev_priv - > engine . fifo . channels * nouveau_fifo_ctx_size ( dev ) ;
switch ( dev_priv - > card_type ) {
case NV_40 :
offset = 0x20000 ;
break ;
default :
offset = 0x11400 ;
break ;
}
ret = nouveau_gpuobj_new_fake ( dev , offset , ~ 0 , length ,
NVOBJ_FLAG_ZERO_ALLOC , & dev_priv - > ramfc ) ;
if ( ret )
return ret ;
/* Only allow space after RAMFC to be used for object allocation */
offset + = length ;
2009-12-11 12:24:15 +03:00
/* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
* on certain NV4x chipsets as well as RAMFC . When 0x2230 = = 0
* ( " new style " control ) the upper 16 - bits of 0x2220 points at this
* other mysterious table that ' s clobbering important things .
*
* We ' re now pointing this at RAMIN + 0x30000 to avoid RAMFC getting
* smashed to pieces on us , so reserve 0x30000 - 0x40000 too . .
*/
if ( dev_priv - > card_type > = NV_40 ) {
if ( offset < 0x40000 )
offset = 0x40000 ;
}
2010-06-01 09:32:24 +04:00
ret = drm_mm_init ( & dev_priv - > ramin_heap , offset ,
dev_priv - > ramin_rsvd_vram - offset ) ;
2009-12-11 12:24:15 +03:00
if ( ret ) {
2010-06-01 09:32:24 +04:00
NV_ERROR ( dev , " Failed to init RAMIN heap: %d \n " , ret ) ;
return ret ;
2009-12-11 12:24:15 +03:00
}
2010-06-01 09:32:24 +04:00
return 0 ;
2009-12-11 12:24:15 +03:00
}
void
nv04_instmem_takedown ( struct drm_device * dev )
{
2010-09-01 09:24:35 +04:00
struct drm_nouveau_private * dev_priv = dev - > dev_private ;
nouveau_ramht_ref ( NULL , & dev_priv - > ramht , NULL ) ;
nouveau_gpuobj_ref ( NULL , & dev_priv - > ramro ) ;
nouveau_gpuobj_ref ( NULL , & dev_priv - > ramfc ) ;
2009-12-11 12:24:15 +03:00
}
int
2010-11-01 04:45:02 +03:00
nv04_instmem_suspend ( struct drm_device * dev )
2009-12-11 12:24:15 +03:00
{
return 0 ;
}
void
2010-11-01 04:45:02 +03:00
nv04_instmem_resume ( struct drm_device * dev )
2009-12-11 12:24:15 +03:00
{
}
int
2010-11-01 04:45:02 +03:00
nv04_instmem_get ( struct nouveau_gpuobj * gpuobj , u32 size , u32 align )
2009-12-11 12:24:15 +03:00
{
2010-11-01 04:45:02 +03:00
struct drm_nouveau_private * dev_priv = gpuobj - > dev - > dev_private ;
struct drm_mm_node * ramin = NULL ;
do {
if ( drm_mm_pre_get ( & dev_priv - > ramin_heap ) )
return - ENOMEM ;
spin_lock ( & dev_priv - > ramin_lock ) ;
ramin = drm_mm_search_free ( & dev_priv - > ramin_heap , size , align , 0 ) ;
if ( ramin = = NULL ) {
spin_unlock ( & dev_priv - > ramin_lock ) ;
return - ENOMEM ;
}
ramin = drm_mm_get_block_atomic ( ramin , size , align ) ;
spin_unlock ( & dev_priv - > ramin_lock ) ;
} while ( ramin = = NULL ) ;
gpuobj - > node = ramin ;
gpuobj - > vinst = ramin - > start ;
2009-12-11 12:24:15 +03:00
return 0 ;
}
void
2010-11-01 04:45:02 +03:00
nv04_instmem_put ( struct nouveau_gpuobj * gpuobj )
2009-12-11 12:24:15 +03:00
{
2010-11-01 04:45:02 +03:00
struct drm_nouveau_private * dev_priv = gpuobj - > dev - > dev_private ;
spin_lock ( & dev_priv - > ramin_lock ) ;
drm_mm_put_block ( gpuobj - > node ) ;
gpuobj - > node = NULL ;
spin_unlock ( & dev_priv - > ramin_lock ) ;
2009-12-11 12:24:15 +03:00
}
int
2010-11-01 04:45:02 +03:00
nv04_instmem_map ( struct nouveau_gpuobj * gpuobj )
2009-12-11 12:24:15 +03:00
{
2010-11-01 04:45:02 +03:00
gpuobj - > pinst = gpuobj - > vinst ;
2009-12-11 12:24:15 +03:00
return 0 ;
}
void
2010-11-01 04:45:02 +03:00
nv04_instmem_unmap ( struct nouveau_gpuobj * gpuobj )
2009-12-11 12:24:15 +03:00
{
}
2010-11-01 04:45:02 +03:00
void
nv04_instmem_flush ( struct drm_device * dev )
{
}