/*
 * Copyright (C) 2008 Maarten Maathuis.
 * All Rights Reserved.
 *
 * 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 (including the
 * next paragraph) 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 OWNER(S) AND/OR ITS SUPPLIERS 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 "nv50_display.h"
#include "nouveau_crtc.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_fb.h"
#include "drm_crtc_helper.h"

static void
nv50_evo_channel_del(struct nouveau_channel **pchan)
{
	struct nouveau_channel *chan = *pchan;

	if (!chan)
		return;
	*pchan = NULL;

	nouveau_gpuobj_channel_takedown(chan);
	nouveau_bo_ref(NULL, &chan->pushbuf_bo);

	if (chan->user)
		iounmap(chan->user);

	kfree(chan);
}

static int
nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name,
		    uint32_t tile_flags, uint32_t magic_flags,
		    uint32_t offset, uint32_t limit)
{
	struct drm_nouveau_private *dev_priv = evo->dev->dev_private;
	struct drm_device *dev = evo->dev;
	struct nouveau_gpuobj *obj = NULL;
	int ret;

	ret = nouveau_gpuobj_new(dev, evo, 6*4, 32, 0, &obj);
	if (ret)
		return ret;
	obj->engine = NVOBJ_ENGINE_DISPLAY;

	ret = nouveau_gpuobj_ref_add(dev, evo, name, obj, NULL);
	if (ret) {
		nouveau_gpuobj_del(dev, &obj);
		return ret;
	}

	dev_priv->engine.instmem.prepare_access(dev, true);
	nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class);
	nv_wo32(dev, obj, 1, limit);
	nv_wo32(dev, obj, 2, offset);
	nv_wo32(dev, obj, 3, 0x00000000);
	nv_wo32(dev, obj, 4, 0x00000000);
	nv_wo32(dev, obj, 5, 0x00010000);
	dev_priv->engine.instmem.finish_access(dev);

	return 0;
}

static int
nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_channel *chan;
	int ret;

	chan = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL);
	if (!chan)
		return -ENOMEM;
	*pchan = chan;

	chan->id = -1;
	chan->dev = dev;
	chan->user_get = 4;
	chan->user_put = 0;

	INIT_LIST_HEAD(&chan->ramht_refs);

	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32768, 0x1000,
				     NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin);
	if (ret) {
		NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret);
		nv50_evo_channel_del(pchan);
		return ret;
	}

	ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj->
				    im_pramin->start, 32768);
	if (ret) {
		NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret);
		nv50_evo_channel_del(pchan);
		return ret;
	}

	ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 4096, 16,
				     0, &chan->ramht);
	if (ret) {
		NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret);
		nv50_evo_channel_del(pchan);
		return ret;
	}

	if (dev_priv->chipset != 0x50) {
		ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB16, 0x70, 0x19,
					  0, 0xffffffff);
		if (ret) {
			nv50_evo_channel_del(pchan);
			return ret;
		}


		ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB32, 0x7a, 0x19,
					  0, 0xffffffff);
		if (ret) {
			nv50_evo_channel_del(pchan);
			return ret;
		}
	}

	ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19,
				  0, nouveau_mem_fb_amount(dev));
	if (ret) {
		nv50_evo_channel_del(pchan);
		return ret;
	}

	ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0,
			     false, true, &chan->pushbuf_bo);
	if (ret == 0)
		ret = nouveau_bo_pin(chan->pushbuf_bo, TTM_PL_FLAG_VRAM);
	if (ret) {
		NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret);
		nv50_evo_channel_del(pchan);
		return ret;
	}

	ret = nouveau_bo_map(chan->pushbuf_bo);
	if (ret) {
		NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret);
		nv50_evo_channel_del(pchan);
		return ret;
	}

	chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
					NV50_PDISPLAY_USER(0), PAGE_SIZE);
	if (!chan->user) {
		NV_ERROR(dev, "Error mapping EVO control regs.\n");
		nv50_evo_channel_del(pchan);
		return -ENOMEM;
	}

	return 0;
}

int
nv50_display_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
	struct nouveau_channel *evo = dev_priv->evo;
	struct drm_connector *connector;
	uint32_t val, ram_amount, hpd_en[2];
	uint64_t start;
	int ret, i;

	NV_DEBUG(dev, "\n");

	nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004));
	/*
	 * I think the 0x006101XX range is some kind of main control area
	 * that enables things.
	 */
	/* CRTC? */
	for (i = 0; i < 2; i++) {
		val = nv_rd32(dev, 0x00616100 + (i * 0x800));
		nv_wr32(dev, 0x00610190 + (i * 0x10), val);
		val = nv_rd32(dev, 0x00616104 + (i * 0x800));
		nv_wr32(dev, 0x00610194 + (i * 0x10), val);
		val = nv_rd32(dev, 0x00616108 + (i * 0x800));
		nv_wr32(dev, 0x00610198 + (i * 0x10), val);
		val = nv_rd32(dev, 0x0061610c + (i * 0x800));
		nv_wr32(dev, 0x0061019c + (i * 0x10), val);
	}
	/* DAC */
	for (i = 0; i < 3; i++) {
		val = nv_rd32(dev, 0x0061a000 + (i * 0x800));
		nv_wr32(dev, 0x006101d0 + (i * 0x04), val);
	}
	/* SOR */
	for (i = 0; i < 4; i++) {
		val = nv_rd32(dev, 0x0061c000 + (i * 0x800));
		nv_wr32(dev, 0x006101e0 + (i * 0x04), val);
	}
	/* Something not yet in use, tv-out maybe. */
	for (i = 0; i < 3; i++) {
		val = nv_rd32(dev, 0x0061e000 + (i * 0x800));
		nv_wr32(dev, 0x006101f0 + (i * 0x04), val);
	}

	for (i = 0; i < 3; i++) {
		nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 |
			NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
		nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001);
	}

	/* This used to be in crtc unblank, but seems out of place there. */
	nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);
	/* RAM is clamped to 256 MiB. */
	ram_amount = nouveau_mem_fb_amount(dev);
	NV_DEBUG(dev, "ram_amount %d\n", ram_amount);
	if (ram_amount > 256*1024*1024)
		ram_amount = 256*1024*1024;
	nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1);
	nv_wr32(dev, NV50_PDISPLAY_UNK_388, 0x150000);
	nv_wr32(dev, NV50_PDISPLAY_UNK_38C, 0);

	/* The precise purpose is unknown, i suspect it has something to do
	 * with text mode.
	 */
	if (nv_rd32(dev, NV50_PDISPLAY_INTR_1) & 0x100) {
		nv_wr32(dev, NV50_PDISPLAY_INTR_1, 0x100);
		nv_wr32(dev, 0x006194e8, nv_rd32(dev, 0x006194e8) & ~1);
		if (!nv_wait(0x006194e8, 2, 0)) {
			NV_ERROR(dev, "timeout: (0x6194e8 & 2) != 0\n");
			NV_ERROR(dev, "0x6194e8 = 0x%08x\n",
						nv_rd32(dev, 0x6194e8));
			return -EBUSY;
		}
	}

	/* taken from nv bug #12637, attempts to un-wedge the hw if it's
	 * stuck in some unspecified state
	 */
	start = ptimer->read(dev);
	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x2b00);
	while ((val = nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))) & 0x1e0000) {
		if ((val & 0x9f0000) == 0x20000)
			nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
							val | 0x800000);

		if ((val & 0x3f0000) == 0x30000)
			nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
							val | 0x200000);

		if (ptimer->read(dev) - start > 1000000000ULL) {
			NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n");
			NV_ERROR(dev, "0x610200 = 0x%08x\n", val);
			return -EBUSY;
		}
	}

	nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_ENABLE);
	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03);
	if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x40000000, 0x40000000)) {
		NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n");
		NV_ERROR(dev, "0x610200 = 0x%08x\n",
			  nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)));
		return -EBUSY;
	}

	for (i = 0; i < 2; i++) {
		nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000);
		if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
			NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n");
			NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n",
				 nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
			return -EBUSY;
		}

		nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
			NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON);
		if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS,
			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) {
			NV_ERROR(dev, "timeout: "
				      "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i);
			NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i,
				 nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
			return -EBUSY;
		}
	}

	nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->instance >> 8) | 9);

	/* initialise fifo */
	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0),
		((evo->pushbuf_bo->bo.mem.mm_node->start << PAGE_SHIFT) >> 8) |
		NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM |
		NV50_PDISPLAY_CHANNEL_DMA_CB_VALID);
	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK2(0), 0x00010000);
	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK3(0), 0x00000002);
	if (!nv_wait(0x610200, 0x80000000, 0x00000000)) {
		NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n");
		NV_ERROR(dev, "0x610200 = 0x%08x\n", nv_rd32(dev, 0x610200));
		return -EBUSY;
	}
	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
		(nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)) & ~0x00000003) |
		 NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED);
	nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0);
	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x01000003 |
		NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED);
	nv_wr32(dev, 0x610300, nv_rd32(dev, 0x610300) & ~1);

	evo->dma.max = (4096/4) - 2;
	evo->dma.put = 0;
	evo->dma.cur = evo->dma.put;
	evo->dma.free = evo->dma.max - evo->dma.cur;

	ret = RING_SPACE(evo, NOUVEAU_DMA_SKIPS);
	if (ret)
		return ret;

	for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
		OUT_RING(evo, 0);

	ret = RING_SPACE(evo, 11);
	if (ret)
		return ret;
	BEGIN_RING(evo, 0, NV50_EVO_UNK84, 2);
	OUT_RING(evo, NV50_EVO_UNK84_NOTIFY_DISABLED);
	OUT_RING(evo, NV50_EVO_DMA_NOTIFY_HANDLE_NONE);
	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, FB_DMA), 1);
	OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE);
	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK0800), 1);
	OUT_RING(evo, 0);
	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, DISPLAY_START), 1);
	OUT_RING(evo, 0);
	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK082C), 1);
	OUT_RING(evo, 0);
	FIRE_RING(evo);
	if (!nv_wait(0x640004, 0xffffffff, evo->dma.put << 2))
		NV_ERROR(dev, "evo pushbuf stalled\n");

	/* enable clock change interrupts. */
	nv_wr32(dev, 0x610028, 0x00010001);
	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, (NV50_PDISPLAY_INTR_EN_CLK_UNK10 |
					     NV50_PDISPLAY_INTR_EN_CLK_UNK20 |
					     NV50_PDISPLAY_INTR_EN_CLK_UNK40));

	/* enable hotplug interrupts */
	hpd_en[0] = hpd_en[1] = 0;
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		struct nouveau_connector *conn = nouveau_connector(connector);
		struct dcb_gpio_entry *gpio;

		if (connector->connector_type != DRM_MODE_CONNECTOR_DVII &&
		    connector->connector_type != DRM_MODE_CONNECTOR_DVID &&
		    connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag);
		if (!gpio)
			continue;

		hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf));
	}

	nv_wr32(dev, 0xe054, 0xffffffff);
	nv_wr32(dev, 0xe050, hpd_en[0]);
	if (dev_priv->chipset >= 0x90) {
		nv_wr32(dev, 0xe074, 0xffffffff);
		nv_wr32(dev, 0xe070, hpd_en[1]);
	}

	return 0;
}

