/*
 * (C) Copyright 2009 Reinhard Arlt, reinhard.arlt@esd-electronics.com
 *
 * base on universe.h by
 *
 * (C) Copyright 2003 Stefan Roese, stefan.roese@esd-electronics.com
 *
 * 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
 */

#define DEBUG

#include <common.h>
#include <command.h>
#include <malloc.h>
#include <asm/io.h>
#include <pci.h>

#include <tsi148.h>

#define PCI_VENDOR PCI_VENDOR_ID_TUNDRA
#define PCI_DEVICE PCI_DEVICE_ID_TUNDRA_TSI148

typedef struct _TSI148_DEV TSI148_DEV;

struct _TSI148_DEV {
	int            bus;
	pci_dev_t      busdevfn;
	TSI148        *uregs;
	unsigned int   pci_bs;
};

static TSI148_DEV *dev;

/*
 * Most of the TSI148 register are BIGENDIAN
 * This is the reason for the __raw_writel(htonl(x), x) usage!
 */

int tsi148_init(void)
{
	int j, result, lastError = 0;
	pci_dev_t busdevfn;
	unsigned int val;

	busdevfn = pci_find_device(PCI_VENDOR, PCI_DEVICE, 0);
	if (busdevfn == -1) {
		puts("Tsi148: No Tundra Tsi148 found!\n");
		return -1;
	}

	/* Lets turn Latency off */
	pci_write_config_dword(busdevfn, 0x0c, 0);

	dev = malloc(sizeof(*dev));
	if (NULL == dev) {
		puts("Tsi148: No memory!\n");
		result = -1;
		goto break_20;
	}

	memset(dev, 0, sizeof(*dev));
	dev->busdevfn = busdevfn;

	pci_read_config_dword(busdevfn, PCI_BASE_ADDRESS_0, &val);
	val &= ~0xf;
	dev->uregs = (TSI148 *)val;

	debug("Tsi148: Base    : %p\n", dev->uregs);

	/* check mapping  */
	debug("Tsi148: Read via mapping, PCI_ID = %08X\n", readl(&dev->uregs->pci_id));
	if (((PCI_DEVICE << 16) | PCI_VENDOR) !=  readl(&dev->uregs->pci_id)) {
		printf("Tsi148: Cannot read PCI-ID via Mapping: %08x\n",
			readl(&dev->uregs->pci_id));
		result = -1;
		goto break_30;
	}

	debug("Tsi148: PCI_BS = %08X\n", readl(&dev->uregs->pci_mbarl));

	dev->pci_bs = readl(&dev->uregs->pci_mbarl);

	/* turn off windows */
	for (j = 0; j < 8; j++) {
		__raw_writel(htonl(0x00000000), &dev->uregs->outbound[j].otat);
		__raw_writel(htonl(0x00000000), &dev->uregs->inbound[j].itat);
	}

	/* Tsi148 VME timeout etc */
	__raw_writel(htonl(0x00000084), &dev->uregs->vctrl);

	if ((__raw_readl(&dev->uregs->vstat) & 0x00000100) != 0)
		debug("Tsi148: System Controller!\n");
	else
		debug("Tsi148: Not System Controller!\n");

	/*
	 * Lets turn off interrupts
	 */
	/* Disable interrupts in Tsi148 first */
	__raw_writel(htonl(0x00000000), &dev->uregs->inten);
	/* Disable interrupt out */
	__raw_writel(htonl(0x00000000), &dev->uregs->inteo);
	eieio();
	/* Reset all IRQ's */
	__raw_writel(htonl(0x03ff3f00), &dev->uregs->intc);
	/* Map all ints to 0 */
	__raw_writel(htonl(0x00000000), &dev->uregs->intm1);
	__raw_writel(htonl(0x00000000), &dev->uregs->intm2);
	eieio();

	val  = __raw_readl(&dev->uregs->vstat);
	val &= ~(0x00004000);
	__raw_writel(val, &dev->uregs->vstat);
	eieio();

	debug("Tsi148: register struct size %08x\n", sizeof(TSI148));

	return 0;

 break_30:
	free(dev);
	dev = NULL;
 break_20:
	lastError = result;

	return result;
}

