/*
 * 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 "nv50.h"
#include "head.h"
#include "ior.h"
#include "channv50.h"
#include "rootnv50.h"

#include <core/client.h>
#include <core/ramht.h>
#include <subdev/bios.h>
#include <subdev/bios/disp.h>
#include <subdev/bios/init.h>
#include <subdev/bios/pll.h>
#include <subdev/devinit.h>
#include <subdev/timer.h>

static const struct nvkm_disp_oclass *
nv50_disp_root_(struct nvkm_disp *base)
{
	return nv50_disp(base)->func->root;
}

static void
nv50_disp_intr_(struct nvkm_disp *base)
{
	struct nv50_disp *disp = nv50_disp(base);
	disp->func->intr(disp);
}

static void
nv50_disp_fini_(struct nvkm_disp *base)
{
	struct nv50_disp *disp = nv50_disp(base);
	disp->func->fini(disp);
}

static int
nv50_disp_init_(struct nvkm_disp *base)
{
	struct nv50_disp *disp = nv50_disp(base);
	return disp->func->init(disp);
}

static void *
nv50_disp_dtor_(struct nvkm_disp *base)
{
	struct nv50_disp *disp = nv50_disp(base);

	nvkm_ramht_del(&disp->ramht);
	nvkm_gpuobj_del(&disp->inst);

	nvkm_event_fini(&disp->uevent);
	if (disp->wq)
		destroy_workqueue(disp->wq);

	return disp;
}

static int
nv50_disp_oneinit_(struct nvkm_disp *base)
{
	struct nv50_disp *disp = nv50_disp(base);
	const struct nv50_disp_func *func = disp->func;
	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	int ret, i;

	if (func->wndw.cnt) {
		disp->wndw.nr = func->wndw.cnt(&disp->base, &disp->wndw.mask);
		nvkm_debug(subdev, "Window(s): %d (%08lx)\n",
			   disp->wndw.nr, disp->wndw.mask);
	}

	disp->head.nr = func->head.cnt(&disp->base, &disp->head.mask);
	nvkm_debug(subdev, "  Head(s): %d (%02lx)\n",
		   disp->head.nr, disp->head.mask);
	for_each_set_bit(i, &disp->head.mask, disp->head.nr) {
		ret = func->head.new(&disp->base, i);
		if (ret)
			return ret;
	}

	if (func->dac.cnt) {
		disp->dac.nr = func->dac.cnt(&disp->base, &disp->dac.mask);
		nvkm_debug(subdev, "   DAC(s): %d (%02lx)\n",
			   disp->dac.nr, disp->dac.mask);
		for_each_set_bit(i, &disp->dac.mask, disp->dac.nr) {
			ret = func->dac.new(&disp->base, i);
			if (ret)
				return ret;
		}
	}

	if (func->pior.cnt) {
		disp->pior.nr = func->pior.cnt(&disp->base, &disp->pior.mask);
		nvkm_debug(subdev, "  PIOR(s): %d (%02lx)\n",
			   disp->pior.nr, disp->pior.mask);
		for_each_set_bit(i, &disp->pior.mask, disp->pior.nr) {
			ret = func->pior.new(&disp->base, i);
			if (ret)
				return ret;
		}
	}

	disp->sor.nr = func->sor.cnt(&disp->base, &disp->sor.mask);
	nvkm_debug(subdev, "   SOR(s): %d (%02lx)\n",
		   disp->sor.nr, disp->sor.mask);
	for_each_set_bit(i, &disp->sor.mask, disp->sor.nr) {
		ret = func->sor.new(&disp->base, i);
		if (ret)
			return ret;
	}

	ret = nvkm_gpuobj_new(device, 0x10000, 0x10000, false, NULL,
			      &disp->inst);
	if (ret)
		return ret;

	return nvkm_ramht_new(device, func->ramht_size ? func->ramht_size :
			      0x1000, 0, disp->inst, &disp->ramht);
}

static const struct nvkm_disp_func
nv50_disp_ = {
	.dtor = nv50_disp_dtor_,
	.oneinit = nv50_disp_oneinit_,
	.init = nv50_disp_init_,
	.fini = nv50_disp_fini_,
	.intr = nv50_disp_intr_,
	.root = nv50_disp_root_,
};

int
nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
	       int index, struct nvkm_disp **pdisp)
{
	struct nv50_disp *disp;
	int ret;

	if (!(disp = kzalloc(sizeof(*disp), GFP_KERNEL)))
		return -ENOMEM;
	disp->func = func;
	*pdisp = &disp->base;

	ret = nvkm_disp_ctor(&nv50_disp_, device, index, &disp->base);
	if (ret)
		return ret;

	disp->wq = create_singlethread_workqueue("nvkm-disp");
	if (!disp->wq)
		return -ENOMEM;

	INIT_WORK(&disp->supervisor, func->super);

	return nvkm_event_init(func->uevent, 1, ARRAY_SIZE(disp->chan),
			       &disp->uevent);
}

static u32
nv50_disp_super_iedt(struct nvkm_head *head, struct nvkm_outp *outp,
		     u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
		     struct nvbios_outp *iedt)
{
	struct nvkm_bios *bios = head->disp->engine.subdev.device->bios;
	const u8  l = ffs(outp->info.link);
	const u16 t = outp->info.hasht;
	const u16 m = (0x0100 << head->id) | (l << 6) | outp->info.or;
	u32 data = nvbios_outp_match(bios, t, m, ver, hdr, cnt, len, iedt);
	if (!data)
		OUTP_DBG(outp, "missing IEDT for %04x:%04x", t, m);
	return data;
}

static void
nv50_disp_super_ied_on(struct nvkm_head *head,
		       struct nvkm_ior *ior, int id, u32 khz)
{
	struct nvkm_subdev *subdev = &head->disp->engine.subdev;
	struct nvkm_bios *bios = subdev->device->bios;
	struct nvkm_outp *outp = ior->asy.outp;
	struct nvbios_ocfg iedtrs;
	struct nvbios_outp iedt;
	u8  ver, hdr, cnt, len, flags = 0x00;
	u32 data;

	if (!outp) {
		IOR_DBG(ior, "nothing to attach");
		return;
	}

	/* Lookup IED table for the device. */
	data = nv50_disp_super_iedt(head, outp, &ver, &hdr, &cnt, &len, &iedt);
	if (!data)
		return;

	/* Lookup IEDT runtime settings for the current configuration. */
	if (ior->type == SOR) {
		if (ior->asy.proto == LVDS) {
			if (head->asy.or.depth == 24)
				flags |= 0x02;
		}
		if (ior->asy.link == 3)
			flags |= 0x01;
	}

	data = nvbios_ocfg_match(bios, data, ior->asy.proto_evo, flags,
				 &ver, &hdr, &cnt, &len, &iedtrs);
	if (!data) {
		OUTP_DBG(outp, "missing IEDT RS for %02x:%02x",
			 ior->asy.proto_evo, flags);
		return;
	}

	/* Execute the OnInt[23] script for the current frequency. */
	data = nvbios_oclk_match(bios, iedtrs.clkcmp[id], khz);
	if (!data) {
		OUTP_DBG(outp, "missing IEDT RSS %d for %02x:%02x %d khz",
			 id, ior->asy.proto_evo, flags, khz);
		return;
	}

	nvbios_init(subdev, data,
		init.outp = &outp->info;
		init.or   = ior->id;
		init.link = ior->asy.link;
		init.head = head->id;
	);
}

