/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2004-2005 Nick Barker <nick.barker@btinternet.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <arch/io.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>
#include <device/pci_ids.h>
#include <console/console.h>
#include <device/cardbus.h>
#include <delay.h>
#include "rl5c476.h"
#include "chip.h"

static int enable_cf_boot = 0;
static unsigned int cf_base;

static void rl5c476_init(device_t dev)
{
	pc16reg_t *pc16;
	unsigned char *base;

	/* cardbus controller function 1 for CF Socket */
	printk(BIOS_DEBUG, "Ricoh RL5c476: Initializing.\n");

	printk(BIOS_DEBUG, "CF Base = %0x\n",cf_base);

	/* misc control register */
	pci_write_config16(dev,0x82,0x00a0);

	/* set up second slot as compact flash port if asked to do so */

	if (!enable_cf_boot) {
		printk(BIOS_DEBUG, "CF boot not enabled.\n");
		return;
	}

	if (PCI_FUNC(dev->path.pci.devfn) != 1) {
		// Only configure if second CF slot.
		return;
	}

	/* make sure isa interrupts are enabled */
	pci_write_config16(dev,0x3e,0x0780);

	/* pick up where 16 bit card control structure is
	 * (0x800 bytes into config structure)
	 */
	base = (unsigned char *)pci_read_config32(dev,0x10);
	pc16 = (pc16reg_t *)(base + 0x800);

	/* disable memory and io windows and turn off socket power */
	pc16->pwctrl = 0;

	/* disable irq lines */
	pc16->igctrl = 0;

	/* disable memory and I/O windows */
	pc16->awinen = 0;

	/* reset card, configure for I/O and set IRQ line */
	pc16->igctrl = 0x69;

	/* set io window 0 for 1e0 - 1ef */
	/* NOTE: This now sets CF up on a contiguous I/O window of
	 * 16 bytes, 0x1e0 to 0x1ef.
	 * Be warned that this is not a standard IDE address as
	 * automatically detected by the likes of FILO, and would need
	 * patching to recognise these addresses as an IDE drive.
	 *
	 * An earlier version of this driver set up 2 I/O windows to
	 * emulate the expected addresses for IDE2, however the PCMCIA
	 * package within Linux then could not re-initialize the
	 * device as it tried to take control of it. So I believe it is
	 * easier to patch Filo or the like to pick up this drive
	 * rather than playing silly games as the kernel tries to
	 * boot.
	 *
	 * Nonetheless, FILO needs a special option enabled to boot
	 * from this configuration, and it needs to clean up
	 * afterwards. Please refer to FILO documentation and source
	 * code for more details.
	 */
	pc16->iostl0 = 0xe0;
	pc16->iosth0 = 1;

	pc16->iospl0 = 0xef;
	pc16->iosph0 = 1;

	pc16->ioffl0 = 0;
	pc16->ioffh0 = 0;

	/* clear window 1 */
	pc16->iostl1 = 0;
	pc16->iosth1 = 0;

	pc16->iospl1 = 0;
	pc16->iosph1 = 0;

	pc16->ioffl1 = 0x0;
	pc16->ioffh1 = 0;

	/* set up CF config window */
	pc16->smpga0 = cf_base>>24;
	pc16->smsth0 = (cf_base>>20)&0x0f;
	pc16->smstl0 = (cf_base>>12)&0xff;
	pc16->smsph0 = ((cf_base>>20)&0x0f) | 0x80;
	pc16->smspl0 = (cf_base>>12)&0xff;
	pc16->moffl0 = 0;
	pc16->moffh0 = 0x40;


	/* set I/O width for Auto Data width */
	pc16->ioctrl = 0x22;


	/* enable I/O window 0 and 1 */
	pc16->awinen = 0xc1;

	pc16->miscc1 = 1;

	/* apply power and enable outputs */
	pc16->pwctrl = 0xb0;

	// delay could be optimised, but this works
	udelay(100000);

	pc16->igctrl = 0x69;


	/* 16 bit CF always have first config byte at 0x200 into
	 * Config structure, but CF+ may not according to spec -
	 * should locate through reading tuple data, but this should
	 * do for now.
	 */
	unsigned char *cptr;
	cptr = (unsigned char *)(cf_base + 0x200);
	printk(BIOS_DEBUG, "CF Config = %x\n",*cptr);

	/* Set CF to decode 16 IO bytes on any 16 byte boundary -
	 * rely on the io windows of the bridge set up above to
	 * map those bytes into the addresses for IDE controller 3
	 * (0x1e8 - 0x1ef and 0x3ed - 0x3ee)
	 */
	*cptr = 0x41;
}

static void rl5c476_read_resources(device_t dev)
{

	struct resource *resource;

	 /* For CF socket we need an extra memory window for
	  * the control structure of the CF itself
	  */
	if( enable_cf_boot && (PCI_FUNC(dev->path.pci.devfn) == 1)){
		/* fake index as it isn't in PCI config space */
		resource = new_resource(dev, 1);
		resource->flags |= IORESOURCE_MEM;
		resource->size = 0x1000;
		resource->align = resource->gran = 12;
		resource->limit= 0xffff0000;
	}
	cardbus_read_resources(dev);
}

static void rl5c476_set_resources(device_t dev)
{
	struct resource *resource;
	printk(BIOS_DEBUG, "%s In set resources \n",dev_path(dev));
	if( enable_cf_boot && (PCI_FUNC(dev->path.pci.devfn) == 1)){
		resource = find_resource(dev,1);
		if( !(resource->flags & IORESOURCE_STORED) ){
			resource->flags |= IORESOURCE_STORED ;
			printk(BIOS_DEBUG, "%s 1 ==> %llx\n", dev_path(dev), resource->base);
			cf_base = resource->base;
		}
	}

	pci_dev_set_resources(dev);

}

static void rl5c476_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
       u16 miscreg = pci_read_config16(dev, 0x82);
       /* Enable subsystem id register writes */
       pci_write_config16(dev, 0x82, miscreg | 0x40);

       pci_write_config16(dev, 0x40, vendor);
       pci_write_config16(dev, 0x42, device);
       /* restore original contents */
       pci_write_config16(dev, 0x82, miscreg);
}

static struct pci_operations rl5c476_pci_ops = {
       .set_subsystem    = rl5c476_set_subsystem,
};

static struct device_operations ricoh_rl5c476_ops = {
	.read_resources   = rl5c476_read_resources,
	.set_resources    = rl5c476_set_resources,
	.enable_resources = cardbus_enable_resources,
	.init             = rl5c476_init,
	.scan_bus         = pci_scan_bridge,
	.ops_pci          = &rl5c476_pci_ops,
};

static const struct pci_driver ricoh_rl5c476_driver __pci_driver = {
	.ops    = &ricoh_rl5c476_ops,
	.vendor = PCI_VENDOR_ID_RICOH,
	.device = PCI_DEVICE_ID_RICOH_RL5C476,
};

static void southbridge_init(device_t dev)
{
	struct southbridge_ricoh_rl5c476_config *conf = dev->chip_info;
	enable_cf_boot = conf->enable_cf;
}

struct chip_operations southbridge_ricoh_rl5c476_ops = {
	CHIP_NAME("Ricoh RL5C476 CardBus Controller")
	.enable_dev    = southbridge_init,
};
