/*
 * 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>
#include <subdev/bar.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);
}

void
nv04_instmem_resume(struct nvkm_instmem *imem)
{
	struct nvkm_instobj *iobj;

	list_for_each_entry(iobj, &imem->boot, head) {
		if (iobj->suspend)
			nvkm_instobj_load(iobj);
	}

	nvkm_bar_bar2_init(imem->subdev.device);

	list_for_each_entry(iobj, &imem->list, head) {
		if (iobj->suspend)
			nvkm_instobj_load(iobj);
	}
}

int
nv04_instmem_suspend(struct nvkm_instmem *imem)
{
	struct nvkm_instobj *iobj;

	list_for_each_entry(iobj, &imem->list, head) {
		if (iobj->preserve) {
			int ret = nvkm_instobj_save(iobj);
			if (ret)
				return ret;
		}
	}

	nvkm_bar_bar2_fini(imem->subdev.device);

	list_for_each_entry(iobj, &imem->boot, head) {
		int ret = nvkm_instobj_save(iobj);
		if (ret)
			return ret;
	}

	return 0;
}

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,
	.suspend = nv04_instmem_suspend,
	.resume = nv04_instmem_resume,
	.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;
}