static void
nv50_disp_super_ied_off(struct nvkm_head *head, struct nvkm_ior *ior, int id)
{
	struct nvkm_outp *outp = ior->arm.outp;
	struct nvbios_outp iedt;
	u8  ver, hdr, cnt, len;
	u32 data;

	if (!outp) {
		IOR_DBG(ior, "nothing attached");
		return;
	}

	data = nv50_disp_super_iedt(head, outp, &ver, &hdr, &cnt, &len, &iedt);
	if (!data)
		return;

	nvbios_init(&head->disp->engine.subdev, iedt.script[id],
		init.outp = &outp->info;
		init.or   = ior->id;
		init.link = ior->arm.link;
		init.head = head->id;
	);
}

static struct nvkm_ior *
nv50_disp_super_ior_asy(struct nvkm_head *head)
{
	struct nvkm_ior *ior;
	list_for_each_entry(ior, &head->disp->ior, head) {
		if (ior->asy.head & (1 << head->id)) {
			HEAD_DBG(head, "to %s", ior->name);
			return ior;
		}
	}
	HEAD_DBG(head, "nothing to attach");
	return NULL;
}

static struct nvkm_ior *
nv50_disp_super_ior_arm(struct nvkm_head *head)
{
	struct nvkm_ior *ior;
	list_for_each_entry(ior, &head->disp->ior, head) {
		if (ior->arm.head & (1 << head->id)) {
			HEAD_DBG(head, "on %s", ior->name);
			return ior;
		}
	}
	HEAD_DBG(head, "nothing attached");
	return NULL;
}

