/*
 * 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 <core/object.h>
#include <core/device.h>
#include <core/client.h>
#include <core/device.h>
#include <core/option.h>

#include <core/class.h>

#include <subdev/device.h>

static DEFINE_MUTEX(nv_devices_mutex);
static LIST_HEAD(nv_devices);

struct nouveau_device *
nouveau_device_find(u64 name)
{
	struct nouveau_device *device, *match = NULL;
	mutex_lock(&nv_devices_mutex);
	list_for_each_entry(device, &nv_devices, head) {
		if (device->handle == name) {
			match = device;
			break;
		}
	}
	mutex_unlock(&nv_devices_mutex);
	return match;
}

/******************************************************************************
 * nouveau_devobj (0x0080): class implementation
 *****************************************************************************/
struct nouveau_devobj {
	struct nouveau_parent base;
	struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
	bool created;
};

static const u64 disable_map[] = {
	[NVDEV_SUBDEV_VBIOS]	= NV_DEVICE_DISABLE_VBIOS,
	[NVDEV_SUBDEV_GPIO]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_I2C]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_DEVINIT]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_MC]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_TIMER]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_FB]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_VM]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_INSTMEM]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_BAR]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_VOLT]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_CLOCK]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_SUBDEV_THERM]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_ENGINE_DMAOBJ]	= NV_DEVICE_DISABLE_CORE,
	[NVDEV_ENGINE_GR]	= NV_DEVICE_DISABLE_GRAPH,
	[NVDEV_ENGINE_MPEG]	= NV_DEVICE_DISABLE_MPEG,
	[NVDEV_ENGINE_ME]	= NV_DEVICE_DISABLE_ME,
	[NVDEV_ENGINE_VP]	= NV_DEVICE_DISABLE_VP,
	[NVDEV_ENGINE_CRYPT]	= NV_DEVICE_DISABLE_CRYPT,
	[NVDEV_ENGINE_BSP]	= NV_DEVICE_DISABLE_BSP,
	[NVDEV_ENGINE_PPP]	= NV_DEVICE_DISABLE_PPP,
	[NVDEV_ENGINE_COPY0]	= NV_DEVICE_DISABLE_COPY0,
	[NVDEV_ENGINE_COPY1]	= NV_DEVICE_DISABLE_COPY1,
	[NVDEV_ENGINE_UNK1C1]	= NV_DEVICE_DISABLE_UNK1C1,
	[NVDEV_ENGINE_FIFO]	= NV_DEVICE_DISABLE_FIFO,
	[NVDEV_ENGINE_DISP]	= NV_DEVICE_DISABLE_DISP,
	[NVDEV_SUBDEV_NR]	= 0,
};

static int
nouveau_devobj_ctor(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, void *data, u32 size,
		    struct nouveau_object **pobject)
{
	struct nouveau_client *client = nv_client(parent);
	struct nouveau_device *device;
	struct nouveau_devobj *devobj;
	struct nv_device_class *args = data;
	u64 disable, boot0, strap;
	u64 mmio_base, mmio_size;
	void __iomem *map;
	int ret, i, c;

	if (size < sizeof(struct nv_device_class))
		return -EINVAL;

