/*
 *   flash rom utility: enable flash writes
 *
 *   Copyright (C) 2000-2004 ???
 *   Copyright (C) 2005 coresystems GmbH <stepan@openbios.org>
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   version 2
 *
 */

#include <sys/io.h>
#include <stdio.h>
#include <pci/pci.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "lbtable.h"
#include "debug.h"

// We keep this for the others.
static struct pci_access *pacc;

static int enable_flash_sis630(struct pci_dev *dev, char *name)
{
	char b;

	/* get io privilege access PCI configuration space */
	if (iopl(3) != 0) {
		perror("Can not set io priviliage");
		exit(1);
	}

	/* Enable 0xFFF8000~0xFFFF0000 decoding on SiS 540/630 */
	outl(0x80000840, 0x0cf8);
	b = inb(0x0cfc) | 0x0b;
	outb(b, 0xcfc);
	/* Flash write enable on SiS 540/630 */
	outl(0x80000845, 0x0cf8);
	b = inb(0x0cfd) | 0x40;
	outb(b, 0xcfd);

	/* The same thing on SiS 950 SuperIO side */
	outb(0x87, 0x2e);
	outb(0x01, 0x2e);
	outb(0x55, 0x2e);
	outb(0x55, 0x2e);

	if (inb(0x2f) != 0x87) {
		outb(0x87, 0x4e);
		outb(0x01, 0x4e);
		outb(0x55, 0x4e);
		outb(0xaa, 0x4e);
		if (inb(0x4f) != 0x87) {
			printf("Can not access SiS 950\n");
			return -1;
		}
		outb(0x24, 0x4e);
		b = inb(0x4f) | 0xfc;
		outb(0x24, 0x4e);
		outb(b, 0x4f);
		outb(0x02, 0x4e);
		outb(0x02, 0x4f);
	}

	outb(0x24, 0x2e);
	printf("2f is %#x\n", inb(0x2f));
	b = inb(0x2f) | 0xfc;
	outb(0x24, 0x2e);
	outb(b, 0x2f);

	outb(0x02, 0x2e);
	outb(0x02, 0x2f);

	return 0;
}

static int enable_flash_e7500(struct pci_dev *dev, char *name)
{
	/* register 4e.b gets or'ed with one */
	uint8_t old, new;
	/* if it fails, it fails. There are so many variations of broken mobos
	 * that it is hard to argue that we should quit at this point. 
	 */

	old = pci_read_byte(dev, 0x4e);

	new = old | 1;

	if (new == old)
		return 0;

	pci_write_byte(dev, 0x4e, new);

	if (pci_read_byte(dev, 0x4e) != new) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       0x4e, new, name);
		return -1;
	}
	return 0;
}

enum {
	ICH4_BIOS_CNTL = 0x4e,
	/* see page 375 of "Intel ICH7 External Design Specification"
	 * http://download.intel.com/design/chipsets/datashts/30701302.pdf */
	ICH7_BIOS_CNTL = 0xdc,
};
static int enable_flash_ich(struct pci_dev *dev, char *name, int bios_cntl)
{
	/* register 4e.b gets or'ed with one */
	uint8_t old, new;
	/* if it fails, it fails. There are so many variations of broken mobos
	 * that it is hard to argue that we should quit at this point. 
	 */

	old = pci_read_byte(dev, bios_cntl);

	new = old | 1;

	if (new == old)
		return 0;

	pci_write_byte(dev, bios_cntl, new);

	if (pci_read_byte(dev, bios_cntl) != new) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       bios_cntl, new, name);
		return -1;
	}
	return 0;
}

static int enable_flash_ich4(struct pci_dev *dev, char *name)
{
	return enable_flash_ich(dev, name, ICH4_BIOS_CNTL);
}

static int enable_flash_ich7(struct pci_dev *dev, char *name)
{
	return enable_flash_ich(dev, name, ICH7_BIOS_CNTL);
}

static int enable_flash_vt8235(struct pci_dev *dev, char *name)
{
	uint8_t old, new, val;
	unsigned int base;
	int ok;

	/* get io privilege access PCI configuration space */
	if (iopl(3) != 0) {
		perror("Can not set io priviliage");
		exit(1);
	}

	old = pci_read_byte(dev, 0x40);

	new = old | 0x10;

	if (new == old)
		return 0;

	ok = pci_write_byte(dev, 0x40, new);
	if (ok != 0) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       old, new, name);
	}

	/* enable GPIO15 which is connected to write protect. */
	base = ((pci_read_byte(dev, 0x88) & 0x80) | pci_read_byte(dev, 0x89) << 8);
	val = inb(base + 0x4d);
	val |= 0x80;
	outb(val, base + 0x4d);

	if (ok != 0) {
		return -1;
	} else {
		return 0;
	}
}

static int enable_flash_vt8231(struct pci_dev *dev, char *name)
{
	uint8_t val;

	val = pci_read_byte(dev, 0x40);
	val |= 0x10;
	pci_write_byte(dev, 0x40, val);

	if (pci_read_byte(dev, 0x40) != val) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       0x40, val, name);
		return -1;
	}
	return 0;
}

