pci_sabre.c 20.5 KB
Newer Older
1
/* pci_sabre.c: Sabre specific PCI controller support.
L
Linus Torvalds 已提交
2
 *
3
 * Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net)
L
Linus Torvalds 已提交
4 5 6 7 8 9 10 11 12 13
 * Copyright (C) 1998, 1999 Eddie C. Dost   (ecd@skynet.be)
 * Copyright (C) 1999 Jakub Jelinek   (jakub@redhat.com)
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
14
#include <linux/of_device.h>
L
Linus Torvalds 已提交
15 16 17 18

#include <asm/apb.h>
#include <asm/iommu.h>
#include <asm/irq.h>
19
#include <asm/prom.h>
20
#include <asm/upa.h>
L
Linus Torvalds 已提交
21 22 23

#include "pci_impl.h"
#include "iommu_common.h"
24
#include "psycho_common.h"
L
Linus Torvalds 已提交
25

26 27 28
#define DRIVER_NAME	"sabre"
#define PFX		DRIVER_NAME ": "

L
Linus Torvalds 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
/* SABRE PCI controller register offsets and definitions. */
#define SABRE_UE_AFSR		0x0030UL
#define  SABRE_UEAFSR_PDRD	 0x4000000000000000UL	/* Primary PCI DMA Read */
#define  SABRE_UEAFSR_PDWR	 0x2000000000000000UL	/* Primary PCI DMA Write */
#define  SABRE_UEAFSR_SDRD	 0x0800000000000000UL	/* Secondary PCI DMA Read */
#define  SABRE_UEAFSR_SDWR	 0x0400000000000000UL	/* Secondary PCI DMA Write */
#define  SABRE_UEAFSR_SDTE	 0x0200000000000000UL	/* Secondary DMA Translation Error */
#define  SABRE_UEAFSR_PDTE	 0x0100000000000000UL	/* Primary DMA Translation Error */
#define  SABRE_UEAFSR_BMSK	 0x0000ffff00000000UL	/* Bytemask */
#define  SABRE_UEAFSR_OFF	 0x00000000e0000000UL	/* Offset (AFAR bits [5:3] */
#define  SABRE_UEAFSR_BLK	 0x0000000000800000UL	/* Was block operation */
#define SABRE_UECE_AFAR		0x0038UL
#define SABRE_CE_AFSR		0x0040UL
#define  SABRE_CEAFSR_PDRD	 0x4000000000000000UL	/* Primary PCI DMA Read */
#define  SABRE_CEAFSR_PDWR	 0x2000000000000000UL	/* Primary PCI DMA Write */
#define  SABRE_CEAFSR_SDRD	 0x0800000000000000UL	/* Secondary PCI DMA Read */
#define  SABRE_CEAFSR_SDWR	 0x0400000000000000UL	/* Secondary PCI DMA Write */
#define  SABRE_CEAFSR_ESYND	 0x00ff000000000000UL	/* ECC Syndrome */
#define  SABRE_CEAFSR_BMSK	 0x0000ffff00000000UL	/* Bytemask */
#define  SABRE_CEAFSR_OFF	 0x00000000e0000000UL	/* Offset */
#define  SABRE_CEAFSR_BLK	 0x0000000000800000UL	/* Was block operation */
#define SABRE_UECE_AFAR_ALIAS	0x0048UL	/* Aliases to 0x0038 */
#define SABRE_IOMMU_CONTROL	0x0200UL
#define  SABRE_IOMMUCTRL_ERRSTS	 0x0000000006000000UL	/* Error status bits */
#define  SABRE_IOMMUCTRL_ERR	 0x0000000001000000UL	/* Error present in IOTLB */
#define  SABRE_IOMMUCTRL_LCKEN	 0x0000000000800000UL	/* IOTLB lock enable */
#define  SABRE_IOMMUCTRL_LCKPTR	 0x0000000000780000UL	/* IOTLB lock pointer */
#define  SABRE_IOMMUCTRL_TSBSZ	 0x0000000000070000UL	/* TSB Size */
#define  SABRE_IOMMU_TSBSZ_1K   0x0000000000000000
#define  SABRE_IOMMU_TSBSZ_2K   0x0000000000010000
#define  SABRE_IOMMU_TSBSZ_4K   0x0000000000020000
#define  SABRE_IOMMU_TSBSZ_8K   0x0000000000030000
#define  SABRE_IOMMU_TSBSZ_16K  0x0000000000040000
#define  SABRE_IOMMU_TSBSZ_32K  0x0000000000050000
#define  SABRE_IOMMU_TSBSZ_64K  0x0000000000060000
#define  SABRE_IOMMU_TSBSZ_128K 0x0000000000070000
#define  SABRE_IOMMUCTRL_TBWSZ	 0x0000000000000004UL	/* TSB assumed page size */
#define  SABRE_IOMMUCTRL_DENAB	 0x0000000000000002UL	/* Diagnostic Mode Enable */
#define  SABRE_IOMMUCTRL_ENAB	 0x0000000000000001UL	/* IOMMU Enable */
#define SABRE_IOMMU_TSBBASE	0x0208UL
#define SABRE_IOMMU_FLUSH	0x0210UL
#define SABRE_IMAP_A_SLOT0	0x0c00UL
#define SABRE_IMAP_B_SLOT0	0x0c20UL
#define SABRE_IMAP_SCSI		0x1000UL
#define SABRE_IMAP_ETH		0x1008UL
#define SABRE_IMAP_BPP		0x1010UL
#define SABRE_IMAP_AU_REC	0x1018UL
#define SABRE_IMAP_AU_PLAY	0x1020UL
#define SABRE_IMAP_PFAIL	0x1028UL
#define SABRE_IMAP_KMS		0x1030UL
#define SABRE_IMAP_FLPY		0x1038UL
#define SABRE_IMAP_SHW		0x1040UL
#define SABRE_IMAP_KBD		0x1048UL
#define SABRE_IMAP_MS		0x1050UL
#define SABRE_IMAP_SER		0x1058UL
#define SABRE_IMAP_UE		0x1070UL
#define SABRE_IMAP_CE		0x1078UL
#define SABRE_IMAP_PCIERR	0x1080UL
#define SABRE_IMAP_GFX		0x1098UL
#define SABRE_IMAP_EUPA		0x10a0UL
#define SABRE_ICLR_A_SLOT0	0x1400UL
#define SABRE_ICLR_B_SLOT0	0x1480UL
#define SABRE_ICLR_SCSI		0x1800UL
#define SABRE_ICLR_ETH		0x1808UL
#define SABRE_ICLR_BPP		0x1810UL
#define SABRE_ICLR_AU_REC	0x1818UL
#define SABRE_ICLR_AU_PLAY	0x1820UL
#define SABRE_ICLR_PFAIL	0x1828UL
#define SABRE_ICLR_KMS		0x1830UL
#define SABRE_ICLR_FLPY		0x1838UL
#define SABRE_ICLR_SHW		0x1840UL
#define SABRE_ICLR_KBD		0x1848UL
#define SABRE_ICLR_MS		0x1850UL
#define SABRE_ICLR_SER		0x1858UL
#define SABRE_ICLR_UE		0x1870UL
#define SABRE_ICLR_CE		0x1878UL
#define SABRE_ICLR_PCIERR	0x1880UL
#define SABRE_WRSYNC		0x1c20UL
#define SABRE_PCICTRL		0x2000UL
#define  SABRE_PCICTRL_MRLEN	 0x0000001000000000UL	/* Use MemoryReadLine for block loads/stores */
#define  SABRE_PCICTRL_SERR	 0x0000000400000000UL	/* Set when SERR asserted on PCI bus */
#define  SABRE_PCICTRL_ARBPARK	 0x0000000000200000UL	/* Bus Parking 0=Ultra-IIi 1=prev-bus-owner */
#define  SABRE_PCICTRL_CPUPRIO	 0x0000000000100000UL	/* Ultra-IIi granted every other bus cycle */
#define  SABRE_PCICTRL_ARBPRIO	 0x00000000000f0000UL	/* Slot which is granted every other bus cycle */
#define  SABRE_PCICTRL_ERREN	 0x0000000000000100UL	/* PCI Error Interrupt Enable */
#define  SABRE_PCICTRL_RTRYWE	 0x0000000000000080UL	/* DMA Flow Control 0=wait-if-possible 1=retry */
#define  SABRE_PCICTRL_AEN	 0x000000000000000fUL	/* Slot PCI arbitration enables */
#define SABRE_PIOAFSR		0x2010UL
#define  SABRE_PIOAFSR_PMA	 0x8000000000000000UL	/* Primary Master Abort */
#define  SABRE_PIOAFSR_PTA	 0x4000000000000000UL	/* Primary Target Abort */
#define  SABRE_PIOAFSR_PRTRY	 0x2000000000000000UL	/* Primary Excessive Retries */
#define  SABRE_PIOAFSR_PPERR	 0x1000000000000000UL	/* Primary Parity Error */
#define  SABRE_PIOAFSR_SMA	 0x0800000000000000UL	/* Secondary Master Abort */
#define  SABRE_PIOAFSR_STA	 0x0400000000000000UL	/* Secondary Target Abort */
#define  SABRE_PIOAFSR_SRTRY	 0x0200000000000000UL	/* Secondary Excessive Retries */
#define  SABRE_PIOAFSR_SPERR	 0x0100000000000000UL	/* Secondary Parity Error */
#define  SABRE_PIOAFSR_BMSK	 0x0000ffff00000000UL	/* Byte Mask */
#define  SABRE_PIOAFSR_BLK	 0x0000000080000000UL	/* Was Block Operation */
#define SABRE_PIOAFAR		0x2018UL
#define SABRE_PCIDIAG		0x2020UL
#define  SABRE_PCIDIAG_DRTRY	 0x0000000000000040UL	/* Disable PIO Retry Limit */
#define  SABRE_PCIDIAG_IPAPAR	 0x0000000000000008UL	/* Invert PIO Address Parity */
#define  SABRE_PCIDIAG_IPDPAR	 0x0000000000000004UL	/* Invert PIO Data Parity */
#define  SABRE_PCIDIAG_IDDPAR	 0x0000000000000002UL	/* Invert DMA Data Parity */
#define  SABRE_PCIDIAG_ELPBK	 0x0000000000000001UL	/* Loopback Enable - not supported */
#define SABRE_PCITASR		0x2028UL
#define  SABRE_PCITASR_EF	 0x0000000000000080UL	/* Respond to 0xe0000000-0xffffffff */
#define  SABRE_PCITASR_CD	 0x0000000000000040UL	/* Respond to 0xc0000000-0xdfffffff */
#define  SABRE_PCITASR_AB	 0x0000000000000020UL	/* Respond to 0xa0000000-0xbfffffff */
#define  SABRE_PCITASR_89	 0x0000000000000010UL	/* Respond to 0x80000000-0x9fffffff */
#define  SABRE_PCITASR_67	 0x0000000000000008UL	/* Respond to 0x60000000-0x7fffffff */
#define  SABRE_PCITASR_45	 0x0000000000000004UL	/* Respond to 0x40000000-0x5fffffff */
#define  SABRE_PCITASR_23	 0x0000000000000002UL	/* Respond to 0x20000000-0x3fffffff */
#define  SABRE_PCITASR_01	 0x0000000000000001UL	/* Respond to 0x00000000-0x1fffffff */
#define SABRE_PIOBUF_DIAG	0x5000UL
#define SABRE_DMABUF_DIAGLO	0x5100UL
#define SABRE_DMABUF_DIAGHI	0x51c0UL
#define SABRE_IMAP_GFX_ALIAS	0x6000UL	/* Aliases to 0x1098 */
#define SABRE_IMAP_EUPA_ALIAS	0x8000UL	/* Aliases to 0x10a0 */
#define SABRE_IOMMU_VADIAG	0xa400UL
#define SABRE_IOMMU_TCDIAG	0xa408UL
#define SABRE_IOMMU_TAG		0xa580UL
#define  SABRE_IOMMUTAG_ERRSTS	 0x0000000001800000UL	/* Error status bits */
#define  SABRE_IOMMUTAG_ERR	 0x0000000000400000UL	/* Error present */
#define  SABRE_IOMMUTAG_WRITE	 0x0000000000200000UL	/* Page is writable */
#define  SABRE_IOMMUTAG_STREAM	 0x0000000000100000UL	/* Streamable bit - unused */
#define  SABRE_IOMMUTAG_SIZE	 0x0000000000080000UL	/* 0=8k 1=16k */
#define  SABRE_IOMMUTAG_VPN	 0x000000000007ffffUL	/* Virtual Page Number [31:13] */
#define SABRE_IOMMU_DATA	0xa600UL
#define SABRE_IOMMUDATA_VALID	 0x0000000040000000UL	/* Valid */
#define SABRE_IOMMUDATA_USED	 0x0000000020000000UL	/* Used (for LRU algorithm) */
#define SABRE_IOMMUDATA_CACHE	 0x0000000010000000UL	/* Cacheable */
#define SABRE_IOMMUDATA_PPN	 0x00000000001fffffUL	/* Physical Page Number [33:13] */
#define SABRE_PCI_IRQSTATE	0xa800UL
#define SABRE_OBIO_IRQSTATE	0xa808UL
#define SABRE_FFBCFG		0xf000UL
#define  SABRE_FFBCFG_SPRQS	 0x000000000f000000	/* Slave P_RQST queue size */
#define  SABRE_FFBCFG_ONEREAD	 0x0000000000004000	/* Slave supports one outstanding read */
#define SABRE_MCCTRL0		0xf010UL
#define  SABRE_MCCTRL0_RENAB	 0x0000000080000000	/* Refresh Enable */
#define  SABRE_MCCTRL0_EENAB	 0x0000000010000000	/* Enable all ECC functions */
#define  SABRE_MCCTRL0_11BIT	 0x0000000000001000	/* Enable 11-bit column addressing */
#define  SABRE_MCCTRL0_DPP	 0x0000000000000f00	/* DIMM Pair Present Bits */
#define  SABRE_MCCTRL0_RINTVL	 0x00000000000000ff	/* Refresh Interval */
#define SABRE_MCCTRL1		0xf018UL
#define  SABRE_MCCTRL1_AMDC	 0x0000000038000000	/* Advance Memdata Clock */
#define  SABRE_MCCTRL1_ARDC	 0x0000000007000000	/* Advance DRAM Read Data Clock */
#define  SABRE_MCCTRL1_CSR	 0x0000000000e00000	/* CAS to RAS delay for CBR refresh */
#define  SABRE_MCCTRL1_CASRW	 0x00000000001c0000	/* CAS length for read/write */
#define  SABRE_MCCTRL1_RCD	 0x0000000000038000	/* RAS to CAS delay */
#define  SABRE_MCCTRL1_CP	 0x0000000000007000	/* CAS Precharge */
#define  SABRE_MCCTRL1_RP	 0x0000000000000e00	/* RAS Precharge */
#define  SABRE_MCCTRL1_RAS	 0x00000000000001c0	/* Length of RAS for refresh */
#define  SABRE_MCCTRL1_CASRW2	 0x0000000000000038	/* Must be same as CASRW */
#define  SABRE_MCCTRL1_RSC	 0x0000000000000007	/* RAS after CAS hold time */
#define SABRE_RESETCTRL		0xf020UL

