// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) Intel Corp. 2007.
 * All Rights Reserved.
 *
 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
 * develop this driver.
 *
 * This file is part of the Vermilion Range fb driver.
 *
 * Authors:
 *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
 *   Michel Dänzer <michel-at-tungstengraphics-dot-com>
 *   Alan Hourihane <alanh-at-tungstengraphics-dot-com>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/pci.h>
#include <asm/set_memory.h>
#include <asm/tlbflush.h>
#include <linux/mmzone.h>

/* #define VERMILION_DEBUG */

#include "vermilion.h"

#define MODULE_NAME "vmlfb"

#define VML_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)

static struct mutex vml_mutex;
static struct list_head global_no_mode;
static struct list_head global_has_mode;
static struct fb_ops vmlfb_ops;
static struct vml_sys *subsys = NULL;
static char *vml_default_mode = "1024x768@60";
static const struct fb_videomode defaultmode = {
	NULL, 60, 1024, 768, 12896, 144, 24, 29, 3, 136, 6,
	0, FB_VMODE_NONINTERLACED
};

static u32 vml_mem_requested = (10 * 1024 * 1024);
static u32 vml_mem_contig = (4 * 1024 * 1024);
static u32 vml_mem_min = (4 * 1024 * 1024);

static u32 vml_clocks[] = {
	6750,
	13500,
	27000,
	29700,
	37125,
	54000,
	59400,
	74250,
	120000,
	148500
};

static u32 vml_num_clocks = ARRAY_SIZE(vml_clocks);

/*
 * Allocate a contiguous vram area and make its linear kernel map
 * uncached.
 */

static int vmlfb_alloc_vram_area(struct vram_area *va, unsigned max_order,
				 unsigned min_order)
{
	gfp_t flags;
	unsigned long i;

	max_order++;
	do {
		/*
		 * Really try hard to get the needed memory.
		 * We need memory below the first 32MB, so we
		 * add the __GFP_DMA flag that guarantees that we are
		 * below the first 16MB.
		 */

		flags = __GFP_DMA | __GFP_HIGH | __GFP_KSWAPD_RECLAIM;
		va->logical =
			 __get_free_pages(flags, --max_order);
	} while (va->logical == 0 && max_order > min_order);

	if (!va->logical)
		return -ENOMEM;

	va->phys = virt_to_phys((void *)va->logical);
	va->size = PAGE_SIZE << max_order;
	va->order = max_order;

	/*
	 * It seems like __get_free_pages only ups the usage count
	 * of the first page. This doesn't work with fault mapping, so
	 * up the usage count once more (XXX: should use split_page or
	 * compound page).
	 */

	memset((void *)va->logical, 0x00, va->size);
	for (i = va->logical; i < va->logical + va->size; i += PAGE_SIZE) {
		get_page(virt_to_page(i));
	}

	/*
	 * Change caching policy of the linear kernel map to avoid
	 * mapping type conflicts with user-space mappings.
	 */
	set_pages_uc(virt_to_page(va->logical), va->size >> PAGE_SHIFT);

	printk(KERN_DEBUG MODULE_NAME
	       ": Allocated %ld bytes vram area at 0x%08lx\n",
	       va->size, va->phys);

	return 0;
}

/*
 * Free a contiguous vram area and reset its linear kernel map
 * mapping type.
 */

static void vmlfb_free_vram_area(struct vram_area *va)
{
	unsigned long j;

	if (va->logical) {

		/*
		 * Reset the linear kernel map caching policy.
		 */

		set_pages_wb(virt_to_page(va->logical),
				 va->size >> PAGE_SHIFT);

		/*
		 * Decrease the usage count on the pages we've used
		 * to compensate for upping when allocating.
		 */

		for (j = va->logical; j < va->logical + va->size;
		     j += PAGE_SIZE) {
			(void)put_page_testzero(virt_to_page(j));
		}

		printk(KERN_DEBUG MODULE_NAME
		       ": Freeing %ld bytes vram area at 0x%08lx\n",
		       va->size, va->phys);
		free_pages(va->logical, va->order);

		va->logical = 0;
	}
}

/*
 * Free allocated vram.
 */

static void vmlfb_free_vram(struct vml_info *vinfo)
{
	int i;

	for (i = 0; i < vinfo->num_areas; ++i) {
		vmlfb_free_vram_area(&vinfo->vram[i]);
	}
	vinfo->num_areas = 0;
}