static int nv50_display_disable(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_crtc *drm_crtc;
	int ret, i;

	NV_DEBUG(dev, "\n");

	list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);

		nv50_crtc_blank(crtc, true);
	}

	ret = RING_SPACE(dev_priv->evo, 2);
	if (ret == 0) {
		BEGIN_RING(dev_priv->evo, 0, NV50_EVO_UPDATE, 1);
		OUT_RING(dev_priv->evo, 0);
	}
	FIRE_RING(dev_priv->evo);

	/* Almost like ack'ing a vblank interrupt, maybe in the spirit of
	 * cleaning up?
	 */
	list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
		uint32_t mask = NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(crtc->index);

		if (!crtc->base.enabled)
			continue;

		nv_wr32(dev, NV50_PDISPLAY_INTR_1, mask);
		if (!nv_wait(NV50_PDISPLAY_INTR_1, mask, mask)) {
			NV_ERROR(dev, "timeout: (0x610024 & 0x%08x) == "
				      "0x%08x\n", mask, mask);
			NV_ERROR(dev, "0x610024 = 0x%08x\n",
				 nv_rd32(dev, NV50_PDISPLAY_INTR_1));
		}
	}

	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0);
	nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, 0);
	if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) {
		NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n");
		NV_ERROR(dev, "0x610200 = 0x%08x\n",
			  nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)));
	}

	for (i = 0; i < 3; i++) {
		if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(i),
			     NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
			NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i);
			NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", i,
				  nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i)));
		}
	}

	/* disable interrupts. */
	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 0x00000000);

	/* disable hotplug interrupts */
	nv_wr32(dev, 0xe054, 0xffffffff);
	nv_wr32(dev, 0xe050, 0x00000000);
	if (dev_priv->chipset >= 0x90) {
		nv_wr32(dev, 0xe074, 0xffffffff);
		nv_wr32(dev, 0xe070, 0x00000000);
	}
	return 0;
}