void
nv50_disp_super_3_0(struct nv50_disp *disp, struct nvkm_head *head)
{
	struct nvkm_ior *ior;

	/* Determine which OR, if any, we're attaching to the head. */
	HEAD_DBG(head, "supervisor 3.0");
	ior = nv50_disp_super_ior_asy(head);
	if (!ior)
		return;

	/* Execute OnInt3 IED script. */
	nv50_disp_super_ied_on(head, ior, 1, head->asy.hz / 1000);

	/* OR-specific handling. */
	if (ior->func->war_3)
		ior->func->war_3(ior);
}

static void
nv50_disp_super_2_2_dp(struct nvkm_head *head, struct nvkm_ior *ior)
{
	struct nvkm_subdev *subdev = &head->disp->engine.subdev;
	const u32      khz = head->asy.hz / 1000;
	const u32 linkKBps = ior->dp.bw * 27000;
	const u32   symbol = 100000;
	int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0;
	int TU, VTUi, VTUf, VTUa;
	u64 link_data_rate, link_ratio, unk;
	u32 best_diff = 64 * symbol;
	u64 h, v;

	/* symbols/hblank - algorithm taken from comments in tegra driver */
	h = head->asy.hblanke + head->asy.htotal - head->asy.hblanks - 7;
	h = h * linkKBps;
	do_div(h, khz);
	h = h - (3 * ior->dp.ef) - (12 / ior->dp.nr);

	/* symbols/vblank - algorithm taken from comments in tegra driver */
	v = head->asy.vblanks - head->asy.vblanke - 25;
	v = v * linkKBps;
	do_div(v, khz);
	v = v - ((36 / ior->dp.nr) + 3) - 1;

	ior->func->dp.audio_sym(ior, head->id, h, v);

	/* watermark / activesym */
	link_data_rate = (khz * head->asy.or.depth / 8) / ior->dp.nr;

	/* calculate ratio of packed data rate to link symbol rate */
	link_ratio = link_data_rate * symbol;
	do_div(link_ratio, linkKBps);

	for (TU = 64; ior->func->dp.activesym && TU >= 32; TU--) {
		/* calculate average number of valid symbols in each TU */
		u32 tu_valid = link_ratio * TU;
		u32 calc, diff;

		/* find a hw representation for the fraction.. */
		VTUi = tu_valid / symbol;
		calc = VTUi * symbol;
		diff = tu_valid - calc;
		if (diff) {
			if (diff >= (symbol / 2)) {
				VTUf = symbol / (symbol - diff);
				if (symbol - (VTUf * diff))
					VTUf++;

				if (VTUf <= 15) {
					VTUa  = 1;
					calc += symbol - (symbol / VTUf);
				} else {
					VTUa  = 0;
					VTUf  = 1;
					calc += symbol;
				}
			} else {
				VTUa  = 0;
				VTUf  = min((int)(symbol / diff), 15);
				calc += symbol / VTUf;
			}

			diff = calc - tu_valid;
		} else {
			/* no remainder, but the hw doesn't like the fractional
			 * part to be zero.  decrement the integer part and
			 * have the fraction add a whole symbol back
			 */
			VTUa = 0;
			VTUf = 1;
			VTUi--;
		}

		if (diff < best_diff) {
			best_diff = diff;
			bestTU = TU;
			bestVTUa = VTUa;
			bestVTUf = VTUf;
			bestVTUi = VTUi;
			if (diff == 0)
				break;
		}
	}

	if (ior->func->dp.activesym) {
		if (!bestTU) {
			nvkm_error(subdev, "unable to determine dp config\n");
			return;
		}
		ior->func->dp.activesym(ior, head->id, bestTU,
					bestVTUa, bestVTUf, bestVTUi);
	} else {
		bestTU = 64;
	}

	/* XXX close to vbios numbers, but not right */
	unk  = (symbol - link_ratio) * bestTU;
	unk *= link_ratio;
	do_div(unk, symbol);
	do_div(unk, symbol);
	unk += 6;

	ior->func->dp.watermark(ior, head->id, unk);
}

