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;
  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        return result;
 130}
 131
 132
 133/*
 134 * Create pci slave window (access: pci -> vme)
 135 */
 136int universe_pci_slave_window(unsigned int pciAddr, unsigned int vmeAddr, int size, int vam, int pms, int vdw)
 137{
 138        int result, i;
 139        unsigned int ctl = 0;
 140
 141        if (NULL == dev) {
 142                result = -1;
 143                goto exit_10;
 144        }
 145
 146        for (i = 0; i < 4; i++) {
 147                if (0x00800000 == readl(&dev->uregs->lsi[i].ctl))
 148                        break;
 149        }
 150
 151        if (i == 4) {
 152                printf ("universe: No Image available\n");
 153                result = -1;
 154                goto exit_10;
 155        }
 156
 157        debug ("universe: Using image %d\n", i);
 158
 159        writel(pciAddr , &dev->uregs->lsi[i].bs);
 160        writel((pciAddr + size), &dev->uregs->lsi[i].bd);
 161        writel((vmeAddr - pciAddr), &dev->uregs->lsi[i].to);
 162
 163        switch (vam & VME_AM_Axx) {
 164        case VME_AM_A16:
 165                ctl = 0x00000000;
 166                break;
 167        case VME_AM_A24:
 168                ctl = 0x00010000;
 169                break;
 170        case VME_AM_A32:
 171                ctl = 0x00020000;
 172                break;
 173        }
 174
 175        switch (vam & VME_AM_Mxx) {
 176        case VME_AM_DATA:
 177                ctl |= 0x00000000;
 178                break;
 179        case VME_AM_PROG:
 180                ctl |= 0x00008000;
 181                break;
 182        }
 183
 184        if (vam & VME_AM_SUP) {
 185                ctl |= 0x00001000;
 186
 187        }
 188
 189        switch (vdw & VME_FLAG_Dxx) {
 190        case VME_FLAG_D8:
 191                ctl |= 0x00000000;
 192                break;
 193        case VME_FLAG_D16:
 194                ctl |= 0x00400000;
 195                break;
 196        case VME_FLAG_D32:
 197                ctl |= 0x00800000;
 198                break;
 199        }
 200
 201        switch (pms & PCI_MS_Mxx) {
 202        case PCI_MS_MEM:
 203                ctl |= 0x00000000;
 204                break;
 205        case PCI_MS_IO:
 206                ctl |= 0x00000001;
 207                break;
 208        case PCI_MS_CONFIG:
 209                ctl |= 0x00000002;
 210                break;
 211        }
 212
 213        ctl |= 0x80000000;    /* enable */
 214
 215        writel(ctl, &dev->uregs->lsi[i].ctl);
 216
 217        debug ("universe: window-addr=%p\n", &dev->uregs->lsi[i].ctl);
 218        debug ("universe: pci slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->lsi[i].ctl));
 219        debug ("universe: pci slave window[%d] bs=%08x\n", i, readl(&dev->uregs->lsi[i].bs));
 220        debug ("universe: pci slave window[%d] bd=%08x\n", i, readl(&dev->uregs->lsi[i].bd));
 221        debug ("universe: pci slave window[%d] to=%08x\n", i, readl(&dev->uregs->lsi[i].to));
 222
 223        return 0;
 224
 225 exit_10:
 226        return -result;
 227}
 228
 229
 230/*
 231 * Create vme slave window (access: vme -> pci)
 232 */
 233int universe_vme_slave_window(unsigned int vmeAddr, unsigned int pciAddr, int size, int vam, int pms)
 234{
 235        int result, i;
 236        unsigned int ctl = 0;
 237
 238        if (NULL == dev) {
 239                result = -1;
 240                goto exit_10;
 241        }
 242
 243        for (i = 0; i < 4; i++) {
 244                if (0x00800000 == readl(&dev->uregs->vsi[i].ctl))
 245                        break;
 246        }
 247
 248        if (i == 4) {
 249                printf ("universe: No Image available\n");
 250                result = -1;
 251                goto exit_10;
 252        }
 253
 254        debug ("universe: Using image %d\n", i);
 255
 256        writel(vmeAddr , &dev->uregs->vsi[i].bs);
 257        writel((vmeAddr + size), &dev->uregs->vsi[i].bd);
 258        writel((pciAddr - vmeAddr), &dev->uregs->vsi[i].to);
 259
 260        switch (vam & VME_AM_Axx) {
 261        case VME_AM_A16:
 262                ctl = 0x00000000;
 263                break;
 264        case VME_AM_A24:
 265                ctl = 0x00010000;
 266                break;
 267        case VME_AM_A32:
 268                ctl = 0x00020000;
 269                break;
 270        }
 271
 272        switch (vam & VME_AM_Mxx) {
 273        case VME_AM_DATA:
 274                ctl |= 0x00000000;
 275                break;
 276        case VME_AM_PROG:
 277                ctl |= 0x00800000;
 278                break;
 279        }
 280
 281        if (vam & VME_AM_SUP) {
 282                ctl |= 0x00100000;
 283
 284        }
 285
 286        switch (pms & PCI_MS_Mxx) {
 287        case PCI_MS_MEM:
 288                ctl |= 0x00000000;
 289                break;
 290        case PCI_MS_IO:
 291                ctl |= 0x00000001;
 292                break;
 293        case PCI_MS_CONFIG:
 294                ctl |= 0x00000002;
 295                break;
 296        }
 297
 298        ctl |= 0x80f00000;    /* enable */
 299
 300        writel(ctl, &dev->uregs->vsi[i].ctl);
 301
 302        debug ("universe: window-addr=%p\n", &dev->uregs->vsi[i].ctl);
 303        debug ("universe: vme slave window[%d] ctl=%08x\n", i, readl(&dev->uregs->vsi[i].ctl));
 304        debug ("universe: vme slave window[%d] bs=%08x\n", i, readl(&dev->uregs->vsi[i].bs));
 305        debug ("universe: vme slave window[%d] bd=%08x\n", i, readl(&dev->uregs->vsi[i].bd));
 306        debug ("universe: vme slave window[%d] to=%08x\n", i, readl(&dev->uregs->vsi[i].to));
 307
 308        return 0;
 309
 310 exit_10:
 311        return -result;
 312}
 313
 314
 315/*
 316 * Tundra Universe configuration
 317 */
 318int do_universe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 319{
 320        ulong addr1 = 0, addr2 = 0, size = 0, vam = 0, pms = 0, vdw = 0;
 321        char cmd = 'x';
 322
 323        /* get parameter */
 324        if (argc > 1)
 325                cmd = argv[1][0];
 326        if (argc > 2)
 327                addr1 = simple_strtoul(argv[2], NULL, 16);
 328        if (argc > 3)
 329                addr2 = simple_strtoul(argv[3], NULL, 16);
 330        if (argc > 4)
 331                size = simple_strtoul(argv[4], NULL, 16);
 332        if (argc > 5)
 333                vam = simple_strtoul(argv[5], NULL, 16);
 334        if (argc > 6)
 335                pms = simple_strtoul(argv[6], NULL, 16);
 336        if (argc > 7)
 337                vdw = simple_strtoul(argv[7], NULL, 16);
 338
 339        switch (cmd) {
 340        case 'i':               /* init */
 341                universe_init();
 342                break;
 343        case 'v':               /* vme */
 344                printf("Configuring Universe VME Slave Window (VME->PCI):\n");
 345                printf("  vme=%08lx pci=%08lx size=%08lx vam=%02lx pms=%02lx\n",
 346                       addr1, addr2, size, vam, pms);
 347                universe_vme_slave_window(addr1, addr2, size, vam, pms);
 348                break;
 349        case 'p':               /* pci */
 350                printf("Configuring Universe PCI Slave Window (PCI->VME):\n");
 351                printf("  pci=%08lx vme=%08lx size=%08lx vam=%02lx pms=%02lx vdw=%02lx\n",
 352                       addr1, addr2, size, vam, pms, vdw);
 353                universe_pci_slave_window(addr1, addr2, size, vam, pms, vdw);
 354                break;
 355        default:
 356                printf("Universe command %s not supported!\n", argv[1]);
 357        }
 358
 359        return 0;
 360}
 361
 362
 363U_BOOT_CMD(
 364        universe,       8,      1,      do_universe,
 365        "initialize and configure Turndra Universe",
 366        "init\n"
 367        "    - initialize universe\n"
 368        "universe vme [vme_addr] [pci_addr] [size] [vam] [pms]\n"
 369        "    - create vme slave window (access: vme->pci)\n"
 370        "universe pci [pci_addr] [vme_addr] [size] [vam] [pms] [vdw]\n"
 371        "    - create pci slave window (access: pci->vme)\n"
 372        "    [vam] = VMEbus Address-Modifier:  01 -> A16 Address Space\n"
 373        "                                      02 -> A24 Address Space\n"
 374        "                                      03 -> A32 Address Space\n"
 375        "                                      04 -> Supervisor AM Code\n"
 376        "                                      10 -> Data AM Code\n"
 377        "                                      20 -> Program AM Code\n"
 378        "    [pms] = PCI Memory Space:         01 -> Memory Space\n"
 379        "                                      02 -> I/O Space\n"
 380        "                                      03 -> Configuration Space\n"
 381        "    [vdw] = VMEbus Maximum Datawidth: 01 -> D8 Data Width\n"
 382        "                                      02 -> D16 Data Width\n"
 383        "                                      03 -> D32 Data Width"
 384);
 385