int nv50_display_create(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct parsed_dcb *dcb = dev_priv->vbios->dcb;
	uint32_t connector[16] = {};
	int ret, i;

	NV_DEBUG(dev, "\n");

	/* init basic kernel modesetting */
	drm_mode_config_init(dev);

	/* Initialise some optional connector properties. */
	drm_mode_create_scaling_mode_property(dev);
	drm_mode_create_dithering_property(dev);

	dev->mode_config.min_width = 0;
	dev->mode_config.min_height = 0;

	dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;

	dev->mode_config.max_width = 8192;
	dev->mode_config.max_height = 8192;

	dev->mode_config.fb_base = dev_priv->fb_phys;

	/* Create EVO channel */
	ret = nv50_evo_channel_new(dev, &dev_priv->evo);
	if (ret) {
		NV_ERROR(dev, "Error creating EVO channel: %d\n", ret);
		return ret;
	}

	/* Create CRTC objects */
	for (i = 0; i < 2; i++)
		nv50_crtc_create(dev, i);

	/* We setup the encoders from the BIOS table */
	for (i = 0 ; i < dcb->entries; i++) {
		struct dcb_entry *entry = &dcb->entry[i];

		if (entry->location != DCB_LOC_ON_CHIP) {
			NV_WARN(dev, "Off-chip encoder %d/%d unsupported\n",
				entry->type, ffs(entry->or) - 1);
			continue;
		}

		switch (entry->type) {
		case OUTPUT_TMDS:
		case OUTPUT_LVDS:
		case OUTPUT_DP:
			nv50_sor_create(dev, entry);
			break;
		case OUTPUT_ANALOG:
			nv50_dac_create(dev, entry);
			break;
		default:
			NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
			continue;
		}

		connector[entry->connector] |= (1 << entry->type);
	}

	/* It appears that DCB 3.0+ VBIOS has a connector table, however,
	 * I'm not 100% certain how to decode it correctly yet so just
	 * look at what encoders are present on each connector index and
	 * attempt to derive the connector type from that.
	 */
	for (i = 0 ; i < dcb->entries; i++) {
		struct dcb_entry *entry = &dcb->entry[i];
		uint16_t encoders;
		int type;

		encoders = connector[entry->connector];
		if (!(encoders & (1 << entry->type)))
			continue;
		connector[entry->connector] = 0;

		if (encoders & (1 << OUTPUT_DP)) {
			type = DRM_MODE_CONNECTOR_DisplayPort;
		} else if (encoders & (1 << OUTPUT_TMDS)) {
			if (encoders & (1 << OUTPUT_ANALOG))
				type = DRM_MODE_CONNECTOR_DVII;
			else
				type = DRM_MODE_CONNECTOR_DVID;
		} else if (encoders & (1 << OUTPUT_ANALOG)) {
			type = DRM_MODE_CONNECTOR_VGA;
		} else if (encoders & (1 << OUTPUT_LVDS)) {
			type = DRM_MODE_CONNECTOR_LVDS;
		} else {
			type = DRM_MODE_CONNECTOR_Unknown;
		}

		if (type == DRM_MODE_CONNECTOR_Unknown)
			continue;

		nouveau_connector_create(dev, entry->connector, type);
	}

	ret = nv50_display_init(dev);
	if (ret)
		return ret;

	return 0;
}