#define SABRE_CONFIGSPACE	0x001000000UL
#define SABRE_IOSPACE		0x002000000UL
#define SABRE_IOSPACE_SIZE	0x000ffffffUL
#define SABRE_MEMSPACE		0x100000000UL
#define SABRE_MEMSPACE_SIZE	0x07fffffffUL

static int hummingbird_p;
static struct pci_bus *sabre_root_bus;

A
Al Viro 已提交
195
static irqreturn_t sabre_ue_intr(int irq, void *dev_id)
L
Linus Torvalds 已提交
196
{
197 198 199
	struct pci_pbm_info *pbm = dev_id;
	unsigned long afsr_reg = pbm->controller_regs + SABRE_UE_AFSR;
	unsigned long afar_reg = pbm->controller_regs + SABRE_UECE_AFAR;
L
Linus Torvalds 已提交
200 201 202 203
	unsigned long afsr, afar, error_bits;
	int reported;

	/* Latch uncorrectable error status. */
204 205
	afar = upa_readq(afar_reg);
	afsr = upa_readq(afsr_reg);
L
Linus Torvalds 已提交
206 207 208 209 210 211 212 213

	/* Clear the primary/secondary error status bits. */
	error_bits = afsr &
		(SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
		 SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
		 SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE);
	if (!error_bits)
		return IRQ_NONE;
214
	upa_writeq(error_bits, afsr_reg);
L
Linus Torvalds 已提交
215 216

	/* Log the error. */
217 218
	printk("%s: Uncorrectable Error, primary error type[%s%s]\n",
	       pbm->name,
L
Linus Torvalds 已提交
219 220 221 222 223 224
	       ((error_bits & SABRE_UEAFSR_PDRD) ?
		"DMA Read" :
		((error_bits & SABRE_UEAFSR_PDWR) ?
		 "DMA Write" : "???")),
	       ((error_bits & SABRE_UEAFSR_PDTE) ?
		":Translation Error" : ""));
225 226
	printk("%s: bytemask[%04lx] dword_offset[%lx] was_block(%d)\n",
	       pbm->name,
L
Linus Torvalds 已提交
227 228 229
	       (afsr & SABRE_UEAFSR_BMSK) >> 32UL,
	       (afsr & SABRE_UEAFSR_OFF) >> 29UL,
	       ((afsr & SABRE_UEAFSR_BLK) ? 1 : 0));
230 231
	printk("%s: UE AFAR [%016lx]\n", pbm->name, afar);
	printk("%s: UE Secondary errors [", pbm->name);
L
Linus Torvalds 已提交
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
	reported = 0;
	if (afsr & SABRE_UEAFSR_SDRD) {
		reported++;
		printk("(DMA Read)");
	}
	if (afsr & SABRE_UEAFSR_SDWR) {
		reported++;
		printk("(DMA Write)");
	}
	if (afsr & SABRE_UEAFSR_SDTE) {
		reported++;
		printk("(Translation Error)");
	}
	if (!reported)
		printk("(none)");
	printk("]\n");

	/* Interrogate IOMMU for error status. */
250
	psycho_check_iommu_error(pbm, afsr, afar, UE_ERR);
L
Linus Torvalds 已提交
251 252 253 254

	return IRQ_HANDLED;
}

