/*
 * (C) Copyright 2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 *
 ********************************************************************
 *
 * Lots of code copied from:
 *
 * i82365.c 1.352 - Linux driver for Intel 82365 and compatible
 * PC Card controllers, and Yenta-compatible PCI-to-CardBus controllers.
 * (C) 1999 David A. Hinds <dahinds@users.sourceforge.net>
 */

#include <common.h>

#ifdef CONFIG_I82365

#include <command.h>
#include <pci.h>
#include <pcmcia.h>
#include <cmd_pcmcia.h>
#include <asm/io.h>

#include <pcmcia/ss.h>
#include <pcmcia/i82365.h>
#include <pcmcia/ti113x.h>
#include <pcmcia/yenta.h>

/* #define DEBUG */

static struct pci_device_id supported[] = {
	{PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510},
	{0, 0}
};

#define CYCLE_TIME	120

#ifdef DEBUG
static void i82365_dump_regions (pci_dev_t dev);
#endif

typedef struct socket_info_t {
    pci_dev_t		dev;
    u_short		bcr;
    u_char		pci_lat, cb_lat, sub_bus, cache;
    u_int		cb_phys;

    socket_cap_t	cap;
    ti113x_state_t	state;
} socket_info_t;

static socket_info_t socket;
static socket_state_t state;
static struct pccard_mem_map mem;
static struct pccard_io_map io;

/*====================================================================*/

/* Some PCI shortcuts */

static int pci_readb (socket_info_t * s, int r, u_char * v)
{
	return pci_read_config_byte (s->dev, r, v);
}
static int pci_writeb (socket_info_t * s, int r, u_char v)
{
	return pci_write_config_byte (s->dev, r, v);
}
static int pci_readw (socket_info_t * s, int r, u_short * v)
{
	return pci_read_config_word (s->dev, r, v);
}
static int pci_writew (socket_info_t * s, int r, u_short v)
{
	return pci_write_config_word (s->dev, r, v);
}
static int pci_readl (socket_info_t * s, int r, u_int * v)
{
	return pci_read_config_dword (s->dev, r, v);
}
static int pci_writel (socket_info_t * s, int r, u_int v)
{
	return pci_write_config_dword (s->dev, r, v);
}

#define cb_readb(s, r)		readb((s)->cb_phys + (r))
#define cb_readl(s, r)		readl((s)->cb_phys + (r))
#define cb_writeb(s, r, v)	writeb(v, (s)->cb_phys + (r))
#define cb_writel(s, r, v)	writel(v, (s)->cb_phys + (r))

/*====================================================================*/

static u_char i365_get (socket_info_t * s, u_short reg)
{
	return cb_readb (s, 0x0800 + reg);
}

static void i365_set (socket_info_t * s, u_short reg, u_char data)
{
	cb_writeb (s, 0x0800 + reg, data);
}

static void i365_bset (socket_info_t * s, u_short reg, u_char mask)
{
	i365_set (s, reg, i365_get (s, reg) | mask);
}

static void i365_bclr (socket_info_t * s, u_short reg, u_char mask)
{
	i365_set (s, reg, i365_get (s, reg) & ~mask);
}

#if 0	/* not used */
static void i365_bflip (socket_info_t * s, u_short reg, u_char mask, int b)
{
	u_char d = i365_get (s, reg);

	i365_set (s, reg, (b) ? (d | mask) : (d & ~mask));
}

static u_short i365_get_pair (socket_info_t * s, u_short reg)
{
	return (i365_get (s, reg) + (i365_get (s, reg + 1) << 8));
}
#endif	/* not used */

static void i365_set_pair (socket_info_t * s, u_short reg, u_short data)
{
	i365_set (s, reg, data & 0xff);
	i365_set (s, reg + 1, data >> 8);
}

/*======================================================================

    Code to save and restore global state information for TI 1130 and
    TI 1131 controllers, and to set and report global configuration
    options.
    
======================================================================*/

static void ti113x_get_state (socket_info_t * s)
{
	ti113x_state_t *p = &s->state;

	pci_readl (s, TI113X_SYSTEM_CONTROL, &p->sysctl);
	pci_readb (s, TI113X_CARD_CONTROL, &p->cardctl);
	pci_readb (s, TI113X_DEVICE_CONTROL, &p->devctl);
	pci_readb (s, TI1250_DIAGNOSTIC, &p->diag);
	pci_readl (s, TI12XX_IRQMUX, &p->irqmux);
}