	/* find the device subdev that matches what the client requested */
	device = nv_device(client->device);
	if (args->device != ~0) {
		device = nouveau_device_find(args->device);
		if (!device)
			return -ENODEV;
	}

	ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, NULL,
				    (1ULL << NVDEV_ENGINE_DMAOBJ) |
				    (1ULL << NVDEV_ENGINE_FIFO) |
				    (1ULL << NVDEV_ENGINE_DISP), &devobj);
	*pobject = nv_object(devobj);
	if (ret)
		return ret;

	mmio_base = pci_resource_start(device->pdev, 0);
	mmio_size = pci_resource_len(device->pdev, 0);

	/* translate api disable mask into internal mapping */
	disable = args->debug0;
	for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
		if (args->disable & disable_map[i])
			disable |= (1ULL << i);
	}

	/* identify the chipset, and determine classes of subdev/engines */
	if (!(args->disable & NV_DEVICE_DISABLE_IDENTIFY) &&
	    !device->card_type) {
		map = ioremap(mmio_base, 0x102000);
		if (map == NULL)
			return -ENOMEM;

		/* switch mmio to cpu's native endianness */
#ifndef __BIG_ENDIAN
		if (ioread32_native(map + 0x000004) != 0x00000000)
#else
		if (ioread32_native(map + 0x000004) == 0x00000000)
#endif
			iowrite32_native(0x01000001, map + 0x000004);

		/* read boot0 and strapping information */
		boot0 = ioread32_native(map + 0x000000);
		strap = ioread32_native(map + 0x101000);
		iounmap(map);

		/* determine chipset and derive architecture from it */
		if ((boot0 & 0x0f000000) > 0) {
			device->chipset = (boot0 & 0xff00000) >> 20;
			switch (device->chipset & 0xf0) {
			case 0x10: device->card_type = NV_10; break;
			case 0x20: device->card_type = NV_20; break;
			case 0x30: device->card_type = NV_30; break;
			case 0x40:
			case 0x60: device->card_type = NV_40; break;
			case 0x50:
			case 0x80:
			case 0x90:
			case 0xa0: device->card_type = NV_50; break;
			case 0xc0: device->card_type = NV_C0; break;
			case 0xd0: device->card_type = NV_D0; break;
			case 0xe0: device->card_type = NV_E0; break;
			default:
				break;
			}
		} else
		if ((boot0 & 0xff00fff0) == 0x20004000) {
			if (boot0 & 0x00f00000)
				device->chipset = 0x05;
			else
				device->chipset = 0x04;
			device->card_type = NV_04;
		}

		switch (device->card_type) {
		case NV_04: ret = nv04_identify(device); break;
		case NV_10: ret = nv10_identify(device); break;
		case NV_20: ret = nv20_identify(device); break;
		case NV_30: ret = nv30_identify(device); break;
		case NV_40: ret = nv40_identify(device); break;
		case NV_50: ret = nv50_identify(device); break;
		case NV_C0:
		case NV_D0: ret = nvc0_identify(device); break;
		case NV_E0: ret = nve0_identify(device); break;
		default:
			ret = -EINVAL;
			break;
		}

		if (ret) {
			nv_error(device, "unknown chipset, 0x%08x\n", boot0);
			return ret;
		}

		nv_info(device, "BOOT0  : 0x%08x\n", boot0);
		nv_info(device, "Chipset: %s (NV%02X)\n",
			device->cname, device->chipset);
		nv_info(device, "Family : NV%02X\n", device->card_type);

		/* determine frequency of timing crystal */
		if ( device->chipset < 0x17 ||
		    (device->chipset >= 0x20 && device->chipset <= 0x25))
			strap &= 0x00000040;
		else
			strap &= 0x00400040;

		switch (strap) {
		case 0x00000000: device->crystal = 13500; break;
		case 0x00000040: device->crystal = 14318; break;
		case 0x00400000: device->crystal = 27000; break;
		case 0x00400040: device->crystal = 25000; break;
		}

		nv_debug(device, "crystal freq: %dKHz\n", device->crystal);
	}

	if (!(args->disable & NV_DEVICE_DISABLE_MMIO) &&
	    !nv_subdev(device)->mmio) {
		nv_subdev(device)->mmio  = ioremap(mmio_base, mmio_size);
		if (!nv_subdev(device)->mmio) {
			nv_error(device, "unable to map device registers\n");
			return -ENOMEM;
		}
	}

	/* ensure requested subsystems are available for use */
	for (i = 0, c = 0; i < NVDEV_SUBDEV_NR; i++) {
		if (!(oclass = device->oclass[i]) || (disable & (1ULL << i)))
			continue;

		if (!device->subdev[i]) {
			ret = nouveau_object_ctor(nv_object(device), NULL,
						  oclass, NULL, i,
						  &devobj->subdev[i]);
			if (ret == -ENODEV)
				continue;
			if (ret)
				return ret;

			if (nv_iclass(devobj->subdev[i], NV_ENGINE_CLASS))
				nouveau_subdev_reset(devobj->subdev[i]);
		} else {
			nouveau_object_ref(device->subdev[i],
					  &devobj->subdev[i]);
		}

		/* note: can't init *any* subdevs until devinit has been run
		 * due to not knowing exactly what the vbios init tables will
		 * mess with.  devinit also can't be run until all of its
		 * dependencies have been created.
		 *
		 * this code delays init of any subdev until all of devinit's
		 * dependencies have been created, and then initialises each
		 * subdev in turn as they're created.
		 */
		while (i >= NVDEV_SUBDEV_DEVINIT_LAST && c <= i) {
			struct nouveau_object *subdev = devobj->subdev[c++];
			if (subdev && !nv_iclass(subdev, NV_ENGINE_CLASS)) {
				ret = nouveau_object_inc(subdev);
				if (ret)
					return ret;
			}
		}
	}

	return 0;
}

static void
nouveau_devobj_dtor(struct nouveau_object *object)
{
	struct nouveau_devobj *devobj = (void *)object;
	int i;

	for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--)
		nouveau_object_ref(NULL, &devobj->subdev[i]);

	nouveau_parent_destroy(&devobj->base);
}