A
Al Viro 已提交
255
static irqreturn_t sabre_ce_intr(int irq, void *dev_id)
L
Linus Torvalds 已提交
256
{
257 258 259
	struct pci_pbm_info *pbm = dev_id;
	unsigned long afsr_reg = pbm->controller_regs + SABRE_CE_AFSR;
	unsigned long afar_reg = pbm->controller_regs + SABRE_UECE_AFAR;
L
Linus Torvalds 已提交
260 261 262 263
	unsigned long afsr, afar, error_bits;
	int reported;

	/* Latch error status. */
264 265
	afar = upa_readq(afar_reg);
	afsr = upa_readq(afsr_reg);
L
Linus Torvalds 已提交
266 267 268 269 270 271 272

	/* Clear primary/secondary error status bits. */
	error_bits = afsr &
		(SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
		 SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR);
	if (!error_bits)
		return IRQ_NONE;
273
	upa_writeq(error_bits, afsr_reg);
L
Linus Torvalds 已提交
274 275

	/* Log the error. */
276 277
	printk("%s: Correctable Error, primary error type[%s]\n",
	       pbm->name,
L
Linus Torvalds 已提交
278 279 280 281 282 283 284 285
	       ((error_bits & SABRE_CEAFSR_PDRD) ?
		"DMA Read" :
		((error_bits & SABRE_CEAFSR_PDWR) ?
		 "DMA Write" : "???")));

	/* XXX Use syndrome and afar to print out module string just like
	 * XXX UDB CE trap handler does... -DaveM
	 */
286
	printk("%s: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] "
L
Linus Torvalds 已提交
287
	       "was_block(%d)\n",
288
	       pbm->name,
L
Linus Torvalds 已提交
289 290 291 292
	       (afsr & SABRE_CEAFSR_ESYND) >> 48UL,
	       (afsr & SABRE_CEAFSR_BMSK) >> 32UL,
	       (afsr & SABRE_CEAFSR_OFF) >> 29UL,
	       ((afsr & SABRE_CEAFSR_BLK) ? 1 : 0));
293 294
	printk("%s: CE AFAR [%016lx]\n", pbm->name, afar);
	printk("%s: CE Secondary errors [", pbm->name);
L
Linus Torvalds 已提交
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
	reported = 0;
	if (afsr & SABRE_CEAFSR_SDRD) {
		reported++;
		printk("(DMA Read)");
	}
	if (afsr & SABRE_CEAFSR_SDWR) {
		reported++;
		printk("(DMA Write)");
	}
	if (!reported)
		printk("(none)");
	printk("]\n");

	return IRQ_HANDLED;
}

