/*
 * Copyright (C) 2006 Ben Skeggs.
 *
 * 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.
 *
 */

/*
 * Authors:
 *   Ben Skeggs <darktama@iinet.net.au>
 */

#include "drmP.h"
#include "drm.h"
#include "nouveau_drm.h"
#include "nouveau_drv.h"
#include "nouveau_reg.h"
#include "nouveau_ramht.h"
#include "nouveau_util.h"

void
nouveau_irq_preinstall(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	/* Master disable */
	nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);

	INIT_LIST_HEAD(&dev_priv->vbl_waiting);
}

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

	/* Master enable */
	nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
	if (dev_priv->msi_enabled)
		nv_wr08(dev, 0x00088068, 0xff);

	return 0;
}

void
nouveau_irq_uninstall(struct drm_device *dev)
{
	/* Master disable */
	nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
}

irqreturn_t
nouveau_irq_handler(DRM_IRQ_ARGS)
{
	struct drm_device *dev = (struct drm_device *)arg;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	unsigned long flags;
	u32 stat;
	int i;

	stat = nv_rd32(dev, NV03_PMC_INTR_0);
	if (stat == 0 || stat == ~0)
		return IRQ_NONE;

	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
	for (i = 0; i < 32 && stat; i++) {
		if (!(stat & (1 << i)) || !dev_priv->irq_handler[i])
			continue;

		dev_priv->irq_handler[i](dev);
		stat &= ~(1 << i);
	}

	if (dev_priv->msi_enabled)
		nv_wr08(dev, 0x00088068, 0xff);
	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);

	if (stat && nouveau_ratelimit())
		NV_ERROR(dev, "PMC - unhandled INTR 0x%08x\n", stat);
	return IRQ_HANDLED;
}

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

	if (nouveau_msi != 0 && dev_priv->card_type >= NV_50) {
		ret = pci_enable_msi(dev->pdev);
		if (ret == 0) {
			NV_INFO(dev, "enabled MSI\n");
			dev_priv->msi_enabled = true;
		}
	}

	return drm_irq_install(dev);
}

void
nouveau_irq_fini(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	drm_irq_uninstall(dev);
	if (dev_priv->msi_enabled)
		pci_disable_msi(dev->pdev);
}

void
nouveau_irq_register(struct drm_device *dev, int status_bit,
		     void (*handler)(struct drm_device *))
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	unsigned long flags;

	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
	dev_priv->irq_handler[status_bit] = handler;
	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
}

void
nouveau_irq_unregister(struct drm_device *dev, int status_bit)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	unsigned long flags;

	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
	dev_priv->irq_handler[status_bit] = NULL;
	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
}
