/*
 *  linux/drivers/video/igafb.c -- Frame buffer device for IGA 1682
 *
 *      Copyright (C) 1998  Vladimir Roganov and Gleb Raiko
 *
 *  This driver is partly based on the Frame buffer device for ATI Mach64
 *  and partially on VESA-related code.
 *
 *      Copyright (C) 1997-1998  Geert Uytterhoeven
 *      Copyright (C) 1998  Bernd Harries
 *      Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License. See the file COPYING in the main directory of this archive for
 *  more details.
 */

/******************************************************************************

  TODO:
       Despite of IGA Card has advanced graphic acceleration, 
       initial version is almost dummy and does not support it.
       Support for video modes and acceleration must be added
       together with accelerated X-Windows driver implementation.

       Most important thing at this moment is that we have working
       JavaEngine1  console & X  with new console interface.

******************************************************************************/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/nvram.h>

#include <asm/io.h>

#ifdef CONFIG_SPARC
#include <asm/prom.h>
#include <asm/pcic.h>
#endif

#include <video/iga.h>

struct pci_mmap_map {
    unsigned long voff;
    unsigned long poff;
    unsigned long size;
    unsigned long prot_flag;
    unsigned long prot_mask;
};

struct iga_par {
	struct pci_mmap_map *mmap_map;
	unsigned long frame_buffer_phys;
	unsigned long io_base;
};

struct fb_info fb_info;

struct fb_fix_screeninfo igafb_fix __initdata = {
        .id		= "IGA 1682",
	.type		= FB_TYPE_PACKED_PIXELS,
	.mmio_len 	= 1000
};

struct fb_var_screeninfo default_var = {
	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
	.xres		= 640,
	.yres		= 480,
	.xres_virtual	= 640,
	.yres_virtual	= 480,
	.bits_per_pixel	= 8,
	.red		= {0, 8, 0 },
	.green		= {0, 8, 0 },
	.blue		= {0, 8, 0 },
	.height		= -1,
	.width		= -1,
	.accel_flags	= FB_ACCEL_NONE,
	.pixclock	= 39722,
	.left_margin	= 48,
	.right_margin	= 16,
	.upper_margin	= 33,
	.lower_margin	= 10,
	.hsync_len	= 96,
	.vsync_len	= 2,
	.vmode		= FB_VMODE_NONINTERLACED
};

#ifdef CONFIG_SPARC
struct fb_var_screeninfo default_var_1024x768 __initdata = {
	/* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
	.xres		= 1024,
	.yres		= 768,
	.xres_virtual	= 1024,
	.yres_virtual	= 768,
	.bits_per_pixel	= 8,
	.red		= {0, 8, 0 },
	.green		= {0, 8, 0 },
	.blue		= {0, 8, 0 },
	.height		= -1,
	.width		= -1,
	.accel_flags	= FB_ACCEL_NONE,
	.pixclock	= 12699,
	.left_margin	= 176,
	.right_margin	= 16,
	.upper_margin	= 28,
	.lower_margin	= 1,
	.hsync_len	= 96,
	.vsync_len	= 3,
	.vmode		= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
};

struct fb_var_screeninfo default_var_1152x900 __initdata = {
	/* 1152x900, 76 Hz, Non-Interlaced (110.0 MHz dotclock) */
	.xres		= 1152,
	.yres		= 900,
	.xres_virtual	= 1152,
	.yres_virtual	= 900,
	.bits_per_pixel	= 8,
	.red		= { 0, 8, 0 },
	.green		= { 0, 8, 0 },
	.blue		= { 0, 8, 0 },
	.height		= -1,
	.width		= -1,
	.accel_flags	= FB_ACCEL_NONE,
	.pixclock	= 9091,
	.left_margin	= 234,
	.right_margin	= 24,
	.upper_margin	= 34,
	.lower_margin	= 3,
	.hsync_len	= 100,
	.vsync_len	= 3,
	.vmode		= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
};