static void ti113x_set_state (socket_info_t * s)
{
	ti113x_state_t *p = &s->state;

	pci_writel (s, TI113X_SYSTEM_CONTROL, p->sysctl);
	pci_writeb (s, TI113X_CARD_CONTROL, p->cardctl);
	pci_writeb (s, TI113X_DEVICE_CONTROL, p->devctl);
	pci_writeb (s, TI1250_MULTIMEDIA_CTL, 0);
	pci_writeb (s, TI1250_DIAGNOSTIC, p->diag);
	pci_writel (s, TI12XX_IRQMUX, p->irqmux);
	i365_set_pair (s, TI113X_IO_OFFSET (0), 0);
	i365_set_pair (s, TI113X_IO_OFFSET (1), 0);
}

static u_int ti113x_set_opts (socket_info_t * s)
{
	ti113x_state_t *p = &s->state;
	u_int mask = 0xffff;

	p->cardctl &= ~TI113X_CCR_ZVENABLE;
	p->cardctl |= TI113X_CCR_SPKROUTEN;

	return mask;
}

/*======================================================================

    Routines to handle common CardBus options
    
======================================================================*/

/* Default settings for PCI command configuration register */
#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \
		  PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)

static void cb_get_state (socket_info_t * s)
{
	pci_readb (s, PCI_CACHE_LINE_SIZE, &s->cache);
	pci_readb (s, PCI_LATENCY_TIMER, &s->pci_lat);
	pci_readb (s, CB_LATENCY_TIMER, &s->cb_lat);
	pci_readb (s, CB_CARDBUS_BUS, &s->cap.cardbus);
	pci_readb (s, CB_SUBORD_BUS, &s->sub_bus);
	pci_readw (s, CB_BRIDGE_CONTROL, &s->bcr);
}

static void cb_set_state (socket_info_t * s)
{
	pci_writel (s, CB_LEGACY_MODE_BASE, 0);
	pci_writel (s, PCI_BASE_ADDRESS_0, s->cb_phys);
	pci_writew (s, PCI_COMMAND, CMD_DFLT);
	pci_writeb (s, PCI_CACHE_LINE_SIZE, s->cache);
	pci_writeb (s, PCI_LATENCY_TIMER, s->pci_lat);
	pci_writeb (s, CB_LATENCY_TIMER, s->cb_lat);
	pci_writeb (s, CB_CARDBUS_BUS, s->cap.cardbus);
	pci_writeb (s, CB_SUBORD_BUS, s->sub_bus);
	pci_writew (s, CB_BRIDGE_CONTROL, s->bcr);
}

static void cb_set_opts (socket_info_t * s)
{
	if (s->cache == 0)
		s->cache = 8;
	if (s->pci_lat == 0)
		s->pci_lat = 0xa8;
	if (s->cb_lat == 0)
		s->cb_lat = 0xb0;
}

/*======================================================================

    Power control for Cardbus controllers: used both for 16-bit and
    Cardbus cards.
    
======================================================================*/

static int cb_set_power (socket_info_t * s, socket_state_t * state)
{
	u_int reg = 0;

	/* restart card voltage detection if it seems appropriate */
	if ((state->Vcc == 0) && (state->Vpp == 0) &&
		!(cb_readl (s, CB_SOCKET_STATE) & CB_SS_VSENSE))
		cb_writel (s, CB_SOCKET_FORCE, CB_SF_CVSTEST);
	switch (state->Vcc) {
	case 0:
		reg = 0;
		break;
	case 33:
		reg = CB_SC_VCC_3V;
		break;
	case 50:
		reg = CB_SC_VCC_5V;
		break;
	default:
		return -1;
	}
	switch (state->Vpp) {
	case 0:
		break;
	case 33:
		reg |= CB_SC_VPP_3V;
		break;
	case 50:
		reg |= CB_SC_VPP_5V;
		break;
	case 120:
		reg |= CB_SC_VPP_12V;
		break;
	default:
		return -1;
	}
	if (reg != cb_readl (s, CB_SOCKET_CONTROL))
		cb_writel (s, CB_SOCKET_CONTROL, reg);
	return 0;
}

/*======================================================================

    Generic routines to get and set controller options
    
======================================================================*/

static void get_bridge_state (socket_info_t * s)
{
	ti113x_get_state (s);
	cb_get_state (s);
}

static void set_bridge_state (socket_info_t * s)
{
	cb_set_state (s);
	i365_set (s, I365_GBLCTL, 0x00);
	i365_set (s, I365_GENCTL, 0x00);
	ti113x_set_state (s);
}

static void set_bridge_opts (socket_info_t * s)
{
	ti113x_set_opts (s);
	cb_set_opts (s);
}

/*====================================================================*/