311
static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
L
Linus Torvalds 已提交
312
{
313
	struct device_node *dp = pbm->op->dev.of_node;
314
	struct platform_device *op;
L
Linus Torvalds 已提交
315 316
	unsigned long base = pbm->controller_regs;
	u64 tmp;
317
	int err;
L
Linus Torvalds 已提交
318

319 320 321 322 323 324 325 326 327 328 329 330 331
	if (pbm->chip_type == PBM_CHIP_TYPE_SABRE)
		dp = dp->parent;

	op = of_find_device_by_node(dp);
	if (!op)
		return;

	/* Sabre/Hummingbird IRQ property layout is:
	 * 0: PCI ERR
	 * 1: UE ERR
	 * 2: CE ERR
	 * 3: POWER FAIL
	 */
332
	if (op->archdata.num_irqs < 4)
333 334
		return;

L
Linus Torvalds 已提交
335 336 337 338
	/* We clear the error bits in the appropriate AFSR before
	 * registering the handler so that we don't get spurious
	 * interrupts.
	 */
339 340 341 342
	upa_writeq((SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
		    SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
		    SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE),
		   base + SABRE_UE_AFSR);
343

344
	err = request_irq(op->archdata.irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm);
345 346 347
	if (err)
		printk(KERN_WARNING "%s: Couldn't register UE, err=%d.\n",
		       pbm->name, err);
L
Linus Torvalds 已提交
348

349 350 351 352
	upa_writeq((SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
		    SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR),
		   base + SABRE_CE_AFSR);

L
Linus Torvalds 已提交
353

354
	err = request_irq(op->archdata.irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm);
355 356 357
	if (err)
		printk(KERN_WARNING "%s: Couldn't register CE, err=%d.\n",
		       pbm->name, err);
358
	err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, 0,
359 360 361 362
			  "SABRE_PCIERR", pbm);
	if (err)
		printk(KERN_WARNING "%s: Couldn't register PCIERR, err=%d.\n",
		       pbm->name, err);