/*
 * Create pci slave window (access: pci -> vme)
 */
int tsi148_pci_slave_window(unsigned int pciAddr, unsigned int vmeAddr, int size, int vam, int vdw)
{
	int result, i;
	unsigned int ctl = 0;

	if (NULL == dev) {
		result = -1;
		goto exit_10;
	}

	for (i = 0; i < 8; i++) {
		if (0x00000000 == readl(&dev->uregs->outbound[i].otat))
			break;
	}

	if (i > 7) {
		printf("Tsi148: No Image available\n");
		result = -1;
		goto exit_10;
	}

	debug("Tsi148: Using image %d\n", i);

	printf("Tsi148: Pci addr %08x\n", pciAddr);


	__raw_writel(htonl(pciAddr) , &dev->uregs->outbound[i].otsal);
	__raw_writel(0x00000000 , &dev->uregs->outbound[i].otsau);
	__raw_writel(htonl(pciAddr + size), &dev->uregs->outbound[i].oteal);
	__raw_writel(0x00000000 , &dev->uregs->outbound[i].oteau);
	__raw_writel(htonl(vmeAddr - pciAddr), &dev->uregs->outbound[i].otofl);
	__raw_writel(0x00000000 , &dev->uregs->outbound[i].otofu);

	switch (vam & VME_AM_Axx) {
	case VME_AM_A16:
		ctl = 0x00000000;
		break;
	case VME_AM_A24:
		ctl = 0x00000001;
		break;
	case VME_AM_A32:
		ctl = 0x00000002;
		break;
	}

	switch (vam & VME_AM_Mxx) {
	case VME_AM_DATA:
		ctl |= 0x00000000;
		break;
	case VME_AM_PROG:
		ctl |= 0x00000010;
		break;
	}

	if (vam & VME_AM_SUP)
		ctl |= 0x00000020;

	switch (vdw & VME_FLAG_Dxx) {
	case VME_FLAG_D16:
		ctl |= 0x00000000;
		break;
	case VME_FLAG_D32:
		ctl |= 0x00000040;
		break;
	}

	ctl |= 0x80040000;    /* enable, no prefetch */

	__raw_writel(htonl(ctl), &dev->uregs->outbound[i].otat);

	debug("Tsi148: window-addr                =%p\n",
	      &dev->uregs->outbound[i].otsau);
	debug("Tsi148: pci slave window[%d] attr  =%08x\n",
	      i, ntohl(__raw_readl(&dev->uregs->outbound[i].otat)));
	debug("Tsi148: pci slave window[%d] start =%08x\n",
	      i, ntohl(__raw_readl(&dev->uregs->outbound[i].otsal)));
	debug("Tsi148: pci slave window[%d] end   =%08x\n",
	      i, ntohl(__raw_readl(&dev->uregs->outbound[i].oteal)));
	debug("Tsi148: pci slave window[%d] offset=%08x\n",
	      i, ntohl(__raw_readl(&dev->uregs->outbound[i].otofl)));

	return 0;

 exit_10:
	return -result;
}

unsigned int tsi148_eval_vam(int vam)
{
	unsigned int ctl = 0;

	switch (vam & VME_AM_Axx) {
	case VME_AM_A16:
		ctl = 0x00000000;
		break;
	case VME_AM_A24:
		ctl = 0x00000010;
		break;
	case VME_AM_A32:
		ctl = 0x00000020;
		break;
	}
	switch (vam & VME_AM_Mxx) {
	case VME_AM_DATA:
		ctl |= 0x00000001;
		break;
	case VME_AM_PROG:
		ctl |= 0x00000002;
		break;
	case (VME_AM_PROG | VME_AM_DATA):
		ctl |= 0x00000003;
		break;
	}

	if (vam & VME_AM_SUP)
		ctl |= 0x00000008;
	if (vam & VME_AM_USR)
		ctl |= 0x00000004;

	return ctl;
}

