/*
 * Copyright 2010 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 <linux/firmware.h>
#include <linux/module.h>

#include "drmP.h"

#include "nouveau_drv.h"
#include <core/mm.h>
#include <engine/fifo.h>

#include "nve0.h"

static void
nve0_graph_ctxctl_debug_unit(struct drm_device *dev, u32 base)
{
	NV_INFO(dev, "PGRAPH: %06x - done 0x%08x\n", base,
		nv_rd32(dev, base + 0x400));
	NV_INFO(dev, "PGRAPH: %06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
		nv_rd32(dev, base + 0x800), nv_rd32(dev, base + 0x804),
		nv_rd32(dev, base + 0x808), nv_rd32(dev, base + 0x80c));
	NV_INFO(dev, "PGRAPH: %06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
		nv_rd32(dev, base + 0x810), nv_rd32(dev, base + 0x814),
		nv_rd32(dev, base + 0x818), nv_rd32(dev, base + 0x81c));
}

static void
nve0_graph_ctxctl_debug(struct drm_device *dev)
{
	u32 gpcnr = nv_rd32(dev, 0x409604) & 0xffff;
	u32 gpc;

	nve0_graph_ctxctl_debug_unit(dev, 0x409000);
	for (gpc = 0; gpc < gpcnr; gpc++)
		nve0_graph_ctxctl_debug_unit(dev, 0x502000 + (gpc * 0x8000));
}

static int
nve0_graph_load_context(struct nouveau_channel *chan)
{
	struct drm_device *dev = chan->dev;

	nv_wr32(dev, 0x409840, 0x00000030);
	nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
	nv_wr32(dev, 0x409504, 0x00000003);
	if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
		NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");

	return 0;
}

static int
nve0_graph_unload_context_to(struct drm_device *dev, u64 chan)
{
	nv_wr32(dev, 0x409840, 0x00000003);
	nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12);
	nv_wr32(dev, 0x409504, 0x00000009);
	if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) {
		NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n");
		return -EBUSY;
	}

	return 0;
}

static int
nve0_graph_construct_context(struct nouveau_channel *chan)
{
	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
	struct nve0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
	struct nve0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
	struct drm_device *dev = chan->dev;
	int ret, i;
	u32 *ctx;

	ctx = kmalloc(priv->grctx_size, GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	nve0_graph_load_context(chan);

	nv_wo32(grch->grctx, 0x1c, 1);
	nv_wo32(grch->grctx, 0x20, 0);
	nv_wo32(grch->grctx, 0x28, 0);
	nv_wo32(grch->grctx, 0x2c, 0);
	dev_priv->engine.instmem.flush(dev);

	ret = nve0_grctx_generate(chan);
	if (ret)
		goto err;

	ret = nve0_graph_unload_context_to(dev, chan->ramin->vinst);
	if (ret)
		goto err;

	for (i = 0; i < priv->grctx_size; i += 4)
		ctx[i / 4] = nv_ro32(grch->grctx, i);

	priv->grctx_vals = ctx;
	return 0;

err:
	kfree(ctx);
	return ret;
}

static int
nve0_graph_create_context_mmio_list(struct nouveau_channel *chan)
{
	struct nve0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
	struct nve0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
	struct drm_device *dev = chan->dev;
	u32 magic[GPC_MAX][2];
	u16 offset = 0x0000;
	int gpc;
	int ret;

	ret = nouveau_gpuobj_new(dev, NULL, 0x3000, 256, 0, &grch->unk408004);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_map_vm(grch->unk408004, NV_MEM_ACCESS_RW |
				    NV_MEM_ACCESS_SYS, chan->vm,
				    &grch->unk408004_vma);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 256, 0, &grch->unk40800c);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_map_vm(grch->unk40800c, NV_MEM_ACCESS_RW |
				    NV_MEM_ACCESS_SYS, chan->vm,
				    &grch->unk40800c_vma);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_new(dev, NULL, 384 * 1024, 4096, 0,
				 &grch->unk418810);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_map_vm(grch->unk418810, NV_MEM_ACCESS_RW,
				    chan->vm, &grch->unk418810_vma);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0, 0, &grch->mmio);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_map_vm(grch->mmio, NV_MEM_ACCESS_RW |
				    NV_MEM_ACCESS_SYS, chan->vm,
				    &grch->mmio_vma);
	if (ret)
		return ret;

#define mmio(r,v) do {                                                         \
	nv_wo32(grch->mmio, (grch->mmio_nr * 8) + 0, (r));                     \
	nv_wo32(grch->mmio, (grch->mmio_nr * 8) + 4, (v));                     \
	grch->mmio_nr++;                                                       \
} while (0)
	mmio(0x40800c, grch->unk40800c_vma.offset >> 8);
	mmio(0x408010, 0x80000000);
	mmio(0x419004, grch->unk40800c_vma.offset >> 8);
	mmio(0x419008, 0x00000000);
	mmio(0x4064cc, 0x80000000);
	mmio(0x408004, grch->unk408004_vma.offset >> 8);
	mmio(0x408008, 0x80000030);
	mmio(0x418808, grch->unk408004_vma.offset >> 8);
	mmio(0x41880c, 0x80000030);
	mmio(0x4064c8, 0x01800600);
	mmio(0x418810, 0x80000000 | grch->unk418810_vma.offset >> 12);
	mmio(0x419848, 0x10000000 | grch->unk418810_vma.offset >> 12);
	mmio(0x405830, 0x02180648);
	mmio(0x4064c4, 0x0192ffff);

	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
		u16 magic0 = 0x0218 * priv->tpc_nr[gpc];
		u16 magic1 = 0x0648 * priv->tpc_nr[gpc];
		magic[gpc][0]  = 0x10000000 | (magic0 << 16) | offset;
		magic[gpc][1]  = 0x00000000 | (magic1 << 16);
		offset += 0x0324 * priv->tpc_nr[gpc];
	}

	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
		mmio(GPC_UNIT(gpc, 0x30c0), magic[gpc][0]);
		mmio(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset);
		offset += 0x07ff * priv->tpc_nr[gpc];
	}

	mmio(0x17e91c, 0x06060609);
	mmio(0x17e920, 0x00090a05);
#undef mmio
	return 0;
}

static int
nve0_graph_context_new(struct nouveau_channel *chan, int engine)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
	struct nve0_graph_priv *priv = nv_engine(dev, engine);
	struct nve0_graph_chan *grch;
	struct nouveau_gpuobj *grctx;
	int ret, i;

	grch = kzalloc(sizeof(*grch), GFP_KERNEL);
	if (!grch)
		return -ENOMEM;
	chan->engctx[NVOBJ_ENGINE_GR] = grch;

	ret = nouveau_gpuobj_new(dev, NULL, priv->grctx_size, 256, 0,
				 &grch->grctx);
	if (ret)
		goto error;

	ret = nouveau_gpuobj_map_vm(grch->grctx, NV_MEM_ACCESS_RW |
				    NV_MEM_ACCESS_SYS, chan->vm,
				    &grch->grctx_vma);
	if (ret)
		return ret;

	grctx = grch->grctx;

	ret = nve0_graph_create_context_mmio_list(chan);
	if (ret)
		goto error;

	nv_wo32(chan->ramin, 0x0210, lower_32_bits(grch->grctx_vma.offset) | 4);
	nv_wo32(chan->ramin, 0x0214, upper_32_bits(grch->grctx_vma.offset));
	pinstmem->flush(dev);

	if (!priv->grctx_vals) {
		ret = nve0_graph_construct_context(chan);
		if (ret)
			goto error;
	}

	for (i = 0; i < priv->grctx_size; i += 4)
		nv_wo32(grctx, i, priv->grctx_vals[i / 4]);
	nv_wo32(grctx, 0xf4, 0);
	nv_wo32(grctx, 0xf8, 0);
	nv_wo32(grctx, 0x10, grch->mmio_nr);
	nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio_vma.offset));
	nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio_vma.offset));
	nv_wo32(grctx, 0x1c, 1);
	nv_wo32(grctx, 0x20, 0);
	nv_wo32(grctx, 0x28, 0);
	nv_wo32(grctx, 0x2c, 0);

	pinstmem->flush(dev);
	return 0;

error:
	priv->base.context_del(chan, engine);
	return ret;
}

static void
nve0_graph_context_del(struct nouveau_channel *chan, int engine)
{
	struct nve0_graph_chan *grch = chan->engctx[engine];

	nouveau_gpuobj_unmap(&grch->mmio_vma);
	nouveau_gpuobj_unmap(&grch->unk418810_vma);
	nouveau_gpuobj_unmap(&grch->unk40800c_vma);
	nouveau_gpuobj_unmap(&grch->unk408004_vma);
	nouveau_gpuobj_unmap(&grch->grctx_vma);
	nouveau_gpuobj_ref(NULL, &grch->mmio);
	nouveau_gpuobj_ref(NULL, &grch->unk418810);
	nouveau_gpuobj_ref(NULL, &grch->unk40800c);
	nouveau_gpuobj_ref(NULL, &grch->unk408004);
	nouveau_gpuobj_ref(NULL, &grch->grctx);
	chan->engctx[engine] = NULL;
}

static int
nve0_graph_object_new(struct nouveau_channel *chan, int engine,
		      u32 handle, u16 class)
{
	return 0;
}

static int
nve0_graph_fini(struct drm_device *dev, int engine, bool suspend)
{
	return 0;
}

static void
nve0_graph_init_obj418880(struct drm_device *dev)
{
	struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
	int i;

	nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000);
	nv_wr32(dev, GPC_BCAST(0x08a4), 0x00000000);
	for (i = 0; i < 4; i++)
		nv_wr32(dev, GPC_BCAST(0x0888) + (i * 4), 0x00000000);
	nv_wr32(dev, GPC_BCAST(0x08b4), priv->unk4188b4->vinst >> 8);
	nv_wr32(dev, GPC_BCAST(0x08b8), priv->unk4188b8->vinst >> 8);
}

static void
nve0_graph_init_regs(struct drm_device *dev)
{
	nv_wr32(dev, 0x400080, 0x003083c2);
	nv_wr32(dev, 0x400088, 0x0001ffe7);
	nv_wr32(dev, 0x40008c, 0x00000000);
	nv_wr32(dev, 0x400090, 0x00000030);
	nv_wr32(dev, 0x40013c, 0x003901f7);
	nv_wr32(dev, 0x400140, 0x00000100);
	nv_wr32(dev, 0x400144, 0x00000000);
	nv_wr32(dev, 0x400148, 0x00000110);
	nv_wr32(dev, 0x400138, 0x00000000);
	nv_wr32(dev, 0x400130, 0x00000000);
	nv_wr32(dev, 0x400134, 0x00000000);
	nv_wr32(dev, 0x400124, 0x00000002);
}

static void
nve0_graph_init_units(struct drm_device *dev)
{
	nv_wr32(dev, 0x409ffc, 0x00000000);
	nv_wr32(dev, 0x409c14, 0x00003e3e);
	nv_wr32(dev, 0x409c24, 0x000f0000);

	nv_wr32(dev, 0x404000, 0xc0000000);
	nv_wr32(dev, 0x404600, 0xc0000000);
	nv_wr32(dev, 0x408030, 0xc0000000);
	nv_wr32(dev, 0x404490, 0xc0000000);
	nv_wr32(dev, 0x406018, 0xc0000000);
	nv_wr32(dev, 0x407020, 0xc0000000);
	nv_wr32(dev, 0x405840, 0xc0000000);
	nv_wr32(dev, 0x405844, 0x00ffffff);

	nv_mask(dev, 0x419cc0, 0x00000008, 0x00000008);
	nv_mask(dev, 0x419eb4, 0x00001000, 0x00001000);

}

static void
nve0_graph_init_gpc_0(struct drm_device *dev)
{
	struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
	const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
	u32 data[TPC_MAX / 8];
	u8  tpcnr[GPC_MAX];
	int i, gpc, tpc;

	nv_wr32(dev, GPC_UNIT(0, 0x3018), 0x00000001);

	memset(data, 0x00, sizeof(data));
	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
	for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
		do {
			gpc = (gpc + 1) % priv->gpc_nr;
		} while (!tpcnr[gpc]);
		tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;

		data[i / 8] |= tpc << ((i % 8) * 4);
	}

	nv_wr32(dev, GPC_BCAST(0x0980), data[0]);
	nv_wr32(dev, GPC_BCAST(0x0984), data[1]);
	nv_wr32(dev, GPC_BCAST(0x0988), data[2]);
	nv_wr32(dev, GPC_BCAST(0x098c), data[3]);

	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
		nv_wr32(dev, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
						  priv->tpc_nr[gpc]);
		nv_wr32(dev, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total);
		nv_wr32(dev, GPC_UNIT(gpc, 0x0918), magicgpc918);
	}

	nv_wr32(dev, GPC_BCAST(0x1bd4), magicgpc918);
	nv_wr32(dev, GPC_BCAST(0x08ac), nv_rd32(dev, 0x100800));
}

static void
nve0_graph_init_gpc_1(struct drm_device *dev)
{
	struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
	int gpc, tpc;

	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
		nv_wr32(dev, GPC_UNIT(gpc, 0x3038), 0xc0000000);
		nv_wr32(dev, GPC_UNIT(gpc, 0x0420), 0xc0000000);
		nv_wr32(dev, GPC_UNIT(gpc, 0x0900), 0xc0000000);
		nv_wr32(dev, GPC_UNIT(gpc, 0x1028), 0xc0000000);
		nv_wr32(dev, GPC_UNIT(gpc, 0x0824), 0xc0000000);
		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
			nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
			nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
			nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
			nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
			nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
			nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
			nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
		}
		nv_wr32(dev, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
		nv_wr32(dev, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
	}
}

static void
nve0_graph_init_rop(struct drm_device *dev)
{
	struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
	int rop;

	for (rop = 0; rop < priv->rop_nr; rop++) {
		nv_wr32(dev, ROP_UNIT(rop, 0x144), 0xc0000000);
		nv_wr32(dev, ROP_UNIT(rop, 0x070), 0xc0000000);
		nv_wr32(dev, ROP_UNIT(rop, 0x204), 0xffffffff);
		nv_wr32(dev, ROP_UNIT(rop, 0x208), 0xffffffff);
	}
}

static void
nve0_graph_init_fuc(struct drm_device *dev, u32 fuc_base,
		    struct nve0_graph_fuc *code, struct nve0_graph_fuc *data)
{
	int i;

	nv_wr32(dev, fuc_base + 0x01c0, 0x01000000);
	for (i = 0; i < data->size / 4; i++)
		nv_wr32(dev, fuc_base + 0x01c4, data->data[i]);

	nv_wr32(dev, fuc_base + 0x0180, 0x01000000);
	for (i = 0; i < code->size / 4; i++) {
		if ((i & 0x3f) == 0)
			nv_wr32(dev, fuc_base + 0x0188, i >> 6);
		nv_wr32(dev, fuc_base + 0x0184, code->data[i]);
	}
}

static int
nve0_graph_init_ctxctl(struct drm_device *dev)
{
	struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
	u32 r000260;

	/* load fuc microcode */
	r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000);
	nve0_graph_init_fuc(dev, 0x409000, &priv->fuc409c, &priv->fuc409d);
	nve0_graph_init_fuc(dev, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
	nv_wr32(dev, 0x000260, r000260);

	/* start both of them running */
	nv_wr32(dev, 0x409840, 0xffffffff);
	nv_wr32(dev, 0x41a10c, 0x00000000);
	nv_wr32(dev, 0x40910c, 0x00000000);
	nv_wr32(dev, 0x41a100, 0x00000002);
	nv_wr32(dev, 0x409100, 0x00000002);
	if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000001))
		NV_INFO(dev, "0x409800 wait failed\n");

	nv_wr32(dev, 0x409840, 0xffffffff);
	nv_wr32(dev, 0x409500, 0x7fffffff);
	nv_wr32(dev, 0x409504, 0x00000021);

	nv_wr32(dev, 0x409840, 0xffffffff);
	nv_wr32(dev, 0x409500, 0x00000000);
	nv_wr32(dev, 0x409504, 0x00000010);
	if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
		NV_ERROR(dev, "fuc09 req 0x10 timeout\n");
		return -EBUSY;
	}
	priv->grctx_size = nv_rd32(dev, 0x409800);

	nv_wr32(dev, 0x409840, 0xffffffff);
	nv_wr32(dev, 0x409500, 0x00000000);
	nv_wr32(dev, 0x409504, 0x00000016);
	if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
		NV_ERROR(dev, "fuc09 req 0x16 timeout\n");
		return -EBUSY;
	}

	nv_wr32(dev, 0x409840, 0xffffffff);
	nv_wr32(dev, 0x409500, 0x00000000);
	nv_wr32(dev, 0x409504, 0x00000025);
	if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
		NV_ERROR(dev, "fuc09 req 0x25 timeout\n");
		return -EBUSY;
	}

	nv_wr32(dev, 0x409800, 0x00000000);
	nv_wr32(dev, 0x409500, 0x00000001);
	nv_wr32(dev, 0x409504, 0x00000030);
	if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
		NV_ERROR(dev, "fuc09 req 0x30 timeout\n");
		return -EBUSY;
	}

	nv_wr32(dev, 0x409810, 0xb00095c8);
	nv_wr32(dev, 0x409800, 0x00000000);
	nv_wr32(dev, 0x409500, 0x00000001);
	nv_wr32(dev, 0x409504, 0x00000031);
	if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
		NV_ERROR(dev, "fuc09 req 0x31 timeout\n");
		return -EBUSY;
	}

	nv_wr32(dev, 0x409810, 0x00080420);
	nv_wr32(dev, 0x409800, 0x00000000);
	nv_wr32(dev, 0x409500, 0x00000001);
	nv_wr32(dev, 0x409504, 0x00000032);
	if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
		NV_ERROR(dev, "fuc09 req 0x32 timeout\n");
		return -EBUSY;
	}

	nv_wr32(dev, 0x409614, 0x00000070);
	nv_wr32(dev, 0x409614, 0x00000770);
	nv_wr32(dev, 0x40802c, 0x00000001);
	return 0;
}

