/*
 *  linux/drivers/video/offb.c -- Open Firmware based frame buffer device
 *
 *	Copyright (C) 1997 Geert Uytterhoeven
 *
 *  This driver is partly based on the PowerMac console driver:
 *
 *	Copyright (C) 1996 Paul Mackerras
 *
 *  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.
 */

#include <linux/config.h>
#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/ioport.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/prom.h>

#ifdef CONFIG_PPC64
#include <asm/pci-bridge.h>
#endif

#ifdef CONFIG_PPC32
#include <asm/bootx.h>
#endif

#include "macmodes.h"

/* Supported palette hacks */
enum {
	cmap_unknown,
	cmap_m64,		/* ATI Mach64 */
	cmap_r128,		/* ATI Rage128 */
	cmap_M3A,		/* ATI Rage Mobility M3 Head A */
	cmap_M3B,		/* ATI Rage Mobility M3 Head B */
	cmap_radeon,		/* ATI Radeon */
	cmap_gxt2000,		/* IBM GXT2000 */
};

struct offb_par {
	volatile void __iomem *cmap_adr;
	volatile void __iomem *cmap_data;
	int cmap_type;
	int blanked;
};

struct offb_par default_par;

    /*
     *  Interface used by the world
     */

int offb_init(void);

static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			  u_int transp, struct fb_info *info);
static int offb_blank(int blank, struct fb_info *info);

#ifdef CONFIG_PPC32
extern boot_infos_t *boot_infos;
#endif

static void offb_init_nodriver(struct device_node *);
static void offb_init_fb(const char *name, const char *full_name,
			 int width, int height, int depth, int pitch,
			 unsigned long address, struct device_node *dp);

static struct fb_ops offb_ops = {
	.owner		= THIS_MODULE,
	.fb_setcolreg	= offb_setcolreg,
	.fb_blank	= offb_blank,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
};

    /*
     *  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.
     */

static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			  u_int transp, struct fb_info *info)
{
	struct offb_par *par = (struct offb_par *) info->par;

	if (!par->cmap_adr || regno > 255)
		return 1;

	red >>= 8;
	green >>= 8;
	blue >>= 8;

	switch (par->cmap_type) {
	case cmap_m64:
		writeb(regno, par->cmap_adr);
		writeb(red, par->cmap_data);
		writeb(green, par->cmap_data);
		writeb(blue, par->cmap_data);
		break;
	case cmap_M3A:
		/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
		out_le32(par->cmap_adr + 0x58,
			 in_le32(par->cmap_adr + 0x58) & ~0x20);
	case cmap_r128:
		/* Set palette index & data */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4,
			 (red << 16 | green << 8 | blue));
		break;
	case cmap_M3B:
		/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
		out_le32(par->cmap_adr + 0x58,
			 in_le32(par->cmap_adr + 0x58) | 0x20);
		/* Set palette index & data */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
		break;
	case cmap_radeon:
		/* Set palette index & data (could be smarter) */
		out_8(par->cmap_adr + 0xb0, regno);
		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
		break;
	case cmap_gxt2000:
		out_le32((unsigned __iomem *) par->cmap_adr + regno,
			 (red << 16 | green << 8 | blue));
		break;
	}

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

    /*
     *  Blank the display.
     */

static int offb_blank(int blank, struct fb_info *info)
{
	struct offb_par *par = (struct offb_par *) info->par;
	int i, j;

	if (!par->cmap_adr)
		return 0;

	if (!par->blanked)
		if (!blank)
			return 0;

	par->blanked = blank;

	if (blank)
		for (i = 0; i < 256; i++) {
			switch (par->cmap_type) {
			case cmap_m64:
				writeb(i, par->cmap_adr);
				for (j = 0; j < 3; j++)
					writeb(0, par->cmap_data);
				break;
			case cmap_M3A:
				/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
				out_le32(par->cmap_adr + 0x58,
					 in_le32(par->cmap_adr + 0x58) & ~0x20);
			case cmap_r128:
				/* Set palette index & data */
				out_8(par->cmap_adr + 0xb0, i);
				out_le32(par->cmap_adr + 0xb4, 0);
				break;
			case cmap_M3B:
				/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
				out_le32(par->cmap_adr + 0x58,
					 in_le32(par->cmap_adr + 0x58) | 0x20);
				/* Set palette index & data */
				out_8(par->cmap_adr + 0xb0, i);
				out_le32(par->cmap_adr + 0xb4, 0);
				break;
			case cmap_radeon:
				out_8(par->cmap_adr + 0xb0, i);
				out_le32(par->cmap_adr + 0xb4, 0);
				break;
			case cmap_gxt2000:
				out_le32((unsigned __iomem *) par->cmap_adr + i,
					 0);
				break;
			}
	} else
		fb_set_cmap(&info->cmap, info);
	return 0;
}

    /*
     *  Initialisation
     */

