/*
 * Copyright 2012 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Ben Skeggs
 */
#include "channv50.h"

#include <core/client.h>
#include <core/ramht.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>

#include <nvif/cl826e.h>

static int
g84_fifo_chan_ntfy(struct nvkm_fifo_chan *chan, u32 type,
		   struct nvkm_event **pevent)
{
	switch (type) {
	case NV826E_V0_NTFY_NON_STALL_INTERRUPT:
		*pevent = &chan->fifo->uevent;
		return 0;
	default:
		break;
	}
	return -EINVAL;
}

static int
g84_fifo_chan_engine_addr(struct nvkm_engine *engine)
{
	switch (engine->subdev.type) {
	case NVKM_ENGINE_DMAOBJ:
	case NVKM_ENGINE_SW    : return -1;
	case NVKM_ENGINE_GR    : return 0x0020;
	case NVKM_ENGINE_VP    :
	case NVKM_ENGINE_MSPDEC: return 0x0040;
	case NVKM_ENGINE_MPEG  :
	case NVKM_ENGINE_MSPPP : return 0x0060;
	case NVKM_ENGINE_BSP   :
	case NVKM_ENGINE_MSVLD : return 0x0080;
	case NVKM_ENGINE_CIPHER:
	case NVKM_ENGINE_SEC   : return 0x00a0;
	case NVKM_ENGINE_CE    : return 0x00c0;
	default:
		WARN_ON(1);
		return -1;
	}
}

static int
g84_fifo_chan_engine_fini(struct nvkm_fifo_chan *base,
			  struct nvkm_engine *engine, bool suspend)
{
	struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
	struct nv50_fifo *fifo = chan->fifo;
	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	u32 engn, save;
	int offset;
	bool done;

	offset = g84_fifo_chan_engine_addr(engine);
	if (offset < 0)
		return 0;

	engn = fifo->base.func->engine_id(&fifo->base, engine) - 1;
	save = nvkm_mask(device, 0x002520, 0x0000003f, 1 << engn);
	nvkm_wr32(device, 0x0032fc, chan->base.inst->addr >> 12);
	done = nvkm_msec(device, 2000,
		if (nvkm_rd32(device, 0x0032fc) != 0xffffffff)
			break;
	) >= 0;
	nvkm_wr32(device, 0x002520, save);
	if (!done) {
		nvkm_error(subdev, "channel %d [%s] unload timeout\n",
			   chan->base.chid, chan->base.object.client->name);
		if (suspend)
			return -EBUSY;
	}

	nvkm_kmap(chan->eng);
	nvkm_wo32(chan->eng, offset + 0x00, 0x00000000);
	nvkm_wo32(chan->eng, offset + 0x04, 0x00000000);
	nvkm_wo32(chan->eng, offset + 0x08, 0x00000000);
	nvkm_wo32(chan->eng, offset + 0x0c, 0x00000000);
	nvkm_wo32(chan->eng, offset + 0x10, 0x00000000);
	nvkm_wo32(chan->eng, offset + 0x14, 0x00000000);
	nvkm_done(chan->eng);
	return 0;
}


static int
g84_fifo_chan_engine_init(struct nvkm_fifo_chan *base,
			  struct nvkm_engine *engine)
{
	struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
	struct nvkm_gpuobj *engn = *nv50_fifo_chan_engine(chan, engine);
	u64 limit, start;
	int offset;

	offset = g84_fifo_chan_engine_addr(engine);
	if (offset < 0)
		return 0;
	limit = engn->addr + engn->size - 1;
	start = engn->addr;

	nvkm_kmap(chan->eng);
	nvkm_wo32(chan->eng, offset + 0x00, 0x00190000);
	nvkm_wo32(chan->eng, offset + 0x04, lower_32_bits(limit));
	nvkm_wo32(chan->eng, offset + 0x08, lower_32_bits(start));
	nvkm_wo32(chan->eng, offset + 0x0c, upper_32_bits(limit) << 24 |
					    upper_32_bits(start));
	nvkm_wo32(chan->eng, offset + 0x10, 0x00000000);
	nvkm_wo32(chan->eng, offset + 0x14, 0x00000000);
	nvkm_done(chan->eng);
	return 0;
}

static int
g84_fifo_chan_engine_ctor(struct nvkm_fifo_chan *base,
			  struct nvkm_engine *engine,
			  struct nvkm_object *object)
{
	struct nv50_fifo_chan *chan = nv50_fifo_chan(base);

	if (g84_fifo_chan_engine_addr(engine) < 0)
		return 0;

	return nvkm_object_bind(object, NULL, 0, nv50_fifo_chan_engine(chan, engine));
}