L
Linus Torvalds 已提交
363

364
	tmp = upa_readq(base + SABRE_PCICTRL);
L
Linus Torvalds 已提交
365
	tmp |= SABRE_PCICTRL_ERREN;
366
	upa_writeq(tmp, base + SABRE_PCICTRL);
L
Linus Torvalds 已提交
367 368
}

369
static void apb_init(struct pci_bus *sabre_bus)
L
Linus Torvalds 已提交
370 371 372 373 374 375 376 377
{
	struct pci_dev *pdev;

	list_for_each_entry(pdev, &sabre_bus->devices, bus_list) {
		if (pdev->vendor == PCI_VENDOR_ID_SUN &&
		    pdev->device == PCI_DEVICE_ID_SUN_SIMBA) {
			u16 word16;

378
			pci_read_config_word(pdev, PCI_COMMAND, &word16);
L
Linus Torvalds 已提交
379 380 381
			word16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
				PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
				PCI_COMMAND_IO;
382
			pci_write_config_word(pdev, PCI_COMMAND, word16);
L
Linus Torvalds 已提交
383 384

			/* Status register bits are "write 1 to clear". */
385 386
			pci_write_config_word(pdev, PCI_STATUS, 0xffff);
			pci_write_config_word(pdev, PCI_SEC_STATUS, 0xffff);
L
Linus Torvalds 已提交
387 388 389 390

			/* Use a primary/seconday latency timer value
			 * of 64.
			 */
391 392
			pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
			pci_write_config_byte(pdev, PCI_SEC_LATENCY_TIMER, 64);
L
Linus Torvalds 已提交
393 394 395 396

			/* Enable reporting/forwarding of master aborts,
			 * parity, and SERR.
			 */
397 398 399 400
			pci_write_config_byte(pdev, PCI_BRIDGE_CONTROL,
					      (PCI_BRIDGE_CTL_PARITY |
					       PCI_BRIDGE_CTL_SERR |
					       PCI_BRIDGE_CTL_MASTER_ABORT));
L
Linus Torvalds 已提交
401 402 403 404
		}
	}
}