struct fb_var_screeninfo default_var_1280x1024 __initdata = {
	/* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
	.xres		= 1280,
	.yres		= 1024,
	.xres_virtual	= 1280,
	.yres_virtual	= 1024,
	.bits_per_pixel	= 8,
	.red		= {0, 8, 0 }, 
	.green		= {0, 8, 0 },
	.blue		= {0, 8, 0 },
	.height		= -1,
	.width		= -1,
	.accel_flags	= 0,
	.pixclock	= 7408,
	.left_margin	= 248,
	.right_margin	= 16,
	.upper_margin	= 38,
	.lower_margin	= 1,
	.hsync_len	= 144,
	.vsync_len	= 3,
	.vmode		= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
};

/*
 *   Memory-mapped I/O functions for Sparc PCI
 *
 * On sparc we happen to access I/O with memory mapped functions too.
 */ 
#define pci_inb(par, reg)        readb(par->io_base+(reg))
#define pci_outb(par, val, reg)  writeb(val, par->io_base+(reg))

static inline unsigned int iga_inb(struct iga_par *par, unsigned int reg,
				   unsigned int idx)
{
        pci_outb(par, idx, reg);
        return pci_inb(par, reg + 1);
}

static inline void iga_outb(struct iga_par *par, unsigned char val,
			    unsigned int reg, unsigned int idx )
{
        pci_outb(par, idx, reg);
        pci_outb(par, val, reg+1);
}

#endif /* CONFIG_SPARC */

/*
 *  Very important functionality for the JavaEngine1 computer:
 *  make screen border black (usign special IGA registers) 
 */
static void iga_blank_border(struct iga_par *par)
{
        int i;
#if 0
	/*
	 * PROM does this for us, so keep this code as a reminder
	 * about required read from 0x3DA and writing of 0x20 in the end.
	 */
	(void) pci_inb(par, 0x3DA);		/* required for every access */
	pci_outb(par, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL);
	(void) pci_inb(par, IGA_ATTR_CTL+1);
	pci_outb(par, 0x38, IGA_ATTR_CTL);
	pci_outb(par, 0x20, IGA_ATTR_CTL);	/* re-enable visual */
#endif
	/*
	 * This does not work as it was designed because the overscan
	 * color is looked up in the palette. Therefore, under X11
	 * overscan changes color.
	 */
	for (i=0; i < 3; i++)
		iga_outb(par, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
}

#ifdef CONFIG_SPARC
static int igafb_mmap(struct fb_info *info,
		      struct vm_area_struct *vma)
{
	struct iga_par *par = (struct iga_par *)info->par;
	unsigned int size, page, map_size = 0;
	unsigned long map_offset = 0;
	int i;

	if (!par->mmap_map)
		return -ENXIO;

	size = vma->vm_end - vma->vm_start;

	/* Each page, see which map applies */
	for (page = 0; page < size; ) {
		map_size = 0;
		for (i = 0; par->mmap_map[i].size; i++) {
			unsigned long start = par->mmap_map[i].voff;
			unsigned long end = start + par->mmap_map[i].size;
			unsigned long offset = (vma->vm_pgoff << PAGE_SHIFT) + page;

			if (start > offset)
				continue;
			if (offset >= end)
				continue;

			map_size = par->mmap_map[i].size - (offset - start);
			map_offset = par->mmap_map[i].poff + (offset - start);
			break;
		}
		if (!map_size) {
			page += PAGE_SIZE;
			continue;
		}
		if (page + map_size > size)
			map_size = size - page;

		pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask);
		pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;

		if (remap_pfn_range(vma, vma->vm_start + page,
			map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
			return -EAGAIN;

		page += map_size;
	}

	if (!map_size)
		return -EINVAL;

	vma->vm_flags |= VM_IO;
	return 0;
}
#endif /* CONFIG_SPARC */

static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green,
                           unsigned blue, unsigned transp,
                           struct fb_info *info)
{
        /*
         *  Set a single color register. The values supplied are
         *  already rounded down to the hardware's capabilities
         *  (according to the entries in the `var' structure). Return
         *  != 0 for invalid regno.
         */
	struct iga_par *par = (struct iga_par *)info->par;

        if (regno >= info->cmap.len)
                return 1;

	pci_outb(par, regno, DAC_W_INDEX);
	pci_outb(par, red,   DAC_DATA);
	pci_outb(par, green, DAC_DATA);
	pci_outb(par, blue,  DAC_DATA);

	if (regno < 16) {
		switch (info->var.bits_per_pixel) {
		case 16:
			((u16*)(info->pseudo_palette))[regno] = 
				(regno << 10) | (regno << 5) | regno;
			break;
		case 24:
			((u32*)(info->pseudo_palette))[regno] = 
				(regno << 16) | (regno << 8) | regno;
		break;
		case 32:
			{ int i;
			i = (regno << 8) | regno;
			((u32*)(info->pseudo_palette))[regno] = (i << 16) | i;
			}
			break;
		}
	}
	return 0;
}

/*
 * Framebuffer option structure
 */
static struct fb_ops igafb_ops = {
	.owner 		= THIS_MODULE,
	.fb_setcolreg 	= igafb_setcolreg,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
#ifdef CONFIG_SPARC
	.fb_mmap 	= igafb_mmap,
#endif
};

static int __init iga_init(struct fb_info *info, struct iga_par *par)
{
        char vramsz = iga_inb(par, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL) 
		                                         & MEM_SIZE_ALIAS;
	int video_cmap_len;

        switch (vramsz) {
        case MEM_SIZE_1M:
                info->fix.smem_len = 0x100000;
                break;
        case MEM_SIZE_2M:
                info->fix.smem_len = 0x200000;
                break;
        case MEM_SIZE_4M:
        case MEM_SIZE_RESERVED:
                info->fix.smem_len = 0x400000;
                break;
        }

        if (info->var.bits_per_pixel > 8) 
                video_cmap_len = 16;
        else 
                video_cmap_len = 256;

	info->fbops = &igafb_ops;
	info->flags = FBINFO_DEFAULT;

	fb_alloc_cmap(&info->cmap, video_cmap_len, 0);

	if (register_framebuffer(info) < 0)
		return 0;

	fb_info(info, "%s frame buffer device at 0x%08lx [%dMB VRAM]\n",
		info->fix.id, par->frame_buffer_phys, info->fix.smem_len >> 20);

	iga_blank_border(par); 
	return 1;
}

static int __init igafb_init(void)
{
        struct fb_info *info;
        struct pci_dev *pdev;
        struct iga_par *par;
	unsigned long addr;
	int size, iga2000 = 0;

	if (fb_get_options("igafb", NULL))
		return -ENODEV;

        pdev = pci_get_device(PCI_VENDOR_ID_INTERG,
                               PCI_DEVICE_ID_INTERG_1682, 0);
	if (pdev == NULL) {
		/*
		 * XXX We tried to use cyber2000fb.c for IGS 2000.
		 * But it does not initialize the chip in JavaStation-E, alas.
		 */
        	pdev = pci_get_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
        	if(pdev == NULL) {
        	        return -ENXIO;
		}
		iga2000 = 1;
	}
	/* We leak a reference here but as it cannot be unloaded this is
	   fine. If you write unload code remember to free it in unload */
	
	size = sizeof(struct iga_par) + sizeof(u32)*16;

	info = framebuffer_alloc(size, &pdev->dev);
        if (!info) {
                printk("igafb_init: can't alloc fb_info\n");
		 pci_dev_put(pdev);
                return -ENOMEM;
        }

	par = info->par;

	if ((addr = pdev->resource[0].start) == 0) {
                printk("igafb_init: no memory start\n");
		kfree(info);
		pci_dev_put(pdev);
		return -ENXIO;
	}

	if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) {
                printk("igafb_init: can't remap %lx[2M]\n", addr);
		kfree(info);
		pci_dev_put(pdev);
		return -ENXIO;
	}

	par->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;

#ifdef CONFIG_SPARC
	/*
	 * The following is sparc specific and this is why:
	 *
	 * IGS2000 has its I/O memory mapped and we want
	 * to generate memory cycles on PCI, e.g. do ioremap(),
	 * then readb/writeb() as in Documentation/io-mapping.txt.
	 *
	 * IGS1682 is more traditional, it responds to PCI I/O
	 * cycles, so we want to access it with inb()/outb().
	 *
	 * On sparc, PCIC converts CPU memory access within
	 * phys window 0x3000xxxx into PCI I/O cycles. Therefore
	 * we may use readb/writeb to access them with IGS1682.
	 *
	 * We do not take io_base_phys from resource[n].start
	 * on IGS1682 because that chip is BROKEN. It does not
	 * have a base register for I/O. We just "know" what its
	 * I/O addresses are.
	 */
	if (iga2000) {
		igafb_fix.mmio_start = par->frame_buffer_phys | 0x00800000;
	} else {
		igafb_fix.mmio_start = 0x30000000;	/* XXX */
	}
	if ((par->io_base = (int) ioremap(igafb_fix.mmio_start, igafb_fix.smem_len)) == 0) {
                printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start);
		iounmap((void *)info->screen_base);
		kfree(info);
		pci_dev_put(pdev);
		return -ENXIO;
	}

