// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2012 Red Hat
 *
 * Authors: Matthew Garrett
 *          Dave Airlie
 */

#include <linux/module.h>
#include <linux/pci.h>

#include <drm/drm_aperture.h>
#include <drm/drm_drv.h>
#include <drm/drm_fbdev_generic.h>
#include <drm/drm_file.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_managed.h>
#include <drm/drm_module.h>
#include <drm/drm_pciids.h>

#include "mgag200_drv.h"

int mgag200_modeset = -1;
MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
module_param_named(modeset, mgag200_modeset, int, 0400);

int mgag200_init_pci_options(struct pci_dev *pdev, u32 option, u32 option2)
{
	struct device *dev = &pdev->dev;
	int err;

	err = pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
	if (err != PCIBIOS_SUCCESSFUL) {
		dev_err(dev, "pci_write_config_dword(PCI_MGA_OPTION) failed: %d\n", err);
		return pcibios_err_to_errno(err);
	}

	err = pci_write_config_dword(pdev, PCI_MGA_OPTION2, option2);
	if (err != PCIBIOS_SUCCESSFUL) {
		dev_err(dev, "pci_write_config_dword(PCI_MGA_OPTION2) failed: %d\n", err);
		return pcibios_err_to_errno(err);
	}

	return 0;
}

resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size)
{
	int offset;
	int orig;
	int test1, test2;
	int orig1, orig2;
	size_t vram_size;

	/* Probe */
	orig = ioread16(mem);
	iowrite16(0, mem);

	vram_size = size;

	for (offset = 0x100000; offset < vram_size; offset += 0x4000) {
		orig1 = ioread8(mem + offset);
		orig2 = ioread8(mem + offset + 0x100);

		iowrite16(0xaa55, mem + offset);
		iowrite16(0xaa55, mem + offset + 0x100);

		test1 = ioread16(mem + offset);
		test2 = ioread16(mem);

		iowrite16(orig1, mem + offset);
		iowrite16(orig2, mem + offset + 0x100);

		if (test1 != 0xaa55)
			break;

		if (test2)
			break;
	}

	iowrite16(orig, mem);

	return offset - 65536;
}

/*
 * DRM driver
 */

DEFINE_DRM_GEM_FOPS(mgag200_driver_fops);

static const struct drm_driver mgag200_driver = {
	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
	.fops = &mgag200_driver_fops,
	.name = DRIVER_NAME,
	.desc = DRIVER_DESC,
	.date = DRIVER_DATE,
	.major = DRIVER_MAJOR,
	.minor = DRIVER_MINOR,
	.patchlevel = DRIVER_PATCHLEVEL,
	DRM_GEM_SHMEM_DRIVER_OPS,
};

/*
 * DRM device
 */

resource_size_t mgag200_device_probe_vram(struct mga_device *mdev)
{
	return mgag200_probe_vram(mdev->vram, resource_size(mdev->vram_res));
}

int mgag200_device_preinit(struct mga_device *mdev)
{
	struct drm_device *dev = &mdev->base;
	struct pci_dev *pdev = to_pci_dev(dev->dev);
	resource_size_t start, len;
	struct resource *res;

	/* BAR 1 contains registers */

	start = pci_resource_start(pdev, 1);
	len = pci_resource_len(pdev, 1);

	res = devm_request_mem_region(dev->dev, start, len, "mgadrmfb_mmio");
	if (!res) {
		drm_err(dev, "devm_request_mem_region(MMIO) failed\n");
		return -ENXIO;
	}
	mdev->rmmio_res = res;

	mdev->rmmio = pcim_iomap(pdev, 1, 0);
	if (!mdev->rmmio)
		return -ENOMEM;

	/* BAR 0 is VRAM */

	start = pci_resource_start(pdev, 0);
	len = pci_resource_len(pdev, 0);

	res = devm_request_mem_region(dev->dev, start, len, "mgadrmfb_vram");
	if (!res) {
		drm_err(dev, "devm_request_mem_region(VRAM) failed\n");
		return -ENXIO;
	}
	mdev->vram_res = res;

	/* Don't fail on errors, but performance might be reduced. */
	devm_arch_io_reserve_memtype_wc(dev->dev, res->start, resource_size(res));
	devm_arch_phys_wc_add(dev->dev, res->start, resource_size(res));

	mdev->vram = devm_ioremap(dev->dev, res->start, resource_size(res));
	if (!mdev->vram)
		return -ENOMEM;

	return 0;
}