int __init offb_init(void)
{
	struct device_node *dp = NULL, *boot_disp = NULL;

#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32)
	struct device_node *macos_display = NULL;
#endif
	if (fb_get_options("offb", NULL))
		return -ENODEV;

#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32)
	/* If we're booted from BootX... */
	if (boot_infos != 0) {
		unsigned long addr =
		    (unsigned long) boot_infos->dispDeviceBase;
		u32 *addrp;
		u64 daddr, dsize;
		unsigned int flags;

		/* find the device node corresponding to the macos display */
		while ((dp = of_find_node_by_type(dp, "display"))) {
			int i;

			/*
			 * Look for an AAPL,address property first.
			 */
			unsigned int na;
			unsigned int *ap =
				(unsigned int *)get_property(dp, "AAPL,address",
							     &na);
			if (ap != 0) {
				for (na /= sizeof(unsigned int); na > 0;
				     --na, ++ap)
					if (*ap <= addr &&
					    addr < *ap + 0x1000000) {
						macos_display = dp;
						goto foundit;
					}
			}

			/*
			 * See if the display address is in one of the address
			 * ranges for this display.
			 */
			i = 0;
			for (;;) {
				addrp = of_get_address(dp, i++, &dsize, &flags);
				if (addrp == NULL)
					break;
				if (!(flags & IORESOURCE_MEM))
					continue;
				daddr = of_translate_address(dp, addrp);
				if (daddr == OF_BAD_ADDR)
					continue;
				if (daddr <= addr && addr < (daddr + dsize)) {
					macos_display = dp;
					goto foundit;
				}
			}
		foundit:
			if (macos_display) {
				printk(KERN_INFO "MacOS display is %s\n",
				       dp->full_name);
				break;
			}
		}

		/* initialize it */
		offb_init_fb(macos_display ? macos_display->
			     name : "MacOS display",
			     macos_display ? macos_display->
			     full_name : "MacOS display",
			     boot_infos->dispDeviceRect[2],
			     boot_infos->dispDeviceRect[3],
			     boot_infos->dispDeviceDepth,
			     boot_infos->dispDeviceRowBytes, addr, NULL);
	}
#endif /* defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) */

	for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
		if (get_property(dp, "linux,opened", NULL) &&
		    get_property(dp, "linux,boot-display", NULL)) {
			boot_disp = dp;
			offb_init_nodriver(dp);
		}
	}
	for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
		if (get_property(dp, "linux,opened", NULL) &&
		    dp != boot_disp)
			offb_init_nodriver(dp);
	}

	return 0;
}


static void __init offb_init_nodriver(struct device_node *dp)
{
	int *pp, i;
	unsigned int len;
	int width = 640, height = 480, depth = 8, pitch;
	unsigned int flags, rsize, *up;
	u64 address = OF_BAD_ADDR;
	u32 *addrp;
	u64 asize;

	if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
	    && len == sizeof(int))
		depth = *pp;
	if ((pp = (int *) get_property(dp, "width", &len)) != NULL
	    && len == sizeof(int))
		width = *pp;
	if ((pp = (int *) get_property(dp, "height", &len)) != NULL
	    && len == sizeof(int))
		height = *pp;
	if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL
	    && len == sizeof(int)) {
		pitch = *pp;
		if (pitch == 1)
			pitch = 0x1000;
	} else
		pitch = width;

       rsize = (unsigned long)pitch * (unsigned long)height *
               (unsigned long)(depth / 8);

       /* Try to match device to a PCI device in order to get a properly
	* translated address rather then trying to decode the open firmware
	* stuff in various incorrect ways
	*/
#ifdef CONFIG_PCI
       /* First try to locate the PCI device if any */
       {
               struct pci_dev *pdev = NULL;

	       for_each_pci_dev(pdev) {
                       if (dp == pci_device_to_OF_node(pdev))
                               break;
	       }
               if (pdev) {
                       for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) {
                               if ((pci_resource_flags(pdev, i) &
				    IORESOURCE_MEM) &&
				   (pci_resource_len(pdev, i) >= rsize))
                                       address = pci_resource_start(pdev, i);
                       }
		       pci_dev_put(pdev);
               }
        }
#endif /* CONFIG_PCI */

       /* This one is dodgy, we may drop it ... */
       if (address == OF_BAD_ADDR &&
	   (up = (unsigned *) get_property(dp, "address", &len)) != NULL &&
	   len == sizeof(unsigned int))
	       address = (u64) * up;

       if (address == OF_BAD_ADDR) {
	       for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
			    != NULL; i++) {
		       if (!(flags & IORESOURCE_MEM))
			       continue;
		       if (asize >= pitch * height * depth / 8)
			       break;
	       }
		if (addrp == NULL) {
			printk(KERN_ERR
			       "no framebuffer address found for %s\n",
			       dp->full_name);
			return;
		}
		address = of_translate_address(dp, addrp);
		if (address == OF_BAD_ADDR) {
			printk(KERN_ERR
			       "can't translate framebuffer address for %s\n",
			       dp->full_name);
			return;
		}

		/* kludge for valkyrie */
		if (strcmp(dp->name, "valkyrie") == 0)
			address += 0x1000;
	}
	offb_init_fb(dp->name, dp->full_name, width, height, depth,
		     pitch, address, dp);

}