405 406
static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm,
				     struct device *parent)
L
Linus Torvalds 已提交
407 408 409 410 411 412
{
	static int once;

	/* The APB bridge speaks to the Sabre host PCI bridge
	 * at 66Mhz, but the front side of APB runs at 33Mhz
	 * for both segments.
413 414 415
	 *
	 * Hummingbird systems do not use APB, so they run
	 * at 66MHZ.
L
Linus Torvalds 已提交
416
	 */
417 418 419 420
	if (hummingbird_p)
		pbm->is_66mhz_capable = 1;
	else
		pbm->is_66mhz_capable = 0;
L
Linus Torvalds 已提交
421 422 423 424 425 426 427 428

	/* This driver has not been verified to handle
	 * multiple SABREs yet, so trap this.
	 *
	 * Also note that the SABRE host bridge is hardwired
	 * to live at bus 0.
	 */
	if (once != 0) {
429 430
		printk(KERN_ERR PFX "Multiple controllers unsupported.\n");
		return;
L
Linus Torvalds 已提交
431 432 433
	}
	once++;

434
	pbm->pci_bus = pci_scan_one_pbm(pbm, parent);
435
	if (!pbm->pci_bus)
436
		return;
L
Linus Torvalds 已提交
437

438
	sabre_root_bus = pbm->pci_bus;
L
Linus Torvalds 已提交
439

440
	apb_init(pbm->pci_bus);
L
Linus Torvalds 已提交
441

442
	sabre_register_error_handlers(pbm);
L
Linus Torvalds 已提交
443 444
}

