diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/u-boot/common/cmd_universe.c | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/u-boot/common/cmd_universe.c')
-rw-r--r-- | qemu/roms/u-boot/common/cmd_universe.c | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/common/cmd_universe.c b/qemu/roms/u-boot/common/cmd_universe.c new file mode 100644 index 000000000..c9310363f --- /dev/null +++ b/qemu/roms/u-boot/common/cmd_universe.c @@ -0,0 +1,368 @@ +/* + * (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 <universe.h> + +#define PCI_VENDOR PCI_VENDOR_ID_TUNDRA +#define PCI_DEVICE PCI_DEVICE_ID_TUNDRA_CA91C042 + + +typedef struct _UNI_DEV UNI_DEV; + +struct _UNI_DEV { + int bus; + pci_dev_t busdevfn; + UNIVERSE *uregs; + unsigned int pci_bs; +}; + +static UNI_DEV *dev; + + +int universe_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("No Tundra Universe found!\n"); + return -1; + } + + /* Lets turn Latency off */ + pci_write_config_dword(busdevfn, 0x0c, 0); + + dev = malloc(sizeof(*dev)); + if (NULL == dev) { + puts("UNIVERSE: No memory!\n"); + result = -1; + goto break_20; + } + + memset(dev, 0, sizeof(*dev)); + dev->busdevfn = busdevfn; + + pci_read_config_dword(busdevfn, PCI_BASE_ADDRESS_1, &val); + if (val & 1) { + pci_read_config_dword(busdevfn, PCI_BASE_ADDRESS_0, &val); + } + val &= ~0xf; + dev->uregs = (UNIVERSE *)val; + + debug ("UNIVERSE-Base : %p\n", dev->uregs); + + /* check mapping */ + debug (" Read via mapping, PCI_ID = %08X\n", readl(&dev->uregs->pci_id)); + if (((PCI_DEVICE <<16) | PCI_VENDOR) != readl(&dev->uregs->pci_id)) { + printf ("UNIVERSE: Cannot read PCI-ID via Mapping: %08x\n", + readl(&dev->uregs->pci_id)); + result = -1; + goto break_30; + } + + debug ("PCI_BS = %08X\n", readl(&dev->uregs->pci_bs)); + + dev->pci_bs = readl(&dev->uregs->pci_bs); + + /* turn off windows */ + for (j=0; j <4; j ++) { + writel(0x00800000, &dev->uregs->lsi[j].ctl); + writel(0x00800000, &dev->uregs->vsi[j].ctl); + } + + /* + * Write to Misc Register + * Set VME Bus Time-out + * Arbitration Mode + * DTACK Enable + */ + writel(0x15040000 | (readl(&dev->uregs->misc_ctl) & 0x00020000), &dev->uregs->misc_ctl); + + if (readl(&dev->uregs->misc_ctl) & 0x00020000) { + debug ("System Controller!\n"); /* test-only */ + } else { + debug ("Not System Controller!\n"); /* test-only */ + } + + /* + * Lets turn off interrupts + */ + writel(0x00000000,&dev->uregs->lint_en); /* Disable interrupts in the Universe first */ + writel(0x0000FFFF,&dev->uregs->lint_stat); /* Clear Any Pending Interrupts */ + eieio(); + writel(0x0000, &dev->uregs->lint_map0); /* Map all ints to 0 */ + writel(0x0000, &dev->uregs->lint_map1); /* Map all ints to 0 */ + eieio(); + + return 0; + + break_30: + free(dev); + break_20: + return result; +} + + +/* + * Create pci slave window (access: pci -> vme) + */ +int universe_pci_slave_window(unsigned int pciAddr, unsigned int vmeAddr, int size, int vam, int pms, int vdw) +{ + int result, i; + unsigned int ctl = 0; + + if (NULL == dev) { + result = -1; + goto exit_10; + } + + for (i = 0; i < 4; i++) { + if (0x00800000 == readl(&dev->uregs->lsi[i].ctl)) + break; + } + + if (i == 4) { + printf ("universe: No Image available\n"); + result = -1; + goto exit_10; + } + + debug ("universe: Using image %d\n", i); + + writel(pciAddr , &dev->uregs->lsi[i].bs); + writel((pciAddr + size), &dev->uregs->lsi[i].bd); + writel((vmeAddr - pciAddr), &dev->uregs->lsi[i].to); + + switch (vam & VME_AM_Axx) { + case VME_AM_A16: + ctl = 0x00000000; + break; + case VME_AM_A24: + ctl = 0x00010000; + break; + case VME_AM_A32: + ctl = 0x00020000; + break; + } + + switch (vam & VME_AM_Mxx) { + case VME_AM_DATA: + ctl |= 0x00000000; + break; + case VME_AM_PROG: + ctl |= 0x00008000; + break; + } + + if (vam & VME_AM_SUP) { + ctl |= 0x00001000; + + } + + switch (vdw & VME_FLAG_Dxx) { + case VME_FLAG_D8: + ctl |= 0x00000000; + break; + case VME_FLAG_D16: + ctl |= 0x00400000; + break; + case VME_FLAG_D32: + ctl |= 0x00800000; + break; + } + + switch (pms & PCI_MS_Mxx) { + case PCI_MS_MEM: + ctl |= 0x00000000; + break; + case PCI_MS_IO: + ctl |= 0x00000001; + break; + case PCI_MS_CONFIG: + ctl |= 0x00000002; + break; + } + + ctl |= 0x80000000; /* enable */ + + writel(ctl, &dev->uregs->lsi[i].ctl); + + debug ("universe: window-addr=%p\n", &dev->uregs->lsi[i].ctl); + debug ("universe: pci slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->lsi[i].ctl)); + debug ("universe: pci slave window[%d] bs=%08x\n", i, readl(&dev->uregs->lsi[i].bs)); + debug ("universe: pci slave window[%d] bd=%08x\n", i, readl(&dev->uregs->lsi[i].bd)); + debug ("universe: pci slave window[%d] to=%08x\n", i, readl(&dev->uregs->lsi[i].to)); + + return 0; + + exit_10: + return -result; +} + + +/* + * Create vme slave window (access: vme -> pci) + */ +int universe_vme_slave_window(unsigned int vmeAddr, unsigned int pciAddr, int size, int vam, int pms) +{ + int result, i; + unsigned int ctl = 0; + + if (NULL == dev) { + result = -1; + goto exit_10; + } + + for (i = 0; i < 4; i++) { + if (0x00800000 == readl(&dev->uregs->vsi[i].ctl)) + break; + } + + if (i == 4) { + printf ("universe: No Image available\n"); + result = -1; + goto exit_10; + } + + debug ("universe: Using image %d\n", i); + + writel(vmeAddr , &dev->uregs->vsi[i].bs); + writel((vmeAddr + size), &dev->uregs->vsi[i].bd); + writel((pciAddr - vmeAddr), &dev->uregs->vsi[i].to); + + switch (vam & VME_AM_Axx) { + case VME_AM_A16: + ctl = 0x00000000; + break; + case VME_AM_A24: + ctl = 0x00010000; + break; + case VME_AM_A32: + ctl = 0x00020000; + break; + } + + switch (vam & VME_AM_Mxx) { + case VME_AM_DATA: + ctl |= 0x00000000; + break; + case VME_AM_PROG: + ctl |= 0x00800000; + break; + } + + if (vam & VME_AM_SUP) { + ctl |= 0x00100000; + + } + + switch (pms & PCI_MS_Mxx) { + case PCI_MS_MEM: + ctl |= 0x00000000; + break; + case PCI_MS_IO: + ctl |= 0x00000001; + break; + case PCI_MS_CONFIG: + ctl |= 0x00000002; + break; + } + + ctl |= 0x80f00000; /* enable */ + + writel(ctl, &dev->uregs->vsi[i].ctl); + + debug ("universe: window-addr=%p\n", &dev->uregs->vsi[i].ctl); + debug ("universe: vme slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->vsi[i].ctl)); + debug ("universe: vme slave window[%d] bs=%08x\n", i, readl(&dev->uregs->vsi[i].bs)); + debug ("universe: vme slave window[%d] bd=%08x\n", i, readl(&dev->uregs->vsi[i].bd)); + debug ("universe: vme slave window[%d] to=%08x\n", i, readl(&dev->uregs->vsi[i].to)); + + return 0; + + exit_10: + return -result; +} + + +/* + * Tundra Universe configuration + */ +int do_universe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + ulong addr1 = 0, addr2 = 0, size = 0, vam = 0, pms = 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) + pms = simple_strtoul(argv[6], NULL, 16); + if (argc > 7) + vdw = simple_strtoul(argv[7], NULL, 16); + + switch (cmd) { + case 'i': /* init */ + universe_init(); + break; + case 'v': /* vme */ + printf("Configuring Universe VME Slave Window (VME->PCI):\n"); + printf(" vme=%08lx pci=%08lx size=%08lx vam=%02lx pms=%02lx\n", + addr1, addr2, size, vam, pms); + universe_vme_slave_window(addr1, addr2, size, vam, pms); + break; + case 'p': /* pci */ + printf("Configuring Universe PCI Slave Window (PCI->VME):\n"); + printf(" pci=%08lx vme=%08lx size=%08lx vam=%02lx pms=%02lx vdw=%02lx\n", + addr1, addr2, size, vam, pms, vdw); + universe_pci_slave_window(addr1, addr2, size, vam, pms, vdw); + break; + default: + printf("Universe command %s not supported!\n", argv[1]); + } + + return 0; +} + + +U_BOOT_CMD( + universe, 8, 1, do_universe, + "initialize and configure Turndra Universe", + "init\n" + " - initialize universe\n" + "universe vme [vme_addr] [pci_addr] [size] [vam] [pms]\n" + " - create vme slave window (access: vme->pci)\n" + "universe pci [pci_addr] [vme_addr] [size] [vam] [pms] [vdw]\n" + " - create pci slave window (access: pci->vme)\n" + " [vam] = VMEbus Address-Modifier: 01 -> A16 Address Space\n" + " 02 -> A24 Address Space\n" + " 03 -> A32 Address Space\n" + " 04 -> Supervisor AM Code\n" + " 10 -> Data AM Code\n" + " 20 -> Program AM Code\n" + " [pms] = PCI Memory Space: 01 -> Memory Space\n" + " 02 -> I/O Space\n" + " 03 -> Configuration Space\n" + " [vdw] = VMEbus Maximum Datawidth: 01 -> D8 Data Width\n" + " 02 -> D16 Data Width\n" + " 03 -> D32 Data Width" +); |