linux/arch/powerpc/boot/mv64x60.c
<<
>>
Prefs
   1/*
   2 * Marvell hostbridge routines
   3 *
   4 * Author: Mark A. Greer <source@mvista.com>
   5 *
   6 * 2004, 2005, 2007 (c) MontaVista Software, Inc. This file is licensed under
   7 * the terms of the GNU General Public License version 2. This program
   8 * is licensed "as is" without any warranty of any kind, whether express
   9 * or implied.
  10 */
  11
  12#include <stdarg.h>
  13#include <stddef.h>
  14#include "types.h"
  15#include "elf.h"
  16#include "page.h"
  17#include "string.h"
  18#include "stdio.h"
  19#include "io.h"
  20#include "ops.h"
  21#include "mv64x60.h"
  22
  23#define PCI_DEVFN(slot,func)    ((((slot) & 0x1f) << 3) | ((func) & 0x07))
  24
  25#define MV64x60_CPU2MEM_WINDOWS                 4
  26#define MV64x60_CPU2MEM_0_BASE                  0x0008
  27#define MV64x60_CPU2MEM_0_SIZE                  0x0010
  28#define MV64x60_CPU2MEM_1_BASE                  0x0208
  29#define MV64x60_CPU2MEM_1_SIZE                  0x0210
  30#define MV64x60_CPU2MEM_2_BASE                  0x0018
  31#define MV64x60_CPU2MEM_2_SIZE                  0x0020
  32#define MV64x60_CPU2MEM_3_BASE                  0x0218
  33#define MV64x60_CPU2MEM_3_SIZE                  0x0220
  34
  35#define MV64x60_ENET2MEM_BAR_ENABLE             0x2290
  36#define MV64x60_ENET2MEM_0_BASE                 0x2200
  37#define MV64x60_ENET2MEM_0_SIZE                 0x2204
  38#define MV64x60_ENET2MEM_1_BASE                 0x2208
  39#define MV64x60_ENET2MEM_1_SIZE                 0x220c
  40#define MV64x60_ENET2MEM_2_BASE                 0x2210
  41#define MV64x60_ENET2MEM_2_SIZE                 0x2214
  42#define MV64x60_ENET2MEM_3_BASE                 0x2218
  43#define MV64x60_ENET2MEM_3_SIZE                 0x221c
  44#define MV64x60_ENET2MEM_4_BASE                 0x2220
  45#define MV64x60_ENET2MEM_4_SIZE                 0x2224
  46#define MV64x60_ENET2MEM_5_BASE                 0x2228
  47#define MV64x60_ENET2MEM_5_SIZE                 0x222c
  48#define MV64x60_ENET2MEM_ACC_PROT_0             0x2294
  49#define MV64x60_ENET2MEM_ACC_PROT_1             0x2298
  50#define MV64x60_ENET2MEM_ACC_PROT_2             0x229c
  51
  52#define MV64x60_MPSC2MEM_BAR_ENABLE             0xf250
  53#define MV64x60_MPSC2MEM_0_BASE                 0xf200
  54#define MV64x60_MPSC2MEM_0_SIZE                 0xf204
  55#define MV64x60_MPSC2MEM_1_BASE                 0xf208
  56#define MV64x60_MPSC2MEM_1_SIZE                 0xf20c
  57#define MV64x60_MPSC2MEM_2_BASE                 0xf210
  58#define MV64x60_MPSC2MEM_2_SIZE                 0xf214
  59#define MV64x60_MPSC2MEM_3_BASE                 0xf218
  60#define MV64x60_MPSC2MEM_3_SIZE                 0xf21c
  61#define MV64x60_MPSC_0_REMAP                    0xf240
  62#define MV64x60_MPSC_1_REMAP                    0xf244
  63#define MV64x60_MPSC2MEM_ACC_PROT_0             0xf254
  64#define MV64x60_MPSC2MEM_ACC_PROT_1             0xf258
  65#define MV64x60_MPSC2REGS_BASE                  0xf25c
  66
  67#define MV64x60_IDMA2MEM_BAR_ENABLE             0x0a80
  68#define MV64x60_IDMA2MEM_0_BASE                 0x0a00
  69#define MV64x60_IDMA2MEM_0_SIZE                 0x0a04
  70#define MV64x60_IDMA2MEM_1_BASE                 0x0a08
  71#define MV64x60_IDMA2MEM_1_SIZE                 0x0a0c
  72#define MV64x60_IDMA2MEM_2_BASE                 0x0a10
  73#define MV64x60_IDMA2MEM_2_SIZE                 0x0a14
  74#define MV64x60_IDMA2MEM_3_BASE                 0x0a18
  75#define MV64x60_IDMA2MEM_3_SIZE                 0x0a1c
  76#define MV64x60_IDMA2MEM_4_BASE                 0x0a20
  77#define MV64x60_IDMA2MEM_4_SIZE                 0x0a24
  78#define MV64x60_IDMA2MEM_5_BASE                 0x0a28
  79#define MV64x60_IDMA2MEM_5_SIZE                 0x0a2c
  80#define MV64x60_IDMA2MEM_6_BASE                 0x0a30
  81#define MV64x60_IDMA2MEM_6_SIZE                 0x0a34
  82#define MV64x60_IDMA2MEM_7_BASE                 0x0a38
  83#define MV64x60_IDMA2MEM_7_SIZE                 0x0a3c
  84#define MV64x60_IDMA2MEM_ACC_PROT_0             0x0a70
  85#define MV64x60_IDMA2MEM_ACC_PROT_1             0x0a74
  86#define MV64x60_IDMA2MEM_ACC_PROT_2             0x0a78
  87#define MV64x60_IDMA2MEM_ACC_PROT_3             0x0a7c
  88
  89#define MV64x60_PCI_ACC_CNTL_WINDOWS            6
  90#define MV64x60_PCI0_PCI_DECODE_CNTL            0x0d3c
  91#define MV64x60_PCI1_PCI_DECODE_CNTL            0x0dbc
  92
  93#define MV64x60_PCI0_BAR_ENABLE                 0x0c3c
  94#define MV64x60_PCI02MEM_0_SIZE                 0x0c08
  95#define MV64x60_PCI0_ACC_CNTL_0_BASE_LO         0x1e00
  96#define MV64x60_PCI0_ACC_CNTL_0_BASE_HI         0x1e04
  97#define MV64x60_PCI0_ACC_CNTL_0_SIZE            0x1e08
  98#define MV64x60_PCI0_ACC_CNTL_1_BASE_LO         0x1e10
  99#define MV64x60_PCI0_ACC_CNTL_1_BASE_HI         0x1e14
 100#define MV64x60_PCI0_ACC_CNTL_1_SIZE            0x1e18
 101#define MV64x60_PCI0_ACC_CNTL_2_BASE_LO         0x1e20
 102#define MV64x60_PCI0_ACC_CNTL_2_BASE_HI         0x1e24
 103#define MV64x60_PCI0_ACC_CNTL_2_SIZE            0x1e28
 104#define MV64x60_PCI0_ACC_CNTL_3_BASE_LO         0x1e30
 105#define MV64x60_PCI0_ACC_CNTL_3_BASE_HI         0x1e34
 106#define MV64x60_PCI0_ACC_CNTL_3_SIZE            0x1e38
 107#define MV64x60_PCI0_ACC_CNTL_4_BASE_LO         0x1e40
 108#define MV64x60_PCI0_ACC_CNTL_4_BASE_HI         0x1e44
 109#define MV64x60_PCI0_ACC_CNTL_4_SIZE            0x1e48
 110#define MV64x60_PCI0_ACC_CNTL_5_BASE_LO         0x1e50
 111#define MV64x60_PCI0_ACC_CNTL_5_BASE_HI         0x1e54
 112#define MV64x60_PCI0_ACC_CNTL_5_SIZE            0x1e58
 113
 114#define MV64x60_PCI1_BAR_ENABLE                 0x0cbc
 115#define MV64x60_PCI12MEM_0_SIZE                 0x0c88
 116#define MV64x60_PCI1_ACC_CNTL_0_BASE_LO         0x1e80
 117#define MV64x60_PCI1_ACC_CNTL_0_BASE_HI         0x1e84
 118#define MV64x60_PCI1_ACC_CNTL_0_SIZE            0x1e88
 119#define MV64x60_PCI1_ACC_CNTL_1_BASE_LO         0x1e90
 120#define MV64x60_PCI1_ACC_CNTL_1_BASE_HI         0x1e94
 121#define MV64x60_PCI1_ACC_CNTL_1_SIZE            0x1e98
 122#define MV64x60_PCI1_ACC_CNTL_2_BASE_LO         0x1ea0
 123#define MV64x60_PCI1_ACC_CNTL_2_BASE_HI         0x1ea4
 124#define MV64x60_PCI1_ACC_CNTL_2_SIZE            0x1ea8
 125#define MV64x60_PCI1_ACC_CNTL_3_BASE_LO         0x1eb0
 126#define MV64x60_PCI1_ACC_CNTL_3_BASE_HI         0x1eb4
 127#define MV64x60_PCI1_ACC_CNTL_3_SIZE            0x1eb8
 128#define MV64x60_PCI1_ACC_CNTL_4_BASE_LO         0x1ec0
 129#define MV64x60_PCI1_ACC_CNTL_4_BASE_HI         0x1ec4
 130#define MV64x60_PCI1_ACC_CNTL_4_SIZE            0x1ec8
 131#define MV64x60_PCI1_ACC_CNTL_5_BASE_LO         0x1ed0
 132#define MV64x60_PCI1_ACC_CNTL_5_BASE_HI         0x1ed4
 133#define MV64x60_PCI1_ACC_CNTL_5_SIZE            0x1ed8
 134
 135#define MV64x60_CPU2PCI_SWAP_NONE               0x01000000
 136
 137#define MV64x60_CPU2PCI0_IO_BASE                0x0048
 138#define MV64x60_CPU2PCI0_IO_SIZE                0x0050
 139#define MV64x60_CPU2PCI0_IO_REMAP               0x00f0
 140#define MV64x60_CPU2PCI0_MEM_0_BASE             0x0058
 141#define MV64x60_CPU2PCI0_MEM_0_SIZE             0x0060
 142#define MV64x60_CPU2PCI0_MEM_0_REMAP_LO         0x00f8
 143#define MV64x60_CPU2PCI0_MEM_0_REMAP_HI         0x0320
 144
 145#define MV64x60_CPU2PCI1_IO_BASE                0x0090
 146#define MV64x60_CPU2PCI1_IO_SIZE                0x0098
 147#define MV64x60_CPU2PCI1_IO_REMAP               0x0108
 148#define MV64x60_CPU2PCI1_MEM_0_BASE             0x00a0
 149#define MV64x60_CPU2PCI1_MEM_0_SIZE             0x00a8
 150#define MV64x60_CPU2PCI1_MEM_0_REMAP_LO         0x0110
 151#define MV64x60_CPU2PCI1_MEM_0_REMAP_HI         0x0340
 152
 153struct mv64x60_mem_win {
 154        u32 hi;
 155        u32 lo;
 156        u32 size;
 157};
 158
 159struct mv64x60_pci_win {
 160        u32 fcn;
 161        u32 hi;
 162        u32 lo;
 163        u32 size;
 164};
 165
 166/* PCI config access routines */
 167struct {
 168        u32 addr;
 169        u32 data;
 170} static mv64x60_pci_cfgio[2] = {
 171        { /* hose 0 */
 172                .addr   = 0xcf8,
 173                .data   = 0xcfc,
 174        },
 175        { /* hose 1 */
 176                .addr   = 0xc78,
 177                .data   = 0xc7c,
 178        }
 179};
 180
 181u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset)
 182{
 183        out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
 184                        (1 << 31) | (bus << 16) | (devfn << 8) | offset);
 185        return in_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data));
 186}
 187
 188void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset,
 189                u32 val)
 190{
 191        out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
 192                        (1 << 31) | (bus << 16) | (devfn << 8) | offset);
 193        out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data), val);
 194}
 195
 196/* I/O ctlr -> system memory setup */
 197static struct mv64x60_mem_win mv64x60_cpu2mem[MV64x60_CPU2MEM_WINDOWS] = {
 198        {
 199                .lo     = MV64x60_CPU2MEM_0_BASE,
 200                .size   = MV64x60_CPU2MEM_0_SIZE,
 201        },
 202        {
 203                .lo     = MV64x60_CPU2MEM_1_BASE,
 204                .size   = MV64x60_CPU2MEM_1_SIZE,
 205        },
 206        {
 207                .lo     = MV64x60_CPU2MEM_2_BASE,
 208                .size   = MV64x60_CPU2MEM_2_SIZE,
 209        },
 210        {
 211                .lo     = MV64x60_CPU2MEM_3_BASE,
 212                .size   = MV64x60_CPU2MEM_3_SIZE,
 213        },
 214};
 215
 216static struct mv64x60_mem_win mv64x60_enet2mem[MV64x60_CPU2MEM_WINDOWS] = {
 217        {
 218                .lo     = MV64x60_ENET2MEM_0_BASE,
 219                .size   = MV64x60_ENET2MEM_0_SIZE,
 220        },
 221        {
 222                .lo     = MV64x60_ENET2MEM_1_BASE,
 223                .size   = MV64x60_ENET2MEM_1_SIZE,
 224        },
 225        {
 226                .lo     = MV64x60_ENET2MEM_2_BASE,
 227                .size   = MV64x60_ENET2MEM_2_SIZE,
 228        },
 229        {
 230                .lo     = MV64x60_ENET2MEM_3_BASE,
 231                .size   = MV64x60_ENET2MEM_3_SIZE,
 232        },
 233};
 234
 235static struct mv64x60_mem_win mv64x60_mpsc2mem[MV64x60_CPU2MEM_WINDOWS] = {
 236        {
 237                .lo     = MV64x60_MPSC2MEM_0_BASE,
 238                .size   = MV64x60_MPSC2MEM_0_SIZE,
 239        },
 240        {
 241                .lo     = MV64x60_MPSC2MEM_1_BASE,
 242                .size   = MV64x60_MPSC2MEM_1_SIZE,
 243        },
 244        {
 245                .lo     = MV64x60_MPSC2MEM_2_BASE,
 246                .size   = MV64x60_MPSC2MEM_2_SIZE,
 247        },
 248        {
 249                .lo     = MV64x60_MPSC2MEM_3_BASE,
 250                .size   = MV64x60_MPSC2MEM_3_SIZE,
 251        },
 252};
 253
 254static struct mv64x60_mem_win mv64x60_idma2mem[MV64x60_CPU2MEM_WINDOWS] = {
 255        {
 256                .lo     = MV64x60_IDMA2MEM_0_BASE,
 257                .size   = MV64x60_IDMA2MEM_0_SIZE,
 258        },
 259        {
 260                .lo     = MV64x60_IDMA2MEM_1_BASE,
 261                .size   = MV64x60_IDMA2MEM_1_SIZE,
 262        },
 263        {
 264                .lo     = MV64x60_IDMA2MEM_2_BASE,
 265                .size   = MV64x60_IDMA2MEM_2_SIZE,
 266        },
 267        {
 268                .lo     = MV64x60_IDMA2MEM_3_BASE,
 269                .size   = MV64x60_IDMA2MEM_3_SIZE,
 270        },
 271};
 272
 273static u32 mv64x60_dram_selects[MV64x60_CPU2MEM_WINDOWS] = {0xe,0xd,0xb,0x7};
 274
 275/*
 276 * ENET, MPSC, and IDMA ctlrs on the MV64x60 have separate windows that
 277 * must be set up so that the respective ctlr can access system memory.
 278 * Configure them to be same as cpu->memory windows.
 279 */
 280void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
 281                u8 is_coherent)
 282{
 283        u32 i, base, size, enables, prot = 0, snoop_bits = 0;
 284
 285        /* Disable ctlr->mem windows */
 286        out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0x3f);
 287        out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), 0xf);
 288        out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0xff);
 289
 290        if (is_coherent)
 291                snoop_bits = 0x2 << 12; /* Writeback */
 292
 293        enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
 294
 295        for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
 296                if (enables & (1 << i)) /* Set means disabled */
 297                        continue;
 298
 299                base = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].lo))
 300                        << 16;
 301                base |= snoop_bits | (mv64x60_dram_selects[i] << 8);
 302                size = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].size))
 303                        << 16;
 304                prot |= (0x3 << (i << 1)); /* RW access */
 305
 306                out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].lo), base);
 307                out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].size), size);
 308                out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].lo), base);
 309                out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].size), size);
 310                out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].lo), base);
 311                out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].size), size);
 312        }
 313
 314        out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_0), prot);
 315        out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_1), prot);
 316        out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_2), prot);
 317        out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_0), prot);
 318        out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_1), prot);
 319        out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_0), prot);
 320        out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_1), prot);
 321        out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_2), prot);
 322        out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_3), prot);
 323
 324        /* Set mpsc->bridge's reg window to the bridge's internal registers. */
 325        out_le32((u32 *)(bridge_base + MV64x60_MPSC2REGS_BASE),
 326                        (u32)bridge_pbase);
 327
 328        out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), enables);
 329        out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), enables);
 330        out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_BAR_ENABLE), enables);
 331}
 332
 333/* PCI MEM -> system memory, et. al. setup */
 334static struct mv64x60_pci_win mv64x60_pci2mem[2] = {
 335        { /* hose 0 */
 336                .fcn    = 0,
 337                .hi     = 0x14,
 338                .lo     = 0x10,
 339                .size   = MV64x60_PCI02MEM_0_SIZE,
 340        },
 341        { /* hose 1 */
 342                .fcn    = 0,
 343                .hi     = 0x94,
 344                .lo     = 0x90,
 345                .size   = MV64x60_PCI12MEM_0_SIZE,
 346        },
 347};
 348
 349static struct
 350mv64x60_mem_win mv64x60_pci_acc[2][MV64x60_PCI_ACC_CNTL_WINDOWS] = {
 351        { /* hose 0 */
 352                {
 353                        .hi     = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
 354                        .lo     = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
 355                        .size   = MV64x60_PCI0_ACC_CNTL_0_SIZE,
 356                },
 357                {
 358                        .hi     = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
 359                        .lo     = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
 360                        .size   = MV64x60_PCI0_ACC_CNTL_1_SIZE,
 361                },
 362                {
 363                        .hi     = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
 364                        .lo     = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
 365                        .size   = MV64x60_PCI0_ACC_CNTL_2_SIZE,
 366                },
 367                {
 368                        .hi     = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
 369                        .lo     = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
 370                        .size   = MV64x60_PCI0_ACC_CNTL_3_SIZE,
 371                },
 372        },
 373        { /* hose 1 */
 374                {
 375                        .hi     = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
 376                        .lo     = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
 377                        .size   = MV64x60_PCI1_ACC_CNTL_0_SIZE,
 378                },
 379                {
 380                        .hi     = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
 381                        .lo     = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
 382                        .size   = MV64x60_PCI1_ACC_CNTL_1_SIZE,
 383                },
 384                {
 385                        .hi     = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
 386                        .lo     = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
 387                        .size   = MV64x60_PCI1_ACC_CNTL_2_SIZE,
 388                },
 389                {
 390                        .hi     = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
 391                        .lo     = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
 392                        .size   = MV64x60_PCI1_ACC_CNTL_3_SIZE,
 393                },
 394        },
 395};
 396
 397static struct mv64x60_mem_win mv64x60_pci2reg[2] = {
 398        {
 399                .hi     = 0x24,
 400                .lo     = 0x20,
 401                .size   = 0,
 402        },
 403        {
 404                .hi     = 0xa4,
 405                .lo     = 0xa0,
 406                .size   = 0,
 407        },
 408};
 409
 410/* Only need to use 1 window (per hose) to get access to all of system memory */
 411void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
 412                u8 bus, u32 mem_size, u32 acc_bits)
 413{
 414        u32 i, offset, bar_enable, enables;
 415
 416        /* Disable all windows but PCI MEM -> Bridge's regs window */
 417        enables = ~(1 << 9);
 418        bar_enable = hose ? MV64x60_PCI1_BAR_ENABLE : MV64x60_PCI0_BAR_ENABLE;
 419        out_le32((u32 *)(bridge_base + bar_enable), enables);
 420
 421        for (i=0; i<MV64x60_PCI_ACC_CNTL_WINDOWS; i++)
 422                out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][i].lo), 0);
 423
 424        /* If mem_size is 0, leave windows disabled */
 425        if (mem_size == 0)
 426                return;
 427
 428        /* Cause automatic updates of PCI remap regs */
 429        offset = hose ?
 430                MV64x60_PCI1_PCI_DECODE_CNTL : MV64x60_PCI0_PCI_DECODE_CNTL;
 431        i = in_le32((u32 *)(bridge_base + offset));
 432        out_le32((u32 *)(bridge_base + offset), i & ~0x1);
 433
 434        mem_size = (mem_size - 1) & 0xfffff000;
 435
 436        /* Map PCI MEM addr 0 -> System Mem addr 0 */
 437        mv64x60_cfg_write(bridge_base, hose, bus,
 438                        PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
 439                        mv64x60_pci2mem[hose].hi, 0);
 440        mv64x60_cfg_write(bridge_base, hose, bus,
 441                        PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
 442                        mv64x60_pci2mem[hose].lo, 0);
 443        out_le32((u32 *)(bridge_base + mv64x60_pci2mem[hose].size),mem_size);
 444
 445        acc_bits |= MV64x60_PCI_ACC_CNTL_ENABLE;
 446        out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].hi), 0);
 447        out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].lo), acc_bits);
 448        out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].size),mem_size);
 449
 450        /* Set PCI MEM->bridge's reg window to where they are in CPU mem map */
 451        i = (u32)bridge_base;
 452        i &= 0xffff0000;
 453        i |= (0x2 << 1);
 454        mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
 455                        mv64x60_pci2reg[hose].hi, 0);
 456        mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
 457                        mv64x60_pci2reg[hose].lo, i);
 458
 459        enables &= ~0x1; /* Enable PCI MEM -> System Mem window 0 */
 460        out_le32((u32 *)(bridge_base + bar_enable), enables);
 461}
 462
 463/* CPU -> PCI I/O & MEM setup */
 464struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2] = {
 465        { /* hose 0 */
 466                .lo             = MV64x60_CPU2PCI0_IO_BASE,
 467                .size           = MV64x60_CPU2PCI0_IO_SIZE,
 468                .remap_hi       = 0,
 469                .remap_lo       = MV64x60_CPU2PCI0_IO_REMAP,
 470        },
 471        { /* hose 1 */
 472                .lo             = MV64x60_CPU2PCI1_IO_BASE,
 473                .size           = MV64x60_CPU2PCI1_IO_SIZE,
 474                .remap_hi       = 0,
 475                .remap_lo       = MV64x60_CPU2PCI1_IO_REMAP,
 476        },
 477};
 478
 479struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2] = {
 480        { /* hose 0 */
 481                .lo             = MV64x60_CPU2PCI0_MEM_0_BASE,
 482                .size           = MV64x60_CPU2PCI0_MEM_0_SIZE,
 483                .remap_hi       = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
 484                .remap_lo       = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
 485        },
 486        { /* hose 1 */
 487                .lo             = MV64x60_CPU2PCI1_MEM_0_BASE,
 488                .size           = MV64x60_CPU2PCI1_MEM_0_SIZE,
 489                .remap_hi       = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
 490                .remap_lo       = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
 491        },
 492};
 493
 494/* Only need to set up 1 window to pci mem space */
 495void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
 496                u32 pci_base_lo, u32 cpu_base, u32 size,
 497                struct mv64x60_cpu2pci_win *offset_tbl)
 498{
 499        cpu_base >>= 16;
 500        cpu_base |= MV64x60_CPU2PCI_SWAP_NONE;
 501        out_le32((u32 *)(bridge_base + offset_tbl[hose].lo), cpu_base);
 502
 503        if (offset_tbl[hose].remap_hi != 0)
 504                out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_hi),
 505                                pci_base_hi);
 506        out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_lo),
 507                        pci_base_lo >> 16);
 508
 509        size = (size - 1) >> 16;
 510        out_le32((u32 *)(bridge_base + offset_tbl[hose].size), size);
 511}
 512
 513/* Read mem ctlr to get the amount of mem in system */
 514u32 mv64x60_get_mem_size(u8 *bridge_base)
 515{
 516        u32 enables, i, v;
 517        u32 mem = 0;
 518
 519        enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
 520
 521        for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
 522                if (!(enables & (1<<i))) {
 523                        v = in_le32((u32*)(bridge_base
 524                                                + mv64x60_cpu2mem[i].size));
 525                        v = ((v & 0xffff) + 1) << 16;
 526                        mem += v;
 527                }
 528
 529        return mem;
 530}
 531
 532/* Get physical address of bridge's registers */
 533u8 *mv64x60_get_bridge_pbase(void)
 534{
 535        u32 v[2];
 536        void *devp;
 537
 538        devp = find_node_by_compatible(NULL, "marvell,mv64360");
 539        if (devp == NULL)
 540                goto err_out;
 541        if (getprop(devp, "reg", v, sizeof(v)) != sizeof(v))
 542                goto err_out;
 543
 544        return (u8 *)v[0];
 545
 546err_out:
 547        return 0;
 548}
 549
 550/* Get virtual address of bridge's registers */
 551u8 *mv64x60_get_bridge_base(void)
 552{
 553        u32 v;
 554        void *devp;
 555
 556        devp = find_node_by_compatible(NULL, "marvell,mv64360");
 557        if (devp == NULL)
 558                goto err_out;
 559        if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
 560                goto err_out;
 561
 562        return (u8 *)v;
 563
 564err_out:
 565        return 0;
 566}
 567
 568u8 mv64x60_is_coherent(void)
 569{
 570        u32 v;
 571        void *devp;
 572
 573        devp = finddevice("/");
 574        if (devp == NULL)
 575                return 1; /* Assume coherency on */
 576
 577        if (getprop(devp, "coherency-off", &v, sizeof(v)) < 0)
 578                return 1; /* Coherency on */
 579        else
 580                return 0;
 581}
 582