/*
 * Create vme slave window (access: vme -> pci)
 */
int tsi148_vme_slave_window(unsigned int vmeAddr, unsigned int pciAddr, int size, int vam)
{
	int result, i;
	unsigned int ctl = 0;

	if (NULL == dev) {
		result = -1;
		goto exit_10;
	}

	for (i = 0; i < 8; i++) {
		if (0x00000000 == readl(&dev->uregs->inbound[i].itat))
			break;
	}

	if (i > 7) {
		printf("Tsi148: No Image available\n");
		result = -1;
		goto exit_10;
	}

	debug("Tsi148: Using image %d\n", i);

	__raw_writel(htonl(vmeAddr), &dev->uregs->inbound[i].itsal);
	__raw_writel(0x00000000, &dev->uregs->inbound[i].itsau);
	__raw_writel(htonl(vmeAddr + size), &dev->uregs->inbound[i].iteal);
	__raw_writel(0x00000000, &dev->uregs->inbound[i].iteau);
	__raw_writel(htonl(pciAddr - vmeAddr), &dev->uregs->inbound[i].itofl);
	if (vmeAddr > pciAddr)
		__raw_writel(0xffffffff, &dev->uregs->inbound[i].itofu);
	else
		__raw_writel(0x00000000, &dev->uregs->inbound[i].itofu);

	ctl = tsi148_eval_vam(vam);
	ctl |= 0x80000000;    /* enable */
	__raw_writel(htonl(ctl), &dev->uregs->inbound[i].itat);

	debug("Tsi148: window-addr                =%p\n",
	      &dev->uregs->inbound[i].itsau);
	debug("Tsi148: vme slave window[%d] attr  =%08x\n",
	      i, ntohl(__raw_readl(&dev->uregs->inbound[i].itat))) ;
	debug("Tsi148: vme slave window[%d] start =%08x\n",
	      i, ntohl(__raw_readl(&dev->uregs->inbound[i].itsal)));
	debug("Tsi148: vme slave window[%d] end   =%08x\n",
	      i, ntohl(__raw_readl(&dev->uregs->inbound[i].iteal)));
	debug("Tsi148: vme slave window[%d] offset=%08x\n",
	      i, ntohl(__raw_readl(&dev->uregs->inbound[i].itofl)));

	return 0;

 exit_10:
	return -result;
}

/*
 * Create vme slave window (access: vme -> gcsr)
 */
int tsi148_vme_gcsr_window(unsigned int vmeAddr, int vam)
{
	int result;
	unsigned int ctl;

	result = 0;

	if (NULL == dev) {
		result = 1;
	} else {
	       __raw_writel(htonl(vmeAddr), &dev->uregs->gbal);
	       __raw_writel(0x00000000, &dev->uregs->gbau);

	       ctl = tsi148_eval_vam(vam);
	       ctl |= 0x00000080;    /* enable */
	       __raw_writel(htonl(ctl), &dev->uregs->gcsrat);
	}

	return result;
}

/*
 * Create vme slave window (access: vme -> crcsr)
 */
int tsi148_vme_crcsr_window(unsigned int vmeAddr)
{
	int result;
	unsigned int ctl;

	result = 0;

	if (NULL == dev) {
		result = 1;
	} else {
	       __raw_writel(htonl(vmeAddr), &dev->uregs->crol);
	       __raw_writel(0x00000000, &dev->uregs->crou);

	       ctl = 0x00000080;    /* enable */
	       __raw_writel(htonl(ctl), &dev->uregs->crat);
	}

	return result;
}


/*
 * Create vme slave window (access: vme -> crg)
 */
int tsi148_vme_crg_window(unsigned int vmeAddr, int vam)
{
	int result;
	unsigned int ctl;

	result = 0;

	if (NULL == dev) {
		result = 1;
	} else {
	       __raw_writel(htonl(vmeAddr), &dev->uregs->cbal);
	       __raw_writel(0x00000000, &dev->uregs->cbau);

	       ctl = tsi148_eval_vam(vam);
	       ctl |= 0x00000080;    /* enable */
	       __raw_writel(htonl(ctl), &dev->uregs->crgat);
	}

	return result;
}

