/*
 * 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 "drmP.h"
#include "nouveau_drv.h"
#include "nouveau_util.h"
#include "nouveau_vm.h"
#include "nouveau_ramht.h"

struct nv84_crypt_engine {
	struct nouveau_exec_engine base;
};

static int
nv84_crypt_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_gpuobj *ramin = chan->ramin;
	struct nouveau_gpuobj *ctx;
	int ret;

	NV_DEBUG(dev, "ch%d\n", chan->id);

	ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
				 NVOBJ_FLAG_ZERO_FREE, &ctx);
	if (ret)
		return ret;

	nv_wo32(ramin, 0xa0, 0x00190000);
	nv_wo32(ramin, 0xa4, ctx->vinst + ctx->size - 1);
	nv_wo32(ramin, 0xa8, ctx->vinst);
	nv_wo32(ramin, 0xac, 0);
	nv_wo32(ramin, 0xb0, 0);
	nv_wo32(ramin, 0xb4, 0);
	dev_priv->engine.instmem.flush(dev);

	atomic_inc(&chan->vm->engref[engine]);
	chan->engctx[engine] = ctx;
	return 0;
}

static void
nv84_crypt_context_del(struct nouveau_channel *chan, int engine)
{
	struct nouveau_gpuobj *ctx = chan->engctx[engine];
	struct drm_device *dev = chan->dev;
	u32 inst;

	inst  = (chan->ramin->vinst >> 12);
	inst |= 0x80000000;

	/* mark context as invalid if still on the hardware, not
	 * doing this causes issues the next time PCRYPT is used,
	 * unsurprisingly :)
	 */
	nv_wr32(dev, 0x10200c, 0x00000000);
	if (nv_rd32(dev, 0x102188) == inst)
		nv_mask(dev, 0x102188, 0x80000000, 0x00000000);
	if (nv_rd32(dev, 0x10218c) == inst)
		nv_mask(dev, 0x10218c, 0x80000000, 0x00000000);
	nv_wr32(dev, 0x10200c, 0x00000010);

	nouveau_gpuobj_ref(NULL, &ctx);

	atomic_dec(&chan->vm->engref[engine]);
	chan->engctx[engine] = NULL;
}

static int
nv84_crypt_object_new(struct nouveau_channel *chan, int engine,
		      u32 handle, u16 class)
{
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpuobj *obj = NULL;
	int ret;

	ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
	if (ret)
		return ret;
	obj->engine = 5;
	obj->class  = class;

	nv_wo32(obj, 0x00, class);
	dev_priv->engine.instmem.flush(dev);

	ret = nouveau_ramht_insert(chan, handle, obj);
	nouveau_gpuobj_ref(NULL, &obj);
	return ret;
}

static void
nv84_crypt_tlb_flush(struct drm_device *dev, int engine)
{
	nv50_vm_flush_engine(dev, 0x0a);
}

static void
nv84_crypt_isr(struct drm_device *dev)
{
	u32 stat = nv_rd32(dev, 0x102130);
	u32 mthd = nv_rd32(dev, 0x102190);
	u32 data = nv_rd32(dev, 0x102194);
	u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff;
	int show = nouveau_ratelimit();

	if (show) {
		NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n",
			     stat, mthd, data, inst);
	}

	nv_wr32(dev, 0x102130, stat);
	nv_wr32(dev, 0x10200c, 0x10);

	nv50_fb_vm_trap(dev, show);
}

static int
nv84_crypt_fini(struct drm_device *dev, int engine)
{
	nv_wr32(dev, 0x102140, 0x00000000);
	return 0;
}

static int
nv84_crypt_init(struct drm_device *dev, int engine)
{
	nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
	nv_mask(dev, 0x000200, 0x00004000, 0x00004000);

	nv_wr32(dev, 0x102130, 0xffffffff);
	nv_wr32(dev, 0x102140, 0xffffffbf);

	nv_wr32(dev, 0x10200c, 0x00000010);
	return 0;
}

static void
nv84_crypt_destroy(struct drm_device *dev, int engine)
{
	struct nv84_crypt_engine *pcrypt = nv_engine(dev, engine);

	NVOBJ_ENGINE_DEL(dev, CRYPT);

	nouveau_irq_unregister(dev, 14);
	kfree(pcrypt);
}

int
nv84_crypt_create(struct drm_device *dev)
{
	struct nv84_crypt_engine *pcrypt;

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

	pcrypt->base.destroy = nv84_crypt_destroy;
	pcrypt->base.init = nv84_crypt_init;
	pcrypt->base.fini = nv84_crypt_fini;
	pcrypt->base.context_new = nv84_crypt_context_new;
	pcrypt->base.context_del = nv84_crypt_context_del;
	pcrypt->base.object_new = nv84_crypt_object_new;
	pcrypt->base.tlb_flush = nv84_crypt_tlb_flush;

	nouveau_irq_register(dev, 14, nv84_crypt_isr);

	NVOBJ_ENGINE_ADD(dev, CRYPT, &pcrypt->base);
	NVOBJ_CLASS (dev, 0x74c1, CRYPT);
	return 0;
}