static void __init offb_init_fb(const char *name, const char *full_name,
				int width, int height, int depth,
				int pitch, unsigned long address,
				struct device_node *dp)
{
	unsigned long res_size = pitch * height * depth / 8;
	struct offb_par *par = &default_par;
	unsigned long res_start = address;
	struct fb_fix_screeninfo *fix;
	struct fb_var_screeninfo *var;
	struct fb_info *info;
	int size;

	if (!request_mem_region(res_start, res_size, "offb"))
		return;

	printk(KERN_INFO
	       "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
	       width, height, name, address, depth, pitch);
	if (depth != 8 && depth != 16 && depth != 32) {
		printk(KERN_ERR "%s: can't use depth = %d\n", full_name,
		       depth);
		release_mem_region(res_start, res_size);
		return;
	}

	size = sizeof(struct fb_info) + sizeof(u32) * 17;

	info = kmalloc(size, GFP_ATOMIC);
	
	if (info == 0) {
		release_mem_region(res_start, res_size);
		return;
	}
	memset(info, 0, size);

	fix = &info->fix;
	var = &info->var;

	strcpy(fix->id, "OFfb ");
	strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb "));
	fix->id[sizeof(fix->id) - 1] = '\0';

	var->xres = var->xres_virtual = width;
	var->yres = var->yres_virtual = height;
	fix->line_length = pitch;

	fix->smem_start = address;
	fix->smem_len = pitch * height;
	fix->type = FB_TYPE_PACKED_PIXELS;
	fix->type_aux = 0;

	par->cmap_type = cmap_unknown;
	if (depth == 8) {

		/* Palette hacks disabled for now */
#if 0
		if (dp && !strncmp(name, "ATY,Rage128", 11)) {
			unsigned long regbase = dp->addrs[2].address;
			par->cmap_adr = ioremap(regbase, 0x1FFF);
			par->cmap_type = cmap_r128;
		} else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
				  || !strncmp(name, "ATY,RageM3p12A", 14))) {
			unsigned long regbase =
			    dp->parent->addrs[2].address;
			par->cmap_adr = ioremap(regbase, 0x1FFF);
			par->cmap_type = cmap_M3A;
		} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
			unsigned long regbase =
			    dp->parent->addrs[2].address;
			par->cmap_adr = ioremap(regbase, 0x1FFF);
			par->cmap_type = cmap_M3B;
		} else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
			unsigned long regbase = dp->addrs[1].address;
			par->cmap_adr = ioremap(regbase, 0x1FFF);
			par->cmap_type = cmap_radeon;
		} else if (!strncmp(name, "ATY,", 4)) {
			unsigned long base = address & 0xff000000UL;
			par->cmap_adr =
			    ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
			par->cmap_data = par->cmap_adr + 1;
			par->cmap_type = cmap_m64;
		} else if (device_is_compatible(dp, "pci1014,b7")) {
			unsigned long regbase = dp->addrs[0].address;
			par->cmap_adr = ioremap(regbase + 0x6000, 0x1000);
			par->cmap_type = cmap_gxt2000;
		}
#endif
		fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
		    : FB_VISUAL_STATIC_PSEUDOCOLOR;
	} else
		fix->visual =	/* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR
				   : */ FB_VISUAL_TRUECOLOR;

	var->xoffset = var->yoffset = 0;
	var->bits_per_pixel = depth;
	switch (depth) {
	case 8:
		var->bits_per_pixel = 8;
		var->red.offset = 0;
		var->red.length = 8;
		var->green.offset = 0;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 16:		/* RGB 555 */
		var->bits_per_pixel = 16;
		var->red.offset = 10;
		var->red.length = 5;
		var->green.offset = 5;
		var->green.length = 5;
		var->blue.offset = 0;
		var->blue.length = 5;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 32:		/* RGB 888 */
		var->bits_per_pixel = 32;
		var->red.offset = 16;
		var->red.length = 8;
		var->green.offset = 8;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 24;
		var->transp.length = 8;
		break;
	}
	var->red.msb_right = var->green.msb_right = var->blue.msb_right =
	    var->transp.msb_right = 0;
	var->grayscale = 0;
	var->nonstd = 0;
	var->activate = 0;
	var->height = var->width = -1;
	var->pixclock = 10000;
	var->left_margin = var->right_margin = 16;
	var->upper_margin = var->lower_margin = 16;
	var->hsync_len = var->vsync_len = 8;
	var->sync = 0;
	var->vmode = FB_VMODE_NONINTERLACED;

	info->fbops = &offb_ops;
	info->screen_base = ioremap(address, fix->smem_len);
	info->par = par;
	info->pseudo_palette = (void *) (info + 1);
	info->flags = FBINFO_DEFAULT;

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

	if (register_framebuffer(info) < 0) {
		kfree(info);
		release_mem_region(res_start, res_size);
		return;
	}

	printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
	       info->node, full_name);
}

module_init(offb_init);
MODULE_LICENSE("GPL");