static int
nve0_graph_init(struct drm_device *dev, int engine)
{
	int ret;

	nv_mask(dev, 0x000200, 0x18001000, 0x00000000);
	nv_mask(dev, 0x000200, 0x18001000, 0x18001000);

	nve0_graph_init_obj418880(dev);
	nve0_graph_init_regs(dev);
	nve0_graph_init_gpc_0(dev);

	nv_wr32(dev, 0x400500, 0x00010001);
	nv_wr32(dev, 0x400100, 0xffffffff);
	nv_wr32(dev, 0x40013c, 0xffffffff);

	nve0_graph_init_units(dev);
	nve0_graph_init_gpc_1(dev);
	nve0_graph_init_rop(dev);

	nv_wr32(dev, 0x400108, 0xffffffff);
	nv_wr32(dev, 0x400138, 0xffffffff);
	nv_wr32(dev, 0x400118, 0xffffffff);
	nv_wr32(dev, 0x400130, 0xffffffff);
	nv_wr32(dev, 0x40011c, 0xffffffff);
	nv_wr32(dev, 0x400134, 0xffffffff);
	nv_wr32(dev, 0x400054, 0x34ce3464);

	ret = nve0_graph_init_ctxctl(dev);
	if (ret)
		return ret;

	return 0;
}