static int i365_get_status (socket_info_t * s, u_int * value)
{
	u_int status;

	status = i365_get (s, I365_STATUS);
	*value = ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
	if (i365_get (s, I365_INTCTL) & I365_PC_IOCARD) {
		*value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
	} else {
		*value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
		*value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
	}
	*value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
	*value |= (status & I365_CS_READY) ? SS_READY : 0;
	*value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;

	status = cb_readl (s, CB_SOCKET_STATE);
	*value |= (status & CB_SS_32BIT) ? SS_CARDBUS : 0;
	*value |= (status & CB_SS_3VCARD) ? SS_3VCARD : 0;
	*value |= (status & CB_SS_XVCARD) ? SS_XVCARD : 0;
	*value |= (status & CB_SS_VSENSE) ? 0 : SS_PENDING;
	/* For now, ignore cards with unsupported voltage keys */
	if (*value & SS_XVCARD)
		*value &= ~(SS_DETECT | SS_3VCARD | SS_XVCARD);

	return 0;
}	/* i365_get_status */

static int i365_set_socket (socket_info_t * s, socket_state_t * state)
{
	u_char reg;

	set_bridge_state (s);

	/* IO card, RESET flag */
	reg = 0;
	reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
	reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
	i365_set (s, I365_INTCTL, reg);

	reg = I365_PWR_NORESET;
	if (state->flags & SS_PWR_AUTO)
		reg |= I365_PWR_AUTO;
	if (state->flags & SS_OUTPUT_ENA)
		reg |= I365_PWR_OUT;

	cb_set_power (s, state);
	reg |= i365_get (s, I365_POWER) & (I365_VCC_MASK | I365_VPP1_MASK);

	if (reg != i365_get (s, I365_POWER))
		i365_set (s, I365_POWER, reg);

	return 0;
}	/* i365_set_socket */

/*====================================================================*/

static int i365_set_mem_map (socket_info_t * s, struct pccard_mem_map *mem)
{
	u_short base, i;
	u_char map;

	map = mem->map;
	if ((map > 4) ||
	    (mem->card_start > 0x3ffffff) ||
	    (mem->sys_start > mem->sys_stop) ||
	    (mem->speed > 1000)) {
		return -1;
	}

	/* Turn off the window before changing anything */
	if (i365_get (s, I365_ADDRWIN) & I365_ENA_MEM (map))
		i365_bclr (s, I365_ADDRWIN, I365_ENA_MEM (map));

	/* Take care of high byte, for PCI controllers */
	i365_set (s, CB_MEM_PAGE (map), mem->sys_start >> 24);

	base = I365_MEM (map);
	i = (mem->sys_start >> 12) & 0x0fff;
	if (mem->flags & MAP_16BIT)
		i |= I365_MEM_16BIT;
	if (mem->flags & MAP_0WS)
		i |= I365_MEM_0WS;
	i365_set_pair (s, base + I365_W_START, i);

	i = (mem->sys_stop >> 12) & 0x0fff;
	switch (mem->speed / CYCLE_TIME) {
	case 0:
		break;
	case 1:
		i |= I365_MEM_WS0;
		break;
	case 2:
		i |= I365_MEM_WS1;
		break;
	default:
		i |= I365_MEM_WS1 | I365_MEM_WS0;
		break;
	}
	i365_set_pair (s, base + I365_W_STOP, i);

	i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
	if (mem->flags & MAP_WRPROT)
		i |= I365_MEM_WRPROT;
	if (mem->flags & MAP_ATTRIB)
		i |= I365_MEM_REG;
	i365_set_pair (s, base + I365_W_OFF, i);

	/* Turn on the window if necessary */
	if (mem->flags & MAP_ACTIVE)
		i365_bset (s, I365_ADDRWIN, I365_ENA_MEM (map));
	return 0;
}	/* i365_set_mem_map */

static int i365_set_io_map (socket_info_t * s, struct pccard_io_map *io)
{
	u_char map, ioctl;

	map = io->map;
	if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
		(io->stop < io->start))
		return -1;
	/* Turn off the window before changing anything */
	if (i365_get (s, I365_ADDRWIN) & I365_ENA_IO (map))
		i365_bclr (s, I365_ADDRWIN, I365_ENA_IO (map));
	i365_set_pair (s, I365_IO (map) + I365_W_START, io->start);
	i365_set_pair (s, I365_IO (map) + I365_W_STOP, io->stop);
	ioctl = i365_get (s, I365_IOCTL) & ~I365_IOCTL_MASK (map);
	if (io->speed)
		ioctl |= I365_IOCTL_WAIT (map);
	if (io->flags & MAP_0WS)
		ioctl |= I365_IOCTL_0WS (map);
	if (io->flags & MAP_16BIT)
		ioctl |= I365_IOCTL_16BIT (map);
	if (io->flags & MAP_AUTOSZ)
		ioctl |= I365_IOCTL_IOCS16 (map);
	i365_set (s, I365_IOCTL, ioctl);
	/* Turn on the window if necessary */
	if (io->flags & MAP_ACTIVE)
		i365_bset (s, I365_ADDRWIN, I365_ENA_IO (map));
	return 0;
}	/* i365_set_io_map */