int nv50_display_destroy(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	NV_DEBUG(dev, "\n");

	drm_mode_config_cleanup(dev);

	nv50_display_disable(dev);
	nv50_evo_channel_del(&dev_priv->evo);

	return 0;
}

static inline uint32_t
nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	uint32_t mc;

	if (sor) {
		if (dev_priv->chipset < 0x90 ||
		    dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
			mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or));
		else
			mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or));
	} else {
		mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or));
	}

	return mc;
}

static int
nv50_display_irq_head(struct drm_device *dev, int *phead,
		      struct dcb_entry **pdcbent)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL);
	uint32_t dac = 0, sor = 0;
	int head, i, or = 0, type = OUTPUT_ANY;

	/* We're assuming that head 0 *or* head 1 will be active here,
	 * and not both.  I'm not sure if the hw will even signal both
	 * ever, but it definitely shouldn't for us as we commit each
	 * CRTC separately, and submission will be blocked by the GPU
	 * until we handle each in turn.
	 */
	NV_DEBUG(dev, "0x610030: 0x%08x\n", unk30);
	head = ffs((unk30 >> 9) & 3) - 1;
	if (head < 0)
		return -EINVAL;

	/* This assumes CRTCs are never bound to multiple encoders, which
	 * should be the case.
	 */
	for (i = 0; i < 3 && type == OUTPUT_ANY; i++) {
		uint32_t mc = nv50_display_mode_ctrl(dev, false, i);
		if (!(mc & (1 << head)))
			continue;

		switch ((mc >> 8) & 0xf) {
		case 0: type = OUTPUT_ANALOG; break;
		case 1: type = OUTPUT_TV; break;
		default:
			NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac);
			return -1;
		}

		or = i;
	}

	for (i = 0; i < 4 && type == OUTPUT_ANY; i++) {
		uint32_t mc = nv50_display_mode_ctrl(dev, true, i);
		if (!(mc & (1 << head)))
			continue;

		switch ((mc >> 8) & 0xf) {
		case 0: type = OUTPUT_LVDS; break;
		case 1: type = OUTPUT_TMDS; break;
		case 2: type = OUTPUT_TMDS; break;
		case 5: type = OUTPUT_TMDS; break;
		case 8: type = OUTPUT_DP; break;
		case 9: type = OUTPUT_DP; break;
		default:
			NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor);
			return -1;
		}

		or = i;
	}

	NV_DEBUG(dev, "type %d, or %d\n", type, or);
	if (type == OUTPUT_ANY) {
		NV_ERROR(dev, "unknown encoder!!\n");
		return -1;
	}

	for (i = 0; i < dev_priv->vbios->dcb->entries; i++) {
		struct dcb_entry *dcbent = &dev_priv->vbios->dcb->entry[i];

		if (dcbent->type != type)
			continue;

		if (!(dcbent->or & (1 << or)))
			continue;

		*phead = head;
		*pdcbent = dcbent;
		return 0;
	}

	NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or);
	return 0;
}