static int
nouveau_devobj_init(struct nouveau_object *object)
{
	struct nouveau_devobj *devobj = (void *)object;
	struct nouveau_object *subdev;
	int ret, i;

	ret = nouveau_parent_init(&devobj->base);
	if (ret)
		return ret;

	for (i = 0; devobj->created && i < NVDEV_SUBDEV_NR; i++) {
		if ((subdev = devobj->subdev[i])) {
			if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
				ret = nouveau_object_inc(subdev);
				if (ret)
					goto fail;
			}
		}
	}

	devobj->created = true;
	return 0;

fail:
	for (--i; i >= 0; i--) {
		if ((subdev = devobj->subdev[i])) {
			if (!nv_iclass(subdev, NV_ENGINE_CLASS))
				nouveau_object_dec(subdev, false);
		}
	}

	return ret;
}

static int
nouveau_devobj_fini(struct nouveau_object *object, bool suspend)
{
	struct nouveau_devobj *devobj = (void *)object;
	struct nouveau_object *subdev;
	int ret, i;

	for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
		if ((subdev = devobj->subdev[i])) {
			if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
				ret = nouveau_object_dec(subdev, suspend);
				if (ret && suspend)
					goto fail;
			}
		}
	}

	ret = nouveau_parent_fini(&devobj->base, suspend);
fail:
	for (; ret && suspend && i < NVDEV_SUBDEV_NR; i++) {
		if ((subdev = devobj->subdev[i])) {
			if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
				ret = nouveau_object_inc(subdev);
				if (ret) {
					/* XXX */
				}
			}
		}
	}

	return ret;
}

static u8
nouveau_devobj_rd08(struct nouveau_object *object, u32 addr)
{
	return nv_rd08(object->engine, addr);
}

static u16
nouveau_devobj_rd16(struct nouveau_object *object, u32 addr)
{
	return nv_rd16(object->engine, addr);
}

static u32
nouveau_devobj_rd32(struct nouveau_object *object, u32 addr)
{
	return nv_rd32(object->engine, addr);
}

static void
nouveau_devobj_wr08(struct nouveau_object *object, u32 addr, u8 data)
{
	nv_wr08(object->engine, addr, data);
}

static void
nouveau_devobj_wr16(struct nouveau_object *object, u32 addr, u16 data)
{
	nv_wr16(object->engine, addr, data);
}

static void
nouveau_devobj_wr32(struct nouveau_object *object, u32 addr, u32 data)
{
	nv_wr32(object->engine, addr, data);
}

static struct nouveau_ofuncs
nouveau_devobj_ofuncs = {
	.ctor = nouveau_devobj_ctor,
	.dtor = nouveau_devobj_dtor,
	.init = nouveau_devobj_init,
	.fini = nouveau_devobj_fini,
	.rd08 = nouveau_devobj_rd08,
	.rd16 = nouveau_devobj_rd16,
	.rd32 = nouveau_devobj_rd32,
	.wr08 = nouveau_devobj_wr08,
	.wr16 = nouveau_devobj_wr16,
	.wr32 = nouveau_devobj_wr32,
};

/******************************************************************************
 * nouveau_device: engine functions
 *****************************************************************************/
struct nouveau_oclass
nouveau_device_sclass[] = {
	{ 0x0080, &nouveau_devobj_ofuncs },
	{}
};

static void
nouveau_device_dtor(struct nouveau_object *object)
{
	struct nouveau_device *device = (void *)object;

	mutex_lock(&nv_devices_mutex);
	list_del(&device->head);
	mutex_unlock(&nv_devices_mutex);

	if (device->base.mmio)
		iounmap(device->base.mmio);

	nouveau_subdev_destroy(&device->base);
}

static struct nouveau_oclass
nouveau_device_oclass = {
	.handle = NV_SUBDEV(DEVICE, 0x00),
	.ofuncs = &(struct nouveau_ofuncs) {
		.dtor = nouveau_device_dtor,
	},
};

int
nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname,
		       const char *cfg, const char *dbg,
		       int length, void **pobject)
{
	struct nouveau_device *device;
	int ret = -EEXIST;

	mutex_lock(&nv_devices_mutex);
	list_for_each_entry(device, &nv_devices, head) {
		if (device->handle == name)
			goto done;
	}

	ret = nouveau_subdev_create_(NULL, NULL, &nouveau_device_oclass, 0,
				     "DEVICE", "device", length, pobject);
	device = *pobject;
	if (ret)
		goto done;

	atomic_set(&nv_object(device)->usecount, 2);
	device->pdev = pdev;
	device->handle = name;
	device->cfgopt = cfg;
	device->dbgopt = dbg;
	device->name = sname;

	nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE");
	list_add(&device->head, &nv_devices);
done:
	mutex_unlock(&nv_devices_mutex);
	return ret;
}
