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