uboot/cpu/mpc8220/pci.c
<<
>>
Prefs
   1/*
   2 * Copyright 2004 Freescale Semiconductor.
   3 * Copyright (C) 2003 Motorola Inc.
   4 * Xianghua Xiao (x.xiao@motorola.com)
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 */
  24
  25/*
  26 * PCI Configuration space access support for MPC8220 PCI Bridge
  27 */
  28#include <common.h>
  29#include <mpc8220.h>
  30#include <pci.h>
  31#include <asm/io.h>
  32
  33#if defined(CONFIG_PCI)
  34
  35/* System RAM mapped over PCI */
  36#define CONFIG_PCI_SYS_MEM_BUS   CONFIG_SYS_SDRAM_BASE
  37#define CONFIG_PCI_SYS_MEM_PHYS  CONFIG_SYS_SDRAM_BASE
  38#define CONFIG_PCI_SYS_MEM_SIZE  (1024 * 1024 * 1024)
  39
  40#define cfg_read(val, addr, type, op)           *val = op((type)(addr));
  41#define cfg_write(val, addr, type, op)          op((type *)(addr), (val));
  42
  43#define PCI_OP(rw, size, type, op, mask)                                \
  44int mpc8220_pci_##rw##_config_##size(struct pci_controller *hose,       \
  45        pci_dev_t dev, int offset, type val)                            \
  46{                                                                       \
  47        u32 addr = 0;                                                   \
  48        u16 cfg_type = 0;                                               \
  49        addr = ((offset & 0xfc) | cfg_type | (dev)  | 0x80000000);      \
  50        out_be32(hose->cfg_addr, addr);                                 \
  51        __asm__ __volatile__("sync");                                   \
  52        cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);      \
  53        out_be32(hose->cfg_addr, addr & 0x7fffffff);                    \
  54        __asm__ __volatile__("sync");                                   \
  55        return 0;                                                       \
  56}
  57
  58PCI_OP(read, byte, u8 *, in_8, 3)
  59PCI_OP(read, word, u16 *, in_le16, 2)
  60PCI_OP(write, byte, u8, out_8, 3)
  61PCI_OP(write, word, u16, out_le16, 2)
  62PCI_OP(write, dword, u32, out_le32, 0)
  63
  64int mpc8220_pci_read_config_dword(struct pci_controller *hose, pci_dev_t dev,
  65        int offset, u32 *val)
  66{
  67        u32 addr;
  68        u32 tmpv;
  69        u32 mask = 2;    /* word access */
  70        /* Read lower 16 bits */
  71        addr = ((offset & 0xfc) | (dev) | 0x80000000);
  72        out_be32(hose->cfg_addr, addr);
  73        __asm__ __volatile__("sync");
  74        *val = (u32) in_le16((u16 *) (hose->cfg_data + (offset & mask)));
  75        out_be32(hose->cfg_addr, addr & 0x7fffffff);
  76        __asm__ __volatile__("sync");
  77
  78        /* Read upper 16 bits */
  79        offset += 2;
  80        addr = ((offset & 0xfc) | 1 | (dev) | 0x80000000);
  81        out_be32(hose->cfg_addr, addr);
  82        __asm__ __volatile__("sync");
  83        tmpv = (u32) in_le16((u16 *) (hose->cfg_data + (offset & mask)));
  84        out_be32(hose->cfg_addr, addr & 0x7fffffff);
  85        __asm__ __volatile__("sync");
  86
  87        /* combine results into dword value */
  88        *val = (tmpv << 16) | *val;
  89
  90        return 0;
  91}
  92
  93void
  94pci_mpc8220_init(struct pci_controller *hose)
  95{
  96        u32 win0, win1, win2;
  97        volatile mpc8220_xcpci_t *xcpci =
  98                (volatile mpc8220_xcpci_t *) MMAP_XCPCI;
  99
 100        volatile pcfg8220_t *portcfg = (volatile pcfg8220_t *) MMAP_PCFG;
 101
 102        win0 = (u32) CONFIG_PCI_MEM_PHYS;
 103        win1 = (u32) CONFIG_PCI_IO_PHYS;
 104        win2 = (u32) CONFIG_PCI_CFG_PHYS;
 105
 106        /* Assert PCI reset */
 107        out_be32 (&xcpci->glb_stat_ctl, PCI_GLB_STAT_CTRL_PR);
 108
 109        /* Disable prefetching but read-multiples will still prefetch */
 110        out_be32 (&xcpci->target_ctrl, 0x00000000);
 111
 112        /* Initiator windows */
 113        out_be32 (&xcpci->init_win0,  (win0 >> 16) | win0 | 0x003f0000);
 114        out_be32 (&xcpci->init_win1, ((win1 >> 16) | win1 ));
 115        out_be32 (&xcpci->init_win2, ((win2 >> 16) | win2 ));
 116
 117        out_be32 (&xcpci->init_win_cfg,
 118                PCI_INIT_WIN_CFG_WIN0_CTRL_EN |
 119                PCI_INIT_WIN_CFG_WIN1_CTRL_EN | PCI_INIT_WIN_CFG_WIN1_CTRL_IO |
 120                PCI_INIT_WIN_CFG_WIN2_CTRL_EN | PCI_INIT_WIN_CFG_WIN2_CTRL_IO);
 121
 122        out_be32 (&xcpci->init_ctrl, 0x00000000);
 123
 124        /* Enable bus master and mem access */
 125        out_be32 (&xcpci->stat_cmd_reg, PCI_STAT_CMD_B | PCI_STAT_CMD_M);
 126
 127        /* Cache line size and master latency */
 128        out_be32 (&xcpci->bist_htyp_lat_cshl, (0xf8 << PCI_CFG1_LT_SHIFT));
 129
 130        out_be32 (&xcpci->base0, PCI_BASE_ADDR_REG0); /* 256MB - MBAR space */
 131        out_be32 (&xcpci->base1, PCI_BASE_ADDR_REG1); /* 1GB - SDRAM space */
 132
 133        out_be32 (&xcpci->target_bar0,
 134                PCI_TARGET_BASE_ADDR_REG0 | PCI_TARGET_BASE_ADDR_EN);
 135        out_be32 (&xcpci->target_bar1,
 136                PCI_TARGET_BASE_ADDR_REG1 | PCI_TARGET_BASE_ADDR_EN);
 137
 138        /* Deassert reset bit */
 139        out_be32 (&xcpci->glb_stat_ctl, 0x00000000);
 140
 141        /* Enable PCI bus master support */
 142        /* Set PCIGNT1, PCIREQ1, PCIREQ0/PCIGNTIN, PCIGNT0/PCIREQOUT,
 143               PCIREQ2, PCIGNT2 */
 144        out_be32((volatile u32 *)&portcfg->pcfg3,
 145                (in_be32((volatile u32 *)&portcfg->pcfg3) & 0xFC3FCE7F));
 146        out_be32((volatile u32 *)&portcfg->pcfg3,
 147                (in_be32((volatile u32 *)&portcfg->pcfg3) | 0x01400180));
 148
 149        hose->first_busno = 0;
 150        hose->last_busno = 0xff;
 151
 152        pci_set_region(hose->regions + 0,
 153                CONFIG_PCI_MEM_BUS,
 154                CONFIG_PCI_MEM_PHYS,
 155                CONFIG_PCI_MEM_SIZE,
 156                PCI_REGION_MEM);
 157
 158        pci_set_region(hose->regions + 1,
 159                CONFIG_PCI_IO_BUS,
 160                CONFIG_PCI_IO_PHYS,
 161                CONFIG_PCI_IO_SIZE,
 162                PCI_REGION_IO);
 163
 164        pci_set_region(hose->regions + 2,
 165                CONFIG_PCI_SYS_MEM_BUS,
 166                CONFIG_PCI_SYS_MEM_PHYS,
 167                CONFIG_PCI_SYS_MEM_SIZE,
 168                PCI_REGION_MEM | PCI_REGION_MEMORY);
 169
 170        hose->region_count = 3;
 171
 172        hose->cfg_addr = &(xcpci->cfg_adr);
 173        hose->cfg_data = (volatile unsigned char *)CONFIG_PCI_CFG_BUS;
 174
 175        pci_set_ops(hose,
 176                mpc8220_pci_read_config_byte,
 177                mpc8220_pci_read_config_word,
 178                mpc8220_pci_read_config_dword,
 179                mpc8220_pci_write_config_byte,
 180                mpc8220_pci_write_config_word,
 181                mpc8220_pci_write_config_dword);
 182
 183        /* Hose scan */
 184        pci_register_hose(hose);
 185        hose->last_busno = pci_hose_scan(hose);
 186
 187        out_be32 (&xcpci->base0, PCI_BASE_ADDR_REG0); /* 256MB - MBAR space */
 188        out_be32 (&xcpci->base1, PCI_BASE_ADDR_REG1); /* 1GB - SDRAM space */
 189}
 190
 191#endif /* CONFIG_PCI */
 192