static uint32_t
nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent,
			   int pxclk)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nvbios *bios = &dev_priv->VBIOS;
	uint32_t mc, script = 0, or;

	or = ffs(dcbent->or) - 1;
	mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or);
	switch (dcbent->type) {
	case OUTPUT_LVDS:
		script = (mc >> 8) & 0xf;
		if (bios->pub.fp_no_ddc) {
			if (bios->fp.dual_link)
				script |= 0x0100;
			if (bios->fp.if_is_24bit)
				script |= 0x0200;
		} else {
			if (pxclk >= bios->fp.duallink_transition_clk) {
				script |= 0x0100;
				if (bios->fp.strapless_is_24bit & 2)
					script |= 0x0200;
			} else
			if (bios->fp.strapless_is_24bit & 1)
				script |= 0x0200;
		}

		if (nouveau_uscript_lvds >= 0) {
			NV_INFO(dev, "override script 0x%04x with 0x%04x "
				     "for output LVDS-%d\n", script,
				     nouveau_uscript_lvds, or);
			script = nouveau_uscript_lvds;
		}
		break;
	case OUTPUT_TMDS:
		script = (mc >> 8) & 0xf;
		if (pxclk >= 165000)
			script |= 0x0100;

		if (nouveau_uscript_tmds >= 0) {
			NV_INFO(dev, "override script 0x%04x with 0x%04x "
				     "for output TMDS-%d\n", script,
				     nouveau_uscript_tmds, or);
			script = nouveau_uscript_tmds;
		}
		break;
	case OUTPUT_DP:
		script = (mc >> 8) & 0xf;
		break;
	case OUTPUT_ANALOG:
		script = 0xff;
		break;
	default:
		NV_ERROR(dev, "modeset on unsupported output type!\n");
		break;
	}

	return script;
}

