uboot/board/armltd/integrator/pci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2002
   4 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   5 * Marius Groeger <mgroeger@sysgo.de>
   6 *
   7 * (C) Copyright 2002
   8 * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
   9 *
  10 * (C) Copyright 2003
  11 * Texas Instruments, <www.ti.com>
  12 * Kshitij Gupta <Kshitij@ti.com>
  13 *
  14 * (C) Copyright 2004
  15 * ARM Ltd.
  16 * Philippe Robin, <philippe.robin@arm.com>
  17 *
  18 * (C) Copyright 2011
  19 * Linaro
  20 * Linus Walleij <linus.walleij@linaro.org>
  21 */
  22#include <common.h>
  23#include <init.h>
  24#include <pci.h>
  25#include <asm/io.h>
  26#include "integrator-sc.h"
  27#include "pci_v3.h"
  28
  29#define INTEGRATOR_BOOT_ROM_BASE        0x20000000
  30#define INTEGRATOR_HDR0_SDRAM_BASE      0x80000000
  31
  32/*
  33 * These are in the physical addresses on the CPU side, i.e.
  34 * where we read and write stuff - you don't want to try to
  35 * move these around
  36 */
  37#define PHYS_PCI_MEM_BASE       0x40000000
  38#define PHYS_PCI_IO_BASE        0x60000000      /* PCI I/O space base */
  39#define PHYS_PCI_CONFIG_BASE    0x61000000
  40#define PHYS_PCI_V3_BASE        0x62000000      /* V360EPC registers */
  41#define SZ_256M                 0x10000000
  42
  43/*
  44 * These are in the PCI BUS address space
  45 * Set to 0x00000000 in the Linux kernel, 0x40000000 in Boot monitor
  46 * we follow the example of the kernel, because that is the address
  47 * range that devices actually use - what would they be doing at
  48 * 0x40000000?
  49 */
  50#define PCI_BUS_NONMEM_START    0x00000000
  51#define PCI_BUS_NONMEM_SIZE     SZ_256M
  52
  53#define PCI_BUS_PREMEM_START    (PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE)
  54#define PCI_BUS_PREMEM_SIZE     SZ_256M
  55
  56#if PCI_BUS_NONMEM_START & 0x000fffff
  57#error PCI_BUS_NONMEM_START must be megabyte aligned
  58#endif
  59#if PCI_BUS_PREMEM_START & 0x000fffff
  60#error PCI_BUS_PREMEM_START must be megabyte aligned
  61#endif
  62
  63/*
  64 * Initialize PCI Devices, report devices found.
  65 */
  66
  67#ifndef CONFIG_PCI_PNP
  68#define PCI_ENET0_IOADDR        0x60000000 /* First card in PCI I/O space */
  69#define PCI_ENET0_MEMADDR       0x40000000 /* First card in PCI memory space */
  70static struct pci_config_table pci_integrator_config_table[] = {
  71        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
  72          pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
  73                                       PCI_ENET0_MEMADDR,
  74                                       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
  75        { }
  76};
  77#endif /* CONFIG_PCI_PNP */
  78
  79/* V3 access routines */
  80#define v3_writeb(o, v) __raw_writeb(v, PHYS_PCI_V3_BASE + (unsigned int)(o))
  81#define v3_readb(o)    (__raw_readb(PHYS_PCI_V3_BASE + (unsigned int)(o)))
  82
  83#define v3_writew(o, v) __raw_writew(v, PHYS_PCI_V3_BASE + (unsigned int)(o))
  84#define v3_readw(o)    (__raw_readw(PHYS_PCI_V3_BASE + (unsigned int)(o)))
  85
  86#define v3_writel(o, v) __raw_writel(v, PHYS_PCI_V3_BASE + (unsigned int)(o))
  87#define v3_readl(o)    (__raw_readl(PHYS_PCI_V3_BASE + (unsigned int)(o)))
  88
  89static unsigned long v3_open_config_window(pci_dev_t bdf, int offset)
  90{
  91        unsigned int address, mapaddress;
  92        unsigned int busnr = PCI_BUS(bdf);
  93        unsigned int devfn = PCI_FUNC(bdf);
  94
  95        /*
  96         * Trap out illegal values
  97         */
  98        if (offset > 255)
  99                BUG();
 100        if (busnr > 255)
 101                BUG();
 102        if (devfn > 255)
 103                BUG();
 104
 105        if (busnr == 0) {
 106                /*
 107                 * Linux calls the thing U-Boot calls "DEV" "SLOT"
 108                 * instead, but it's the same 5 bits
 109                 */
 110                int slot = PCI_DEV(bdf);
 111
 112                /*
 113                 * local bus segment so need a type 0 config cycle
 114                 *
 115                 * build the PCI configuration "address" with one-hot in
 116                 * A31-A11
 117                 *
 118                 * mapaddress:
 119                 *  3:1 = config cycle (101)
 120                 *  0   = PCI A1 & A0 are 0 (0)
 121                 */
 122                address = PCI_FUNC(bdf) << 8;
 123                mapaddress = V3_LB_MAP_TYPE_CONFIG;
 124
 125                if (slot > 12)
 126                        /*
 127                         * high order bits are handled by the MAP register
 128                         */
 129                        mapaddress |= 1 << (slot - 5);
 130                else
 131                        /*
 132                         * low order bits handled directly in the address
 133                         */
 134                        address |= 1 << (slot + 11);
 135        } else {
 136                /*
 137                 * not the local bus segment so need a type 1 config cycle
 138                 *
 139                 * address:
 140                 *  23:16 = bus number
 141                 *  15:11 = slot number (7:3 of devfn)
 142                 *  10:8  = func number (2:0 of devfn)
 143                 *
 144                 * mapaddress:
 145                 *  3:1 = config cycle (101)
 146                 *  0   = PCI A1 & A0 from host bus (1)
 147                 */
 148                mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN;
 149                address = (busnr << 16) | (devfn << 8);
 150        }
 151
 152        /*
 153         * Set up base0 to see all 512Mbytes of memory space (not
 154         * prefetchable), this frees up base1 for re-use by
 155         * configuration memory
 156         */
 157        v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
 158                        V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE);
 159
 160        /*
 161         * Set up base1/map1 to point into configuration space.
 162         */
 163        v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) |
 164                        V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE);
 165        v3_writew(V3_LB_MAP1, mapaddress);
 166
 167        return PHYS_PCI_CONFIG_BASE + address + offset;
 168}
 169
 170static void v3_close_config_window(void)
 171{
 172        /*
 173         * Reassign base1 for use by prefetchable PCI memory
 174         */
 175        v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
 176                        V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
 177                        V3_LB_BASE_ENABLE);
 178        v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
 179                        V3_LB_MAP_TYPE_MEM_MULTIPLE);
 180
 181        /*
 182         * And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
 183         */
 184        v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
 185                        V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
 186}
 187
 188static int pci_integrator_read_byte(struct pci_controller *hose, pci_dev_t bdf,
 189                                    int offset, unsigned char *val)
 190{
 191        unsigned long addr;
 192
 193        addr = v3_open_config_window(bdf, offset);
 194        *val = __raw_readb(addr);
 195        v3_close_config_window();
 196        return 0;
 197}
 198
 199static int pci_integrator_read__word(struct pci_controller *hose,
 200                                     pci_dev_t bdf, int offset,
 201                                     unsigned short *val)
 202{
 203        unsigned long addr;
 204
 205        addr = v3_open_config_window(bdf, offset);
 206        *val = __raw_readw(addr);
 207        v3_close_config_window();
 208        return 0;
 209}
 210
 211static int pci_integrator_read_dword(struct pci_controller *hose,
 212                                     pci_dev_t bdf, int offset,
 213                                     unsigned int *val)
 214{
 215        unsigned long addr;
 216
 217        addr = v3_open_config_window(bdf, offset);
 218        *val = __raw_readl(addr);
 219        v3_close_config_window();
 220        return 0;
 221}
 222
 223static int pci_integrator_write_byte(struct pci_controller *hose,
 224                                     pci_dev_t bdf, int offset,
 225                                     unsigned char val)
 226{
 227        unsigned long addr;
 228
 229        addr = v3_open_config_window(bdf, offset);
 230        __raw_writeb((u8)val, addr);
 231        __raw_readb(addr);
 232        v3_close_config_window();
 233        return 0;
 234}
 235
 236static int pci_integrator_write_word(struct pci_controller *hose,
 237                                     pci_dev_t bdf, int offset,
 238                                     unsigned short val)
 239{
 240        unsigned long addr;
 241
 242        addr = v3_open_config_window(bdf, offset);
 243        __raw_writew((u8)val, addr);
 244        __raw_readw(addr);
 245        v3_close_config_window();
 246        return 0;
 247}
 248
 249static int pci_integrator_write_dword(struct pci_controller *hose,
 250                                      pci_dev_t bdf, int offset,
 251                                      unsigned int val)
 252{
 253        unsigned long addr;
 254
 255        addr = v3_open_config_window(bdf, offset);
 256        __raw_writel((u8)val, addr);
 257        __raw_readl(addr);
 258        v3_close_config_window();
 259        return 0;
 260}
 261
 262struct pci_controller integrator_hose = {
 263#ifndef CONFIG_PCI_PNP
 264        config_table: pci_integrator_config_table,
 265#endif
 266};
 267
 268void pci_init_board(void)
 269{
 270        struct pci_controller *hose = &integrator_hose;
 271        u16 val;
 272
 273        /* setting this register will take the V3 out of reset */
 274        __raw_writel(SC_PCI_PCIEN, SC_PCI);
 275
 276        /* Wait for 230 ms (from spec) before accessing any V3 registers */
 277        mdelay(230);
 278
 279        /* Now write the Base I/O Address Word to PHYS_PCI_V3_BASE + 0x6E */
 280        v3_writew(V3_LB_IO_BASE, (PHYS_PCI_V3_BASE >> 16));
 281
 282        /* Wait for the mailbox to settle */
 283        do {
 284                v3_writeb(V3_MAIL_DATA, 0xAA);
 285                v3_writeb(V3_MAIL_DATA + 4, 0x55);
 286        } while (v3_readb(V3_MAIL_DATA) != 0xAA ||
 287                 v3_readb(V3_MAIL_DATA + 4) != 0x55);
 288
 289        /* Make sure that V3 register access is not locked, if it is, unlock it */
 290        if (v3_readw(V3_SYSTEM) & V3_SYSTEM_M_LOCK)
 291                v3_writew(V3_SYSTEM, 0xA05F);
 292
 293        /*
 294         * Ensure that the slave accesses from PCI are disabled while we
 295         * setup memory windows
 296         */
 297        val = v3_readw(V3_PCI_CMD);
 298        val &= ~(V3_COMMAND_M_MEM_EN | V3_COMMAND_M_IO_EN);
 299        v3_writew(V3_PCI_CMD, val);
 300
 301        /* Clear RST_OUT to 0; keep the PCI bus in reset until we've finished */
 302        val = v3_readw(V3_SYSTEM);
 303        val &= ~V3_SYSTEM_M_RST_OUT;
 304        v3_writew(V3_SYSTEM, val);
 305
 306        /* Make all accesses from PCI space retry until we're ready for them */
 307        val = v3_readw(V3_PCI_CFG);
 308        val |= V3_PCI_CFG_M_RETRY_EN;
 309        v3_writew(V3_PCI_CFG, val);
 310
 311        /*
 312         * Set up any V3 PCI Configuration Registers that we absolutely have to.
 313         * LB_CFG controls Local Bus protocol.
 314         * Enable LocalBus byte strobes for READ accesses too.
 315         * set bit 7 BE_IMODE and bit 6 BE_OMODE
 316         */
 317        val = v3_readw(V3_LB_CFG);
 318        val |= 0x0C0;
 319        v3_writew(V3_LB_CFG, val);
 320
 321        /* PCI_CMD controls overall PCI operation. Enable PCI bus master. */
 322        val = v3_readw(V3_PCI_CMD);
 323        val |= V3_COMMAND_M_MASTER_EN;
 324        v3_writew(V3_PCI_CMD, val);
 325
 326        /*
 327         * PCI_MAP0 controls where the PCI to CPU memory window is on
 328         * Local Bus
 329         */
 330        v3_writel(V3_PCI_MAP0,
 331                  (INTEGRATOR_BOOT_ROM_BASE) | (V3_PCI_MAP_M_ADR_SIZE_512MB |
 332                                                V3_PCI_MAP_M_REG_EN |
 333                                                V3_PCI_MAP_M_ENABLE));
 334
 335        /* PCI_BASE0 is the PCI address of the start of the window */
 336        v3_writel(V3_PCI_BASE0, INTEGRATOR_BOOT_ROM_BASE);
 337
 338        /* PCI_MAP1 is LOCAL address of the start of the window */
 339        v3_writel(V3_PCI_MAP1,
 340                  (INTEGRATOR_HDR0_SDRAM_BASE) | (V3_PCI_MAP_M_ADR_SIZE_1GB |
 341                                                  V3_PCI_MAP_M_REG_EN |
 342                                                  V3_PCI_MAP_M_ENABLE));
 343
 344        /* PCI_BASE1 is the PCI address of the start of the window */
 345        v3_writel(V3_PCI_BASE1, INTEGRATOR_HDR0_SDRAM_BASE);
 346
 347        /*
 348         * Set up memory the windows from local bus memory into PCI
 349         * configuration, I/O and Memory regions.
 350         * PCI I/O, LB_BASE2 and LB_MAP2 are used exclusively for this.
 351         */
 352        v3_writew(V3_LB_BASE2,
 353                  v3_addr_to_lb_map(PHYS_PCI_IO_BASE) | V3_LB_BASE_ENABLE);
 354        v3_writew(V3_LB_MAP2, 0);
 355
 356        /* PCI Configuration, use LB_BASE1/LB_MAP1. */
 357
 358        /*
 359         * PCI Memory use LB_BASE0/LB_MAP0 and LB_BASE1/LB_MAP1
 360         * Map first 256Mbytes as non-prefetchable via BASE0/MAP0
 361         */
 362        v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
 363                        V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
 364        v3_writew(V3_LB_MAP0,
 365                  v3_addr_to_lb_map(PCI_BUS_NONMEM_START) | V3_LB_MAP_TYPE_MEM);
 366
 367        /* Map second 256 Mbytes as prefetchable via BASE1/MAP1 */
 368        v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
 369                        V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
 370                        V3_LB_BASE_ENABLE);
 371        v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
 372                        V3_LB_MAP_TYPE_MEM_MULTIPLE);
 373
 374        /* Dump PCI to local address space mappings */
 375        debug("LB_BASE0 = %08x\n", v3_readl(V3_LB_BASE0));
 376        debug("LB_MAP0 = %04x\n", v3_readw(V3_LB_MAP0));
 377        debug("LB_BASE1 = %08x\n", v3_readl(V3_LB_BASE1));
 378        debug("LB_MAP1 = %04x\n", v3_readw(V3_LB_MAP1));
 379        debug("LB_BASE2 = %04x\n", v3_readw(V3_LB_BASE2));
 380        debug("LB_MAP2 = %04x\n", v3_readw(V3_LB_MAP2));
 381        debug("LB_IO_BASE = %04x\n", v3_readw(V3_LB_IO_BASE));
 382
 383        /*
 384         * Allow accesses to PCI Configuration space and set up A1, A0 for
 385         * type 1 config cycles
 386         */
 387        val = v3_readw(V3_PCI_CFG);
 388        val &= ~(V3_PCI_CFG_M_RETRY_EN | V3_PCI_CFG_M_AD_LOW1);
 389        val |= V3_PCI_CFG_M_AD_LOW0;
 390        v3_writew(V3_PCI_CFG, val);
 391
 392        /* now we can allow incoming PCI MEMORY accesses */
 393        val = v3_readw(V3_PCI_CMD);
 394        val |= V3_COMMAND_M_MEM_EN;
 395        v3_writew(V3_PCI_CMD, val);
 396
 397        /*
 398         * Set RST_OUT to take the PCI bus is out of reset, PCI devices can
 399         * now initialise.
 400         */
 401        val = v3_readw(V3_SYSTEM);
 402        val |= V3_SYSTEM_M_RST_OUT;
 403        v3_writew(V3_SYSTEM, val);
 404
 405        /*  Lock the V3 system register so that no one else can play with it */
 406        val = v3_readw(V3_SYSTEM);
 407        val |= V3_SYSTEM_M_LOCK;
 408        v3_writew(V3_SYSTEM, val);
 409
 410        /*
 411         * Configure and register the PCI hose
 412         */
 413        hose->first_busno = 0;
 414        hose->last_busno = 0xff;
 415
 416        /* System memory space, window 0 256 MB non-prefetchable */
 417        pci_set_region(hose->regions + 0,
 418                       PCI_BUS_NONMEM_START, PHYS_PCI_MEM_BASE,
 419                       SZ_256M,
 420                       PCI_REGION_MEM);
 421
 422        /* System memory space, window 1 256 MB prefetchable */
 423        pci_set_region(hose->regions + 1,
 424                       PCI_BUS_PREMEM_START, PHYS_PCI_MEM_BASE + SZ_256M,
 425                       SZ_256M,
 426                       PCI_REGION_MEM |
 427                       PCI_REGION_PREFETCH);
 428
 429        /* PCI I/O space */
 430        pci_set_region(hose->regions + 2,
 431                       0x00000000, PHYS_PCI_IO_BASE, 0x01000000,
 432                       PCI_REGION_IO);
 433
 434        /* PCI Memory - config space */
 435        pci_set_region(hose->regions + 3,
 436                       0x00000000, PHYS_PCI_CONFIG_BASE, 0x01000000,
 437                       PCI_REGION_MEM);
 438        /* PCI V3 regs */
 439        pci_set_region(hose->regions + 4,
 440                       0x00000000, PHYS_PCI_V3_BASE, 0x01000000,
 441                       PCI_REGION_MEM);
 442
 443        hose->region_count = 5;
 444
 445        pci_set_ops(hose,
 446                    pci_integrator_read_byte,
 447                    pci_integrator_read__word,
 448                    pci_integrator_read_dword,
 449                    pci_integrator_write_byte,
 450                    pci_integrator_write_word,
 451                    pci_integrator_write_dword);
 452
 453        pci_register_hose(hose);
 454
 455        pciauto_config_init(hose);
 456        pciauto_config_device(hose, 0);
 457
 458        hose->last_busno = pci_hose_scan(hose);
 459}
 460