void
nv50_disp_super_2_2(struct nv50_disp *disp, struct nvkm_head *head)
{
	const u32 khz = head->asy.hz / 1000;
	struct nvkm_outp *outp;
	struct nvkm_ior *ior;

	/* Determine which OR, if any, we're attaching from the head. */
	HEAD_DBG(head, "supervisor 2.2");
	ior = nv50_disp_super_ior_asy(head);
	if (!ior)
		return;

	/* For some reason, NVIDIA decided not to:
	 *
	 * A) Give dual-link LVDS a separate EVO protocol, like for TMDS.
	 *  and
	 * B) Use SetControlOutputResource.PixelDepth on LVDS.
	 *
	 * Override the values we usually read from HW with the same
	 * data we pass though an ioctl instead.
	 */
	if (ior->type == SOR && ior->asy.proto == LVDS) {
		head->asy.or.depth = (disp->sor.lvdsconf & 0x0200) ? 24 : 18;
		ior->asy.link      = (disp->sor.lvdsconf & 0x0100) ? 3  : 1;
	}

	/* Handle any link training, etc. */
	if ((outp = ior->asy.outp) && outp->func->acquire)
		outp->func->acquire(outp);

	/* Execute OnInt2 IED script. */
	nv50_disp_super_ied_on(head, ior, 0, khz);

	/* Program RG clock divider. */
	head->func->rgclk(head, ior->asy.rgdiv);

	/* Mode-specific internal DP configuration. */
	if (ior->type == SOR && ior->asy.proto == DP)
		nv50_disp_super_2_2_dp(head, ior);

	/* OR-specific handling. */
	ior->func->clock(ior);
	if (ior->func->war_2)
		ior->func->war_2(ior);
}

void
nv50_disp_super_2_1(struct nv50_disp *disp, struct nvkm_head *head)
{
	struct nvkm_devinit *devinit = disp->base.engine.subdev.device->devinit;
	const u32 khz = head->asy.hz / 1000;
	HEAD_DBG(head, "supervisor 2.1 - %d khz", khz);
	if (khz)
		nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head->id, khz);
}

void
nv50_disp_super_2_0(struct nv50_disp *disp, struct nvkm_head *head)
{
	struct nvkm_outp *outp;
	struct nvkm_ior *ior;

	/* Determine which OR, if any, we're detaching from the head. */
	HEAD_DBG(head, "supervisor 2.0");
	ior = nv50_disp_super_ior_arm(head);
	if (!ior)
		return;

	/* Execute OffInt2 IED script. */
	nv50_disp_super_ied_off(head, ior, 2);

	/* If we're shutting down the OR's only active head, execute
	 * the output path's disable function.
	 */
	if (ior->arm.head == (1 << head->id)) {
		if ((outp = ior->arm.outp) && outp->func->disable)
			outp->func->disable(outp, ior);
	}
}

void
nv50_disp_super_1_0(struct nv50_disp *disp, struct nvkm_head *head)
{
	struct nvkm_ior *ior;

	/* Determine which OR, if any, we're detaching from the head. */
	HEAD_DBG(head, "supervisor 1.0");
	ior = nv50_disp_super_ior_arm(head);
	if (!ior)
		return;

	/* Execute OffInt1 IED script. */
	nv50_disp_super_ied_off(head, ior, 1);
}

void
nv50_disp_super_1(struct nv50_disp *disp)
{
	struct nvkm_head *head;
	struct nvkm_ior *ior;

	list_for_each_entry(head, &disp->base.head, head) {
		head->func->state(head, &head->arm);
		head->func->state(head, &head->asy);
	}

	list_for_each_entry(ior, &disp->base.ior, head) {
		ior->func->state(ior, &ior->arm);
		ior->func->state(ior, &ior->asy);
	}
}

