/*
 * Copyright 2021 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.
 */
#include <nvif/outp.h>
#include <nvif/disp.h>
#include <nvif/printf.h>

#include <nvif/class.h>

int
nvif_outp_dp_mst_vcpi(struct nvif_outp *outp, int head,
		      u8 start_slot, u8 num_slots, u16 pbn, u16 aligned_pbn)
{
	struct nvif_outp_dp_mst_vcpi_v0 args;
	int ret;

	args.version = 0;
	args.head = head;
	args.start_slot = start_slot;
	args.num_slots = num_slots;
	args.pbn = pbn;
	args.aligned_pbn = aligned_pbn;

	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_MST_VCPI, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object,
		   "[DP_MST_VCPI head:%d start_slot:%02x num_slots:%02x pbn:%04x aligned_pbn:%04x]",
		   args.head, args.start_slot, args.num_slots, args.pbn, args.aligned_pbn);
	return ret;
}

int
nvif_outp_dp_mst_id_put(struct nvif_outp *outp, u32 id)
{
	struct nvif_outp_dp_mst_id_get_v0 args;
	int ret;

	args.version = 0;
	args.id = id;
	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_MST_ID_PUT, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[DP_MST_ID_PUT id:%08x]", args.id);
	return ret;
}

int
nvif_outp_dp_mst_id_get(struct nvif_outp *outp, u32 *id)
{
	struct nvif_outp_dp_mst_id_get_v0 args;
	int ret;

	args.version = 0;
	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_MST_ID_GET, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[DP_MST_ID_GET] id:%08x", args.id);
	if (ret)
		return ret;

	*id = args.id;
	return 0;
}

int
nvif_outp_dp_sst(struct nvif_outp *outp, int head, u32 watermark, u32 hblanksym, u32 vblanksym)
{
	struct nvif_outp_dp_sst_v0 args;
	int ret;

	args.version = 0;
	args.head = head;
	args.watermark = watermark;
	args.hblanksym = hblanksym;
	args.vblanksym = vblanksym;
	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_SST, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object,
		   "[DP_SST head:%d watermark:%d hblanksym:%d vblanksym:%d]",
		   args.head, args.watermark, args.hblanksym, args.vblanksym);
	return ret;
}

int
nvif_outp_dp_drive(struct nvif_outp *outp, u8 link_nr, u8 pe[4], u8 vs[4])
{
	struct nvif_outp_dp_drive_v0 args;
	int ret;

	args.version = 0;
	args.lanes   = link_nr;
	memcpy(args.pe, pe, sizeof(args.pe));
	memcpy(args.vs, vs, sizeof(args.vs));

	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_DRIVE, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[DP_DRIVE lanes:%d]", args.lanes);
	return ret;
}

int
nvif_outp_dp_train(struct nvif_outp *outp, u8 dpcd[DP_RECEIVER_CAP_SIZE], u8 lttprs,
		   u8 link_nr, u32 link_bw, bool mst, bool post_lt_adj, bool retrain)
{
	struct nvif_outp_dp_train_v0 args;
	int ret;

	args.version = 0;
	args.retrain = retrain;
	args.mst = mst;
	args.lttprs = lttprs;
	args.post_lt_adj = post_lt_adj;
	args.link_nr = link_nr;
	args.link_bw = link_bw;
	memcpy(args.dpcd, dpcd, sizeof(args.dpcd));

	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_TRAIN, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object,
		   "[DP_TRAIN retrain:%d mst:%d lttprs:%d post_lt_adj:%d nr:%d bw:%d]",
		   args.retrain, args.mst, args.lttprs, args.post_lt_adj, args.link_nr,
		   args.link_bw);
	return ret;
}

int
nvif_outp_dp_rates(struct nvif_outp *outp, struct nvif_outp_dp_rate *rate, int rate_nr)
{
	struct nvif_outp_dp_rates_v0 args;
	int ret;

	if (rate_nr > ARRAY_SIZE(args.rate))
		return -EINVAL;

	args.version = 0;
	args.rates = rate_nr;
	for (int i = 0; i < args.rates; i++, rate++) {
		args.rate[i].dpcd = rate->dpcd;
		args.rate[i].rate = rate->rate;
	}

	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_RATES, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[DP_RATES rates:%d]", args.rates);
	return ret;
}