int
nve0_graph_isr_chid(struct drm_device *dev, u64 inst)
{
	struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_channel *chan;
	unsigned long flags;
	int i;

	spin_lock_irqsave(&dev_priv->channels.lock, flags);
	for (i = 0; i < pfifo->channels; i++) {
		chan = dev_priv->channels.ptr[i];
		if (!chan || !chan->ramin)
			continue;

		if (inst == chan->ramin->vinst)
			break;
	}
	spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
	return i;
}

static void
nve0_graph_ctxctl_isr(struct drm_device *dev)
{
	u32 ustat = nv_rd32(dev, 0x409c18);

	if (ustat & 0x00000001)
		NV_INFO(dev, "PGRAPH: CTXCTRL ucode error\n");
	if (ustat & 0x00080000)
		NV_INFO(dev, "PGRAPH: CTXCTRL watchdog timeout\n");
	if (ustat & ~0x00080001)
		NV_INFO(dev, "PGRAPH: CTXCTRL 0x%08x\n", ustat);

	nve0_graph_ctxctl_debug(dev);
	nv_wr32(dev, 0x409c20, ustat);
}

static void
nve0_graph_trap_isr(struct drm_device *dev, int chid)
{
	struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
	u32 trap = nv_rd32(dev, 0x400108);
	int rop;

	if (trap & 0x00000001) {
		u32 stat = nv_rd32(dev, 0x404000);
		NV_INFO(dev, "PGRAPH: DISPATCH ch %d 0x%08x\n", chid, stat);
		nv_wr32(dev, 0x404000, 0xc0000000);
		nv_wr32(dev, 0x400108, 0x00000001);
		trap &= ~0x00000001;
	}

	if (trap & 0x00000010) {
		u32 stat = nv_rd32(dev, 0x405840);
		NV_INFO(dev, "PGRAPH: SHADER ch %d 0x%08x\n", chid, stat);
		nv_wr32(dev, 0x405840, 0xc0000000);
		nv_wr32(dev, 0x400108, 0x00000010);
		trap &= ~0x00000010;
	}

	if (trap & 0x02000000) {
		for (rop = 0; rop < priv->rop_nr; rop++) {
			u32 statz = nv_rd32(dev, ROP_UNIT(rop, 0x070));
			u32 statc = nv_rd32(dev, ROP_UNIT(rop, 0x144));
			NV_INFO(dev, "PGRAPH: ROP%d ch %d 0x%08x 0x%08x\n",
				     rop, chid, statz, statc);
			nv_wr32(dev, ROP_UNIT(rop, 0x070), 0xc0000000);
			nv_wr32(dev, ROP_UNIT(rop, 0x144), 0xc0000000);
		}
		nv_wr32(dev, 0x400108, 0x02000000);
		trap &= ~0x02000000;
	}

	if (trap) {
		NV_INFO(dev, "PGRAPH: TRAP ch %d 0x%08x\n", chid, trap);
		nv_wr32(dev, 0x400108, trap);
	}
}