445
static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm,
446
				     struct platform_device *op)
L
Linus Torvalds 已提交
447
{
448
	psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE);
449 450 451
	pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR;
	pbm->pci_afar = pbm->controller_regs + SABRE_PIOAFAR;
	pbm->pci_csr = pbm->controller_regs + SABRE_PCICTRL;
452
	sabre_scan_bus(pbm, &op->dev);
L
Linus Torvalds 已提交
453 454
}

455
static const struct of_device_id sabre_match[];
456
static int __devinit sabre_probe(struct platform_device *op)
L
Linus Torvalds 已提交
457
{
458
	const struct of_device_id *match;
459
	const struct linux_prom64_registers *pr_regs;
460
	struct device_node *dp = op->dev.of_node;
461
	struct pci_pbm_info *pbm;
462
	u32 upa_portid, dma_mask;
463
	struct iommu *iommu;
464
	int tsbsize, err;
465
	const u32 *vdma;
L
Linus Torvalds 已提交
466 467
	u64 clear_irq;

468 469
	match = of_match_device(sabre_match, &op->dev);
	hummingbird_p = match && (match->data != NULL);
470 471 472 473 474 475 476 477 478
	if (!hummingbird_p) {
		struct device_node *cpu_dp;

		/* Of course, Sun has to encode things a thousand
		 * different ways, inconsistently.
		 */
		for_each_node_by_type(cpu_dp, "cpu") {
			if (!strcmp(cpu_dp->name, "SUNW,UltraSPARC-IIe"))
				hummingbird_p = 1;
L
Linus Torvalds 已提交
479 480 481
		}
	}

482
	err = -ENOMEM;
483 484 485
	pbm = kzalloc(sizeof(*pbm), GFP_KERNEL);
	if (!pbm) {
		printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n");
486
		goto out_err;
487
	}
L
Linus Torvalds 已提交
488

489
	iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
490 491
	if (!iommu) {
		printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n");
492
		goto out_free_controller;
493 494
	}

495
	pbm->iommu = iommu;
L
Linus Torvalds 已提交
496

497
	upa_portid = of_getintprop_default(dp, "upa-portid", 0xff);
L
Linus Torvalds 已提交
498

499
	pbm->portid = upa_portid;
L
Linus Torvalds 已提交
500 501 502 503

	/*
	 * Map in SABRE register set and report the presence of this SABRE.
	 */
504
	
505
	pr_regs = of_get_property(dp, "reg", NULL);
506 507 508
	err = -ENODEV;
	if (!pr_regs) {
		printk(KERN_ERR PFX "No reg property\n");
509
		goto out_free_iommu;
510
	}
L
Linus Torvalds 已提交
511 512 513 514

	/*
	 * First REG in property is base of entire SABRE register space.
	 */
515
	pbm->controller_regs = pr_regs[0].phys_addr;
L
Linus Torvalds 已提交
516 517 518 519 520

	/* Clear interrupts */

	/* PCI first */
	for (clear_irq = SABRE_ICLR_A_SLOT0; clear_irq < SABRE_ICLR_B_SLOT0 + 0x80; clear_irq += 8)
521
		upa_writeq(0x0UL, pbm->controller_regs + clear_irq);
L
Linus Torvalds 已提交
522 523 524

	/* Then OBIO */
	for (clear_irq = SABRE_ICLR_SCSI; clear_irq < SABRE_ICLR_SCSI + 0x80; clear_irq += 8)
525
		upa_writeq(0x0UL, pbm->controller_regs + clear_irq);
L
Linus Torvalds 已提交
526 527

	/* Error interrupts are enabled later after the bus scan. */
528 529 530
	upa_writeq((SABRE_PCICTRL_MRLEN   | SABRE_PCICTRL_SERR |
		    SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN),
		   pbm->controller_regs + SABRE_PCICTRL);
L
Linus Torvalds 已提交
531 532

	/* Now map in PCI config space for entire SABRE. */
533
	pbm->config_space = pbm->controller_regs + SABRE_CONFIGSPACE;
534

535
	vdma = of_get_property(dp, "virtual-dma", NULL);
536 537
	if (!vdma) {
		printk(KERN_ERR PFX "No virtual-dma property\n");
538
		goto out_free_iommu;
539
	}
L
Linus Torvalds 已提交
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556

	dma_mask = vdma[0];
	switch(vdma[1]) {
		case 0x20000000:
			dma_mask |= 0x1fffffff;
			tsbsize = 64;
			break;
		case 0x40000000:
			dma_mask |= 0x3fffffff;
			tsbsize = 128;
			break;

		case 0x80000000:
			dma_mask |= 0x7fffffff;
			tsbsize = 128;
			break;
		default:
557
			printk(KERN_ERR PFX "Strange virtual-dma size.\n");
558
			goto out_free_iommu;
L
Linus Torvalds 已提交
559 560
	}

561
	err = psycho_iommu_init(pbm, tsbsize, vdma[0], dma_mask, SABRE_WRSYNC);
562
	if (err)
563
		goto out_free_iommu;
L
Linus Torvalds 已提交
564 565 566 567

	/*
	 * Look for APB underneath.
	 */
568 569 570 571 572 573 574
	sabre_pbm_init(pbm, op);

	pbm->next = pci_pbm_root;
	pci_pbm_root = pbm;

	dev_set_drvdata(&op->dev, pbm);

575
	return 0;
576

577
out_free_iommu:
578
	kfree(pbm->iommu);
579 580

out_free_controller:
581
	kfree(pbm);
582 583

out_err:
584
	return err;
L
Linus Torvalds 已提交
585
}
586

587
static const struct of_device_id sabre_match[] = {
588 589 590 591 592 593 594 595 596 597 598 599
	{
		.name = "pci",
		.compatible = "pci108e,a001",
		.data = (void *) 1,
	},
	{
		.name = "pci",
		.compatible = "pci108e,a000",
	},
	{},
};

600
static struct platform_driver sabre_driver = {
601 602 603 604 605
	.driver = {
		.name = DRIVER_NAME,
		.owner = THIS_MODULE,
		.of_match_table = sabre_match,
	},
606 607 608 609 610
	.probe		= sabre_probe,
};

static int __init sabre_init(void)
{
611
	return platform_driver_register(&sabre_driver);
612 613 614
}

subsys_initcall(sabre_init);