	/*
	 * Figure mmap addresses from PCI config space.
	 * We need two regions: for video memory and for I/O ports.
	 * Later one can add region for video coprocessor registers.
	 * However, mmap routine loops until size != 0, so we put
	 * one additional region with size == 0. 
	 */

	par->mmap_map = kzalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC);
	if (!par->mmap_map) {
		printk("igafb_init: can't alloc mmap_map\n");
		iounmap((void *)par->io_base);
		iounmap(info->screen_base);
		kfree(info);
		pci_dev_put(pdev);
		return -ENOMEM;
	}

	/*
	 * Set default vmode and cmode from PROM properties.
	 */
	{
		struct device_node *dp = pci_device_to_OF_node(pdev);
                int node = dp->node;
                int width = prom_getintdefault(node, "width", 1024);
                int height = prom_getintdefault(node, "height", 768);
                int depth = prom_getintdefault(node, "depth", 8);
                switch (width) {
                    case 1024:
                        if (height == 768)
                            default_var = default_var_1024x768;
                        break;
                    case 1152:
                        if (height == 900)
                            default_var = default_var_1152x900;
                        break;
                    case 1280:
                        if (height == 1024)
                            default_var = default_var_1280x1024;
                        break;
                    default:
                        break;
                }

                switch (depth) {
                    case 8:
                        default_var.bits_per_pixel = 8;
                        break;
                    case 16:
                        default_var.bits_per_pixel = 16;
                        break;
                    case 24:
                        default_var.bits_per_pixel = 24;
                        break;
                    case 32:
                        default_var.bits_per_pixel = 32;
                        break;
                    default:
                        break;
                }
            }