static int enable_flash_cs5530(struct pci_dev *dev, char *name)
{
	uint8_t new;

	pci_write_byte(dev, 0x52, 0xee);

	new = pci_read_byte(dev, 0x52);

	if (new != 0xee) {
		printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       0x52, new, name);
		return -1;
	}
	
	new = pci_read_byte(dev, 0x5b) | 0x20;
	pci_write_byte(dev, 0x5b, new);
	
	return 0;
}


static int enable_flash_sc1100(struct pci_dev *dev, char *name)
{
	uint8_t new;

	pci_write_byte(dev, 0x52, 0xee);

	new = pci_read_byte(dev, 0x52);

	if (new != 0xee) {
		printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       0x52, new, name);
		return -1;
	}
	return 0;
}

static int enable_flash_sis5595(struct pci_dev *dev, char *name)
{
	uint8_t new, newer;

	new = pci_read_byte(dev, 0x45);

	/* clear bit 5 */
	new &= (~0x20);
	/* set bit 2 */
	new |= 0x4;

	pci_write_byte(dev, 0x45, new);

	newer = pci_read_byte(dev, 0x45);
	if (newer != new) {
		printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       0x45, new, name);
		printf("Stuck at 0x%x\n", newer);
		return -1;
	}
	return 0;
}

static int enable_flash_amd8111(struct pci_dev *dev, char *name)
{
	/* register 4e.b gets or'ed with one */
	uint8_t old, new;
	/* if it fails, it fails. There are so many variations of broken mobos
	 * that it is hard to argue that we should quit at this point. 
	 */

	/* enable decoding at 0xffb00000 to 0xffffffff */
	old = pci_read_byte(dev, 0x43);
	new = old | 0xC0;
	if (new != old) {
		pci_write_byte(dev, 0x43, new);
		if (pci_read_byte(dev, 0x43) != new) {
			printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
			       0x43, new, name);
		}
	}

	old = pci_read_byte(dev, 0x40);
	new = old | 0x01;
	if (new == old)
		return 0;
	pci_write_byte(dev, 0x40, new);

	if (pci_read_byte(dev, 0x40) != new) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       0x40, new, name);
		return -1;
	}
	return 0;
}

//By yhlu
static int enable_flash_ck804(struct pci_dev *dev, char *name)
{
        /* register 4e.b gets or'ed with one */
        uint8_t old, new;
        /* if it fails, it fails. There are so many variations of broken mobos
         * that it is hard to argue that we should quit at this point. 
         */

        //dump_pci_device(dev); 
        
        old = pci_read_byte(dev, 0x88);
        new = old | 0xc0;
        if (new != old) {
                pci_write_byte(dev, 0x88, new);
                if (pci_read_byte(dev, 0x88) != new) {
                        printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
                               0x88, new, name);
                }
        }

        old = pci_read_byte(dev, 0x6d);
        new = old | 0x01;
        if (new == old)
                return 0;
        pci_write_byte(dev, 0x6d, new);

        if (pci_read_byte(dev, 0x6d) != new) {
                printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
                       0x6d, new, name);
                return -1;
        }
        return 0;
}

static int enable_flash_sb400(struct pci_dev *dev, char *name)
{
        uint8_t tmp;

	struct pci_filter f;
	struct pci_dev *smbusdev;

	/* get io privilege access */
	if (iopl(3) != 0) {
		perror("Can not set io priviliage");
		exit(1);
	}

	/* then look for the smbus device */
	pci_filter_init((struct pci_access *) 0, &f);
	f.vendor = 0x1002;
	f.device = 0x4372;
	
	for (smbusdev = pacc->devices; smbusdev; smbusdev = smbusdev->next) {
		if (pci_filter_match(&f, smbusdev)) {
			break;
		}
	}
	
	if(!smbusdev) {
		perror("smbus device not found. aborting\n");
		exit(1);
	}
	
	// enable some smbus stuff
	tmp=pci_read_byte(smbusdev, 0x79);
	tmp|=0x01;
	pci_write_byte(smbusdev, 0x79, tmp);

	// change southbridge
	tmp=pci_read_byte(dev, 0x48);
	tmp|=0x21;
	pci_write_byte(dev, 0x48, tmp);

	// now become a bit silly. 
	tmp=inb(0xc6f);
	outb(tmp,0xeb);
	outb(tmp, 0xeb);
	tmp|=0x40;
	outb(tmp, 0xc6f);
	outb(tmp, 0xeb);
	outb(tmp, 0xeb);

	return 0;
}

typedef struct penable {
	unsigned short vendor, device;
	char *name;
	int (*doit) (struct pci_dev * dev, char *name);
} FLASH_ENABLE;

