diff options
Diffstat (limited to 'shared-core/nouveau_state.c')
| -rw-r--r-- | shared-core/nouveau_state.c | 225 | 
1 files changed, 177 insertions, 48 deletions
| diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index ed45c166..e7930b9e 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -26,22 +26,12 @@  #include "drm.h"  #include "drm_sarea.h"  #include "nouveau_drv.h" +#include "nouveau_drm.h" -/* here a client dies, release the stuff that was allocated for its filp */ -void nouveau_preclose(drm_device_t * dev, DRMFILE filp) +static int nouveau_init_card_mappings(drm_device_t *dev)  {  	drm_nouveau_private_t *dev_priv = dev->dev_private; - -	nouveau_mem_release(filp,dev_priv->fb_heap); -	nouveau_mem_release(filp,dev_priv->agp_heap); -	nouveau_fifo_cleanup(dev, filp); -} - -/* first module load, setup the mmio/fb mapping */ -int nouveau_firstopen(struct drm_device *dev) -{  	int ret; -	drm_nouveau_private_t *dev_priv = dev->dev_private;  	/* resource 0 is mmio regs */  	/* resource 1 is linear FB */ @@ -49,19 +39,16 @@ int nouveau_firstopen(struct drm_device *dev)  	/* resource 6 is bios */  	/* map the mmio regs */ -	ret = drm_addmap(dev, drm_get_resource_start(dev, 0), drm_get_resource_len(dev, 0),  -			_DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); -	if (dev_priv->mmio) -	{ -		DRM_INFO("regs mapped ok at 0x%lx\n",dev_priv->mmio->offset); -	} -	else -	{ -		DRM_ERROR("Unable to initialize the mmio mapping. Please report your setup to " DRIVER_EMAIL "\n"); -		return 1;  +	ret = drm_addmap(dev, drm_get_resource_start(dev, 0), +			      drm_get_resource_len(dev, 0),  +			      _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); +	if (ret) { +		DRM_ERROR("Unable to initialize the mmio mapping (%d). " +			  "Please report your setup to " DRIVER_EMAIL "\n", +			  ret); +		return 1;  	} - -	DRM_INFO("%lld MB of video ram detected\n",nouveau_mem_fb_amount(dev)>>20); +	DRM_DEBUG("regs mapped ok at 0x%lx\n", dev_priv->mmio->offset);  	/* map larger RAMIN aperture on NV40 cards */  	if (dev_priv->card_type >= NV_40) { @@ -69,11 +56,11 @@ int nouveau_firstopen(struct drm_device *dev)  		if (drm_get_resource_len(dev, ramin_resource) == 0)  			ramin_resource = 3; -		ret = drm_addmap(dev, drm_get_resource_start(dev, ramin_resource), -				      drm_get_resource_len(dev, ramin_resource), -				      _DRM_REGISTERS, -				      _DRM_READ_ONLY, -				      &dev_priv->ramin); +		ret = drm_addmap(dev, +				 drm_get_resource_start(dev, ramin_resource), +				 drm_get_resource_len(dev, ramin_resource), +				 _DRM_REGISTERS, _DRM_READ_ONLY, +				 &dev_priv->ramin);  		if (ret) {  			DRM_ERROR("Failed to init RAMIN mapping, "  				  "limited instance memory available\n"); @@ -82,33 +69,165 @@ int nouveau_firstopen(struct drm_device *dev)  	} else  		dev_priv->ramin = NULL; +	return 0; +} + +static void nouveau_stub_takedown(drm_device_t *dev) {} +static int nouveau_init_engine_ptrs(drm_device_t *dev) +{ +	drm_nouveau_private_t *dev_priv = dev->dev_private; +	struct nouveau_engine_func *engine = &dev_priv->Engine; + +	switch (dev_priv->chipset & 0xf0) { +	case 0x00: +		engine->Mc.Init		= nv04_mc_init; +		engine->Mc.Takedown	= nv04_mc_takedown; +		engine->Timer.Init	= nv04_timer_init; +		engine->Timer.Takedown	= nv04_timer_takedown; +		engine->Fb.Init		= nv04_fb_init; +		engine->Fb.Takedown	= nv04_fb_takedown; +		engine->Graph.Init	= nv04_graph_init; +		engine->Graph.Takedown	= nv04_graph_takedown; +		engine->Fifo.Init	= nouveau_fifo_init; +		engine->Fifo.Takedown	= nouveau_stub_takedown; +		break; +	case 0x10: +		engine->Mc.Init		= nv04_mc_init; +		engine->Mc.Takedown	= nv04_mc_takedown; +		engine->Timer.Init	= nv04_timer_init; +		engine->Timer.Takedown	= nv04_timer_takedown; +		engine->Fb.Init		= nv10_fb_init; +		engine->Fb.Takedown	= nv10_fb_takedown; +		engine->Graph.Init	= nv10_graph_init; +		engine->Graph.Takedown	= nv10_graph_takedown; +		engine->Fifo.Init	= nouveau_fifo_init; +		engine->Fifo.Takedown	= nouveau_stub_takedown; +		break; +	case 0x20: +		engine->Mc.Init		= nv04_mc_init; +		engine->Mc.Takedown	= nv04_mc_takedown; +		engine->Timer.Init	= nv04_timer_init; +		engine->Timer.Takedown	= nv04_timer_takedown; +		engine->Fb.Init		= nv10_fb_init; +		engine->Fb.Takedown	= nv10_fb_takedown; +		engine->Graph.Init	= nv20_graph_init; +		engine->Graph.Takedown	= nv20_graph_takedown; +		engine->Fifo.Init	= nouveau_fifo_init; +		engine->Fifo.Takedown	= nouveau_stub_takedown; +		break; +	case 0x30: +		engine->Mc.Init		= nv04_mc_init; +		engine->Mc.Takedown	= nv04_mc_takedown; +		engine->Timer.Init	= nv04_timer_init; +		engine->Timer.Takedown	= nv04_timer_takedown; +		engine->Fb.Init		= nv10_fb_init; +		engine->Fb.Takedown	= nv10_fb_takedown; +		engine->Graph.Init	= nv30_graph_init; +		engine->Graph.Takedown	= nv30_graph_takedown; +		engine->Fifo.Init	= nouveau_fifo_init; +		engine->Fifo.Takedown	= nouveau_stub_takedown; +		break; +	case 0x40: +		engine->Mc.Init		= nv40_mc_init; +		engine->Mc.Takedown	= nv40_mc_takedown; +		engine->Timer.Init	= nv04_timer_init; +		engine->Timer.Takedown	= nv04_timer_takedown; +		engine->Fb.Init		= nv40_fb_init; +		engine->Fb.Takedown	= nv40_fb_takedown; +		engine->Graph.Init	= nv40_graph_init; +		engine->Graph.Takedown	= nv40_graph_takedown; +		engine->Fifo.Init	= nouveau_fifo_init; +		engine->Fifo.Takedown	= nouveau_stub_takedown; +		break; +	case 0x50: +	default: +		DRM_ERROR("NV%02x unsupported\n", dev_priv->chipset); +		return 1; +	} + +	return 0; +} + +static int nouveau_card_init(drm_device_t *dev) +{ +	drm_nouveau_private_t *dev_priv = dev->dev_private; +	struct nouveau_engine_func *engine; +	int ret; + +	/* Map any PCI resources we need on the card */ +	ret = nouveau_init_card_mappings(dev); +	if (ret) return ret; +  	/* Determine exact chipset we're running on */  	if (dev_priv->card_type < NV_10)  		dev_priv->chipset = dev_priv->card_type;  	else -		dev_priv->chipset =(NV_READ(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20; +		dev_priv->chipset = +			(NV_READ(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20; -	/* Clear RAMIN -	 * Determine locations for RAMHT/FC/RO -	 * Initialise PFIFO +	/* Initialise internal driver API hooks */ +	ret = nouveau_init_engine_ptrs(dev); +	if (ret) return ret; +	engine = &dev_priv->Engine; + +	/* Initialise instance memory, must happen before mem_init so we +	 * know exactly how much VRAM we're able to use for "normal" +	 * purposes.  	 */ -	ret = nouveau_fifo_init(dev); +	ret = nouveau_instmem_init(dev); +	if (ret) return ret; + +	/* Setup the memory manager */ +	ret = nouveau_mem_init(dev); +	if (ret) return ret; + +	/* Parse BIOS tables / Run init tables? */ + +	/* PMC */ +	ret = engine->Mc.Init(dev); +	if (ret) return ret; + +	/* PTIMER */ +	ret = engine->Timer.Init(dev); +	if (ret) return ret; + +	/* PFB */ +	ret = engine->Fb.Init(dev); +	if (ret) return ret; + +	/* PGRAPH */ +	ret = engine->Graph.Init(dev); +	if (ret) return ret; + +	/* PFIFO */ +	ret = engine->Fifo.Init(dev);  	if (ret) return ret; -	/* setup a mtrr over the FB */ -	dev_priv->fb_mtrr=drm_mtrr_add(drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC); - -	/* FIXME: doesn't belong here, and have no idea what it's for.. */ -	if (dev_priv->card_type >= NV_40) -		nv40_graph_init(dev); -	else if (dev_priv->card_type >= NV_30) -		nv30_graph_init(dev); -	else if (dev_priv->card_type >= NV_20) -		nv20_graph_init(dev); -	else if (dev_priv->card_type >= NV_10) -		nv10_graph_init(dev); -	else if (dev_priv->card_type >= NV_04) -		nv04_graph_init(dev); +	/* what about PVIDEO/PCRTC/PRAMDAC etc? */ + +	return 0; +} + +/* here a client dies, release the stuff that was allocated for its filp */ +void nouveau_preclose(drm_device_t * dev, DRMFILE filp) +{ +	drm_nouveau_private_t *dev_priv = dev->dev_private; + +	nouveau_mem_release(filp,dev_priv->fb_heap); +	nouveau_mem_release(filp,dev_priv->agp_heap); +	nouveau_fifo_cleanup(dev, filp); +} + +/* first module load, setup the mmio/fb mapping */ +int nouveau_firstopen(struct drm_device *dev) +{ +	int ret; + +	ret = nouveau_card_init(dev); +	if (ret) { +		DRM_ERROR("nouveau_card_init() failed! (%d)\n", ret); +		return ret; +	}  	return 0;  } @@ -116,6 +235,7 @@ int nouveau_firstopen(struct drm_device *dev)  int nouveau_load(struct drm_device *dev, unsigned long flags)  {  	drm_nouveau_private_t *dev_priv; +	int ret;  	if (flags==NV_UNKNOWN)  		return DRM_ERR(EINVAL); @@ -130,6 +250,14 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)  	dev->dev_private = (void *)dev_priv; +#if 0 +	ret = nouveau_card_init(dev); +	if (ret) { +		DRM_ERROR("nouveau_card_init() failed! (%d)\n", ret); +		return ret; +	} +#endif +  	return 0;  } @@ -244,3 +372,4 @@ void nouveau_wait_for_idle(struct drm_device *dev)  	}  } + | 