/*
 * Allocate vram. Currently we try to allocate contiguous areas from the
 * __GFP_DMA zone and puzzle them together. A better approach would be to
 * allocate one contiguous area for scanout and use one-page allocations for
 * offscreen areas. This requires user-space and GPU virtual mappings.
 */

static int vmlfb_alloc_vram(struct vml_info *vinfo,
			    size_t requested,
			    size_t min_total, size_t min_contig)
{
	int i, j;
	int order;
	int contiguous;
	int err;
	struct vram_area *va;
	struct vram_area *va2;

	vinfo->num_areas = 0;
	for (i = 0; i < VML_VRAM_AREAS; ++i) {
		va = &vinfo->vram[i];
		order = 0;

		while (requested > (PAGE_SIZE << order) && order < MAX_ORDER)
			order++;

		err = vmlfb_alloc_vram_area(va, order, 0);

		if (err)
			break;

		if (i == 0) {
			vinfo->vram_start = va->phys;
			vinfo->vram_logical = (void __iomem *) va->logical;
			vinfo->vram_contig_size = va->size;
			vinfo->num_areas = 1;
		} else {
			contiguous = 0;

			for (j = 0; j < i; ++j) {
				va2 = &vinfo->vram[j];
				if (va->phys + va->size == va2->phys ||
				    va2->phys + va2->size == va->phys) {
					contiguous = 1;
					break;
				}
			}

			if (contiguous) {
				vinfo->num_areas++;
				if (va->phys < vinfo->vram_start) {
					vinfo->vram_start = va->phys;
					vinfo->vram_logical =
						(void __iomem *)va->logical;
				}
				vinfo->vram_contig_size += va->size;
			} else {
				vmlfb_free_vram_area(va);
				break;
			}
		}

		if (requested < va->size)
			break;
		else
			requested -= va->size;
	}

	if (vinfo->vram_contig_size > min_total &&
	    vinfo->vram_contig_size > min_contig) {

		printk(KERN_DEBUG MODULE_NAME
		       ": Contiguous vram: %ld bytes at physical 0x%08lx.\n",
		       (unsigned long)vinfo->vram_contig_size,
		       (unsigned long)vinfo->vram_start);

		return 0;
	}

	printk(KERN_ERR MODULE_NAME
	       ": Could not allocate requested minimal amount of vram.\n");

	vmlfb_free_vram(vinfo);

	return -ENOMEM;
}

/*
 * Find the GPU to use with our display controller.
 */

static int vmlfb_get_gpu(struct vml_par *par)
{
	mutex_lock(&vml_mutex);

	par->gpu = pci_get_device(PCI_VENDOR_ID_INTEL, VML_DEVICE_GPU, NULL);

	if (!par->gpu) {
		mutex_unlock(&vml_mutex);
		return -ENODEV;
	}

	mutex_unlock(&vml_mutex);

	if (pci_enable_device(par->gpu) < 0)
		return -ENODEV;

	return 0;
}

/*
 * Find a contiguous vram area that contains a given offset from vram start.
 */
static int vmlfb_vram_offset(struct vml_info *vinfo, unsigned long offset)
{
	unsigned long aoffset;
	unsigned i;

	for (i = 0; i < vinfo->num_areas; ++i) {
		aoffset = offset - (vinfo->vram[i].phys - vinfo->vram_start);

		if (aoffset < vinfo->vram[i].size) {
			return 0;
		}
	}

	return -EINVAL;
}

/*
 * Remap the MMIO register spaces of the VDC and the GPU.
 */