static void
nve0_graph_isr(struct drm_device *dev)
{
	u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12;
	u32 chid = nve0_graph_isr_chid(dev, inst);
	u32 stat = nv_rd32(dev, 0x400100);
	u32 addr = nv_rd32(dev, 0x400704);
	u32 mthd = (addr & 0x00003ffc);
	u32 subc = (addr & 0x00070000) >> 16;
	u32 data = nv_rd32(dev, 0x400708);
	u32 code = nv_rd32(dev, 0x400110);
	u32 class = nv_rd32(dev, 0x404200 + (subc * 4));

	if (stat & 0x00000010) {
		if (nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) {
			NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] "
				     "subc %d class 0x%04x mthd 0x%04x "
				     "data 0x%08x\n",
				chid, inst, subc, class, mthd, data);
		}
		nv_wr32(dev, 0x400100, 0x00000010);
		stat &= ~0x00000010;
	}

	if (stat & 0x00000020) {
		NV_INFO(dev, "PGRAPH: ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
			     "class 0x%04x mthd 0x%04x data 0x%08x\n",
			chid, inst, subc, class, mthd, data);
		nv_wr32(dev, 0x400100, 0x00000020);
		stat &= ~0x00000020;
	}

	if (stat & 0x00100000) {
		NV_INFO(dev, "PGRAPH: DATA_ERROR [");
		nouveau_enum_print(nv50_data_error_names, code);
		printk("] ch %d [0x%010llx] subc %d class 0x%04x "
		       "mthd 0x%04x data 0x%08x\n",
		       chid, inst, subc, class, mthd, data);
		nv_wr32(dev, 0x400100, 0x00100000);
		stat &= ~0x00100000;
	}

	if (stat & 0x00200000) {
		nve0_graph_trap_isr(dev, chid);
		nv_wr32(dev, 0x400100, 0x00200000);
		stat &= ~0x00200000;
	}

	if (stat & 0x00080000) {
		nve0_graph_ctxctl_isr(dev);
		nv_wr32(dev, 0x400100, 0x00080000);
		stat &= ~0x00080000;
	}

	if (stat) {
		NV_INFO(dev, "PGRAPH: unknown stat 0x%08x\n", stat);
		nv_wr32(dev, 0x400100, stat);
	}

	nv_wr32(dev, 0x400500, 0x00010001);
}

