Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
static struct pci_port_ops lba_pat_port_ops = {
.inb = lba_pat_in8,
.inw = lba_pat_in16,
.inl = lba_pat_in32,
.outb = lba_pat_out8,
.outw = lba_pat_out16,
.outl = lba_pat_out32
};
/*
** make range information from PDC available to PCI subsystem.
** We make the PDC call here in order to get the PCI bus range
** numbers. The rest will get forwarded in pcibios_fixup_bus().
** We don't have a struct pci_bus assigned to us yet.
*/
static void
lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
{
unsigned long bytecnt;
long io_count;
long status; /* PDC return status */
long pa_count;
pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; /* PA_VIEW */
pdc_pat_cell_mod_maddr_block_t *io_pdc_cell; /* IO_VIEW */
pa_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL);
if (!pa_pdc_cell)
return;
io_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL);
kfree(pa_pdc_cell);
return;
}
/* return cell module (IO view) */
status = pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
PA_VIEW, pa_pdc_cell);
pa_count = pa_pdc_cell->mod[1];
status |= pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
IO_VIEW, io_pdc_cell);
io_count = io_pdc_cell->mod[1];
/* We've already done this once for device discovery...*/
if (status != PDC_OK) {
panic("pdc_pat_cell_module() call failed for LBA!\n");
}
if (PAT_GET_ENTITY(pa_pdc_cell->mod_info) != PAT_ENTITY_LBA) {
panic("pdc_pat_cell_module() entity returned != PAT_ENTITY_LBA!\n");
}
/*
** Inspect the resources PAT tells us about
*/
for (i = 0; i < pa_count; i++) {
struct {
unsigned long type;
unsigned long start;
unsigned long end; /* aka finish */
} *p, *io;
struct resource *r;
p = (void *) &(pa_pdc_cell->mod[2+i*3]);
io = (void *) &(io_pdc_cell->mod[2+i*3]);
/* Convert the PAT range data to PCI "struct resource" */
switch(p->type & 0xff) {
case PAT_PBNUM:
lba_dev->hba.bus_num.start = p->start;
lba_dev->hba.bus_num.end = p->end;
lba_dev->hba.bus_num.flags = IORESOURCE_BUS;
break;
case PAT_LMMIO:
/* used to fix up pre-initialized MEM BARs */
Helge Deller
committed
if (!lba_dev->hba.lmmio_space.flags) {
unsigned long lba_len;
lba_len = ~READ_REG32(lba_dev->hba.base_addr
+ LBA_LMMIO_MASK);
if ((p->end - p->start) != lba_len)
p->end = extend_lmmio_len(p->start,
p->end, lba_len);
"PCI%02x LMMIO",
(int)lba_dev->hba.bus_num.start);
lba_dev->hba.lmmio_space_offset = p->start -
io->start;
r = &lba_dev->hba.lmmio_space;
r->name = lba_dev->hba.lmmio_name;
Helge Deller
committed
} else if (!lba_dev->hba.elmmio_space.flags) {
"PCI%02x ELMMIO",
(int)lba_dev->hba.bus_num.start);
r = &lba_dev->hba.elmmio_space;
r->name = lba_dev->hba.elmmio_name;
} else {
printk(KERN_WARNING MODULE_NAME
" only supports 2 LMMIO resources!\n");
break;
}
r->start = p->start;
r->end = p->end;
r->flags = IORESOURCE_MEM;
r->parent = r->sibling = r->child = NULL;
break;
case PAT_GMMIO:
/* MMIO space > 4GB phys addr; for 64-bit BAR */
sprintf(lba_dev->hba.gmmio_name, "PCI%02x GMMIO",
(int)lba_dev->hba.bus_num.start);
r = &lba_dev->hba.gmmio_space;
r->name = lba_dev->hba.gmmio_name;
r->start = p->start;
r->end = p->end;
r->flags = IORESOURCE_MEM;
r->parent = r->sibling = r->child = NULL;
break;
case PAT_NPIOP:
printk(KERN_WARNING MODULE_NAME
" range[%d] : ignoring NPIOP (0x%lx)\n",
i, p->start);
break;
case PAT_PIOP:
/*
** Postable I/O port space is per PCI host adapter.
** base of 64MB PIOP region
*/
lba_dev->iop_base = ioremap_nocache(p->start, 64 * 1024 * 1024);
sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
(int)lba_dev->hba.bus_num.start);
r = &lba_dev->hba.io_space;
r->name = lba_dev->hba.io_name;
r->start = HBA_PORT_BASE(lba_dev->hba.hba_num);
r->end = r->start + HBA_PORT_SPACE_SIZE - 1;
r->flags = IORESOURCE_IO;
r->parent = r->sibling = r->child = NULL;
break;
default:
printk(KERN_WARNING MODULE_NAME
" range[%d] : unknown pat range type (0x%lx)\n",
i, p->type & 0xff);
break;
}
}
kfree(pa_pdc_cell);
kfree(io_pdc_cell);
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
}
#else
/* keep compiler from complaining about missing declarations */
#define lba_pat_port_ops lba_astro_port_ops
#define lba_pat_resources(pa_dev, lba_dev)
#endif /* CONFIG_64BIT */
extern void sba_distributed_lmmio(struct parisc_device *, struct resource *);
extern void sba_directed_lmmio(struct parisc_device *, struct resource *);
static void
lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
{
struct resource *r;
int lba_num;
lba_dev->hba.lmmio_space_offset = PCI_F_EXTEND;
/*
** With "legacy" firmware, the lowest byte of FW_SCRATCH
** represents bus->secondary and the second byte represents
** bus->subsidiary (i.e. highest PPB programmed by firmware).
** PCI bus walk *should* end up with the same result.
** FIXME: But we don't have sanity checks in PCI or LBA.
*/
lba_num = READ_REG32(lba_dev->hba.base_addr + LBA_FW_SCRATCH);
r = &(lba_dev->hba.bus_num);
r->name = "LBA PCI Busses";
r->start = lba_num & 0xff;
r->end = (lba_num>>8) & 0xff;
r->flags = IORESOURCE_BUS;
/* Set up local PCI Bus resources - we don't need them for
** Legacy boxes but it's nice to see in /proc/iomem.
*/
r = &(lba_dev->hba.lmmio_space);
sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO",
(int)lba_dev->hba.bus_num.start);
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
r->name = lba_dev->hba.lmmio_name;
#if 1
/* We want the CPU -> IO routing of addresses.
* The SBA BASE/MASK registers control CPU -> IO routing.
* Ask SBA what is routed to this rope/LBA.
*/
sba_distributed_lmmio(pa_dev, r);
#else
/*
* The LBA BASE/MASK registers control IO -> System routing.
*
* The following code works but doesn't get us what we want.
* Well, only because firmware (v5.0) on C3000 doesn't program
* the LBA BASE/MASE registers to be the exact inverse of
* the corresponding SBA registers. Other Astro/Pluto
* based platform firmware may do it right.
*
* Should someone want to mess with MSI, they may need to
* reprogram LBA BASE/MASK registers. Thus preserve the code
* below until MSI is known to work on C3000/A500/N4000/RP3440.
*
* Using the code below, /proc/iomem shows:
* ...
* f0000000-f0ffffff : PCI00 LMMIO
* f05d0000-f05d0000 : lcd_data
* f05d0008-f05d0008 : lcd_cmd
* f1000000-f1ffffff : PCI01 LMMIO
* f4000000-f4ffffff : PCI02 LMMIO
* f4000000-f4001fff : sym53c8xx
* f4002000-f4003fff : sym53c8xx
* f4004000-f40043ff : sym53c8xx
* f4005000-f40053ff : sym53c8xx
* f4007000-f4007fff : ohci_hcd
* f4008000-f40083ff : tulip
* f6000000-f6ffffff : PCI03 LMMIO
* f8000000-fbffffff : PCI00 ELMMIO
* fa100000-fa4fffff : stifb mmio
* fb000000-fb1fffff : stifb fb
*
* But everything listed under PCI02 actually lives under PCI00.
* This is clearly wrong.
*
* Asking SBA how things are routed tells the correct story:
* LMMIO_BASE/MASK/ROUTE f4000001 fc000000 00000000
* DIR0_BASE/MASK/ROUTE fa000001 fe000000 00000006
* DIR1_BASE/MASK/ROUTE f9000001 ff000000 00000004
* DIR2_BASE/MASK/ROUTE f0000000 fc000000 00000000
* DIR3_BASE/MASK/ROUTE f0000000 fc000000 00000000
*
* Which looks like this in /proc/iomem:
* f4000000-f47fffff : PCI00 LMMIO
* f4000000-f4001fff : sym53c8xx
* ...[deteled core devices - same as above]...
* f4008000-f40083ff : tulip
* f4800000-f4ffffff : PCI01 LMMIO
* f6000000-f67fffff : PCI02 LMMIO
* f7000000-f77fffff : PCI03 LMMIO
* f9000000-f9ffffff : PCI02 ELMMIO
* fa000000-fbffffff : PCI03 ELMMIO
* fa100000-fa4fffff : stifb mmio
* fb000000-fb1fffff : stifb fb
*
* ie all Built-in core are under now correctly under PCI00.
* The "PCI02 ELMMIO" directed range is for:
* +-[02]---03.0 3Dfx Interactive, Inc. Voodoo 2
*
* All is well now.
*/
r->start = READ_REG32(lba_dev->hba.base_addr + LBA_LMMIO_BASE);
if (r->start & 1) {
unsigned long rsize;
r->flags = IORESOURCE_MEM;
/* mmio_mask also clears Enable bit */
r->start &= mmio_mask;
r->start = PCI_HOST_ADDR(HBA_DATA(lba_dev), r->start);
rsize = ~ READ_REG32(lba_dev->hba.base_addr + LBA_LMMIO_MASK);
/*
** Each rope only gets part of the distributed range.
** Adjust "window" for this rope.
*/
rsize /= ROPES_PER_IOC;
r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa.start);
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
r->end = r->start + rsize;
} else {
r->end = r->start = 0; /* Not enabled. */
}
#endif
/*
** "Directed" ranges are used when the "distributed range" isn't
** sufficient for all devices below a given LBA. Typically devices
** like graphics cards or X25 may need a directed range when the
** bus has multiple slots (ie multiple devices) or the device
** needs more than the typical 4 or 8MB a distributed range offers.
**
** The main reason for ignoring it now frigging complications.
** Directed ranges may overlap (and have precedence) over
** distributed ranges. Or a distributed range assigned to a unused
** rope may be used by a directed range on a different rope.
** Support for graphics devices may require fixing this
** since they may be assigned a directed range which overlaps
** an existing (but unused portion of) distributed range.
*/
r = &(lba_dev->hba.elmmio_space);
sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO",
(int)lba_dev->hba.bus_num.start);
r->name = lba_dev->hba.elmmio_name;
#if 1
/* See comment which precedes call to sba_directed_lmmio() */
sba_directed_lmmio(pa_dev, r);
#else
r->start = READ_REG32(lba_dev->hba.base_addr + LBA_ELMMIO_BASE);
if (r->start & 1) {
unsigned long rsize;
r->flags = IORESOURCE_MEM;
/* mmio_mask also clears Enable bit */
r->start &= mmio_mask;
r->start = PCI_HOST_ADDR(HBA_DATA(lba_dev), r->start);
rsize = READ_REG32(lba_dev->hba.base_addr + LBA_ELMMIO_MASK);
r->end = r->start + ~rsize;
}
#endif
r = &(lba_dev->hba.io_space);
sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
(int)lba_dev->hba.bus_num.start);
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
r->name = lba_dev->hba.io_name;
r->flags = IORESOURCE_IO;
r->start = READ_REG32(lba_dev->hba.base_addr + LBA_IOS_BASE) & ~1L;
r->end = r->start + (READ_REG32(lba_dev->hba.base_addr + LBA_IOS_MASK) ^ (HBA_PORT_SPACE_SIZE - 1));
/* Virtualize the I/O Port space ranges */
lba_num = HBA_PORT_BASE(lba_dev->hba.hba_num);
r->start |= lba_num;
r->end |= lba_num;
}
/**************************************************************************
**
** LBA initialization code (HW and SW)
**
** o identify LBA chip itself
** o initialize LBA chip modes (HardFail)
** o FIXME: initialize DMA hints for reasonable defaults
** o enable configuration functions
** o call pci_register_ops() to discover devs (fixup/fixup_bus get invoked)
**
**************************************************************************/
static int __init
lba_hw_init(struct lba_device *d)
{
u32 stat;
u32 bus_reset; /* PDC_PAT_BUG */
#if 0
printk(KERN_DEBUG "LBA %lx STAT_CTL %Lx ERROR_CFG %Lx STATUS %Lx DMA_CTL %Lx\n",
d->hba.base_addr,
READ_REG64(d->hba.base_addr + LBA_STAT_CTL),
READ_REG64(d->hba.base_addr + LBA_ERROR_CONFIG),
READ_REG64(d->hba.base_addr + LBA_ERROR_STATUS),
READ_REG64(d->hba.base_addr + LBA_DMA_CTL) );
printk(KERN_DEBUG " ARB mask %Lx pri %Lx mode %Lx mtlt %Lx\n",
READ_REG64(d->hba.base_addr + LBA_ARB_MASK),
READ_REG64(d->hba.base_addr + LBA_ARB_PRI),
READ_REG64(d->hba.base_addr + LBA_ARB_MODE),
READ_REG64(d->hba.base_addr + LBA_ARB_MTLT) );
printk(KERN_DEBUG " HINT cfg 0x%Lx\n",
READ_REG64(d->hba.base_addr + LBA_HINT_CFG));
printk(KERN_DEBUG " HINT reg ");
{ int i;
for (i=LBA_HINT_BASE; i< (14*8 + LBA_HINT_BASE); i+=8)
printk(" %Lx", READ_REG64(d->hba.base_addr + i));
}
printk("\n");
#endif /* DEBUG_LBA_PAT */
#ifdef CONFIG_64BIT
/*
* FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
* Only N-Class and up can really make use of Get slot status.
* maybe L-class too but I've never played with it there.
*/
#endif
/* PDC_PAT_BUG: exhibited in rev 40.48 on L2000 */
bus_reset = READ_REG32(d->hba.base_addr + LBA_STAT_CTL + 4) & 1;
if (bus_reset) {
printk(KERN_DEBUG "NOTICE: PCI bus reset still asserted! (clearing)\n");
}
stat = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG);
if (stat & LBA_SMART_MODE) {
printk(KERN_DEBUG "NOTICE: LBA in SMART mode! (cleared)\n");
stat &= ~LBA_SMART_MODE;
WRITE_REG32(stat, d->hba.base_addr + LBA_ERROR_CONFIG);
}
/* Set HF mode as the default (vs. -1 mode). */
stat = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);
WRITE_REG32(stat | HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL);
/*
** Writing a zero to STAT_CTL.rf (bit 0) will clear reset signal
** if it's not already set. If we just cleared the PCI Bus Reset
** signal, wait a bit for the PCI devices to recover and setup.
*/
if (bus_reset)
mdelay(pci_post_reset_delay);
if (0 == READ_REG32(d->hba.base_addr + LBA_ARB_MASK)) {
/*
** PDC_PAT_BUG: PDC rev 40.48 on L2000.
** B2000/C3600/J6000 also have this problem?
**
** Elroys with hot pluggable slots don't get configured
** correctly if the slot is empty. ARB_MASK is set to 0
** and we can't master transactions on the bus if it's
** not at least one. 0x3 enables elroy and first slot.
*/
printk(KERN_DEBUG "NOTICE: Enabling PCI Arbitration\n");
WRITE_REG32(0x3, d->hba.base_addr + LBA_ARB_MASK);
}
/*
** FIXME: Hint registers are programmed with default hint
** values by firmware. Hints should be sane even if we
** can't reprogram them the way drivers want.
*/
return 0;
}
/*
* Unfortunately, when firmware numbers busses, it doesn't take into account
* Cardbus bridges. So we have to renumber the busses to suit ourselves.
* Elroy/Mercury don't actually know what bus number they're attached to;
* we use bus 0 to indicate the directly attached bus and any other bus
* number will be taken care of by the PCI-PCI bridge.
*/
static unsigned int lba_next_bus = 0;
* Determine if lba should claim this chip (return 0) or not (return 1).
* If so, initialize the chip and tell other partners in crime they
* have work to do.
*/
static int __init
lba_driver_probe(struct parisc_device *dev)
{
struct lba_device *lba_dev;
Bjorn Helgaas
committed
LIST_HEAD(resources);
struct pci_bus *lba_bus;
struct pci_ops *cfg_ops;
u32 func_class;
void *tmp_obj;
char *version;
void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096);
/* Read HW Rev First */
func_class = READ_REG32(addr + LBA_FCLASS);
if (IS_ELROY(dev)) {
func_class &= 0xf;
switch (func_class) {
case 0: version = "TR1.0"; break;
case 1: version = "TR2.0"; break;
case 2: version = "TR2.1"; break;
case 3: version = "TR2.2"; break;
case 4: version = "TR3.0"; break;
case 5: version = "TR4.0"; break;
default: version = "TR4+";
}
printk(KERN_INFO "Elroy version %s (0x%x) found at 0x%lx\n",
version, func_class & 0xf, (long)dev->hpa.start);
if (func_class < 2) {
printk(KERN_WARNING "Can't support LBA older than "
"TR2.1 - continuing under adversity.\n");
}
#if 0
/* Elroy TR4.0 should work with simple algorithm.
But it doesn't. Still missing something. *sigh*
*/
if (func_class > 4) {
cfg_ops = &mercury_cfg_ops;
} else
#endif
{
cfg_ops = &elroy_cfg_ops;
}
} else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) {
int major, minor;
major = func_class >> 4, minor = func_class & 0xf;
/* We could use one printk for both Elroy and Mercury,
* but for the mask for func_class.
*/
printk(KERN_INFO "%s version TR%d.%d (0x%x) found at 0x%lx\n",
IS_MERCURY(dev) ? "Mercury" : "Quicksilver", major,
minor, func_class, (long)dev->hpa.start);
printk(KERN_ERR "Unknown LBA found at 0x%lx\n",
(long)dev->hpa.start);
/* Tell I/O SAPIC driver we have a IRQ handler/region. */
tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE);
/* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't
** have an IRT entry will get NULL back from iosapic code.
*/
lba_dev = kzalloc(sizeof(struct lba_device), GFP_KERNEL);
if (!lba_dev) {
printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n");
return(1);
}
/* ---------- First : initialize data we already have --------- */
lba_dev->hw_rev = func_class;
lba_dev->hba.base_addr = addr;
lba_dev->hba.dev = dev;
lba_dev->iosapic_obj = tmp_obj; /* save interrupt handle */
lba_dev->hba.iommu = sba_get_iommu(dev); /* get iommu data */
parisc_set_drvdata(dev, lba_dev);
/* ------------ Second : initialize common stuff ---------- */
pci_bios = &lba_bios_ops;
pcibios_register_hba(HBA_DATA(lba_dev));
spin_lock_init(&lba_dev->lba_lock);
if (lba_hw_init(lba_dev))
return(1);
/* ---------- Third : setup I/O Port and MMIO resources --------- */
if (is_pdc_pat()) {
/* PDC PAT firmware uses PIOP region of GMMIO space. */
pci_port = &lba_pat_port_ops;
/* Go ask PDC PAT what resources this LBA has */
lba_pat_resources(dev, lba_dev);
} else {
if (!astro_iop_base) {
/* Sprockets PDC uses NPIOP region */
astro_iop_base = ioremap_nocache(LBA_PORT_BASE, 64 * 1024);
pci_port = &lba_astro_port_ops;
}
/* Poke the chip a bit for /proc output */
lba_legacy_resources(dev, lba_dev);
}
if (lba_dev->hba.bus_num.start < lba_next_bus)
lba_dev->hba.bus_num.start = lba_next_bus;
/* Overlaps with elmmio can (and should) fail here.
* We will prune (or ignore) the distributed range.
*
* FIXME: SBA code should register all elmmio ranges first.
* that would take care of elmmio ranges routed
* to a different rope (already discovered) from
* getting registered *after* LBA code has already
* registered it's distributed lmmio range.
*/
if (truncate_pat_collision(&iomem_resource,
&(lba_dev->hba.lmmio_space))) {
printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
(long)lba_dev->hba.lmmio_space.start,
(long)lba_dev->hba.lmmio_space.end);
lba_dev->hba.lmmio_space.flags = 0;
}
pci_add_resource_offset(&resources, &lba_dev->hba.io_space,
HBA_PORT_BASE(lba_dev->hba.hba_num));
Helge Deller
committed
if (lba_dev->hba.elmmio_space.flags)
pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space,
lba_dev->hba.lmmio_space_offset);
Bjorn Helgaas
committed
if (lba_dev->hba.lmmio_space.flags)
pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space,
lba_dev->hba.lmmio_space_offset);
if (lba_dev->hba.gmmio_space.flags) {
/* Not registering GMMIO space - according to docs it's not
* even used on HP-UX. */
/* pci_add_resource(&resources, &lba_dev->hba.gmmio_space); */
}
Bjorn Helgaas
committed
pci_add_resource(&resources, &lba_dev->hba.bus_num);
dev->dev.platform_data = lba_dev;
lba_bus = lba_dev->hba.hba_bus =
Bjorn Helgaas
committed
pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
cfg_ops, NULL, &resources);
if (!lba_bus) {
pci_free_resource_list(&resources);
return 0;
Bjorn Helgaas
committed
}
max = pci_scan_child_bus(lba_bus);
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
/* This is in lieu of calling pci_assign_unassigned_resources() */
if (is_pdc_pat()) {
/* assign resources to un-initialized devices */
DBG_PAT("LBA pci_bus_size_bridges()\n");
pci_bus_size_bridges(lba_bus);
DBG_PAT("LBA pci_bus_assign_resources()\n");
pci_bus_assign_resources(lba_bus);
#ifdef DEBUG_LBA_PAT
DBG_PAT("\nLBA PIOP resource tree\n");
lba_dump_res(&lba_dev->hba.io_space, 2);
DBG_PAT("\nLBA LMMIO resource tree\n");
lba_dump_res(&lba_dev->hba.lmmio_space, 2);
#endif
}
/*
** Once PCI register ops has walked the bus, access to config
** space is restricted. Avoids master aborts on config cycles.
** Early LBA revs go fatal on *any* master abort.
*/
if (cfg_ops == &elroy_cfg_ops) {
lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
}
pci_bus_add_devices(lba_bus);
/* Whew! Finally done! Tell services we got this one covered. */
return 0;
}
static const struct parisc_device_id lba_tbl[] __initconst = {
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, ELROY_HVERS, 0xa },
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, MERCURY_HVERS, 0xa },
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, QUICKSILVER_HVERS, 0xa },
{ 0, }
};
static struct parisc_driver lba_driver __refdata = {
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
.name = MODULE_NAME,
.id_table = lba_tbl,
.probe = lba_driver_probe,
};
/*
** One time initialization to let the world know the LBA was found.
** Must be called exactly once before pci_init().
*/
void __init lba_init(void)
{
register_parisc_driver(&lba_driver);
}
/*
** Initialize the IBASE/IMASK registers for LBA (Elroy).
** Only called from sba_iommu.c in order to route ranges (MMIO vs DMA).
** sba_iommu is responsible for locking (none needed at init time).
*/
void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
{
void __iomem * base_addr = ioremap_nocache(lba->hpa.start, 4096);
imask <<= 2; /* adjust for hints - 2 more bits */
/* Make sure we aren't trying to set bits that aren't writeable. */
WARN_ON((ibase & 0x001fffff) != 0);
WARN_ON((imask & 0x001fffff) != 0);
DBG("%s() ibase 0x%x imask 0x%x\n", __func__, ibase, imask);
WRITE_REG32( imask, base_addr + LBA_IMASK);
WRITE_REG32( ibase, base_addr + LBA_IBASE);
iounmap(base_addr);
}
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
/*
* The design of the Diva management card in rp34x0 machines (rp3410, rp3440)
* seems rushed, so that many built-in components simply don't work.
* The following quirks disable the serial AUX port and the built-in ATI RV100
* Radeon 7000 graphics card which both don't have any external connectors and
* thus are useless, and even worse, e.g. the AUX port occupies ttyS0 and as
* such makes those machines the only PARISC machines on which we can't use
* ttyS0 as boot console.
*/
static void quirk_diva_ati_card(struct pci_dev *dev)
{
if (dev->subsystem_vendor != PCI_VENDOR_ID_HP ||
dev->subsystem_device != 0x1292)
return;
dev_info(&dev->dev, "Hiding Diva built-in ATI card");
dev->device = 0;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY,
quirk_diva_ati_card);
static void quirk_diva_aux_disable(struct pci_dev *dev)
{
if (dev->subsystem_vendor != PCI_VENDOR_ID_HP ||
dev->subsystem_device != 0x1291)
return;
dev_info(&dev->dev, "Hiding Diva built-in AUX serial device");
dev->device = 0;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX,
quirk_diva_aux_disable);