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

#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);

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

	/*
	 * 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,
	"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"
);
