uboot/drivers/pci/pci_sh7751.c
<<
>>
Prefs
   1/*
   2 * SH7751 PCI Controller (PCIC) for U-Boot.
   3 * (C) Dustin McIntire (dustin@sensoria.com)
   4 * (C) 2007,2008 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
   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#include <common.h>
  26#include <pci.h>
  27#include <asm/processor.h>
  28#include <asm/io.h>
  29#include <asm/pci.h>
  30
  31/* Register addresses and such */
  32#define SH7751_BCR1     (vu_long *)0xFF800000
  33#define SH7751_BCR2     (vu_short *)0xFF800004
  34#define SH7751_WCR1     (vu_long *)0xFF800008
  35#define SH7751_WCR2     (vu_long *)0xFF80000C
  36#define SH7751_WCR3     (vu_long *)0xFF800010
  37#define SH7751_MCR      (vu_long *)0xFF800014
  38#define SH7751_BCR3     (vu_short *)0xFF800050
  39#define SH7751_PCICONF0 (vu_long *)0xFE200000
  40#define SH7751_PCICONF1 (vu_long *)0xFE200004
  41#define SH7751_PCICONF2 (vu_long *)0xFE200008
  42#define SH7751_PCICONF3 (vu_long *)0xFE20000C
  43#define SH7751_PCICONF4 (vu_long *)0xFE200010
  44#define SH7751_PCICONF5 (vu_long *)0xFE200014
  45#define SH7751_PCICONF6 (vu_long *)0xFE200018
  46#define SH7751_PCICR    (vu_long *)0xFE200100
  47#define SH7751_PCILSR0  (vu_long *)0xFE200104
  48#define SH7751_PCILSR1  (vu_long *)0xFE200108
  49#define SH7751_PCILAR0  (vu_long *)0xFE20010C
  50#define SH7751_PCILAR1  (vu_long *)0xFE200110
  51#define SH7751_PCIMBR   (vu_long *)0xFE2001C4
  52#define SH7751_PCIIOBR  (vu_long *)0xFE2001C8
  53#define SH7751_PCIPINT  (vu_long *)0xFE2001CC
  54#define SH7751_PCIPINTM (vu_long *)0xFE2001D0
  55#define SH7751_PCICLKR  (vu_long *)0xFE2001D4
  56#define SH7751_PCIBCR1  (vu_long *)0xFE2001E0
  57#define SH7751_PCIBCR2  (vu_long *)0xFE2001E4
  58#define SH7751_PCIWCR1  (vu_long *)0xFE2001E8
  59#define SH7751_PCIWCR2  (vu_long *)0xFE2001EC
  60#define SH7751_PCIWCR3  (vu_long *)0xFE2001F0
  61#define SH7751_PCIMCR   (vu_long *)0xFE2001F4
  62#define SH7751_PCIBCR3  (vu_long *)0xFE2001F8
  63
  64#define BCR1_BREQEN                             0x00080000
  65#define PCI_SH7751_ID                   0x35051054
  66#define PCI_SH7751R_ID                  0x350E1054
  67#define SH7751_PCICONF1_WCC             0x00000080
  68#define SH7751_PCICONF1_PER             0x00000040
  69#define SH7751_PCICONF1_BUM             0x00000004
  70#define SH7751_PCICONF1_MES             0x00000002
  71#define SH7751_PCICONF1_CMDS    0x000000C6
  72#define SH7751_PCI_HOST_BRIDGE  0x6
  73#define SH7751_PCICR_PREFIX             0xa5000000
  74#define SH7751_PCICR_PRST               0x00000002
  75#define SH7751_PCICR_CFIN               0x00000001
  76#define SH7751_PCIPINT_D3               0x00000002
  77#define SH7751_PCIPINT_D0               0x00000001
  78#define SH7751_PCICLKR_PREFIX   0xa5000000
  79
  80#define SH7751_PCI_MEM_BASE             0xFD000000
  81#define SH7751_PCI_MEM_SIZE             0x01000000
  82#define SH7751_PCI_IO_BASE              0xFE240000
  83#define SH7751_PCI_IO_SIZE              0x00040000
  84
  85#define SH7751_CS3_BASE_ADDR    0x0C000000
  86#define SH7751_P2CS3_BASE_ADDR  0xAC000000
  87
  88#define SH7751_PCIPAR   (vu_long *)0xFE2001C0
  89#define SH7751_PCIPDR   (vu_long *)0xFE200220
  90
  91#define p4_in(addr)     (*addr)
  92#define p4_out(data, addr) (*addr) = (data)
  93
  94/* Double word */
  95int pci_sh4_read_config_dword(struct pci_controller *hose,
  96                              pci_dev_t dev, int offset, u32 *value)
  97{
  98        u32 par_data = 0x80000000 | dev;
  99
 100        p4_out(par_data | (offset & 0xfc), SH7751_PCIPAR);
 101        *value = p4_in(SH7751_PCIPDR);
 102
 103        return 0;
 104}
 105
 106int pci_sh4_write_config_dword(struct pci_controller *hose,
 107                               pci_dev_t dev, int offset, u32 value)
 108{
 109        u32 par_data = 0x80000000 | dev;
 110
 111        p4_out(par_data | (offset & 0xfc), SH7751_PCIPAR);
 112        p4_out(value, SH7751_PCIPDR);
 113
 114        return 0;
 115}
 116
 117int pci_sh7751_init(struct pci_controller *hose)
 118{
 119        /* Double-check that we're a 7751 or 7751R chip */
 120        if (p4_in(SH7751_PCICONF0) != PCI_SH7751_ID
 121            && p4_in(SH7751_PCICONF0) != PCI_SH7751R_ID) {
 122                printf("PCI: Unknown PCI host bridge.\n");
 123                return 1;
 124        }
 125        printf("PCI: SH7751 PCI host bridge found.\n");
 126
 127        /* Double-check some BSC config settings */
 128        /* (Area 3 non-MPX 32-bit, PCI bus pins) */
 129        if ((p4_in(SH7751_BCR1) & 0x20008) == 0x20000) {
 130                printf("SH7751_BCR1 value is wrong(0x%08X)\n",
 131                        (unsigned int)p4_in(SH7751_BCR1));
 132                return 2;
 133        }
 134        if ((p4_in(SH7751_BCR2) & 0xC0) != 0xC0) {
 135                printf("SH7751_BCR2 value is wrong(0x%08X)\n",
 136                        (unsigned int)p4_in(SH7751_BCR2));
 137                return 3;
 138        }
 139        if (p4_in(SH7751_BCR2) & 0x01) {
 140                printf("SH7751_BCR2 value is wrong(0x%08X)\n",
 141                        (unsigned int)p4_in(SH7751_BCR2));
 142                return 4;
 143        }
 144
 145        /* Force BREQEN in BCR1 to allow PCIC access */
 146        p4_out((p4_in(SH7751_BCR1) | BCR1_BREQEN), SH7751_BCR1);
 147
 148        /* Toggle PCI reset pin */
 149        p4_out((SH7751_PCICR_PREFIX | SH7751_PCICR_PRST), SH7751_PCICR);
 150        udelay(32);
 151        p4_out(SH7751_PCICR_PREFIX, SH7751_PCICR);
 152
 153        /* Set cmd bits: WCC, PER, BUM, MES */
 154        /* (Addr/Data stepping, Parity enabled, Bus Master, Memory enabled) */
 155        p4_out(0xfb900047, SH7751_PCICONF1);    /* K.Kino */
 156
 157        /* Define this host as the host bridge */
 158        p4_out((SH7751_PCI_HOST_BRIDGE << 24), SH7751_PCICONF2);
 159
 160        /* Force PCI clock(s) on */
 161        p4_out(0, SH7751_PCICLKR);
 162        p4_out(0x03, SH7751_PCICLKR);
 163
 164        /* Clear powerdown IRQs, also mask them (unused) */
 165        p4_out((SH7751_PCIPINT_D0 | SH7751_PCIPINT_D3), SH7751_PCIPINT);
 166        p4_out(0, SH7751_PCIPINTM);
 167
 168        p4_out(0xab000001, SH7751_PCICONF4);
 169
 170        /* Set up target memory mappings (for external DMA access) */
 171        /* Map both P0 and P2 range to Area 3 RAM for ease of use */
 172        p4_out((64 - 1) << 20, SH7751_PCILSR0);
 173        p4_out(SH7751_CS3_BASE_ADDR, SH7751_PCILAR0);
 174        p4_out(0, SH7751_PCILSR1);
 175        p4_out(0, SH7751_PCILAR1);
 176        p4_out(SH7751_CS3_BASE_ADDR, SH7751_PCICONF5);
 177        p4_out(0xd0000000, SH7751_PCICONF6);
 178
 179        /* Map memory window to same address on PCI bus */
 180        p4_out(SH7751_PCI_MEM_BASE, SH7751_PCIMBR);
 181
 182        /* Map IO window to same address on PCI bus */
 183        p4_out(0x2000 & 0xfffc0000, SH7751_PCIIOBR);
 184
 185        /* set BREQEN */
 186        p4_out(inl(SH7751_BCR1) | 0x00080000, SH7751_BCR1);
 187
 188        /* Copy BSC registers into PCI BSC */
 189        p4_out(inl(SH7751_BCR1), SH7751_PCIBCR1);
 190        p4_out(inw(SH7751_BCR2), SH7751_PCIBCR2);
 191        p4_out(inw(SH7751_BCR3), SH7751_PCIBCR3);
 192        p4_out(inl(SH7751_WCR1), SH7751_PCIWCR1);
 193        p4_out(inl(SH7751_WCR2), SH7751_PCIWCR2);
 194        p4_out(inl(SH7751_WCR3), SH7751_PCIWCR3);
 195        p4_out(inl(SH7751_MCR), SH7751_PCIMCR);
 196
 197        /* Finally, set central function init complete */
 198        p4_out((SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN), SH7751_PCICR);
 199
 200        pci_sh4_init(hose);
 201
 202        return 0;
 203}
 204