/*
 * 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
 */
#define nv04_instmem(p) container_of((p), struct nv04_instmem, base)
#include "priv.h"

#include <core/ramht.h>

struct nv04_instmem {
	struct nvkm_instmem base;
	struct nvkm_mm heap;
};

/******************************************************************************
 * instmem object implementation
 *****************************************************************************/
#define nv04_instobj(p) container_of((p), struct nv04_instobj, base.memory)

struct nv04_instobj {
	struct nvkm_instobj base;
	struct nv04_instmem *imem;
	struct nvkm_mm_node *node;
};

static void
nv04_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
{
	struct nv04_instobj *iobj = nv04_instobj(memory);
	struct nvkm_device *device = iobj->imem->base.subdev.device;
	nvkm_wr32(device, 0x700000 + iobj->node->offset + offset, data);
}

static u32
nv04_instobj_rd32(struct nvkm_memory *memory, u64 offset)
{
	struct nv04_instobj *iobj = nv04_instobj(memory);
	struct nvkm_device *device = iobj->imem->base.subdev.device;
	return nvkm_rd32(device, 0x700000 + iobj->node->offset + offset);
}

static const struct nvkm_memory_ptrs
nv04_instobj_ptrs = {
	.rd32 = nv04_instobj_rd32,
	.wr32 = nv04_instobj_wr32,
};

static void
nv04_instobj_release(struct nvkm_memory *memory)
{
}

static void __iomem *
nv04_instobj_acquire(struct nvkm_memory *memory)
{
	struct nv04_instobj *iobj = nv04_instobj(memory);
	struct nvkm_device *device = iobj->imem->base.subdev.device;
	return device->pri + 0x700000 + iobj->node->offset;
}

static u64
nv04_instobj_size(struct nvkm_memory *memory)
{
	return nv04_instobj(memory)->node->length;
}

static u64
nv04_instobj_addr(struct nvkm_memory *memory)
{
	return nv04_instobj(memory)->node->offset;
}

static enum nvkm_memory_target
nv04_instobj_target(struct nvkm_memory *memory)
{
	return NVKM_MEM_TARGET_INST;
}

static void *
nv04_instobj_dtor(struct nvkm_memory *memory)
{
	struct nv04_instobj *iobj = nv04_instobj(memory);
	mutex_lock(&iobj->imem->base.mutex);
	nvkm_mm_free(&iobj->imem->heap, &iobj->node);
	mutex_unlock(&iobj->imem->base.mutex);
	nvkm_instobj_dtor(&iobj->imem->base, &iobj->base);
	return iobj;
}

static const struct nvkm_memory_func
nv04_instobj_func = {
	.dtor = nv04_instobj_dtor,
	.target = nv04_instobj_target,
	.size = nv04_instobj_size,
	.addr = nv04_instobj_addr,
	.acquire = nv04_instobj_acquire,
	.release = nv04_instobj_release,
};

static int
nv04_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
		 struct nvkm_memory **pmemory)
{
	struct nv04_instmem *imem = nv04_instmem(base);
	struct nv04_instobj *iobj;
	int ret;

	if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL)))
		return -ENOMEM;
	*pmemory = &iobj->base.memory;

	nvkm_instobj_ctor(&nv04_instobj_func, &imem->base, &iobj->base);
	iobj->base.memory.ptrs = &nv04_instobj_ptrs;
	iobj->imem = imem;

	mutex_lock(&imem->base.mutex);
	ret = nvkm_mm_head(&imem->heap, 0, 1, size, size, align ? align : 1, &iobj->node);
	mutex_unlock(&imem->base.mutex);
	return ret;
}

/******************************************************************************
 * instmem subdev implementation
 *****************************************************************************/

static u32
nv04_instmem_rd32(struct nvkm_instmem *imem, u32 addr)
{
	return nvkm_rd32(imem->subdev.device, 0x700000 + addr);
}

static void
nv04_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 data)
{
	nvkm_wr32(imem->subdev.device, 0x700000 + addr, data);
}

static int
nv04_instmem_oneinit(struct nvkm_instmem *base)
{
	struct nv04_instmem *imem = nv04_instmem(base);
	struct nvkm_device *device = imem->base.subdev.device;
	int ret;

	/* PRAMIN aperture maps over the end of VRAM, reserve it */
	imem->base.reserved = 512 * 1024;

	ret = nvkm_mm_init(&imem->heap, 0, 0, imem->base.reserved, 1);
	if (ret)
		return ret;

	/* 0x00000-0x10000: reserve for probable vbios image */
	ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x10000, 0, false,
			      &imem->base.vbios);
	if (ret)
		return ret;

	/* 0x10000-0x18000: reserve for RAMHT */
	ret = nvkm_ramht_new(device, 0x08000, 0, NULL, &imem->base.ramht);
	if (ret)
		return ret;

	/* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */
	ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x00800, 0, true,
			      &imem->base.ramfc);
	if (ret)
		return ret;

	/* 0x18800-0x18a00: reserve for RAMRO */
	ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x00200, 0, false,
			      &imem->base.ramro);
	if (ret)
		return ret;

	return 0;
}

static void *
nv04_instmem_dtor(struct nvkm_instmem *base)
{
	struct nv04_instmem *imem = nv04_instmem(base);
	nvkm_memory_unref(&imem->base.ramfc);
	nvkm_memory_unref(&imem->base.ramro);
	nvkm_ramht_del(&imem->base.ramht);
	nvkm_memory_unref(&imem->base.vbios);
	nvkm_mm_fini(&imem->heap);
	return imem;
}

static const struct nvkm_instmem_func
nv04_instmem = {
	.dtor = nv04_instmem_dtor,
	.oneinit = nv04_instmem_oneinit,
	.rd32 = nv04_instmem_rd32,
	.wr32 = nv04_instmem_wr32,
	.memory_new = nv04_instobj_new,
	.zero = false,
};

int
nv04_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
		 struct nvkm_instmem **pimem)
{
	struct nv04_instmem *imem;

	if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
		return -ENOMEM;
	nvkm_instmem_ctor(&nv04_instmem, device, type, inst, &imem->base);
	*pimem = &imem->base;
	return 0;
}