static int
g84_fifo_chan_object_ctor(struct nvkm_fifo_chan *base,
			  struct nvkm_object *object)
{
	struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
	u32 handle = object->handle;
	u32 context;

	switch (object->engine->subdev.type) {
	case NVKM_ENGINE_DMAOBJ:
	case NVKM_ENGINE_SW    : context = 0x00000000; break;
	case NVKM_ENGINE_GR    : context = 0x00100000; break;
	case NVKM_ENGINE_MPEG  :
	case NVKM_ENGINE_MSPPP : context = 0x00200000; break;
	case NVKM_ENGINE_ME    :
	case NVKM_ENGINE_CE    : context = 0x00300000; break;
	case NVKM_ENGINE_VP    :
	case NVKM_ENGINE_MSPDEC: context = 0x00400000; break;
	case NVKM_ENGINE_CIPHER:
	case NVKM_ENGINE_SEC   :
	case NVKM_ENGINE_VIC   : context = 0x00500000; break;
	case NVKM_ENGINE_BSP   :
	case NVKM_ENGINE_MSVLD : context = 0x00600000; break;
	default:
		WARN_ON(1);
		return -EINVAL;
	}

	return nvkm_ramht_insert(chan->ramht, object, 0, 4, handle, context);
}

static void
g84_fifo_chan_init(struct nvkm_fifo_chan *base)
{
	struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
	struct nv50_fifo *fifo = chan->fifo;
	struct nvkm_device *device = fifo->base.engine.subdev.device;
	u64 addr = chan->ramfc->addr >> 8;
	u32 chid = chan->base.chid;

	nvkm_wr32(device, 0x002600 + (chid * 4), 0x80000000 | addr);
	nv50_fifo_runlist_update(fifo);
}

static const struct nvkm_fifo_chan_func
g84_fifo_chan_func = {
	.dtor = nv50_fifo_chan_dtor,
	.init = g84_fifo_chan_init,
	.fini = nv50_fifo_chan_fini,
	.ntfy = g84_fifo_chan_ntfy,
	.engine_ctor = g84_fifo_chan_engine_ctor,
	.engine_dtor = nv50_fifo_chan_engine_dtor,
	.engine_init = g84_fifo_chan_engine_init,
	.engine_fini = g84_fifo_chan_engine_fini,
	.object_ctor = g84_fifo_chan_object_ctor,
	.object_dtor = nv50_fifo_chan_object_dtor,
};

int
g84_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vmm, u64 push,
		   const struct nvkm_oclass *oclass,
		   struct nv50_fifo_chan *chan)
{
	struct nvkm_device *device = fifo->base.engine.subdev.device;
	int ret;

	if (!vmm)
		return -EINVAL;

	ret = nvkm_fifo_chan_ctor(&g84_fifo_chan_func, &fifo->base,
				  0x10000, 0x1000, false, vmm, push,
				  BIT(G84_FIFO_ENGN_SW) |
				  BIT(G84_FIFO_ENGN_GR) |
				  BIT(G84_FIFO_ENGN_MPEG) |
				  BIT(G84_FIFO_ENGN_MSPPP) |
				  BIT(G84_FIFO_ENGN_ME) |
				  BIT(G84_FIFO_ENGN_CE0) |
				  BIT(G84_FIFO_ENGN_VP) |
				  BIT(G84_FIFO_ENGN_MSPDEC) |
				  BIT(G84_FIFO_ENGN_CIPHER) |
				  BIT(G84_FIFO_ENGN_SEC) |
				  BIT(G84_FIFO_ENGN_VIC) |
				  BIT(G84_FIFO_ENGN_BSP) |
				  BIT(G84_FIFO_ENGN_MSVLD) |
				  BIT(G84_FIFO_ENGN_DMA),
				  0, 0xc00000, 0x2000, oclass, &chan->base);
	chan->fifo = fifo;
	if (ret)
		return ret;

	ret = nvkm_gpuobj_new(device, 0x0200, 0, true, chan->base.inst,
			      &chan->eng);
	if (ret)
		return ret;

	ret = nvkm_gpuobj_new(device, 0x4000, 0, false, chan->base.inst,
			      &chan->pgd);
	if (ret)
		return ret;

	ret = nvkm_gpuobj_new(device, 0x1000, 0x400, true, chan->base.inst,
			      &chan->cache);
	if (ret)
		return ret;

	ret = nvkm_gpuobj_new(device, 0x100, 0x100, true, chan->base.inst,
			      &chan->ramfc);
	if (ret)
		return ret;

	return nvkm_ramht_new(device, 0x8000, 16, chan->base.inst, &chan->ramht);
}
