uboot/cmd/universe.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2003 Stefan Roese, stefan.roese@esd-electronics.com
   4 */
   5
   6#include <common.h>
   7#include <command.h>
   8#include <malloc.h>
   9#include <asm/io.h>
  10#include <pci.h>
  11
  12#include <universe.h>
  13
  14#define PCI_VENDOR PCI_VENDOR_ID_TUNDRA
  15#define PCI_DEVICE PCI_DEVICE_ID_TUNDRA_CA91C042
  16
  17
  18typedef struct _UNI_DEV UNI_DEV;
  19
  20struct _UNI_DEV {
  21        int            bus;
  22        pci_dev_t      busdevfn;
  23        UNIVERSE       *uregs;
  24        unsigned int   pci_bs;
  25};
  26
  27static UNI_DEV   *dev;
  28
  29
  30int universe_init(void)
  31{
  32        int j, result;
  33        pci_dev_t busdevfn;
  34        unsigned int val;
  35
  36        busdevfn = pci_find_device(PCI_VENDOR, PCI_DEVICE, 0);
  37        if (busdevfn == -1) {
  38                puts("No Tundra Universe found!\n");
  39                return -1;
  40        }
  41
  42        /* Lets turn Latency off */
  43        pci_write_config_dword(busdevfn, 0x0c, 0);
  44
  45        dev = malloc(sizeof(*dev));
  46        if (NULL == dev) {
  47                puts("UNIVERSE: No memory!\n");
  48                result = -1;
  49                goto break_20;
  50        }
  51
  52        memset(dev, 0, sizeof(*dev));
  53        dev->busdevfn = busdevfn;
  54
  55        pci_read_config_dword(busdevfn, PCI_BASE_ADDRESS_1, &val);
  56        if (val & 1) {
  57                pci_read_config_dword(busdevfn, PCI_BASE_ADDRESS_0, &val);
  58        }
  59        val &= ~0xf;
  60        dev->uregs = (UNIVERSE *)val;
  61
  62        debug ("UNIVERSE-Base    : %p\n", dev->uregs);
  63
  64        /* check mapping  */
  65        debug (" Read via mapping, PCI_ID = %08X\n", readl(&dev->uregs->pci_id));
  66        if (((PCI_DEVICE <<16) | PCI_VENDOR) !=  readl(&dev->uregs->pci_id)) {
  67                printf ("UNIVERSE: Cannot read PCI-ID via Mapping: %08x\n",
  68                        readl(&dev->uregs->pci_id));
  69                result = -1;
  70                goto break_30;
  71        }
  72
  73        debug ("PCI_BS = %08X\n", readl(&dev->uregs->pci_bs));
  74
  75        dev->pci_bs = readl(&dev->uregs->pci_bs);
  76
  77        /* turn off windows */
  78        for (j=0; j <4; j ++) {
  79                writel(0x00800000, &dev->uregs->lsi[j].ctl);
  80                writel(0x00800000, &dev->uregs->vsi[j].ctl);
  81        }
  82
  83        /*
  84         * Write to Misc Register
  85         * Set VME Bus Time-out
  86         *   Arbitration Mode
  87         *   DTACK Enable
  88         */
  89        writel(0x15040000 | (readl(&dev->uregs->misc_ctl) & 0x00020000), &dev->uregs->misc_ctl);
  90
  91        if (readl(&dev->uregs->misc_ctl) & 0x00020000) {
  92                debug ("System Controller!\n"); /* test-only */
  93        } else {
  94                debug ("Not System Controller!\n"); /* test-only */
  95        }
  96
  97        /*
  98         * Lets turn off interrupts
  99         */
 100        writel(0x00000000,&dev->uregs->lint_en);   /* Disable interrupts in the Universe first */
 101        writel(0x0000FFFF,&dev->uregs->lint_stat); /* Clear Any Pending Interrupts */
 102        eieio();
 103        writel(0x0000, &dev->uregs->lint_map0);  /* Map all ints to 0 */
 104        writel(0x0000, &dev->uregs->lint_map1);  /* Map all ints to 0 */
 105        eieio();
 106
 107        return 0;
 108
 109 break_30:
 110        free(dev);
 111 break_20:
 112        return result;
 113}
 114
 115
 116/*
 117 * Create pci slave window (access: pci -> vme)
 118 */
 119int universe_pci_slave_window(unsigned int pciAddr, unsigned int vmeAddr, int size, int vam, int pms, int vdw)
 120{
 121        int result, i;
 122        unsigned int ctl = 0;
 123
 124        if (NULL == dev) {
 125                result = -1;
 126                goto exit_10;
 127        }
 128
 129        for (i = 0; i < 4; i++) {
 130                if (0x00800000 == readl(&dev->uregs->lsi[i].ctl))
 131                        break;
 132        }
 133
 134        if (i == 4) {
 135                printf ("universe: No Image available\n");
 136                result = -1;
 137                goto exit_10;
 138        }
 139
 140        debug ("universe: Using image %d\n", i);
 141
 142        writel(pciAddr , &dev->uregs->lsi[i].bs);
 143        writel((pciAddr + size), &dev->uregs->lsi[i].bd);
 144        writel((vmeAddr - pciAddr), &dev->uregs->lsi[i].to);
 145
 146        switch (vam & VME_AM_Axx) {
 147        case VME_AM_A16:
 148                ctl = 0x00000000;
 149                break;
 150        case VME_AM_A24:
 151                ctl = 0x00010000;
 152                break;
 153        case VME_AM_A32:
 154                ctl = 0x00020000;
 155                break;
 156        }
 157
 158        switch (vam & VME_AM_Mxx) {
 159        case VME_AM_DATA:
 160                ctl |= 0x00000000;
 161                break;
 162        case VME_AM_PROG:
 163                ctl |= 0x00008000;
 164                break;
 165        }
 166
 167        if (vam & VME_AM_SUP) {
 168                ctl |= 0x00001000;
 169
 170        }
 171
 172        switch (vdw & VME_FLAG_Dxx) {
 173        case VME_FLAG_D8:
 174                ctl |= 0x00000000;
 175                break;
 176        case VME_FLAG_D16:
 177                ctl |= 0x00400000;
 178                break;
 179        case VME_FLAG_D32:
 180                ctl |= 0x00800000;
 181                break;
 182        }
 183
 184        switch (pms & PCI_MS_Mxx) {
 185        case PCI_MS_MEM:
 186                ctl |= 0x00000000;
 187                break;
 188        case PCI_MS_IO:
 189                ctl |= 0x00000001;
 190                break;
 191        case PCI_MS_CONFIG:
 192                ctl |= 0x00000002;
 193                break;
 194        }
 195
 196        ctl |= 0x80000000;    /* enable */
 197
 198        writel(ctl, &dev->uregs->lsi[i].ctl);
 199
 200        debug ("universe: window-addr=%p\n", &dev->uregs->lsi[i].ctl);
 201        debug ("universe: pci slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->lsi[i].ctl));
 202        debug ("universe: pci slave window[%d] bs=%08x\n", i, readl(&dev->uregs->lsi[i].bs));
 203        debug ("universe: pci slave window[%d] bd=%08x\n", i, readl(&dev->uregs->lsi[i].bd));
 204        debug ("universe: pci slave window[%d] to=%08x\n", i, readl(&dev->uregs->lsi[i].to));
 205
 206        return 0;
 207
 208 exit_10:
 209        return -result;
 210}
 211
 212
 213/*
 214 * Create vme slave window (access: vme -> pci)
 215 */
 216int universe_vme_slave_window(unsigned int vmeAddr, unsigned int pciAddr, int size, int vam, int pms)
 217{
 218        int result, i;
 219        unsigned int ctl = 0;
 220
 221        if (NULL == dev) {
 222                result = -1;
 223                goto exit_10;
 224        }
 225
 226        for (i = 0; i < 4; i++) {
 227                if (0x00800000 == readl(&dev->uregs->vsi[i].ctl))
 228                        break;
 229        }
 230
 231        if (i == 4) {
 232                printf ("universe: No Image available\n");
 233                result = -1;
 234                goto exit_10;
 235        }
 236
 237        debug ("universe: Using image %d\n", i);
 238
 239        writel(vmeAddr , &dev->uregs->vsi[i].bs);
 240        writel((vmeAddr + size), &dev->uregs->vsi[i].bd);
 241        writel((pciAddr - vmeAddr), &dev->uregs->vsi[i].to);
 242
 243        switch (vam & VME_AM_Axx) {
 244        case VME_AM_A16:
 245                ctl = 0x00000000;
 246                break;
 247        case VME_AM_A24:
 248                ctl = 0x00010000;
 249                break;
 250        case VME_AM_A32:
 251                ctl = 0x00020000;
 252                break;
 253        }
 254
 255        switch (vam & VME_AM_Mxx) {
 256        case VME_AM_DATA:
 257                ctl |= 0x00000000;
 258                break;
 259        case VME_AM_PROG:
 260                ctl |= 0x00800000;
 261                break;
 262        }
 263
 264        if (vam & VME_AM_SUP) {
 265                ctl |= 0x00100000;
 266
 267        }
 268
 269        switch (pms & PCI_MS_Mxx) {
 270        case PCI_MS_MEM:
 271                ctl |= 0x00000000;
 272                break;
 273        case PCI_MS_IO:
 274                ctl |= 0x00000001;
 275                break;
 276        case PCI_MS_CONFIG:
 277                ctl |= 0x00000002;
 278                break;
 279        }
 280
 281        ctl |= 0x80f00000;    /* enable */
 282
 283        writel(ctl, &dev->uregs->vsi[i].ctl);
 284
 285        debug ("universe: window-addr=%p\n", &dev->uregs->vsi[i].ctl);
 286        debug ("universe: vme slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->vsi[i].ctl));
 287        debug ("universe: vme slave window[%d] bs=%08x\n", i, readl(&dev->uregs->vsi[i].bs));
 288        debug ("universe: vme slave window[%d] bd=%08x\n", i, readl(&dev->uregs->vsi[i].bd));
 289        debug ("universe: vme slave window[%d] to=%08x\n", i, readl(&dev->uregs->vsi[i].to));
 290
 291        return 0;
 292
 293 exit_10:
 294        return -result;
 295}
 296
 297
 298/*
 299 * Tundra Universe configuration
 300 */
 301int do_universe(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 302{
 303        ulong addr1 = 0, addr2 = 0, size = 0, vam = 0, pms = 0, vdw = 0;
 304        char cmd = 'x';
 305
 306        /* get parameter */
 307        if (argc > 1)
 308                cmd = argv[1][0];
 309        if (argc > 2)
 310                addr1 = hextoul(argv[2], NULL);
 311        if (argc > 3)
 312                addr2 = hextoul(argv[3], NULL);
 313        if (argc > 4)
 314                size = hextoul(argv[4], NULL);
 315        if (argc > 5)
 316                vam = hextoul(argv[5], NULL);
 317        if (argc > 6)
 318                pms = hextoul(argv[6], NULL);
 319        if (argc > 7)
 320                vdw = hextoul(argv[7], NULL);
 321
 322        switch (cmd) {
 323        case 'i':               /* init */
 324                universe_init();
 325                break;
 326        case 'v':               /* vme */
 327                printf("Configuring Universe VME Slave Window (VME->PCI):\n");
 328                printf("  vme=%08lx pci=%08lx size=%08lx vam=%02lx pms=%02lx\n",
 329                       addr1, addr2, size, vam, pms);
 330                universe_vme_slave_window(addr1, addr2, size, vam, pms);
 331                break;
 332        case 'p':               /* pci */
 333                printf("Configuring Universe PCI Slave Window (PCI->VME):\n");
 334                printf("  pci=%08lx vme=%08lx size=%08lx vam=%02lx pms=%02lx vdw=%02lx\n",
 335                       addr1, addr2, size, vam, pms, vdw);
 336                universe_pci_slave_window(addr1, addr2, size, vam, pms, vdw);
 337                break;
 338        default:
 339                printf("Universe command %s not supported!\n", argv[1]);
 340        }
 341
 342        return 0;
 343}
 344
 345
 346U_BOOT_CMD(
 347        universe,       8,      1,      do_universe,
 348        "initialize and configure Turndra Universe",
 349        "init\n"
 350        "    - initialize universe\n"
 351        "universe vme [vme_addr] [pci_addr] [size] [vam] [pms]\n"
 352        "    - create vme slave window (access: vme->pci)\n"
 353        "universe pci [pci_addr] [vme_addr] [size] [vam] [pms] [vdw]\n"
 354        "    - create pci slave window (access: pci->vme)\n"
 355        "    [vam] = VMEbus Address-Modifier:  01 -> A16 Address Space\n"
 356        "                                      02 -> A24 Address Space\n"
 357        "                                      03 -> A32 Address Space\n"
 358        "                                      04 -> Supervisor AM Code\n"
 359        "                                      10 -> Data AM Code\n"
 360        "                                      20 -> Program AM Code\n"
 361        "    [pms] = PCI Memory Space:         01 -> Memory Space\n"
 362        "                                      02 -> I/O Space\n"
 363        "                                      03 -> Configuration Space\n"
 364        "    [vdw] = VMEbus Maximum Datawidth: 01 -> D8 Data Width\n"
 365        "                                      02 -> D16 Data Width\n"
 366        "                                      03 -> D32 Data Width"
 367);
 368