static FLASH_ENABLE enables[] = {
	{0x1039, 0x0630, "sis630", enable_flash_sis630},
	{0x8086, 0x2480, "E7500", enable_flash_e7500},
	{0x8086, 0x24c0, "ICH4", enable_flash_ich4},
	{0x8086, 0x24cc, "ICH4-M", enable_flash_ich4},
	{0x8086, 0x24d0, "ICH5", enable_flash_ich4},
	{0x8086, 0x27b8, "ICH7", enable_flash_ich7},
	{0x1106, 0x8231, "VT8231", enable_flash_vt8231},
	{0x1106, 0x3177, "VT8235", enable_flash_vt8235},
	{0x1078, 0x0100, "CS5530", enable_flash_cs5530},
	{0x100b, 0x0510, "SC1100", enable_flash_sc1100},
	{0x1039, 0x0008, "SIS5595", enable_flash_sis5595},
	{0x1022, 0x7468, "AMD8111", enable_flash_amd8111},
	// this fallthrough looks broken.
        {0x10de, 0x0050, "NVIDIA CK804", enable_flash_ck804}, // LPC
        {0x10de, 0x0051, "NVIDIA CK804", enable_flash_ck804}, // Pro
        {0x10de, 0x00d3, "NVIDIA CK804", enable_flash_ck804}, // Slave, should not be here, to fix known bug for A01.
	{0x10de, 0x0261, "NVIDIA C51",   enable_flash_ck804},
	{0x1002, 0x4377, "ATI SB400", enable_flash_sb400}, // ATI Technologies Inc IXP SB400 PCI-ISA Bridge (rev 80)
};

static int mbenable_island_aruma(void)
{
#define EFIR 0x2e      /* Extended function index register, either 0x2e or 0x4e    */
#define EFDR EFIR + 1  /* Extended function data register, one plus the index reg. */
	char b;

/*  Disable the flash write protect.  The flash write protect is 
 *  connected to the WinBond w83627hf GPIO 24.
 */

	/* get io privilege access winbond config space */
	if (iopl(3) != 0) {
		perror("Can not set io priviliage");
		exit(1);
	}
	
	printf("Disabling mainboard flash write protection.\n");

	outb(0x87, EFIR); // sequence to unlock extended functions
	outb(0x87, EFIR);

	outb(0x20, EFIR); // SIO device ID register
	b = inb(EFDR); 
	printf_debug("W83627HF device ID = 0x%x\n",b);

	if (b != 0x52) {
		perror("Incorrect device ID, aborting write protect disable\n");
		exit(1);
	}

	outb(0x2b, EFIR); // GPIO multiplexed pin reg.
	b = inb(EFDR) | 0x10; 
	outb(0x2b, EFIR); 
	outb(b, EFDR); // select GPIO 24 instead of WDTO

	outb(0x7, EFIR); // logical device select
	outb(0x8, EFDR); // point to device 8, GPIO port 2

	outb(0x30, EFIR); // logic device activation control
	outb(0x1, EFDR); // activate

	outb(0xf0, EFIR); // GPIO 20-27 I/O selection register
	b = inb(EFDR) & ~0x10; 
	outb(0xf0, EFIR); 
	outb(b, EFDR); // set GPIO 24 as an output

	outb(0xf1, EFIR); // GPIO 20-27 data register
	b = inb(EFDR) | 0x10; 
	outb(0xf1, EFIR); 
	outb(b, EFDR); // set GPIO 24

	outb(0xaa, EFIR); // command to exit extended functions

	return 0;
}

typedef struct mbenable {
	char *vendor, *part;
	int (*doit)(void);
} MAINBOARD_ENABLE;

static MAINBOARD_ENABLE mbenables[] = {
	{ "ISLAND", "ARUMA", mbenable_island_aruma },
};

int enable_flash_write()
{
	int i;
	struct pci_dev *dev = 0;
	FLASH_ENABLE *enable = 0;

	pacc = pci_alloc();	/* Get the pci_access structure */
	/* Set all options you want -- here we stick with the defaults */
	pci_init(pacc);		/* Initialize the PCI library */
	pci_scan_bus(pacc);	/* We want to get the list of devices */

	
	/* First look whether we have to do something for this
	 * motherboard.
	 */
	for (i = 0; i < sizeof(mbenables) / sizeof(mbenables[0]); i++) {
		if(lb_vendor && !strcmp(mbenables[i].vendor, lb_vendor) &&
		   lb_part && !strcmp(mbenables[i].part, lb_part)) {
			mbenables[i].doit();
			break;
		}
	}
	
	/* now let's try to find the chipset we have ... */
	for (i = 0; i < sizeof(enables) / sizeof(enables[0]) && (!dev);
	     i++) {
		struct pci_filter f;
		struct pci_dev *z;
		/* the first param is unused. */
		pci_filter_init((struct pci_access *) 0, &f);
		f.vendor = enables[i].vendor;
		f.device = enables[i].device;
		for (z = pacc->devices; z; z = z->next)
			if (pci_filter_match(&f, z)) {
				enable = &enables[i];
				dev = z;
			}
	}

	/* now do the deed. */
	if (enable) {
		printf("Enabling flash write on %s...", enable->name);
		if (enable->doit(dev, enable->name) == 0)
			printf("OK\n");
	}
	return 0;
}