static int
nve0_graph_create_fw(struct drm_device *dev, const char *fwname,
		     struct nve0_graph_fuc *fuc)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	const struct firmware *fw;
	char f[32];
	int ret;

	snprintf(f, sizeof(f), "nouveau/nv%02x_%s", dev_priv->chipset, fwname);
	ret = request_firmware(&fw, f, &dev->pdev->dev);
	if (ret)
		return ret;

	fuc->size = fw->size;
	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
	release_firmware(fw);
	return (fuc->data != NULL) ? 0 : -ENOMEM;
}

static void
nve0_graph_destroy_fw(struct nve0_graph_fuc *fuc)
{
	if (fuc->data) {
		kfree(fuc->data);
		fuc->data = NULL;
	}
}

static void
nve0_graph_destroy(struct drm_device *dev, int engine)
{
	struct nve0_graph_priv *priv = nv_engine(dev, engine);

	nve0_graph_destroy_fw(&priv->fuc409c);
	nve0_graph_destroy_fw(&priv->fuc409d);
	nve0_graph_destroy_fw(&priv->fuc41ac);
	nve0_graph_destroy_fw(&priv->fuc41ad);

	nouveau_irq_unregister(dev, 12);

	nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
	nouveau_gpuobj_ref(NULL, &priv->unk4188b4);

	if (priv->grctx_vals)
		kfree(priv->grctx_vals);

	NVOBJ_ENGINE_DEL(dev, GR);
	kfree(priv);
}

