/*
 * 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 "subdev/bios.h"
#include "subdev/bios/bit.h"
#include "subdev/bios/dp.h"

static u16
nvbios_dp_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	struct bit_entry d;

	if (!bit_entry(bios, 'd', &d)) {
		if (d.version == 1 && d.length >= 2) {
			u16 data = nv_ro16(bios, d.offset);
			if (data) {
				*ver = nv_ro08(bios, data + 0x00);
				switch (*ver) {
				case 0x21:
				case 0x30:
				case 0x40:
					*hdr = nv_ro08(bios, data + 0x01);
					*len = nv_ro08(bios, data + 0x02);
					*cnt = nv_ro08(bios, data + 0x03);
					return data;
				default:
					break;
				}
			}
		}
	}

	return 0x0000;
}

static u16
nvbios_dpout_entry(struct nouveau_bios *bios, u8 idx,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	u16 data = nvbios_dp_table(bios, ver, hdr, cnt, len);
	if (data && idx < *cnt) {
		u16 outp = nv_ro16(bios, data + *hdr + idx * *len);
		switch (*ver * !!outp) {
		case 0x21:
		case 0x30:
			*hdr = nv_ro08(bios, data + 0x04);
			*len = nv_ro08(bios, data + 0x05);
			*cnt = nv_ro08(bios, outp + 0x04);
			break;
		case 0x40:
			*hdr = nv_ro08(bios, data + 0x04);
			*cnt = 0;
			*len = 0;
			break;
		default:
			break;
		}
		return outp;
	}
	*ver = 0x00;
	return 0x0000;
}

u16
nvbios_dpout_parse(struct nouveau_bios *bios, u8 idx,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		   struct nvbios_dpout *info)
{
	u16 data = nvbios_dpout_entry(bios, idx, ver, hdr, cnt, len);
	if (data && *ver) {
		info->type = nv_ro16(bios, data + 0x00);
		info->mask = nv_ro16(bios, data + 0x02);
		switch (*ver) {
		case 0x21:
		case 0x30:
			info->flags     = nv_ro08(bios, data + 0x05);
			info->script[0] = nv_ro16(bios, data + 0x06);
			info->script[1] = nv_ro16(bios, data + 0x08);
			info->lnkcmp    = nv_ro16(bios, data + 0x0a);
			info->script[2] = nv_ro16(bios, data + 0x0c);
			info->script[3] = nv_ro16(bios, data + 0x0e);
			info->script[4] = nv_ro16(bios, data + 0x10);
			break;
		case 0x40:
			info->flags     = nv_ro08(bios, data + 0x04);
			info->script[0] = nv_ro16(bios, data + 0x05);
			info->script[1] = nv_ro16(bios, data + 0x07);
			info->lnkcmp    = nv_ro16(bios, data + 0x09);
			info->script[2] = nv_ro16(bios, data + 0x0b);
			info->script[3] = nv_ro16(bios, data + 0x0d);
			info->script[4] = nv_ro16(bios, data + 0x0f);
			break;
		default:
			data = 0x0000;
			break;
		}
	}
	return data;
}

u16
nvbios_dpout_match(struct nouveau_bios *bios, u16 type, u16 mask,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		   struct nvbios_dpout *info)
{
	u16 data, idx = 0;
	while ((data = nvbios_dpout_parse(bios, idx++, ver, hdr, cnt, len, info)) || *ver) {
		if (data && info->type == type) {
			if ((info->mask & mask) == mask)
				break;
		}
	}
	return data;
}

static u16
nvbios_dpcfg_entry(struct nouveau_bios *bios, u16 outp, u8 idx,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
	if (*ver >= 0x40) {
		outp = nvbios_dp_table(bios, ver, hdr, cnt, len);
		*hdr = *hdr + (*len * * cnt);
		*len = nv_ro08(bios, outp + 0x06);
		*cnt = nv_ro08(bios, outp + 0x07);
	}

	if (idx < *cnt)
		return outp + *hdr + (idx * *len);

	return 0x0000;
}

u16
nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		   struct nvbios_dpcfg *info)
{
	u16 data = nvbios_dpcfg_entry(bios, outp, idx, ver, hdr, cnt, len);
	if (data) {
		switch (*ver) {
		case 0x21:
			info->drv = nv_ro08(bios, data + 0x02);
			info->pre = nv_ro08(bios, data + 0x03);
			info->unk = nv_ro08(bios, data + 0x04);
			break;
		case 0x30:
		case 0x40:
			info->drv = nv_ro08(bios, data + 0x01);
			info->pre = nv_ro08(bios, data + 0x02);
			info->unk = nv_ro08(bios, data + 0x03);
			break;
		default:
			data = 0x0000;
			break;
		}
	}
	return data;
}

u16
nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 un, u8 vs, u8 pe,
		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		   struct nvbios_dpcfg *info)
{
	u8 idx = 0xff;
	u16 data;

	if (*ver >= 0x30) {
		const u8 vsoff[] = { 0, 4, 7, 9 };
		idx = (un * 10) + vsoff[vs] + pe;
	} else {
		while ((data = nvbios_dpcfg_entry(bios, outp, idx,
						  ver, hdr, cnt, len))) {
			if (nv_ro08(bios, data + 0x00) == vs &&
			    nv_ro08(bios, data + 0x01) == pe)
				break;
			idx++;
		}
	}

	return nvbios_dpcfg_parse(bios, outp, pe, ver, hdr, cnt, len, info);
}
