Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / common / cmd_tsi148.c
diff --git a/qemu/roms/u-boot/common/cmd_tsi148.c b/qemu/roms/u-boot/common/cmd_tsi148.c
new file mode 100644 (file)
index 0000000..dc488b2
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * (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
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#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;
+       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");
+               return -1;
+       }
+
+       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;
+
+       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 * const 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[6], 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, 7,      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"
+);