/*
 * Tundra Tsi148 configuration
 */
int do_tsi148(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong addr1 = 0, addr2 = 0, size = 0, vam = 0, vdw = 0;
	char cmd = 'x';

	/* get parameter */
	if (argc > 1)
		cmd = argv[1][0];
	if (argc > 2)
		addr1 = simple_strtoul(argv[2], NULL, 16);
	if (argc > 3)
		addr2 = simple_strtoul(argv[3], NULL, 16);
	if (argc > 4)
		size = simple_strtoul(argv[4], NULL, 16);
	if (argc > 5)
		vam = simple_strtoul(argv[5], NULL, 16);
	if (argc > 6)
		vdw = simple_strtoul(argv[7], NULL, 16);

	switch (cmd) {
	case 'c':
		if (strcmp(argv[1], "crg") == 0) {
			vam = addr2;
			printf("Tsi148: Configuring VME CRG Window (VME->CRG):\n");
			printf("  vme=%08lx vam=%02lx\n", addr1, vam);
			tsi148_vme_crg_window(addr1, vam);
		} else {
			printf("Tsi148: Configuring VME CR/CSR Window (VME->CR/CSR):\n");
			printf("  pci=%08lx\n", addr1);
			tsi148_vme_crcsr_window(addr1);
		}
		break;
	case 'i':		/* init */
		tsi148_init();
		break;
	case 'g':
		vam = addr2;
		printf("Tsi148: Configuring VME GCSR Window (VME->GCSR):\n");
		printf("  vme=%08lx vam=%02lx\n", addr1, vam);
		tsi148_vme_gcsr_window(addr1, vam);
		break;
	case 'v':		/* vme */
		printf("Tsi148: Configuring VME Slave Window (VME->PCI):\n");
		printf("  vme=%08lx pci=%08lx size=%08lx vam=%02lx\n",
		       addr1, addr2, size, vam);
		tsi148_vme_slave_window(addr1, addr2, size, vam);
		break;
	case 'p':		/* pci */
		printf("Tsi148: Configuring PCI Slave Window (PCI->VME):\n");
		printf("  pci=%08lx vme=%08lx size=%08lx vam=%02lx vdw=%02lx\n",
		       addr1, addr2, size, vam, vdw);
		tsi148_pci_slave_window(addr1, addr2, size, vam, vdw);
		break;
	default:
		printf("Tsi148: Command %s not supported!\n", argv[1]);
	}

	return 0;
}

U_BOOT_CMD(
	tsi148,	8,	1,	do_tsi148,
	"tsi148  - initialize and configure Turndra Tsi148\n",
	"init\n"
	"    - initialize tsi148\n"
	"tsi148 vme   [vme_addr] [pci_addr] [size] [vam]\n"
	"    - create vme slave window (access: vme->pci)\n"
	"tsi148 pci   [pci_addr] [vme_addr] [size] [vam] [vdw]\n"
	"    - create pci slave window (access: pci->vme)\n"
	"tsi148 crg   [vme_addr] [vam]\n"
	"    - create vme slave window: (access vme->CRG\n"
	"tsi148 crcsr [pci_addr]\n"
	"    - create vme slave window: (access vme->CR/CSR\n"
	"tsi148 gcsr  [vme_addr] [vam]\n"
	"    - create vme slave window: (access vme->GCSR\n"
	"    [vam] = VMEbus Address-Modifier:  01 -> A16 Address Space\n"
	"                                      02 -> A24 Address Space\n"
	"                                      03 -> A32 Address Space\n"
	"                                      04 -> Usr        AM Code\n"
	"                                      08 -> Supervisor AM Code\n"
	"                                      10 -> Data AM Code\n"
	"                                      20 -> Program AM Code\n"
	"    [vdw] = VMEbus Maximum Datawidth: 02 -> D16 Data Width\n"
	"                                      03 -> D32 Data Width\n"
);
