2009-12-11 12:24:15 +03:00
# include "drmP.h"
# include "drm.h"
# include "nouveau_drv.h"
/* 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 ;
}
static void
nv04_instmem_determine_amount ( struct drm_device * dev )
{
struct drm_nouveau_private * dev_priv = dev - > dev_private ;
int i ;
/* Figure out how much instance memory we need */
if ( dev_priv - > card_type > = NV_40 ) {
/* We'll want more instance memory than this on some NV4x cards.
* There ' s a 16 MB aperture to play with that maps onto the end
* of vram . For now , only reserve a small piece until we know
* more about what each chipset requires .
*/
2010-01-15 05:21:37 +03:00
switch ( dev_priv - > chipset ) {
2009-12-11 12:24:15 +03:00
case 0x40 :
case 0x47 :
case 0x49 :
case 0x4b :
dev_priv - > ramin_rsvd_vram = ( 2 * 1024 * 1024 ) ;
break ;
default :
dev_priv - > ramin_rsvd_vram = ( 1 * 1024 * 1024 ) ;
break ;
}
} else {
/*XXX: what *are* the limits on <NV40 cards?
*/
dev_priv - > ramin_rsvd_vram = ( 512 * 1024 ) ;
}
NV_DEBUG ( dev , " RAMIN size: %dKiB \n " , dev_priv - > ramin_rsvd_vram > > 10 ) ;
/* Clear all of it, except the BIOS image that's in the first 64KiB */
for ( i = 64 * 1024 ; i < dev_priv - > ramin_rsvd_vram ; i + = 4 )
nv_wi32 ( dev , i , 0x00000000 ) ;
}
static void
nv04_instmem_configure_fixed_tables ( struct drm_device * dev )
{
struct drm_nouveau_private * dev_priv = dev - > dev_private ;
struct nouveau_engine * engine = & dev_priv - > engine ;
/* FIFO hash table (RAMHT)
* use 4 k hash table at RAMIN + 0x10000
* TODO : extend the hash table
*/
dev_priv - > ramht_offset = 0x10000 ;
dev_priv - > ramht_bits = 9 ;
dev_priv - > ramht_size = ( 1 < < dev_priv - > ramht_bits ) ; /* nr entries */
dev_priv - > ramht_size * = 8 ; /* 2 32-bit values per entry in RAMHT */
NV_DEBUG ( dev , " RAMHT offset=0x%x, size=%d \n " , dev_priv - > ramht_offset ,
dev_priv - > ramht_size ) ;
/* FIFO runout table (RAMRO) - 512k at 0x11200 */
dev_priv - > ramro_offset = 0x11200 ;
dev_priv - > ramro_size = 512 ;
NV_DEBUG ( dev , " RAMRO offset=0x%x, size=%d \n " , dev_priv - > ramro_offset ,
dev_priv - > ramro_size ) ;
/* FIFO context table (RAMFC)
* NV40 : Not sure exactly how to position RAMFC on some cards ,
* 0x30002 seems to position it at RAMIN + 0x20000 on these
* cards . RAMFC is 4 kb ( 32 fifos , 128 byte entries ) .
* Others : Position RAMFC at RAMIN + 0x11400
*/
dev_priv - > ramfc_size = engine - > fifo . channels *
nouveau_fifo_ctx_size ( dev ) ;
switch ( dev_priv - > card_type ) {
case NV_40 :
dev_priv - > ramfc_offset = 0x20000 ;
break ;
case NV_30 :
case NV_20 :
case NV_10 :
case NV_04 :
default :
dev_priv - > ramfc_offset = 0x11400 ;
break ;
}
NV_DEBUG ( dev , " RAMFC offset=0x%x, size=%d \n " , dev_priv - > ramfc_offset ,
dev_priv - > ramfc_size ) ;
}
int nv04_instmem_init ( struct drm_device * dev )
{
struct drm_nouveau_private * dev_priv = dev - > dev_private ;
uint32_t offset ;
2010-06-01 09:32:24 +04:00
int ret ;
2009-12-11 12:24:15 +03:00
nv04_instmem_determine_amount ( dev ) ;
nv04_instmem_configure_fixed_tables ( dev ) ;
/* Create a heap to manage RAMIN allocations, we don't allocate
* the space that was reserved for RAMHT / FC / RO .
*/
offset = dev_priv - > ramfc_offset + dev_priv - > ramfc_size ;
/* 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 )
{
}
int
nv04_instmem_populate ( struct drm_device * dev , struct nouveau_gpuobj * gpuobj , uint32_t * sz )
{
if ( gpuobj - > im_backing )
return - EINVAL ;
return 0 ;
}
void
nv04_instmem_clear ( struct drm_device * dev , struct nouveau_gpuobj * gpuobj )
{
struct drm_nouveau_private * dev_priv = dev - > dev_private ;
if ( gpuobj & & gpuobj - > im_backing ) {
if ( gpuobj - > im_bound )
dev_priv - > engine . instmem . unbind ( dev , gpuobj ) ;
gpuobj - > im_backing = NULL ;
}
}
int
nv04_instmem_bind ( struct drm_device * dev , struct nouveau_gpuobj * gpuobj )
{
if ( ! gpuobj - > im_pramin | | gpuobj - > im_bound )
return - EINVAL ;
gpuobj - > im_bound = 1 ;
return 0 ;
}
int
nv04_instmem_unbind ( struct drm_device * dev , struct nouveau_gpuobj * gpuobj )
{
if ( gpuobj - > im_bound = = 0 )
return - EINVAL ;
gpuobj - > im_bound = 0 ;
return 0 ;
}
void
2010-07-08 05:29:10 +04:00
nv04_instmem_flush ( struct drm_device * dev )
2009-12-11 12:24:15 +03:00
{
}
int
nv04_instmem_suspend ( struct drm_device * dev )
{
return 0 ;
}
void
nv04_instmem_resume ( struct drm_device * dev )
{
}