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
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
.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;
pdc_pat_cell_mod_maddr_block_t pa_pdc_cell; /* PA_VIEW */
pdc_pat_cell_mod_maddr_block_t io_pdc_cell; /* IO_VIEW */
long io_count;
long status; /* PDC return status */
long pa_count;
int i;
/* 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;
break;
case PAT_LMMIO:
/* used to fix up pre-initialized MEM BARs */
if (!lba_dev->hba.lmmio_space.start) {
sprintf(lba_dev->hba.lmmio_name,
"PCI%02lx LMMIO",
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;
} else if (!lba_dev->hba.elmmio_space.start) {
sprintf(lba_dev->hba.elmmio_name,
"PCI%02lx ELMMIO",
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%02lx GMMIO",
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);
1114
1115
1116
1117
1118
1119
1120
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
1153
1154
1155
1156
1157
1158
1159
1160
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
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
sprintf(lba_dev->hba.io_name, "PCI%02lx Ports",
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;
}
}
}
#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;
/* 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%02lx LMMIO",
lba_dev->hba.bus_num.start);
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);
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
1286
1287
1288
1289
1290
1291
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
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
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%02lx ELMMIO",
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%02lx Ports",
lba_dev->hba.bus_num.start);
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;
}
/*
** 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;
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, 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, dev->hpa.start);
printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
return -ENODEV;
}
/*
** 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);
}
/*
** Tell PCI support another PCI bus was found.
** Walks PCI bus for us too.
*/
dev->dev.platform_data = lba_dev;
lba_bus = lba_dev->hba.hba_bus =
pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
cfg_ops, NULL);
if (lba_bus)
pci_bus_add_devices(lba_bus);
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
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
1601
1602
1603
1604
/* 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
}
pci_enable_bridges(lba_bus);
/*
** 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;
}
/* 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", __FUNCTION__, ibase, imask);
WRITE_REG32( imask, base_addr + LBA_IMASK);
WRITE_REG32( ibase, base_addr + LBA_IBASE);
iounmap(base_addr);
}