int
nve0_graph_create(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nve0_graph_priv *priv;
	int ret, gpc, i;
	u32 kepler;

	kepler = nve0_graph_class(dev);
	if (!kepler) {
		NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n");
		return 0;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->base.destroy = nve0_graph_destroy;
	priv->base.init = nve0_graph_init;
	priv->base.fini = nve0_graph_fini;
	priv->base.context_new = nve0_graph_context_new;
	priv->base.context_del = nve0_graph_context_del;
	priv->base.object_new = nve0_graph_object_new;

	NVOBJ_ENGINE_ADD(dev, GR, &priv->base);
	nouveau_irq_register(dev, 12, nve0_graph_isr);

	NV_INFO(dev, "PGRAPH: using external firmware\n");
	if (nve0_graph_create_fw(dev, "fuc409c", &priv->fuc409c) ||
	    nve0_graph_create_fw(dev, "fuc409d", &priv->fuc409d) ||
	    nve0_graph_create_fw(dev, "fuc41ac", &priv->fuc41ac) ||
	    nve0_graph_create_fw(dev, "fuc41ad", &priv->fuc41ad)) {
		ret = 0;
		goto error;
	}

	ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4);
	if (ret)
		goto error;

	ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8);
	if (ret)
		goto error;

	for (i = 0; i < 0x1000; i += 4) {
		nv_wo32(priv->unk4188b4, i, 0x00000010);
		nv_wo32(priv->unk4188b8, i, 0x00000010);
	}

	priv->gpc_nr  =  nv_rd32(dev, 0x409604) & 0x0000001f;
	priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16;
	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
		priv->tpc_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
		priv->tpc_total += priv->tpc_nr[gpc];
	}

	switch (dev_priv->chipset) {
	case 0xe4:
		if (priv->tpc_total == 8)
			priv->magic_not_rop_nr = 3;
		else
		if (priv->tpc_total == 7)
			priv->magic_not_rop_nr = 1;
		break;
	case 0xe7:
		priv->magic_not_rop_nr = 1;
		break;
	default:
		break;
	}

	if (!priv->magic_not_rop_nr) {
		NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
			 priv->tpc_nr[0], priv->tpc_nr[1], priv->tpc_nr[2],
			 priv->tpc_nr[3], priv->rop_nr);
		priv->magic_not_rop_nr = 0x00;
	}

	NVOBJ_CLASS(dev, 0xa097, GR); /* subc 0: 3D */
	NVOBJ_CLASS(dev, 0xa0c0, GR); /* subc 1: COMPUTE */
	NVOBJ_CLASS(dev, 0xa040, GR); /* subc 2: P2MF */
	NVOBJ_CLASS(dev, 0x902d, GR); /* subc 3: 2D */
	NVOBJ_CLASS(dev, 0xa0b5, GR); /* subc 4: COPY */
	return 0;

error:
	nve0_graph_destroy(dev, NVOBJ_ENGINE_GR);
	return ret;
}
