Commit 6de12538 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/fifo: expose runlist topology info on all chipsets



Previously only available from Kepler onwards.

- also fixes the info() queries causing fifo init()/fini() unnecessarily

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent d94470e9
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
	struct nouveau_abi16_chan *chan;
	struct nvif_device *device;
	u64 engine;
	u64 engine, runm;
	int ret;

	if (unlikely(!abi16))
@@ -263,6 +263,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
		return nouveau_abi16_put(abi16, -ENODEV);

	device = &abi16->device;
	engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;

	/* hack to allow channel engine type specification on kepler */
	if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
@@ -276,19 +277,18 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
			default:
				return nouveau_abi16_put(abi16, -ENOSYS);
			}
		} else {
			engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;

			init->fb_ctxdma_handle = 0;
			init->tt_ctxdma_handle = 0;
		}
	}

	if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_CE)
			engine = nvif_fifo_runlist(device, engine);
		runm = nvif_fifo_runlist(device, engine);
	else
			engine = nvif_fifo_runlist_ce(device);
		init->fb_ctxdma_handle = engine;
		init->tt_ctxdma_handle = 0;
	}
		runm = nvif_fifo_runlist_ce(device);

	if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
	if (!runm || init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
		return nouveau_abi16_put(abi16, -EINVAL);

	/* allocate "abi16 channel" data and make up a handle for it */
@@ -300,8 +300,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
	list_add(&chan->head, &abi16->channels);

	/* create channel object and initialise dma and fence management */
	ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle,
				  init->tt_ctxdma_handle, false, &chan->chan);
	ret = nouveau_channel_new(drm, device, false, runm, init->fb_ctxdma_handle,
				  init->tt_ctxdma_handle, &chan->chan);
	if (ret)
		goto done;

+3 −4
Original line number Diff line number Diff line
@@ -513,14 +513,13 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)

int
nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
		    u32 arg0, u32 arg1, bool priv,
		    struct nouveau_channel **pchan)
		    bool priv, u64 runm, u32 vram, u32 gart, struct nouveau_channel **pchan)
{
	struct nouveau_cli *cli = (void *)device->object.client;
	int ret;

	/* hack until fencenv50 is fixed, and agp access relaxed */
	ret = nouveau_channel_ind(drm, device, arg0, priv, pchan);
	ret = nouveau_channel_ind(drm, device, runm, priv, pchan);
	if (ret) {
		NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
		ret = nouveau_channel_dma(drm, device, pchan);
@@ -530,7 +529,7 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
		}
	}

	ret = nouveau_channel_init(*pchan, arg0, arg1);
	ret = nouveau_channel_init(*pchan, vram, gart);
	if (ret) {
		NV_PRINTK(err, cli, "channel failed to initialise, %d\n", ret);
		nouveau_channel_del(pchan);
+2 −3
Original line number Diff line number Diff line
@@ -56,9 +56,8 @@ struct nouveau_channel {

int nouveau_channels_init(struct nouveau_drm *);

int  nouveau_channel_new(struct nouveau_drm *, struct nvif_device *,
			 u32 arg0, u32 arg1, bool priv,
			 struct nouveau_channel **);
int  nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, bool priv, u64 runm,
			 u32 vram, u32 gart, struct nouveau_channel **);
void nouveau_channel_del(struct nouveau_channel **);
int  nouveau_channel_idle(struct nouveau_channel *);

+12 −24
Original line number Diff line number Diff line
@@ -316,28 +316,19 @@ static void
nouveau_accel_ce_init(struct nouveau_drm *drm)
{
	struct nvif_device *device = &drm->client.device;
	u64 runm;
	int ret = 0;

	/* Allocate channel that has access to a (preferably async) copy
	 * engine, to use for TTM buffer moves.
	 */
	if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
		ret = nouveau_channel_new(drm, device,
					  nvif_fifo_runlist_ce(device), 0,
					  true, &drm->cechan);
	} else
	if (device->info.chipset >= 0xa3 &&
	    device->info.chipset != 0xaa &&
	    device->info.chipset != 0xac) {
		/* Prior to Kepler, there's only a single runlist, so all
		 * engines can be accessed from any channel.
		 *
		 * We still want to use a separate channel though.
		 */
		ret = nouveau_channel_new(drm, device, NvDmaFB, NvDmaTT, false,
					  &drm->cechan);
	runm = nvif_fifo_runlist_ce(device);
	if (!runm) {
		NV_DEBUG(drm, "no ce runlist\n");
		return;
	}

	ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->cechan);
	if (ret)
		NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
}
@@ -355,23 +346,20 @@ static void
nouveau_accel_gr_init(struct nouveau_drm *drm)
{
	struct nvif_device *device = &drm->client.device;
	u32 arg0, arg1;
	u64 runm;
	int ret;

	if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE)
		return;

	/* Allocate channel that has access to the graphics engine. */
	if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
		arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
		arg1 = 1;
	} else {
		arg0 = NvDmaFB;
		arg1 = NvDmaTT;
	runm = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
	if (!runm) {
		NV_DEBUG(drm, "no gr runlist\n");
		return;
	}

	ret = nouveau_channel_new(drm, device, arg0, arg1, false,
				  &drm->channel);
	ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->channel);
	if (ret) {
		NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
		nouveau_accel_gr_fini(drm);
+4 −8
Original line number Diff line number Diff line
@@ -80,14 +80,10 @@ static int
nvkm_engine_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data)
{
	struct nvkm_engine *engine = nvkm_engine(subdev);
	if (engine->func->info) {
		if (!IS_ERR((engine = nvkm_engine_ref(engine)))) {
			int ret = engine->func->info(engine, mthd, data);
			nvkm_engine_unref(&engine);
			return ret;
		}
		return PTR_ERR(engine);
	}

	if (engine->func->info)
		return engine->func->info(engine, mthd, data);

	return -ENOSYS;
}

Loading