static int vmlfb_enable_mmio(struct vml_par *par)
{
	int err;

	par->vdc_mem_base = pci_resource_start(par->vdc, 0);
	par->vdc_mem_size = pci_resource_len(par->vdc, 0);
	if (!request_mem_region(par->vdc_mem_base, par->vdc_mem_size, "vmlfb")) {
		printk(KERN_ERR MODULE_NAME
		       ": Could not claim display controller MMIO.\n");
		return -EBUSY;
	}
	par->vdc_mem = ioremap(par->vdc_mem_base, par->vdc_mem_size);
	if (par->vdc_mem == NULL) {
		printk(KERN_ERR MODULE_NAME
		       ": Could not map display controller MMIO.\n");
		err = -ENOMEM;
		goto out_err_0;
	}

	par->gpu_mem_base = pci_resource_start(par->gpu, 0);
	par->gpu_mem_size = pci_resource_len(par->gpu, 0);
	if (!request_mem_region(par->gpu_mem_base, par->gpu_mem_size, "vmlfb")) {
		printk(KERN_ERR MODULE_NAME ": Could not claim GPU MMIO.\n");
		err = -EBUSY;
		goto out_err_1;
	}
	par->gpu_mem = ioremap(par->gpu_mem_base, par->gpu_mem_size);
	if (par->gpu_mem == NULL) {
		printk(KERN_ERR MODULE_NAME ": Could not map GPU MMIO.\n");
		err = -ENOMEM;
		goto out_err_2;
	}

	return 0;

out_err_2:
	release_mem_region(par->gpu_mem_base, par->gpu_mem_size);
out_err_1:
	iounmap(par->vdc_mem);
out_err_0:
	release_mem_region(par->vdc_mem_base, par->vdc_mem_size);
	return err;
}

/*
 * Unmap the VDC and GPU register spaces.
 */

static void vmlfb_disable_mmio(struct vml_par *par)
{
	iounmap(par->gpu_mem);
	release_mem_region(par->gpu_mem_base, par->gpu_mem_size);
	iounmap(par->vdc_mem);
	release_mem_region(par->vdc_mem_base, par->vdc_mem_size);
}

/*
 * Release and uninit the VDC and GPU.
 */

static void vmlfb_release_devices(struct vml_par *par)
{
	if (atomic_dec_and_test(&par->refcount)) {
		pci_disable_device(par->gpu);
		pci_disable_device(par->vdc);
	}
}

/*
 * Free up allocated resources for a device.
 */

static void vml_pci_remove(struct pci_dev *dev)
{
	struct fb_info *info;
	struct vml_info *vinfo;
	struct vml_par *par;

	info = pci_get_drvdata(dev);
	if (info) {
		vinfo = container_of(info, struct vml_info, info);
		par = vinfo->par;
		mutex_lock(&vml_mutex);
		unregister_framebuffer(info);
		fb_dealloc_cmap(&info->cmap);
		vmlfb_free_vram(vinfo);
		vmlfb_disable_mmio(par);
		vmlfb_release_devices(par);
		kfree(vinfo);
		kfree(par);
		mutex_unlock(&vml_mutex);
	}
}

static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var)
{
	switch (var->bits_per_pixel) {
	case 16:
		var->blue.offset = 0;
		var->blue.length = 5;
		var->green.offset = 5;
		var->green.length = 5;
		var->red.offset = 10;
		var->red.length = 5;
		var->transp.offset = 15;
		var->transp.length = 1;
		break;
	case 32:
		var->blue.offset = 0;
		var->blue.length = 8;
		var->green.offset = 8;
		var->green.length = 8;
		var->red.offset = 16;
		var->red.length = 8;
		var->transp.offset = 24;
		var->transp.length = 0;
		break;
	default:
		break;
	}

	var->blue.msb_right = var->green.msb_right =
	    var->red.msb_right = var->transp.msb_right = 0;
}

/*
 * Device initialization.
 * We initialize one vml_par struct per device and one vml_info
 * struct per pipe. Currently we have only one pipe.
 */

