/*
 * Copyright 2013 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 "priv.h"
#include "conn.h"
#include "outp.h"

#include <core/client.h>
#include <core/notify.h>
#include <core/oproxy.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>

#include <nvif/class.h>
#include <nvif/cl0046.h>
#include <nvif/event.h>
#include <nvif/unpack.h>

static void
nvkm_disp_vblank_fini(struct nvkm_event *event, int type, int head)
{
	struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank);
	disp->func->head.vblank_fini(disp, head);
}

static void
nvkm_disp_vblank_init(struct nvkm_event *event, int type, int head)
{
	struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank);
	disp->func->head.vblank_init(disp, head);
}

static int
nvkm_disp_vblank_ctor(struct nvkm_object *object, void *data, u32 size,
		      struct nvkm_notify *notify)
{
	struct nvkm_disp *disp =
		container_of(notify->event, typeof(*disp), vblank);
	union {
		struct nvif_notify_head_req_v0 v0;
	} *req = data;
	int ret = -ENOSYS;

	if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, false))) {
		notify->size = sizeof(struct nvif_notify_head_rep_v0);
		if (ret = -ENXIO, req->v0.head <= disp->vblank.index_nr) {
			notify->types = 1;
			notify->index = req->v0.head;
			return 0;
		}
	}

	return ret;
}

static const struct nvkm_event_func
nvkm_disp_vblank_func = {
	.ctor = nvkm_disp_vblank_ctor,
	.init = nvkm_disp_vblank_init,
	.fini = nvkm_disp_vblank_fini,
};

void
nvkm_disp_vblank(struct nvkm_disp *disp, int head)
{
	struct nvif_notify_head_rep_v0 rep = {};
	nvkm_event_send(&disp->vblank, 1, head, &rep, sizeof(rep));
}

static int
nvkm_disp_hpd_ctor(struct nvkm_object *object, void *data, u32 size,
		   struct nvkm_notify *notify)
{
	struct nvkm_disp *disp =
		container_of(notify->event, typeof(*disp), hpd);
	union {
		struct nvif_notify_conn_req_v0 v0;
	} *req = data;
	struct nvkm_output *outp;
	int ret = -ENOSYS;

	if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, false))) {
		notify->size = sizeof(struct nvif_notify_conn_rep_v0);
		list_for_each_entry(outp, &disp->outp, head) {
			if (ret = -ENXIO, outp->conn->index == req->v0.conn) {
				if (ret = -ENODEV, outp->conn->hpd.event) {
					notify->types = req->v0.mask;
					notify->index = req->v0.conn;
					ret = 0;
				}
				break;
			}
		}
	}

	return ret;
}

static const struct nvkm_event_func
nvkm_disp_hpd_func = {
	.ctor = nvkm_disp_hpd_ctor
};

int
nvkm_disp_ntfy(struct nvkm_object *object, u32 type, struct nvkm_event **event)
{
	struct nvkm_disp *disp = nvkm_disp(object->engine);
	switch (type) {
	case NV04_DISP_NTFY_VBLANK:
		*event = &disp->vblank;
		return 0;
	case NV04_DISP_NTFY_CONN:
		*event = &disp->hpd;
		return 0;
	default:
		break;
	}
	return -EINVAL;
}

static void
nvkm_disp_class_del(struct nvkm_oproxy *oproxy)
{
	struct nvkm_disp *disp = nvkm_disp(oproxy->base.engine);
	mutex_lock(&disp->engine.subdev.mutex);
	if (disp->client == oproxy)
		disp->client = NULL;
	mutex_unlock(&disp->engine.subdev.mutex);
}

static const struct nvkm_oproxy_func
nvkm_disp_class = {
	.dtor[1] = nvkm_disp_class_del,
};

static int
nvkm_disp_class_new(struct nvkm_device *device,
		    const struct nvkm_oclass *oclass, void *data, u32 size,
		    struct nvkm_object **pobject)
{
	const struct nvkm_disp_oclass *sclass = oclass->engn;
	struct nvkm_disp *disp = nvkm_disp(oclass->engine);
	struct nvkm_oproxy *oproxy;
	int ret;

	ret = nvkm_oproxy_new_(&nvkm_disp_class, oclass, &oproxy);
	if (ret)
		return ret;
	*pobject = &oproxy->base;

	mutex_lock(&disp->engine.subdev.mutex);
	if (disp->client) {
		mutex_unlock(&disp->engine.subdev.mutex);
		return -EBUSY;
	}
	disp->client = oproxy;
	mutex_unlock(&disp->engine.subdev.mutex);

	return sclass->ctor(disp, oclass, data, size, &oproxy->object);
}

static const struct nvkm_device_oclass
nvkm_disp_sclass = {
	.ctor = nvkm_disp_class_new,
};

static int
nvkm_disp_class_get(struct nvkm_oclass *oclass, int index,
		    const struct nvkm_device_oclass **class)
{
	struct nvkm_disp *disp = nvkm_disp(oclass->engine);
	if (index == 0) {
		const struct nvkm_disp_oclass *root = disp->func->root(disp);
		oclass->base = root->base;
		oclass->engn = root;
		*class = &nvkm_disp_sclass;
		return 0;
	}
	return 1;
}

static void
nvkm_disp_intr(struct nvkm_engine *engine)
{
	struct nvkm_disp *disp = nvkm_disp(engine);
	disp->func->intr(disp);
}

static int
nvkm_disp_fini(struct nvkm_engine *engine, bool suspend)
{
	struct nvkm_disp *disp = nvkm_disp(engine);
	struct nvkm_connector *conn;
	struct nvkm_output *outp;

	list_for_each_entry(outp, &disp->outp, head) {
		nvkm_output_fini(outp);
	}

	list_for_each_entry(conn, &disp->conn, head) {
		nvkm_connector_fini(conn);
	}

	return 0;
}

static int
nvkm_disp_init(struct nvkm_engine *engine)
{
	struct nvkm_disp *disp = nvkm_disp(engine);
	struct nvkm_connector *conn;
	struct nvkm_output *outp;

	list_for_each_entry(conn, &disp->conn, head) {
		nvkm_connector_init(conn);
	}

	list_for_each_entry(outp, &disp->outp, head) {
		nvkm_output_init(outp);
	}

	return 0;
}

static void *
nvkm_disp_dtor(struct nvkm_engine *engine)
{
	struct nvkm_disp *disp = nvkm_disp(engine);
	struct nvkm_connector *conn;
	struct nvkm_output *outp;
	void *data = disp;

	if (disp->func->dtor)
		data = disp->func->dtor(disp);

	nvkm_event_fini(&disp->vblank);
	nvkm_event_fini(&disp->hpd);

	while (!list_empty(&disp->outp)) {
		outp = list_first_entry(&disp->outp, typeof(*outp), head);
		list_del(&outp->head);
		nvkm_output_del(&outp);
	}

	while (!list_empty(&disp->conn)) {
		conn = list_first_entry(&disp->conn, typeof(*conn), head);
		list_del(&conn->head);
		nvkm_connector_del(&conn);
	}

	return data;
}

static const struct nvkm_engine_func
nvkm_disp = {
	.dtor = nvkm_disp_dtor,
	.init = nvkm_disp_init,
	.fini = nvkm_disp_fini,
	.intr = nvkm_disp_intr,
	.base.sclass = nvkm_disp_class_get,
};

int
nvkm_disp_ctor(const struct nvkm_disp_func *func, struct nvkm_device *device,
	       int index, int heads, struct nvkm_disp *disp)
{
	struct nvkm_bios *bios = device->bios;
	struct nvkm_output *outp, *outt, *pair;
	struct nvkm_connector *conn;
	struct nvbios_connE connE;
	struct dcb_output dcbE;
	u8  hpd = 0, ver, hdr;
	u32 data;
	int ret, i;

	INIT_LIST_HEAD(&disp->outp);
	INIT_LIST_HEAD(&disp->conn);
	disp->func = func;
	disp->head.nr = heads;

	ret = nvkm_engine_ctor(&nvkm_disp, device, index, true, &disp->engine);
	if (ret)
		return ret;

	/* create output objects for each display path in the vbios */
	i = -1;
	while ((data = dcb_outp_parse(bios, ++i, &ver, &hdr, &dcbE))) {
		const struct nvkm_disp_func_outp *outps;
		int (*ctor)(struct nvkm_disp *, int, struct dcb_output *,
			    struct nvkm_output **);

		if (dcbE.type == DCB_OUTPUT_UNUSED)
			continue;
		if (dcbE.type == DCB_OUTPUT_EOL)
			break;
		outp = NULL;

		switch (dcbE.location) {
		case 0: outps = &disp->func->outp.internal; break;
		case 1: outps = &disp->func->outp.external; break;
		default:
			nvkm_warn(&disp->engine.subdev,
				  "dcb %d locn %d unknown\n", i, dcbE.location);
			continue;
		}

		switch (dcbE.type) {
		case DCB_OUTPUT_ANALOG: ctor = outps->crt ; break;
		case DCB_OUTPUT_TV    : ctor = outps->tv  ; break;
		case DCB_OUTPUT_TMDS  : ctor = outps->tmds; break;
		case DCB_OUTPUT_LVDS  : ctor = outps->lvds; break;
		case DCB_OUTPUT_DP    : ctor = outps->dp  ; break;
		default:
			nvkm_warn(&disp->engine.subdev,
				  "dcb %d type %d unknown\n", i, dcbE.type);
			continue;
		}

		if (ctor)
			ret = ctor(disp, i, &dcbE, &outp);
		else
			ret = -ENODEV;

		if (ret) {
			if (ret == -ENODEV) {
				nvkm_debug(&disp->engine.subdev,
					   "dcb %d %d/%d not supported\n",
					   i, dcbE.location, dcbE.type);
				continue;
			}
			nvkm_error(&disp->engine.subdev,
				   "failed to create output %d\n", i);
			nvkm_output_del(&outp);
			continue;
		}

		list_add_tail(&outp->head, &disp->outp);
		hpd = max(hpd, (u8)(dcbE.connector + 1));
	}

	/* create connector objects based on the outputs we support */
	list_for_each_entry_safe(outp, outt, &disp->outp, head) {
		/* bios data *should* give us the most useful information */
		data = nvbios_connEp(bios, outp->info.connector, &ver, &hdr,
				     &connE);

		/* no bios connector data... */
		if (!data) {
			/* heuristic: anything with the same ccb index is
			 * considered to be on the same connector, any
			 * output path without an associated ccb entry will
			 * be put on its own connector
			 */
			int ccb_index = outp->info.i2c_index;
			if (ccb_index != 0xf) {
				list_for_each_entry(pair, &disp->outp, head) {
					if (pair->info.i2c_index == ccb_index) {
						outp->conn = pair->conn;
						break;
					}
				}
			}

			/* connector shared with another output path */
			if (outp->conn)
				continue;

			memset(&connE, 0x00, sizeof(connE));
			connE.type = DCB_CONNECTOR_NONE;
			i = -1;
		} else {
			i = outp->info.connector;
		}

		/* check that we haven't already created this connector */
		list_for_each_entry(conn, &disp->conn, head) {
			if (conn->index == outp->info.connector) {
				outp->conn = conn;
				break;
			}
		}

		if (outp->conn)
			continue;

		/* apparently we need to create a new one! */
		ret = nvkm_connector_new(disp, i, &connE, &outp->conn);
		if (ret) {
			nvkm_error(&disp->engine.subdev,
				   "failed to create output %d conn: %d\n",
				   outp->index, ret);
			nvkm_connector_del(&outp->conn);
			list_del(&outp->head);
			nvkm_output_del(&outp);
			continue;
		}

		list_add_tail(&outp->conn->head, &disp->conn);
	}

	ret = nvkm_event_init(&nvkm_disp_hpd_func, 3, hpd, &disp->hpd);
	if (ret)
		return ret;

	ret = nvkm_event_init(&nvkm_disp_vblank_func, 1, heads, &disp->vblank);
	if (ret)
		return ret;

	return 0;
}

int
nvkm_disp_new_(const struct nvkm_disp_func *func, struct nvkm_device *device,
	       int index, int heads, struct nvkm_disp **pdisp)
{
	if (!(*pdisp = kzalloc(sizeof(**pdisp), GFP_KERNEL)))
		return -ENOMEM;
	return nvkm_disp_ctor(func, device, index, heads, *pdisp);
}