int
nvif_outp_dp_aux_xfer(struct nvif_outp *outp, u8 type, u8 *psize, u32 addr, u8 *data)
{
	struct nvif_outp_dp_aux_xfer_v0 args;
	u8 size = *psize;
	int ret;

	args.version = 0;
	args.type = type;
	args.size = size;
	args.addr = addr;
	memcpy(args.data, data, size);
	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_AUX_XFER, &args, sizeof(args));
	NVIF_DEBUG(&outp->object, "[DP_AUX_XFER type:%d size:%d addr:%05x] %d size:%d (ret: %d)",
		   args.type, size, args.addr, ret, args.size, ret);
	if (ret < 0)
		return ret;

	*psize = args.size;

	memcpy(data, args.data, size);
	return ret;
}

int
nvif_outp_dp_aux_pwr(struct nvif_outp *outp, bool enable)
{
	struct nvif_outp_dp_aux_pwr_v0 args;
	int ret;

	args.version = 0;
	args.state = enable;

	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_DP_AUX_PWR, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[DP_AUX_PWR state:%d]", args.state);
	return ret;
}

int
nvif_outp_hda_eld(struct nvif_outp *outp, int head, void *data, u32 size)
{
	struct {
		struct nvif_outp_hda_eld_v0 mthd;
		u8 data[128];
	} args;
	int ret;

	if (WARN_ON(size > ARRAY_SIZE(args.data)))
		return -EINVAL;

	args.mthd.version = 0;
	args.mthd.head = head;

	memcpy(args.data, data, size);
	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_HDA_ELD, &args, sizeof(args.mthd) + size);
	NVIF_ERRON(ret, &outp->object, "[HDA_ELD head:%d size:%d]", head, size);
	return ret;
}

int
nvif_outp_infoframe(struct nvif_outp *outp, u8 type, struct nvif_outp_infoframe_v0 *args, u32 size)
{
	int ret;

	args->type = type;

	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_INFOFRAME, args, sizeof(*args) + size);
	NVIF_ERRON(ret, &outp->object, "[INFOFRAME type:%d size:%d]", type, size);
	return ret;
}

int
nvif_outp_hdmi(struct nvif_outp *outp, int head, bool enable, u8 max_ac_packet, u8 rekey,
	       u32 khz, bool scdc, bool scdc_scrambling, bool scdc_low_rates)
{
	struct nvif_outp_hdmi_v0 args;
	int ret;

	args.version = 0;
	args.head = head;
	args.enable = enable;
	args.max_ac_packet = max_ac_packet;
	args.rekey = rekey;
	args.khz = khz;
	args.scdc = scdc;
	args.scdc_scrambling = scdc_scrambling;
	args.scdc_low_rates = scdc_low_rates;

	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_HDMI, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object,
		   "[HDMI head:%d enable:%d max_ac_packet:%d rekey:%d khz:%d scdc:%d "
		   "scdc_scrambling:%d scdc_low_rates:%d]",
		   args.head, args.enable, args.max_ac_packet, args.rekey, args.khz,
		   args.scdc, args.scdc_scrambling, args.scdc_low_rates);
	return ret;
}

int
nvif_outp_lvds(struct nvif_outp *outp, bool dual, bool bpc8)
{
	struct nvif_outp_lvds_v0 args;
	int ret;

	args.version = 0;
	args.dual = dual;
	args.bpc8 = bpc8;

	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_LVDS, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[LVDS dual:%d 8bpc:%d]", args.dual, args.bpc8);
	return ret;
}

int
nvif_outp_bl_set(struct nvif_outp *outp, int level)
{
	struct nvif_outp_bl_set_v0 args;
	int ret;

	args.version = 0;
	args.level = level;

	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_BL_SET, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[BL_SET level:%d]", args.level);
	return ret;
}

int
nvif_outp_bl_get(struct nvif_outp *outp)
{
	struct nvif_outp_bl_get_v0 args;
	int ret;

	args.version = 0;

	ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_BL_GET, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[BL_GET level:%d]", args.level);
	return ret ? ret : args.level;
}