static int vml_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct vml_info *vinfo;
	struct fb_info *info;
	struct vml_par *par;
	int err = 0;

	par = kzalloc(sizeof(*par), GFP_KERNEL);
	if (par == NULL)
		return -ENOMEM;

	vinfo = kzalloc(sizeof(*vinfo), GFP_KERNEL);
	if (vinfo == NULL) {
		err = -ENOMEM;
		goto out_err_0;
	}

	vinfo->par = par;
	par->vdc = dev;
	atomic_set(&par->refcount, 1);

	switch (id->device) {
	case VML_DEVICE_VDC:
		if ((err = vmlfb_get_gpu(par)))
			goto out_err_1;
		pci_set_drvdata(dev, &vinfo->info);
		break;
	default:
		err = -ENODEV;
		goto out_err_1;
	}

	info = &vinfo->info;
	info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK;

	err = vmlfb_enable_mmio(par);
	if (err)
		goto out_err_2;

	err = vmlfb_alloc_vram(vinfo, vml_mem_requested,
			       vml_mem_contig, vml_mem_min);
	if (err)
		goto out_err_3;

	strcpy(info->fix.id, "Vermilion Range");
	info->fix.mmio_start = 0;
	info->fix.mmio_len = 0;
	info->fix.smem_start = vinfo->vram_start;
	info->fix.smem_len = vinfo->vram_contig_size;
	info->fix.type = FB_TYPE_PACKED_PIXELS;
	info->fix.visual = FB_VISUAL_TRUECOLOR;
	info->fix.ypanstep = 1;
	info->fix.xpanstep = 1;
	info->fix.ywrapstep = 0;
	info->fix.accel = FB_ACCEL_NONE;
	info->screen_base = vinfo->vram_logical;
	info->pseudo_palette = vinfo->pseudo_palette;
	info->par = par;
	info->fbops = &vmlfb_ops;
	info->device = &dev->dev;

	INIT_LIST_HEAD(&vinfo->head);
	vinfo->pipe_disabled = 1;
	vinfo->cur_blank_mode = FB_BLANK_UNBLANK;

	info->var.grayscale = 0;
	info->var.bits_per_pixel = 16;
	vmlfb_set_pref_pixel_format(&info->var);

	if (!fb_find_mode
	    (&info->var, info, vml_default_mode, NULL, 0, &defaultmode, 16)) {
		printk(KERN_ERR MODULE_NAME ": Could not find initial mode\n");
	}

	if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
		err = -ENOMEM;
		goto out_err_4;
	}

	err = register_framebuffer(info);
	if (err) {
		printk(KERN_ERR MODULE_NAME ": Register framebuffer error.\n");
		goto out_err_5;
	}

	printk("Initialized vmlfb\n");

	return 0;

out_err_5:
	fb_dealloc_cmap(&info->cmap);
out_err_4:
	vmlfb_free_vram(vinfo);
out_err_3:
	vmlfb_disable_mmio(par);
out_err_2:
	vmlfb_release_devices(par);
out_err_1:
	kfree(vinfo);
out_err_0:
	kfree(par);
	return err;
}

static int vmlfb_open(struct fb_info *info, int user)
{
	/*
	 * Save registers here?
	 */
	return 0;
}

static int vmlfb_release(struct fb_info *info, int user)
{
	/*
	 * Restore registers here.
	 */

	return 0;
}

static int vml_nearest_clock(int clock)
{

	int i;
	int cur_index;
	int cur_diff;
	int diff;

	cur_index = 0;
	cur_diff = clock - vml_clocks[0];
	cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff;
	for (i = 1; i < vml_num_clocks; ++i) {
		diff = clock - vml_clocks[i];
		diff = (diff < 0) ? -diff : diff;
		if (diff < cur_diff) {
			cur_index = i;
			cur_diff = diff;
		}
	}
	return vml_clocks[cur_index];
}

static int vmlfb_check_var_locked(struct fb_var_screeninfo *var,
				  struct vml_info *vinfo)
{
	u32 pitch;
	u64 mem;
	int nearest_clock;
	int clock;
	int clock_diff;
	struct fb_var_screeninfo v;

	v = *var;
	clock = PICOS2KHZ(var->pixclock);

	if (subsys && subsys->nearest_clock) {
		nearest_clock = subsys->nearest_clock(subsys, clock);
	} else {
		nearest_clock = vml_nearest_clock(clock);
	}

	/*
	 * Accept a 20% diff.
	 */

	clock_diff = nearest_clock - clock;
	clock_diff = (clock_diff < 0) ? -clock_diff : clock_diff;
	if (clock_diff > clock / 5) {
#if 0
		printk(KERN_DEBUG MODULE_NAME ": Diff failure. %d %d\n",clock_diff,clock);
#endif
		return -EINVAL;
	}

	v.pixclock = KHZ2PICOS(nearest_clock);

	if (var->xres > VML_MAX_XRES || var->yres > VML_MAX_YRES) {
		printk(KERN_DEBUG MODULE_NAME ": Resolution failure.\n");
		return -EINVAL;
	}
	if (var->xres_virtual > VML_MAX_XRES_VIRTUAL) {
		printk(KERN_DEBUG MODULE_NAME
		       ": Virtual resolution failure.\n");
		return -EINVAL;
	}
	switch (v.bits_per_pixel) {
	case 0 ... 16:
		v.bits_per_pixel = 16;
		break;
	case 17 ... 32:
		v.bits_per_pixel = 32;
		break;
	default:
		printk(KERN_DEBUG MODULE_NAME ": Invalid bpp: %d.\n",
		       var->bits_per_pixel);
		return -EINVAL;
	}