static void
nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_channel *chan;
	struct list_head *entry, *tmp;

	list_for_each_safe(entry, tmp, &dev_priv->vbl_waiting) {
		chan = list_entry(entry, struct nouveau_channel, nvsw.vbl_wait);

		nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset,
						chan->nvsw.vblsem_rval);
		list_del(&chan->nvsw.vbl_wait);
	}
}

static void
nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
{
	intr &= NV50_PDISPLAY_INTR_1_VBLANK_CRTC;

	if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0)
		nv50_display_vblank_crtc_handler(dev, 0);

	if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1)
		nv50_display_vblank_crtc_handler(dev, 1);

	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev,
		     NV50_PDISPLAY_INTR_EN) & ~intr);
	nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr);
}

static void
nv50_display_unk10_handler(struct drm_device *dev)
{
	struct dcb_entry *dcbent;
	int head, ret;

	ret = nv50_display_irq_head(dev, &head, &dcbent);
	if (ret)
		goto ack;

	nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8);

	nouveau_bios_run_display_table(dev, dcbent, 0, -1);

ack:
	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10);
	nv_wr32(dev, 0x610030, 0x80000000);
}

static void
nv50_display_unk20_handler(struct drm_device *dev)
{
	struct dcb_entry *dcbent;
	uint32_t tmp, pclk, script;
	int head, or, ret;

	ret = nv50_display_irq_head(dev, &head, &dcbent);
	if (ret)
		goto ack;
	or = ffs(dcbent->or) - 1;
	pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
	script = nv50_display_script_select(dev, dcbent, pclk);

	NV_DEBUG(dev, "head %d pxclk: %dKHz\n", head, pclk);

	if (dcbent->type != OUTPUT_DP)
		nouveau_bios_run_display_table(dev, dcbent, 0, -2);

	nv50_crtc_set_clock(dev, head, pclk);

	nouveau_bios_run_display_table(dev, dcbent, script, pclk);

	tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head));
	tmp &= ~0x000000f;
	nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp);

	if (dcbent->type != OUTPUT_ANALOG) {
		tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or));
		tmp &= ~0x00000f0f;
		if (script & 0x0100)
			tmp |= 0x00000101;
		nv_wr32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or), tmp);
	} else {
		nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0);
	}

ack:
	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20);
	nv_wr32(dev, 0x610030, 0x80000000);
}

static void
nv50_display_unk40_handler(struct drm_device *dev)
{
	struct dcb_entry *dcbent;
	int head, pclk, script, ret;

	ret = nv50_display_irq_head(dev, &head, &dcbent);
	if (ret)
		goto ack;
	pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
	script = nv50_display_script_select(dev, dcbent, pclk);

	nouveau_bios_run_display_table(dev, dcbent, script, -pclk);

ack:
	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40);
	nv_wr32(dev, 0x610030, 0x80000000);
	nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8);
}