void
nvif_outp_release(struct nvif_outp *outp)
{
	int ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_RELEASE, NULL, 0);
	NVIF_ERRON(ret, &outp->object, "[RELEASE]");
	outp->or.id = -1;
}

static inline int
nvif_outp_acquire(struct nvif_outp *outp, u8 type, struct nvif_outp_acquire_v0 *args)
{
	int ret;

	args->version = 0;
	args->type = type;

	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_ACQUIRE, args, sizeof(*args));
	if (ret)
		return ret;

	outp->or.id = args->or;
	outp->or.link = args->link;
	return 0;
}

int
nvif_outp_acquire_pior(struct nvif_outp *outp)
{
	struct nvif_outp_acquire_v0 args;
	int ret;

	ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_PIOR, &args);
	NVIF_ERRON(ret, &outp->object, "[ACQUIRE PIOR] or:%d", args.or);
	return ret;
}

int
nvif_outp_acquire_sor(struct nvif_outp *outp, bool hda)
{
	struct nvif_outp_acquire_v0 args;
	int ret;

	args.sor.hda = hda;

	ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_SOR, &args);
	NVIF_ERRON(ret, &outp->object, "[ACQUIRE SOR] or:%d link:%d", args.or, args.link);
	return ret;
}

int
nvif_outp_acquire_dac(struct nvif_outp *outp)
{
	struct nvif_outp_acquire_v0 args;
	int ret;

	ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_DAC, &args);
	NVIF_ERRON(ret, &outp->object, "[ACQUIRE DAC] or:%d", args.or);
	return ret;
}

static int
nvif_outp_inherit(struct nvif_outp *outp,
		  u8 proto,
		  struct nvif_outp_inherit_v0 *args,
		  u8 *proto_out)
{
	int ret;

	args->version = 0;
	args->proto = proto;

	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_INHERIT, args, sizeof(*args));
	if (ret)
		return ret;

	outp->or.id = args->or;
	outp->or.link = args->link;
	*proto_out = args->proto;
	return 0;
}

int
nvif_outp_inherit_lvds(struct nvif_outp *outp, u8 *proto_out)
{
	struct nvif_outp_inherit_v0 args;
	int ret;

	ret = nvif_outp_inherit(outp, NVIF_OUTP_INHERIT_V0_LVDS, &args, proto_out);
	NVIF_ERRON(ret && ret != -ENODEV, &outp->object, "[INHERIT proto:LVDS] ret:%d", ret);
	return ret ?: args.head;
}

int
nvif_outp_inherit_tmds(struct nvif_outp *outp, u8 *proto_out)
{
	struct nvif_outp_inherit_v0 args;
	int ret;

	ret = nvif_outp_inherit(outp, NVIF_OUTP_INHERIT_V0_TMDS, &args, proto_out);
	NVIF_ERRON(ret && ret != -ENODEV, &outp->object, "[INHERIT proto:TMDS] ret:%d", ret);
	return ret ?: args.head;
}

int
nvif_outp_inherit_dp(struct nvif_outp *outp, u8 *proto_out)
{
	struct nvif_outp_inherit_v0 args;
	int ret;

	ret = nvif_outp_inherit(outp, NVIF_OUTP_INHERIT_V0_DP, &args, proto_out);
	NVIF_ERRON(ret && ret != -ENODEV, &outp->object, "[INHERIT proto:DP] ret:%d", ret);

	// TODO: Get current link info

	return ret ?: args.head;
}

int
nvif_outp_inherit_rgb_crt(struct nvif_outp *outp, u8 *proto_out)
{
	struct nvif_outp_inherit_v0 args;
	int ret;

	ret = nvif_outp_inherit(outp, NVIF_OUTP_INHERIT_V0_RGB_CRT, &args, proto_out);
	NVIF_ERRON(ret && ret != -ENODEV, &outp->object, "[INHERIT proto:RGB_CRT] ret:%d", ret);
	return ret ?: args.head;
}

int
nvif_outp_load_detect(struct nvif_outp *outp, u32 loadval)
{
	struct nvif_outp_load_detect_v0 args;
	int ret;

	args.version = 0;
	args.data = loadval;

	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_LOAD_DETECT, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[LOAD_DETECT data:%08x] load:%02x", args.data, args.load);
	return ret < 0 ? ret : args.load;
}