	pitch = ALIGN((var->xres * var->bits_per_pixel) >> 3, 0x40);
	mem = (u64)pitch * var->yres_virtual;
	if (mem > vinfo->vram_contig_size) {
		return -ENOMEM;
	}

	switch (v.bits_per_pixel) {
	case 16:
		if (var->blue.offset != 0 ||
		    var->blue.length != 5 ||
		    var->green.offset != 5 ||
		    var->green.length != 5 ||
		    var->red.offset != 10 ||
		    var->red.length != 5 ||
		    var->transp.offset != 15 || var->transp.length != 1) {
			vmlfb_set_pref_pixel_format(&v);
		}
		break;
	case 32:
		if (var->blue.offset != 0 ||
		    var->blue.length != 8 ||
		    var->green.offset != 8 ||
		    var->green.length != 8 ||
		    var->red.offset != 16 ||
		    var->red.length != 8 ||
		    (var->transp.length != 0 && var->transp.length != 8) ||
		    (var->transp.length == 8 && var->transp.offset != 24)) {
			vmlfb_set_pref_pixel_format(&v);
		}
		break;
	default:
		return -EINVAL;
	}

	*var = v;

	return 0;
}

static int vmlfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
	struct vml_info *vinfo = container_of(info, struct vml_info, info);
	int ret;

	mutex_lock(&vml_mutex);
	ret = vmlfb_check_var_locked(var, vinfo);
	mutex_unlock(&vml_mutex);

	return ret;
}

static void vml_wait_vblank(struct vml_info *vinfo)
{
	/* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */
	mdelay(20);
}