void
nv50_disp_super(struct work_struct *work)
{
	struct nv50_disp *disp =
		container_of(work, struct nv50_disp, supervisor);
	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	struct nvkm_head *head;
	u32 super = nvkm_rd32(device, 0x610030);

	nvkm_debug(subdev, "supervisor %08x %08x\n", disp->super, super);

	if (disp->super & 0x00000010) {
		nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
		nv50_disp_super_1(disp);
		list_for_each_entry(head, &disp->base.head, head) {
			if (!(super & (0x00000020 << head->id)))
				continue;
			if (!(super & (0x00000080 << head->id)))
				continue;
			nv50_disp_super_1_0(disp, head);
		}
	} else
	if (disp->super & 0x00000020) {
		list_for_each_entry(head, &disp->base.head, head) {
			if (!(super & (0x00000080 << head->id)))
				continue;
			nv50_disp_super_2_0(disp, head);
		}
		nvkm_outp_route(&disp->base);
		list_for_each_entry(head, &disp->base.head, head) {
			if (!(super & (0x00000200 << head->id)))
				continue;
			nv50_disp_super_2_1(disp, head);
		}
		list_for_each_entry(head, &disp->base.head, head) {
			if (!(super & (0x00000080 << head->id)))
				continue;
			nv50_disp_super_2_2(disp, head);
		}
	} else
	if (disp->super & 0x00000040) {
		list_for_each_entry(head, &disp->base.head, head) {
			if (!(super & (0x00000080 << head->id)))
				continue;
			nv50_disp_super_3_0(disp, head);
		}
	}

	nvkm_wr32(device, 0x610030, 0x80000000);
}

const struct nvkm_enum
nv50_disp_intr_error_type[] = {
	{ 0, "NONE" },
	{ 1, "PUSHBUFFER_ERR" },
	{ 2, "TRAP" },
	{ 3, "RESERVED_METHOD" },
	{ 4, "INVALID_ARG" },
	{ 5, "INVALID_STATE" },
	{ 7, "UNRESOLVABLE_HANDLE" },
	{}
};

static const struct nvkm_enum
nv50_disp_intr_error_code[] = {
	{ 0x00, "" },
	{}
};

static void
nv50_disp_intr_error(struct nv50_disp *disp, int chid)
{
	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
	struct nvkm_device *device = subdev->device;
	u32 data = nvkm_rd32(device, 0x610084 + (chid * 0x08));
	u32 addr = nvkm_rd32(device, 0x610080 + (chid * 0x08));
	u32 code = (addr & 0x00ff0000) >> 16;
	u32 type = (addr & 0x00007000) >> 12;
	u32 mthd = (addr & 0x00000ffc);
	const struct nvkm_enum *ec, *et;

	et = nvkm_enum_find(nv50_disp_intr_error_type, type);
	ec = nvkm_enum_find(nv50_disp_intr_error_code, code);

	nvkm_error(subdev,
		   "ERROR %d [%s] %02x [%s] chid %d mthd %04x data %08x\n",
		   type, et ? et->name : "", code, ec ? ec->name : "",
		   chid, mthd, data);

	if (chid < ARRAY_SIZE(disp->chan)) {
		switch (mthd) {
		case 0x0080:
			nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR);
			break;
		default:
			break;
		}
	}

	nvkm_wr32(device, 0x610020, 0x00010000 << chid);
	nvkm_wr32(device, 0x610080 + (chid * 0x08), 0x90000000);
}