int
nvif_outp_edid_get(struct nvif_outp *outp, u8 **pedid)
{
	struct nvif_outp_edid_get_v0 *args;
	int ret;

	args = kmalloc(sizeof(*args), GFP_KERNEL);
	if (!args)
		return -ENOMEM;

	args->version = 0;

	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_EDID_GET, args, sizeof(*args));
	NVIF_ERRON(ret, &outp->object, "[EDID_GET] size:%d", args->size);
	if (ret)
		goto done;

	*pedid = kmalloc(args->size, GFP_KERNEL);
	if (!*pedid) {
		ret = -ENOMEM;
		goto done;
	}

	memcpy(*pedid, args->data, args->size);
	ret = args->size;
done:
	kfree(args);
	return ret;
}

enum nvif_outp_detect_status
nvif_outp_detect(struct nvif_outp *outp)
{
	struct nvif_outp_detect_v0 args;
	int ret;

	args.version = 0;

	ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_DETECT, &args, sizeof(args));
	NVIF_ERRON(ret, &outp->object, "[DETECT] status:%02x", args.status);
	if (ret)
		return UNKNOWN;

	switch (args.status) {
	case NVIF_OUTP_DETECT_V0_NOT_PRESENT: return NOT_PRESENT;
	case NVIF_OUTP_DETECT_V0_PRESENT: return PRESENT;
	case NVIF_OUTP_DETECT_V0_UNKNOWN: return UNKNOWN;
	default:
		WARN_ON(1);
		break;
	}

	return UNKNOWN;
}

void
nvif_outp_dtor(struct nvif_outp *outp)
{
	nvif_object_dtor(&outp->object);
}

int
nvif_outp_ctor(struct nvif_disp *disp, const char *name, int id, struct nvif_outp *outp)
{
	struct nvif_outp_v0 args;
	int ret;

	args.version = 0;
	args.id = id;

	ret = nvif_object_ctor(&disp->object, name ?: "nvifOutp", id, NVIF_CLASS_OUTP,
			       &args, sizeof(args), &outp->object);
	NVIF_ERRON(ret, &disp->object, "[NEW outp id:%d]", id);
	if (ret)
		return ret;

	outp->id = args.id;

	switch (args.type) {
	case NVIF_OUTP_V0_TYPE_DAC : outp->info.type = NVIF_OUTP_DAC; break;
	case NVIF_OUTP_V0_TYPE_SOR : outp->info.type = NVIF_OUTP_SOR; break;
	case NVIF_OUTP_V0_TYPE_PIOR: outp->info.type = NVIF_OUTP_PIOR; break;
		break;
	default:
		WARN_ON(1);
		nvif_outp_dtor(outp);
		return -EINVAL;
	}

	switch (args.proto) {
	case NVIF_OUTP_V0_PROTO_RGB_CRT:
		outp->info.proto = NVIF_OUTP_RGB_CRT;
		outp->info.rgb_crt.freq_max = args.rgb_crt.freq_max;
		break;
	case NVIF_OUTP_V0_PROTO_TMDS:
		outp->info.proto = NVIF_OUTP_TMDS;
		outp->info.tmds.dual = args.tmds.dual;
		break;
	case NVIF_OUTP_V0_PROTO_LVDS:
		outp->info.proto = NVIF_OUTP_LVDS;
		outp->info.lvds.acpi_edid = args.lvds.acpi_edid;
		break;
	case NVIF_OUTP_V0_PROTO_DP:
		outp->info.proto = NVIF_OUTP_DP;
		outp->info.dp.aux = args.dp.aux;
		outp->info.dp.mst = args.dp.mst;
		outp->info.dp.increased_wm = args.dp.increased_wm;
		outp->info.dp.link_nr = args.dp.link_nr;
		outp->info.dp.link_bw = args.dp.link_bw;
		break;
	default:
		WARN_ON(1);
		nvif_outp_dtor(outp);
		return -EINVAL;
	}

	outp->info.heads = args.heads;
	outp->info.ddc = args.ddc;
	outp->info.conn = args.conn;

	outp->or.id = -1;
	return 0;
}