int mgag200_device_init(struct mga_device *mdev,
			const struct mgag200_device_info *info,
			const struct mgag200_device_funcs *funcs)
{
	struct drm_device *dev = &mdev->base;
	u8 crtcext3, misc;
	int ret;

	mdev->info = info;
	mdev->funcs = funcs;

	ret = drmm_mutex_init(dev, &mdev->rmmio_lock);
	if (ret)
		return ret;

	mutex_lock(&mdev->rmmio_lock);

	RREG_ECRT(0x03, crtcext3);
	crtcext3 |= MGAREG_CRTCEXT3_MGAMODE;
	WREG_ECRT(0x03, crtcext3);

	WREG_ECRT(0x04, 0x00);

	misc = RREG8(MGA_MISC_IN);
	misc |= MGAREG_MISC_RAMMAPEN |
		MGAREG_MISC_HIGH_PG_SEL;
	WREG8(MGA_MISC_OUT, misc);

	mutex_unlock(&mdev->rmmio_lock);

	return 0;
}

/*
 * PCI driver
 */

static const struct pci_device_id mgag200_pciidlist[] = {
	{ PCI_VENDOR_ID_MATROX, 0x520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_PCI },
	{ PCI_VENDOR_ID_MATROX, 0x521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_AGP },
	{ PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A },
	{ PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },
	{ PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV },
	{ PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
	{ PCI_VENDOR_ID_MATROX, 0x533, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH },
	{ PCI_VENDOR_ID_MATROX, 0x534, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_ER },
	{ PCI_VENDOR_ID_MATROX, 0x536, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EW3 },
	{ PCI_VENDOR_ID_MATROX, 0x538, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH3 },
	{0,}
};

MODULE_DEVICE_TABLE(pci, mgag200_pciidlist);

static int
mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	enum mga_type type = (enum mga_type)ent->driver_data;
	struct mga_device *mdev;
	struct drm_device *dev;
	int ret;

	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &mgag200_driver);
	if (ret)
		return ret;

	ret = pcim_enable_device(pdev);
	if (ret)
		return ret;

	switch (type) {
	case G200_PCI:
	case G200_AGP:
		mdev = mgag200_g200_device_create(pdev, &mgag200_driver);
		break;
	case G200_SE_A:
	case G200_SE_B:
		mdev = mgag200_g200se_device_create(pdev, &mgag200_driver, type);
		break;
	case G200_WB:
		mdev = mgag200_g200wb_device_create(pdev, &mgag200_driver);
		break;
	case G200_EV:
		mdev = mgag200_g200ev_device_create(pdev, &mgag200_driver);
		break;
	case G200_EH:
		mdev = mgag200_g200eh_device_create(pdev, &mgag200_driver);
		break;
	case G200_EH3:
		mdev = mgag200_g200eh3_device_create(pdev, &mgag200_driver);
		break;
	case G200_ER:
		mdev = mgag200_g200er_device_create(pdev, &mgag200_driver);
		break;
	case G200_EW3:
		mdev = mgag200_g200ew3_device_create(pdev, &mgag200_driver);
		break;
	default:
		dev_err(&pdev->dev, "Device type %d is unsupported\n", type);
		return -ENODEV;
	}
	if (IS_ERR(mdev))
		return PTR_ERR(mdev);
	dev = &mdev->base;

	ret = drm_dev_register(dev, 0);
	if (ret)
		return ret;

	/*
	 * FIXME: A 24-bit color depth does not work with 24 bpp on
	 * G200ER. Force 32 bpp.
	 */
	drm_fbdev_generic_setup(dev, 32);

	return 0;
}

static void mgag200_pci_remove(struct pci_dev *pdev)
{
	struct drm_device *dev = pci_get_drvdata(pdev);

	drm_dev_unregister(dev);
}

static struct pci_driver mgag200_pci_driver = {
	.name = DRIVER_NAME,
	.id_table = mgag200_pciidlist,
	.probe = mgag200_pci_probe,
	.remove = mgag200_pci_remove,
};

drm_module_pci_driver_if_modeset(mgag200_pci_driver, mgag200_modeset);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