void
nv50_disp_intr(struct nv50_disp *disp)
{
	struct nvkm_device *device = disp->base.engine.subdev.device;
	u32 intr0 = nvkm_rd32(device, 0x610020);
	u32 intr1 = nvkm_rd32(device, 0x610024);

	while (intr0 & 0x001f0000) {
		u32 chid = __ffs(intr0 & 0x001f0000) - 16;
		nv50_disp_intr_error(disp, chid);
		intr0 &= ~(0x00010000 << chid);
	}

	while (intr0 & 0x0000001f) {
		u32 chid = __ffs(intr0 & 0x0000001f);
		nv50_disp_chan_uevent_send(disp, chid);
		intr0 &= ~(0x00000001 << chid);
	}

	if (intr1 & 0x00000004) {
		nvkm_disp_vblank(&disp->base, 0);
		nvkm_wr32(device, 0x610024, 0x00000004);
	}

	if (intr1 & 0x00000008) {
		nvkm_disp_vblank(&disp->base, 1);
		nvkm_wr32(device, 0x610024, 0x00000008);
	}

	if (intr1 & 0x00000070) {
		disp->super = (intr1 & 0x00000070);
		queue_work(disp->wq, &disp->supervisor);
		nvkm_wr32(device, 0x610024, disp->super);
	}
}

void
nv50_disp_fini(struct nv50_disp *disp)
{
	struct nvkm_device *device = disp->base.engine.subdev.device;
	/* disable all interrupts */
	nvkm_wr32(device, 0x610024, 0x00000000);
	nvkm_wr32(device, 0x610020, 0x00000000);
}

int
nv50_disp_init(struct nv50_disp *disp)
{
	struct nvkm_device *device = disp->base.engine.subdev.device;
	struct nvkm_head *head;
	u32 tmp;
	int i;

	/* The below segments of code copying values from one register to
	 * another appear to inform EVO of the display capabilities or
	 * something similar.  NFI what the 0x614004 caps are for..
	 */
	tmp = nvkm_rd32(device, 0x614004);
	nvkm_wr32(device, 0x610184, tmp);

	/* ... CRTC caps */
	list_for_each_entry(head, &disp->base.head, head) {
		tmp = nvkm_rd32(device, 0x616100 + (head->id * 0x800));
		nvkm_wr32(device, 0x610190 + (head->id * 0x10), tmp);
		tmp = nvkm_rd32(device, 0x616104 + (head->id * 0x800));
		nvkm_wr32(device, 0x610194 + (head->id * 0x10), tmp);
		tmp = nvkm_rd32(device, 0x616108 + (head->id * 0x800));
		nvkm_wr32(device, 0x610198 + (head->id * 0x10), tmp);
		tmp = nvkm_rd32(device, 0x61610c + (head->id * 0x800));
		nvkm_wr32(device, 0x61019c + (head->id * 0x10), tmp);
	}

	/* ... DAC caps */
	for (i = 0; i < disp->dac.nr; i++) {
		tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800));
		nvkm_wr32(device, 0x6101d0 + (i * 0x04), tmp);
	}

	/* ... SOR caps */
	for (i = 0; i < disp->sor.nr; i++) {
		tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
		nvkm_wr32(device, 0x6101e0 + (i * 0x04), tmp);
	}

	/* ... PIOR caps */
	for (i = 0; i < disp->pior.nr; i++) {
		tmp = nvkm_rd32(device, 0x61e000 + (i * 0x800));
		nvkm_wr32(device, 0x6101f0 + (i * 0x04), tmp);
	}

	/* steal display away from vbios, or something like that */
	if (nvkm_rd32(device, 0x610024) & 0x00000100) {
		nvkm_wr32(device, 0x610024, 0x00000100);
		nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000);
		if (nvkm_msec(device, 2000,
			if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002))
				break;
		) < 0)
			return -EBUSY;
	}

	/* point at display engine memory area (hash table, objects) */
	nvkm_wr32(device, 0x610010, (disp->inst->addr >> 8) | 9);

	/* enable supervisor interrupts, disable everything else */
	nvkm_wr32(device, 0x61002c, 0x00000370);
	nvkm_wr32(device, 0x610028, 0x00000000);
	return 0;
}

static const struct nv50_disp_func
nv50_disp = {
	.init = nv50_disp_init,
	.fini = nv50_disp_fini,
	.intr = nv50_disp_intr,
	.uevent = &nv50_disp_chan_uevent,
	.super = nv50_disp_super,
	.root = &nv50_disp_root_oclass,
	.head = { .cnt = nv50_head_cnt, .new = nv50_head_new },
	.dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new },
	.sor = { .cnt = nv50_sor_cnt, .new = nv50_sor_new },
	.pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new },
};

int
nv50_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
{
	return nv50_disp_new_(&nv50_disp, device, index, pdisp);
}