static void vmlfb_disable_pipe(struct vml_info *vinfo)
{
	struct vml_par *par = vinfo->par;

	/* Disable the MDVO pad */
	VML_WRITE32(par, VML_RCOMPSTAT, 0);
	while (!(VML_READ32(par, VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ;

	/* Disable display planes */
	VML_WRITE32(par, VML_DSPCCNTR,
		    VML_READ32(par, VML_DSPCCNTR) & ~VML_GFX_ENABLE);
	(void)VML_READ32(par, VML_DSPCCNTR);
	/* Wait for vblank for the disable to take effect */
	vml_wait_vblank(vinfo);

	/* Next, disable display pipes */
	VML_WRITE32(par, VML_PIPEACONF, 0);
	(void)VML_READ32(par, VML_PIPEACONF);

	vinfo->pipe_disabled = 1;
}

#ifdef VERMILION_DEBUG
static void vml_dump_regs(struct vml_info *vinfo)
{
	struct vml_par *par = vinfo->par;

	printk(KERN_DEBUG MODULE_NAME ": Modesetting register dump:\n");
	printk(KERN_DEBUG MODULE_NAME ": \tHTOTAL_A         : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_HTOTAL_A));
	printk(KERN_DEBUG MODULE_NAME ": \tHBLANK_A         : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_HBLANK_A));
	printk(KERN_DEBUG MODULE_NAME ": \tHSYNC_A          : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_HSYNC_A));
	printk(KERN_DEBUG MODULE_NAME ": \tVTOTAL_A         : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_VTOTAL_A));
	printk(KERN_DEBUG MODULE_NAME ": \tVBLANK_A         : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_VBLANK_A));
	printk(KERN_DEBUG MODULE_NAME ": \tVSYNC_A          : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_VSYNC_A));
	printk(KERN_DEBUG MODULE_NAME ": \tDSPCSTRIDE       : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_DSPCSTRIDE));
	printk(KERN_DEBUG MODULE_NAME ": \tDSPCSIZE         : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_DSPCSIZE));
	printk(KERN_DEBUG MODULE_NAME ": \tDSPCPOS          : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_DSPCPOS));
	printk(KERN_DEBUG MODULE_NAME ": \tDSPARB           : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_DSPARB));
	printk(KERN_DEBUG MODULE_NAME ": \tDSPCADDR         : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_DSPCADDR));
	printk(KERN_DEBUG MODULE_NAME ": \tBCLRPAT_A        : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_BCLRPAT_A));
	printk(KERN_DEBUG MODULE_NAME ": \tCANVSCLR_A       : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_CANVSCLR_A));
	printk(KERN_DEBUG MODULE_NAME ": \tPIPEASRC         : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_PIPEASRC));
	printk(KERN_DEBUG MODULE_NAME ": \tPIPEACONF        : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_PIPEACONF));
	printk(KERN_DEBUG MODULE_NAME ": \tDSPCCNTR         : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_DSPCCNTR));
	printk(KERN_DEBUG MODULE_NAME ": \tRCOMPSTAT        : 0x%08x\n",
	       (unsigned)VML_READ32(par, VML_RCOMPSTAT));
	printk(KERN_DEBUG MODULE_NAME ": End of modesetting register dump.\n");
}
#endif

static int vmlfb_set_par_locked(struct vml_info *vinfo)
{
	struct vml_par *par = vinfo->par;
	struct fb_info *info = &vinfo->info;
	struct fb_var_screeninfo *var = &info->var;
	u32 htotal, hactive, hblank_start, hblank_end, hsync_start, hsync_end;
	u32 vtotal, vactive, vblank_start, vblank_end, vsync_start, vsync_end;
	u32 dspcntr;
	int clock;

	vinfo->bytes_per_pixel = var->bits_per_pixel >> 3;
	vinfo->stride = ALIGN(var->xres_virtual * vinfo->bytes_per_pixel, 0x40);
	info->fix.line_length = vinfo->stride;

	if (!subsys)
		return 0;

	htotal =
	    var->xres + var->right_margin + var->hsync_len + var->left_margin;
	hactive = var->xres;
	hblank_start = var->xres;
	hblank_end = htotal;
	hsync_start = hactive + var->right_margin;
	hsync_end = hsync_start + var->hsync_len;

	vtotal =
	    var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
	vactive = var->yres;
	vblank_start = var->yres;
	vblank_end = vtotal;
	vsync_start = vactive + var->lower_margin;
	vsync_end = vsync_start + var->vsync_len;

	dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS;
	clock = PICOS2KHZ(var->pixclock);

	if (subsys->nearest_clock) {
		clock = subsys->nearest_clock(subsys, clock);
	} else {
		clock = vml_nearest_clock(clock);
	}
	printk(KERN_DEBUG MODULE_NAME
	       ": Set mode Hfreq : %d kHz, Vfreq : %d Hz.\n", clock / htotal,
	       ((clock / htotal) * 1000) / vtotal);

	switch (var->bits_per_pixel) {
	case 16:
		dspcntr |= VML_GFX_ARGB1555;
		break;
	case 32:
		if (var->transp.length == 8)
			dspcntr |= VML_GFX_ARGB8888 | VML_GFX_ALPHAMULT;
		else
			dspcntr |= VML_GFX_RGB0888;
		break;
	default:
		return -EINVAL;
	}

	vmlfb_disable_pipe(vinfo);
	mb();

	if (subsys->set_clock)
		subsys->set_clock(subsys, clock);
	else
		return -EINVAL;

	VML_WRITE32(par, VML_HTOTAL_A, ((htotal - 1) << 16) | (hactive - 1));
	VML_WRITE32(par, VML_HBLANK_A,
		    ((hblank_end - 1) << 16) | (hblank_start - 1));
	VML_WRITE32(par, VML_HSYNC_A,
		    ((hsync_end - 1) << 16) | (hsync_start - 1));
	VML_WRITE32(par, VML_VTOTAL_A, ((vtotal - 1) << 16) | (vactive - 1));
	VML_WRITE32(par, VML_VBLANK_A,
		    ((vblank_end - 1) << 16) | (vblank_start - 1));
	VML_WRITE32(par, VML_VSYNC_A,
		    ((vsync_end - 1) << 16) | (vsync_start - 1));
	VML_WRITE32(par, VML_DSPCSTRIDE, vinfo->stride);
	VML_WRITE32(par, VML_DSPCSIZE,
		    ((var->yres - 1) << 16) | (var->xres - 1));
	VML_WRITE32(par, VML_DSPCPOS, 0x00000000);
	VML_WRITE32(par, VML_DSPARB, VML_FIFO_DEFAULT);
	VML_WRITE32(par, VML_BCLRPAT_A, 0x00000000);
	VML_WRITE32(par, VML_CANVSCLR_A, 0x00000000);
	VML_WRITE32(par, VML_PIPEASRC,
		    ((var->xres - 1) << 16) | (var->yres - 1));

	wmb();
	VML_WRITE32(par, VML_PIPEACONF, VML_PIPE_ENABLE);
	wmb();
	VML_WRITE32(par, VML_DSPCCNTR, dspcntr);
	wmb();
	VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start +
		    var->yoffset * vinfo->stride +
		    var->xoffset * vinfo->bytes_per_pixel);

	VML_WRITE32(par, VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE);

	while (!(VML_READ32(par, VML_RCOMPSTAT) &
		 (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ;

	vinfo->pipe_disabled = 0;
#ifdef VERMILION_DEBUG
	vml_dump_regs(vinfo);
#endif

	return 0;
}

static int vmlfb_set_par(struct fb_info *info)
{
	struct vml_info *vinfo = container_of(info, struct vml_info, info);
	int ret;

	mutex_lock(&vml_mutex);
	list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
	ret = vmlfb_set_par_locked(vinfo);

	mutex_unlock(&vml_mutex);
	return ret;
}

static int vmlfb_blank_locked(struct vml_info *vinfo)
{
	struct vml_par *par = vinfo->par;
	u32 cur = VML_READ32(par, VML_PIPEACONF);

	switch (vinfo->cur_blank_mode) {
	case FB_BLANK_UNBLANK:
		if (vinfo->pipe_disabled) {
			vmlfb_set_par_locked(vinfo);
		}
		VML_WRITE32(par, VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER);
		(void)VML_READ32(par, VML_PIPEACONF);
		break;
	case FB_BLANK_NORMAL:
		if (vinfo->pipe_disabled) {
			vmlfb_set_par_locked(vinfo);
		}
		VML_WRITE32(par, VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER);
		(void)VML_READ32(par, VML_PIPEACONF);
		break;
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
		if (!vinfo->pipe_disabled) {
			vmlfb_disable_pipe(vinfo);
		}
		break;
	case FB_BLANK_POWERDOWN:
		if (!vinfo->pipe_disabled) {
			vmlfb_disable_pipe(vinfo);
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int vmlfb_blank(int blank_mode, struct fb_info *info)
{
	struct vml_info *vinfo = container_of(info, struct vml_info, info);
	int ret;

	mutex_lock(&vml_mutex);
	vinfo->cur_blank_mode = blank_mode;
	ret = vmlfb_blank_locked(vinfo);
	mutex_unlock(&vml_mutex);
	return ret;
}

static int vmlfb_pan_display(struct fb_var_screeninfo *var,
			     struct fb_info *info)
{
	struct vml_info *vinfo = container_of(info, struct vml_info, info);
	struct vml_par *par = vinfo->par;

	mutex_lock(&vml_mutex);
	VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start +
		    var->yoffset * vinfo->stride +
		    var->xoffset * vinfo->bytes_per_pixel);
	(void)VML_READ32(par, VML_DSPCADDR);
	mutex_unlock(&vml_mutex);

	return 0;
}

static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			   u_int transp, struct fb_info *info)
{
	u32 v;

	if (regno >= 16)
		return -EINVAL;

	if (info->var.grayscale) {
		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
	}

	if (info->fix.visual != FB_VISUAL_TRUECOLOR)
		return -EINVAL;

	red = VML_TOHW(red, info->var.red.length);
	blue = VML_TOHW(blue, info->var.blue.length);
	green = VML_TOHW(green, info->var.green.length);
	transp = VML_TOHW(transp, info->var.transp.length);

	v = (red << info->var.red.offset) |
	    (green << info->var.green.offset) |
	    (blue << info->var.blue.offset) |
	    (transp << info->var.transp.offset);

	switch (info->var.bits_per_pixel) {
	case 16:
		((u32 *) info->pseudo_palette)[regno] = v;
		break;
	case 24:
	case 32:
		((u32 *) info->pseudo_palette)[regno] = v;
		break;
	}
	return 0;
}

static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
	struct vml_info *vinfo = container_of(info, struct vml_info, info);
	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
	int ret;
	unsigned long prot;

	ret = vmlfb_vram_offset(vinfo, offset);
	if (ret)
		return -EINVAL;

	prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK;
	pgprot_val(vma->vm_page_prot) =
		prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);

	return vm_iomap_memory(vma, vinfo->vram_start,
			vinfo->vram_contig_size);
}

static int vmlfb_sync(struct fb_info *info)
{
	return 0;
}

static int vmlfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
	return -EINVAL;	/* just to force soft_cursor() call */
}

static struct fb_ops vmlfb_ops = {
	.owner = THIS_MODULE,
	.fb_open = vmlfb_open,
	.fb_release = vmlfb_release,
	.fb_check_var = vmlfb_check_var,
	.fb_set_par = vmlfb_set_par,
	.fb_blank = vmlfb_blank,
	.fb_pan_display = vmlfb_pan_display,
	.fb_fillrect = cfb_fillrect,
	.fb_copyarea = cfb_copyarea,
	.fb_imageblit = cfb_imageblit,
	.fb_cursor = vmlfb_cursor,
	.fb_sync = vmlfb_sync,
	.fb_mmap = vmlfb_mmap,
	.fb_setcolreg = vmlfb_setcolreg
};

static const struct pci_device_id vml_ids[] = {
	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, VML_DEVICE_VDC)},
	{0}
};

static struct pci_driver vmlfb_pci_driver = {
	.name = "vmlfb",
	.id_table = vml_ids,
	.probe = vml_pci_probe,
	.remove = vml_pci_remove,
};

static void __exit vmlfb_cleanup(void)
{
	pci_unregister_driver(&vmlfb_pci_driver);
}

static int __init vmlfb_init(void)
{

#ifndef MODULE
	char *option = NULL;

	if (fb_get_options(MODULE_NAME, &option))
		return -ENODEV;
#endif

	printk(KERN_DEBUG MODULE_NAME ": initializing\n");
	mutex_init(&vml_mutex);
	INIT_LIST_HEAD(&global_no_mode);
	INIT_LIST_HEAD(&global_has_mode);

	return pci_register_driver(&vmlfb_pci_driver);
}

int vmlfb_register_subsys(struct vml_sys *sys)
{
	struct vml_info *entry;
	struct list_head *list;
	u32 save_activate;

	mutex_lock(&vml_mutex);
	if (subsys != NULL) {
		subsys->restore(subsys);
	}
	subsys = sys;
	subsys->save(subsys);

	/*
	 * We need to restart list traversal for each item, since we
	 * release the list mutex in the loop.
	 */

	list = global_no_mode.next;
	while (list != &global_no_mode) {
		list_del_init(list);
		entry = list_entry(list, struct vml_info, head);

		/*
		 * First, try the current mode which might not be
		 * completely validated with respect to the pixel clock.
		 */

		if (!vmlfb_check_var_locked(&entry->info.var, entry)) {
			vmlfb_set_par_locked(entry);
			list_add_tail(list, &global_has_mode);
		} else {

			/*
			 * Didn't work. Try to find another mode,
			 * that matches this subsys.
			 */

			mutex_unlock(&vml_mutex);
			save_activate = entry->info.var.activate;
			entry->info.var.bits_per_pixel = 16;
			vmlfb_set_pref_pixel_format(&entry->info.var);
			if (fb_find_mode(&entry->info.var,
					 &entry->info,
					 vml_default_mode, NULL, 0, NULL, 16)) {
				entry->info.var.activate |=
				    FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
				fb_set_var(&entry->info, &entry->info.var);
			} else {
				printk(KERN_ERR MODULE_NAME
				       ": Sorry. no mode found for this subsys.\n");
			}
			entry->info.var.activate = save_activate;
			mutex_lock(&vml_mutex);
		}
		vmlfb_blank_locked(entry);
		list = global_no_mode.next;
	}
	mutex_unlock(&vml_mutex);

	printk(KERN_DEBUG MODULE_NAME ": Registered %s subsystem.\n",
				subsys->name ? subsys->name : "unknown");
	return 0;
}

EXPORT_SYMBOL_GPL(vmlfb_register_subsys);

void vmlfb_unregister_subsys(struct vml_sys *sys)
{
	struct vml_info *entry, *next;

	mutex_lock(&vml_mutex);
	if (subsys != sys) {
		mutex_unlock(&vml_mutex);
		return;
	}
	subsys->restore(subsys);
	subsys = NULL;
	list_for_each_entry_safe(entry, next, &global_has_mode, head) {
		printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n");
		vmlfb_disable_pipe(entry);
		list_move_tail(&entry->head, &global_no_mode);
	}
	mutex_unlock(&vml_mutex);
}

EXPORT_SYMBOL_GPL(vmlfb_unregister_subsys);

module_init(vmlfb_init);
module_exit(vmlfb_cleanup);

MODULE_AUTHOR("Tungsten Graphics");
MODULE_DESCRIPTION("Initialization of the Vermilion display devices");
MODULE_VERSION("1.0.0");
MODULE_LICENSE("GPL");