/*====================================================================*/

int i82365_init (void)
{
	u_int val;
	int i;

	if ((socket.dev = pci_find_devices (supported, 0)) < 0) {
		/* Controller not found */
		return 1;
	}

	pci_read_config_dword (socket.dev, PCI_BASE_ADDRESS_0, &socket.cb_phys);
	socket.cb_phys &= ~0xf;

	get_bridge_state (&socket);
	set_bridge_opts (&socket);

	i365_get_status (&socket, &val);

	if (val & SS_DETECT) {
		if (val & SS_3VCARD) {
			state.Vcc = state.Vpp = 33;
			puts (" 3.3V card found: ");
		} else if (!(val & SS_XVCARD)) {
			state.Vcc = state.Vpp = 50;
			puts (" 5.0V card found: ");
		} else {
			printf ("i82365: unsupported voltage key\n");
			state.Vcc = state.Vpp = 0;
		}
	} else {
		/* No card inserted */
		return 1;
	}

	state.flags = SS_IOCARD | SS_OUTPUT_ENA;
	state.csc_mask = 0;
	state.io_irq = 0;

	i365_set_socket (&socket, &state);

	for (i = 500; i; i--) {
		if ((i365_get (&socket, I365_STATUS) & I365_CS_READY))
			break;
		udelay (1000);
	}

	if (i == 0) {
		/* PC Card not ready for data transfer */
		return 1;
	}

	mem.map = 0;
	mem.flags = MAP_ATTRIB | MAP_ACTIVE;
	mem.speed = 300;
	mem.sys_start = CFG_PCMCIA_MEM_ADDR;
	mem.sys_stop = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE - 1;
	mem.card_start = 0;

	i365_set_mem_map (&socket, &mem);

	io.map = 0;
	io.flags = MAP_AUTOSZ | MAP_ACTIVE;
	io.speed = 0;
	io.start = 0x0100;
	io.stop = 0x010F;

	i365_set_io_map (&socket, &io);

#ifdef DEBUG
	i82365_dump_regions (socket.dev);
#endif

	return 0;
}

void i82365_exit (void)
{
	io.map = 0;
	io.flags = 0;
	io.speed = 0;
	io.start = 0;
	io.stop = 0x1;

	i365_set_io_map (&socket, &io);

	mem.map = 0;
	mem.flags = 0;
	mem.speed = 0;
	mem.sys_start = 0;
	mem.sys_stop = 0x1000;
	mem.card_start = 0;

	i365_set_mem_map (&socket, &mem);

	socket.state.sysctl &= 0xFFFF00FF;

	state.Vcc = state.Vpp = 0;

	i365_set_socket (&socket, &state);
}

/*======================================================================

    Debug stuff
    
======================================================================*/

#ifdef DEBUG
static void i82365_dump_regions (pci_dev_t dev)
{
	u_int tmp[2];
	u_int *mem = (void *) sock.cb_phys;
	u_char *cis = (void *) CFG_PCMCIA_MEM_ADDR;
	u_char *ide = (void *) (CFG_ATA_BASE_ADDR + CFG_ATA_REG_OFFSET);

	pci_read_config_dword (dev, 0x00, tmp + 0);
	pci_read_config_dword (dev, 0x80, tmp + 1);

	printf ("PCI CONF: %08X ... %08X\n", tmp[0], tmp[1]);
	printf ("PCI MEM:  ... %08X ... %08X\n", mem[0x8 / 4], mem[0x800 / 4]);
	printf ("CIS:      ...%c%c%c%c%c%c%c%c...\n",
		cis[0x38], cis[0x3a], cis[0x3c], cis[0x3e],
		cis[0x40], cis[0x42], cis[0x44], cis[0x48]);
	printf ("CIS CONF: %02X %02X %02X ...\n",
		cis[0x200], cis[0x202], cis[0x204]);
	printf ("IDE:      %02X %02X %02X %02X %02X %02X %02X %02X\n",
		ide[0], ide[1], ide[2], ide[3],
		ide[4], ide[5], ide[6], ide[7]);
}
#endif	/* DEBUG */

#endif /* CONFIG_I82365 */
