Newer
Older
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);
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
}
#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);
1161
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
1194
1195
1196
1197
1198
1199
1200
1201
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
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);
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
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);
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
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
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);
Bjorn Helgaas
committed
if (lba_dev->hba.gmmio_space.flags)
pci_add_resource(&resources, &lba_dev->hba.gmmio_space);
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);
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
/* 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);
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
/* Whew! Finally done! Tell services we got this one covered. */
return 0;
}
static struct parisc_device_id lba_tbl[] = {
{ 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 = {
.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);
}