diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_object.c')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 118 | 
1 files changed, 16 insertions, 102 deletions
| diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 67a16e01ffa6..8f97016f5b26 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -361,20 +361,6 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst,  	return 0;  } - -static uint32_t -nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class) -{ -	struct drm_nouveau_private *dev_priv = dev->dev_private; - -	/*XXX: dodgy hack for now */ -	if (dev_priv->card_type >= NV_50) -		return 24; -	if (dev_priv->card_type >= NV_40) -		return 32; -	return 16; -} -  /*     DMA objects are used to reference a piece of memory in the     framebuffer, PCI or AGP address space. Each object is 16 bytes big @@ -606,11 +592,11 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base,     set to 0?  */  static int -nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, -		      struct nouveau_gpuobj **gpuobj_ret) +nouveau_gpuobj_sw_new(struct nouveau_channel *chan, u32 handle, u16 class)  {  	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;  	struct nouveau_gpuobj *gpuobj; +	int ret;  	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);  	if (!gpuobj) @@ -624,8 +610,10 @@ nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,  	spin_lock(&dev_priv->ramin_lock);  	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);  	spin_unlock(&dev_priv->ramin_lock); -	*gpuobj_ret = gpuobj; -	return 0; + +	ret = nouveau_ramht_insert(chan, handle, gpuobj); +	nouveau_gpuobj_ref(NULL, &gpuobj); +	return ret;  }  int @@ -634,101 +622,30 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class)  	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;  	struct drm_device *dev = chan->dev;  	struct nouveau_gpuobj_class *oc; -	struct nouveau_gpuobj *gpuobj;  	int ret;  	NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);  	list_for_each_entry(oc, &dev_priv->classes, head) { -		if (oc->id == class) -			goto found; -	} - -	NV_ERROR(dev, "illegal object class: 0x%x\n", class); -	return -EINVAL; +		struct nouveau_exec_engine *eng = dev_priv->eng[oc->engine]; -found: -	switch (oc->engine) { -	case NVOBJ_ENGINE_SW: -		if (dev_priv->card_type < NV_C0) { -			ret = nouveau_gpuobj_sw_new(chan, class, &gpuobj); -			if (ret) -				return ret; -			goto insert; -		} -		break; -	case NVOBJ_ENGINE_GR: -		if ((dev_priv->card_type >= NV_20 && !chan->ramin_grctx) || -		    (dev_priv->card_type  < NV_20 && !chan->pgraph_ctx)) { -			struct nouveau_pgraph_engine *pgraph = -				&dev_priv->engine.graph; +		if (oc->id != class) +			continue; -			ret = pgraph->create_context(chan); -			if (ret) -				return ret; -		} -		break; -	case NVOBJ_ENGINE_CRYPT: -		if (!chan->crypt_ctx) { -			struct nouveau_crypt_engine *pcrypt = -				&dev_priv->engine.crypt; +		if (oc->engine == NVOBJ_ENGINE_SW) +			return nouveau_gpuobj_sw_new(chan, handle, class); -			ret = pcrypt->create_context(chan); +		if (!chan->engctx[oc->engine]) { +			ret = eng->context_new(chan, oc->engine);  			if (ret)  				return ret;  		} -		break; -	} - -	/* we're done if this is fermi */ -	if (dev_priv->card_type >= NV_C0) -		return 0; - -	ret = nouveau_gpuobj_new(dev, chan, -				 nouveau_gpuobj_class_instmem_size(dev, class), -				 16, -				 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, -				 &gpuobj); -	if (ret) { -		NV_ERROR(dev, "error creating gpuobj: %d\n", ret); -		return ret; -	} -	if (dev_priv->card_type >= NV_50) { -		nv_wo32(gpuobj,  0, class); -		nv_wo32(gpuobj, 20, 0x00010000); -	} else { -		switch (class) { -		case NV_CLASS_NULL: -			nv_wo32(gpuobj, 0, 0x00001030); -			nv_wo32(gpuobj, 4, 0xFFFFFFFF); -			break; -		default: -			if (dev_priv->card_type >= NV_40) { -				nv_wo32(gpuobj, 0, class); -#ifdef __BIG_ENDIAN -				nv_wo32(gpuobj, 8, 0x01000000); -#endif -			} else { -#ifdef __BIG_ENDIAN -				nv_wo32(gpuobj, 0, class | 0x00080000); -#else -				nv_wo32(gpuobj, 0, class); -#endif -			} -		} +		return eng->object_new(chan, oc->engine, handle, class);  	} -	dev_priv->engine.instmem.flush(dev); - -	gpuobj->engine = oc->engine; -	gpuobj->class  = oc->id; -insert: -	ret = nouveau_ramht_insert(chan, handle, gpuobj); -	if (ret) -		NV_ERROR(dev, "error adding gpuobj to RAMHT: %d\n", ret); -	nouveau_gpuobj_ref(NULL, &gpuobj); -	return ret; +	NV_ERROR(dev, "illegal object class: 0x%x\n", class); +	return -EINVAL;  }  static int @@ -746,9 +663,6 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)  	size = 0x2000;  	base = 0; -	/* PGRAPH context */ -	size += dev_priv->engine.graph.grctx_size; -  	if (dev_priv->card_type == NV_50) {  		/* Various fixed table thingos */  		size += 0x1400; /* mostly unknown stuff */ |