void
nv50_display_irq_handler_bh(struct work_struct *work)
{
	struct drm_nouveau_private *dev_priv =
		container_of(work, struct drm_nouveau_private, irq_work);
	struct drm_device *dev = dev_priv->dev;

	for (;;) {
		uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
		uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);

		NV_DEBUG(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1);

		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10)
			nv50_display_unk10_handler(dev);
		else
		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK20)
			nv50_display_unk20_handler(dev);
		else
		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK40)
			nv50_display_unk40_handler(dev);
		else
			break;
	}

	nv_wr32(dev, NV03_PMC_INTR_EN_0, 1);
}

static void
nv50_display_error_handler(struct drm_device *dev)
{
	uint32_t addr, data;

	nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000);
	addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR);
	data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA);

	NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x (0x%04x 0x%02x)\n",
		 0, addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf);

	nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000);
}

static void
nv50_display_irq_hotplug(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_connector *connector;
	const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
	uint32_t unplug_mask, plug_mask, change_mask;
	uint32_t hpd0, hpd1 = 0;

	hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050);
	if (dev_priv->chipset >= 0x90)
		hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070);

	plug_mask   = (hpd0 & 0x0000ffff) | (hpd1 << 16);
	unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000);
	change_mask = plug_mask | unplug_mask;

	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		struct drm_encoder_helper_funcs *helper;
		struct nouveau_connector *nv_connector =
			nouveau_connector(connector);
		struct nouveau_encoder *nv_encoder;
		struct dcb_gpio_entry *gpio;
		uint32_t reg;
		bool plugged;

		if (!nv_connector->dcb)
			continue;

		gpio = nouveau_bios_gpio_entry(dev, nv_connector->dcb->gpio_tag);
		if (!gpio || !(change_mask & (1 << gpio->line)))
			continue;

		reg = nv_rd32(dev, gpio_reg[gpio->line >> 3]);
		plugged = !!(reg & (4 << ((gpio->line & 7) << 2)));
		NV_INFO(dev, "%splugged %s\n", plugged ? "" : "un",
			drm_get_connector_name(connector)) ;

		if (!connector->encoder || !connector->encoder->crtc ||
		    !connector->encoder->crtc->enabled)
			continue;
		nv_encoder = nouveau_encoder(connector->encoder);
		helper = connector->encoder->helper_private;

		if (nv_encoder->dcb->type != OUTPUT_DP)
			continue;

		if (plugged)
			helper->dpms(connector->encoder, DRM_MODE_DPMS_ON);
		else
			helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF);
	}

	nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054));
	if (dev_priv->chipset >= 0x90)
		nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
}

void
nv50_display_irq_handler(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	uint32_t delayed = 0;

	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG)
		nv50_display_irq_hotplug(dev);

	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
		uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
		uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
		uint32_t clock;

		NV_DEBUG(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1);

		if (!intr0 && !(intr1 & ~delayed))
			break;

		if (intr0 & 0x00010000) {
			nv50_display_error_handler(dev);
			intr0 &= ~0x00010000;
		}

		if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) {
			nv50_display_vblank_handler(dev, intr1);
			intr1 &= ~NV50_PDISPLAY_INTR_1_VBLANK_CRTC;
		}

		clock = (intr1 & (NV50_PDISPLAY_INTR_1_CLK_UNK10 |
				  NV50_PDISPLAY_INTR_1_CLK_UNK20 |
				  NV50_PDISPLAY_INTR_1_CLK_UNK40));
		if (clock) {
			nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
			if (!work_pending(&dev_priv->irq_work))
				queue_work(dev_priv->wq, &dev_priv->irq_work);
			delayed |= clock;
			intr1 &= ~clock;
		}

		if (intr0) {
			NV_ERROR(dev, "unknown PDISPLAY_INTR_0: 0x%08x\n", intr0);
			nv_wr32(dev, NV50_PDISPLAY_INTR_0, intr0);
		}

		if (intr1) {
			NV_ERROR(dev,
				 "unknown PDISPLAY_INTR_1: 0x%08x\n", intr1);
			nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr1);
		}
	}
}

