/*
 *  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/tty.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 __sparc__
#include <asm/pbm.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 __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_virtaul	= 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 /* __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 __sparc__
static int igafb_mmap(struct fb_info *info, struct file *file,
		      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;

	/* To stop the swapper from even considering these pages. */
	vma->vm_flags |= (VM_SHM | VM_LOCKED);

	/* 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_page_range(vma, vma->vm_start + page, map_offset,
				     map_size, vma->vm_page_prot))
			return -EAGAIN;

		page += map_size;
	}

	if (!map_size)
		return -EINVAL;

	vma->vm_flags |= VM_IO;
	return 0;
}
#endif /* __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:
			info->pseudo_palette[regno] = 
				(regno << 10) | (regno << 5) | regno;
			break;
		case 24:
			info->pseudo_palette[regno] = 
				(regno << 16) | (regno << 8) | regno;
		break;
		case 32:
			{ int i;
			i = (regno << 8) | regno;
			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 __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->node  = NODEV;
	info->fbops = &igafb_ops;
	info->flags = FBINFO_FLAG_DEFAULT;

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

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

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

	iga_blank_border(par); 
	return 1;
}

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

        /* Do not attach when we have a serial console. */
        if (!con_is_present())
                return -ENXIO;

        pdev = pci_find_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_find_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
        	if(pdev == NULL) {
        	        return -ENXIO;
		}
		iga2000 = 1;
	}
	
	size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16;

        info = kmalloc(size, GFP_ATOMIC);
        if (!info) {
                printk("igafb_init: can't alloc fb_info\n");
                return -ENOMEM;
        }
        memset(info, 0, size);

	par = (struct iga_par *) (info + 1);
	

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

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

	par->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;

#ifdef __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);
		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 = kmalloc(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);
		return -ENOMEM;
	}

	memset(par->mmap_map, 0, 4 * sizeof(*par->mmap_map));

	/*
	 * Set default vmode and cmode from PROM properties.
	 */
	{
                struct pcidev_cookie *cookie = pdev->sysdata;
                int node = cookie->prom_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);
		if (par->mmap_map)
			kfree(par->mmap_map);
		kfree(info);
        }

#ifdef __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 /* __sparc__ */

	return 0;
}

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

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

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

MODULE_LICENSE("GPL");
