ia64/linux-2.6.18-xen.hg

annotate arch/mips/pci/pci-bcm1480ht.c @ 912:dd42cdb0ab89

[IA64] Build blktap2 driver by default in x86 builds.

add CONFIG_XEN_BLKDEV_TAP2=y to buildconfigs/linux-defconfig_xen_ia64.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 12:09:16 2009 +0900 (2009-06-29)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * Copyright (C) 2001,2002,2005 Broadcom Corporation
ian@0 3 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
ian@0 4 *
ian@0 5 * This program is free software; you can redistribute it and/or
ian@0 6 * modify it under the terms of the GNU General Public License
ian@0 7 * as published by the Free Software Foundation; either version 2
ian@0 8 * of the License, or (at your option) any later version.
ian@0 9 *
ian@0 10 * This program is distributed in the hope that it will be useful,
ian@0 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ian@0 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ian@0 13 * GNU General Public License for more details.
ian@0 14 *
ian@0 15 * You should have received a copy of the GNU General Public License
ian@0 16 * along with this program; if not, write to the Free Software
ian@0 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
ian@0 18 */
ian@0 19
ian@0 20 /*
ian@0 21 * BCM1480/1455-specific HT support (looking like PCI)
ian@0 22 *
ian@0 23 * This module provides the glue between Linux's PCI subsystem
ian@0 24 * and the hardware. We basically provide glue for accessing
ian@0 25 * configuration space, and set up the translation for I/O
ian@0 26 * space accesses.
ian@0 27 *
ian@0 28 * To access configuration space, we use ioremap. In the 32-bit
ian@0 29 * kernel, this consumes either 4 or 8 page table pages, and 16MB of
ian@0 30 * kernel mapped memory. Hopefully neither of these should be a huge
ian@0 31 * problem.
ian@0 32 *
ian@0 33 */
ian@0 34 #include <linux/types.h>
ian@0 35 #include <linux/pci.h>
ian@0 36 #include <linux/kernel.h>
ian@0 37 #include <linux/init.h>
ian@0 38 #include <linux/mm.h>
ian@0 39 #include <linux/console.h>
ian@0 40 #include <linux/tty.h>
ian@0 41
ian@0 42 #include <asm/sibyte/bcm1480_regs.h>
ian@0 43 #include <asm/sibyte/bcm1480_scd.h>
ian@0 44 #include <asm/sibyte/board.h>
ian@0 45 #include <asm/io.h>
ian@0 46
ian@0 47 /*
ian@0 48 * Macros for calculating offsets into config space given a device
ian@0 49 * structure or dev/fun/reg
ian@0 50 */
ian@0 51 #define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
ian@0 52 #define CFGADDR(bus,devfn,where) CFGOFFSET((bus)->number,(devfn),where)
ian@0 53
ian@0 54 static void *ht_cfg_space;
ian@0 55
ian@0 56 #define PCI_BUS_ENABLED 1
ian@0 57 #define PCI_DEVICE_MODE 2
ian@0 58
ian@0 59 static int bcm1480ht_bus_status = 0;
ian@0 60
ian@0 61 #define PCI_BRIDGE_DEVICE 0
ian@0 62 #define HT_BRIDGE_DEVICE 1
ian@0 63
ian@0 64 /*
ian@0 65 * HT's level-sensitive interrupts require EOI, which is generated
ian@0 66 * through a 4MB memory-mapped region
ian@0 67 */
ian@0 68 unsigned long ht_eoi_space;
ian@0 69
ian@0 70 /*
ian@0 71 * Read/write 32-bit values in config space.
ian@0 72 */
ian@0 73 static inline u32 READCFG32(u32 addr)
ian@0 74 {
ian@0 75 return *(u32 *)(ht_cfg_space + (addr&~3));
ian@0 76 }
ian@0 77
ian@0 78 static inline void WRITECFG32(u32 addr, u32 data)
ian@0 79 {
ian@0 80 *(u32 *)(ht_cfg_space + (addr & ~3)) = data;
ian@0 81 }
ian@0 82
ian@0 83 /*
ian@0 84 * Some checks before doing config cycles:
ian@0 85 * In PCI Device Mode, hide everything on bus 0 except the LDT host
ian@0 86 * bridge. Otherwise, access is controlled by bridge MasterEn bits.
ian@0 87 */
ian@0 88 static int bcm1480ht_can_access(struct pci_bus *bus, int devfn)
ian@0 89 {
ian@0 90 u32 devno;
ian@0 91
ian@0 92 if (!(bcm1480ht_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
ian@0 93 return 0;
ian@0 94
ian@0 95 if (bus->number == 0) {
ian@0 96 devno = PCI_SLOT(devfn);
ian@0 97 if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
ian@0 98 return 0;
ian@0 99 }
ian@0 100 return 1;
ian@0 101 }
ian@0 102
ian@0 103 /*
ian@0 104 * Read/write access functions for various sizes of values
ian@0 105 * in config space. Return all 1's for disallowed accesses
ian@0 106 * for a kludgy but adequate simulation of master aborts.
ian@0 107 */
ian@0 108
ian@0 109 static int bcm1480ht_pcibios_read(struct pci_bus *bus, unsigned int devfn,
ian@0 110 int where, int size, u32 * val)
ian@0 111 {
ian@0 112 u32 data = 0;
ian@0 113
ian@0 114 if ((size == 2) && (where & 1))
ian@0 115 return PCIBIOS_BAD_REGISTER_NUMBER;
ian@0 116 else if ((size == 4) && (where & 3))
ian@0 117 return PCIBIOS_BAD_REGISTER_NUMBER;
ian@0 118
ian@0 119 if (bcm1480ht_can_access(bus, devfn))
ian@0 120 data = READCFG32(CFGADDR(bus, devfn, where));
ian@0 121 else
ian@0 122 data = 0xFFFFFFFF;
ian@0 123
ian@0 124 if (size == 1)
ian@0 125 *val = (data >> ((where & 3) << 3)) & 0xff;
ian@0 126 else if (size == 2)
ian@0 127 *val = (data >> ((where & 3) << 3)) & 0xffff;
ian@0 128 else
ian@0 129 *val = data;
ian@0 130
ian@0 131 return PCIBIOS_SUCCESSFUL;
ian@0 132 }
ian@0 133
ian@0 134 static int bcm1480ht_pcibios_write(struct pci_bus *bus, unsigned int devfn,
ian@0 135 int where, int size, u32 val)
ian@0 136 {
ian@0 137 u32 cfgaddr = CFGADDR(bus, devfn, where);
ian@0 138 u32 data = 0;
ian@0 139
ian@0 140 if ((size == 2) && (where & 1))
ian@0 141 return PCIBIOS_BAD_REGISTER_NUMBER;
ian@0 142 else if ((size == 4) && (where & 3))
ian@0 143 return PCIBIOS_BAD_REGISTER_NUMBER;
ian@0 144
ian@0 145 if (!bcm1480ht_can_access(bus, devfn))
ian@0 146 return PCIBIOS_BAD_REGISTER_NUMBER;
ian@0 147
ian@0 148 data = READCFG32(cfgaddr);
ian@0 149
ian@0 150 if (size == 1)
ian@0 151 data = (data & ~(0xff << ((where & 3) << 3))) |
ian@0 152 (val << ((where & 3) << 3));
ian@0 153 else if (size == 2)
ian@0 154 data = (data & ~(0xffff << ((where & 3) << 3))) |
ian@0 155 (val << ((where & 3) << 3));
ian@0 156 else
ian@0 157 data = val;
ian@0 158
ian@0 159 WRITECFG32(cfgaddr, data);
ian@0 160
ian@0 161 return PCIBIOS_SUCCESSFUL;
ian@0 162 }
ian@0 163
ian@0 164 static int bcm1480ht_pcibios_get_busno(void)
ian@0 165 {
ian@0 166 return 0;
ian@0 167 }
ian@0 168
ian@0 169 struct pci_ops bcm1480ht_pci_ops = {
ian@0 170 .read = bcm1480ht_pcibios_read,
ian@0 171 .write = bcm1480ht_pcibios_write,
ian@0 172 };
ian@0 173
ian@0 174 static struct resource bcm1480ht_mem_resource = {
ian@0 175 .name = "BCM1480 HT MEM",
ian@0 176 .start = 0x40000000UL,
ian@0 177 .end = 0x5fffffffUL,
ian@0 178 .flags = IORESOURCE_MEM,
ian@0 179 };
ian@0 180
ian@0 181 static struct resource bcm1480ht_io_resource = {
ian@0 182 .name = "BCM1480 HT I/O",
ian@0 183 .start = 0x00000000UL,
ian@0 184 .end = 0x01ffffffUL,
ian@0 185 .flags = IORESOURCE_IO,
ian@0 186 };
ian@0 187
ian@0 188 struct pci_controller bcm1480ht_controller = {
ian@0 189 .pci_ops = &bcm1480ht_pci_ops,
ian@0 190 .mem_resource = &bcm1480ht_mem_resource,
ian@0 191 .io_resource = &bcm1480ht_io_resource,
ian@0 192 .index = 1,
ian@0 193 .get_busno = bcm1480ht_pcibios_get_busno,
ian@0 194 };
ian@0 195
ian@0 196 static int __init bcm1480ht_pcibios_init(void)
ian@0 197 {
ian@0 198 uint32_t cmdreg;
ian@0 199
ian@0 200 ht_cfg_space = ioremap(A_BCM1480_PHYS_HT_CFG_MATCH_BITS, 16*1024*1024);
ian@0 201
ian@0 202 /*
ian@0 203 * See if the PCI bus has been configured by the firmware.
ian@0 204 */
ian@0 205 cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
ian@0 206 PCI_COMMAND));
ian@0 207 if (!(cmdreg & PCI_COMMAND_MASTER)) {
ian@0 208 printk("HT: Skipping HT probe. Bus is not initialized.\n");
ian@0 209 iounmap(ht_cfg_space);
ian@0 210 return 1; /* XXX */
ian@0 211 }
ian@0 212 bcm1480ht_bus_status |= PCI_BUS_ENABLED;
ian@0 213
ian@0 214 ht_eoi_space = (unsigned long)
ian@0 215 ioremap(A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES,
ian@0 216 4 * 1024 * 1024);
ian@0 217
ian@0 218 register_pci_controller(&bcm1480ht_controller);
ian@0 219
ian@0 220 return 0;
ian@0 221 }
ian@0 222
ian@0 223 arch_initcall(bcm1480ht_pcibios_init);