#endif
	igafb_fix.smem_start = (unsigned long) info->screen_base;
	igafb_fix.line_length = default_var.xres*(default_var.bits_per_pixel/8);
	igafb_fix.visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;

	info->var = default_var;
	info->fix = igafb_fix;
	info->pseudo_palette = (void *)(par + 1);

	if (!iga_init(info, par)) {
		iounmap((void *)par->io_base);
		iounmap(info->screen_base);
		kfree(par->mmap_map);
		kfree(info);
		return -ENODEV;
        }

#ifdef CONFIG_SPARC
	    /*
	     * Add /dev/fb mmap values.
	     */
	    
	    /* First region is for video memory */
	    par->mmap_map[0].voff = 0x0;  
	    par->mmap_map[0].poff = par->frame_buffer_phys & PAGE_MASK;
	    par->mmap_map[0].size = info->fix.smem_len & PAGE_MASK;
	    par->mmap_map[0].prot_mask = SRMMU_CACHE;
	    par->mmap_map[0].prot_flag = SRMMU_WRITE;

	    /* Second region is for I/O ports */
	    par->mmap_map[1].voff = par->frame_buffer_phys & PAGE_MASK;
	    par->mmap_map[1].poff = info->fix.smem_start & PAGE_MASK;
	    par->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */
	    par->mmap_map[1].prot_mask = SRMMU_CACHE;
	    par->mmap_map[1].prot_flag = SRMMU_WRITE;
#endif /* CONFIG_SPARC */

	return 0;
}

static int __init igafb_setup(char *options)
{
    char *this_opt;

    if (!options || !*options)
        return 0;

    while ((this_opt = strsep(&options, ",")) != NULL) {
    }
    return 0;
}

module_init(igafb_init);
MODULE_LICENSE("GPL");
static struct pci_device_id igafb_pci_tbl[] = {
	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
	{ }
};

MODULE_DEVICE_TABLE(pci, igafb_pci_tbl);
