linux/arch/x86/kernel/pci-calgary_64.c
<<
>>
Prefs
   1/*
   2 * Derived from arch/powerpc/kernel/iommu.c
   3 *
   4 * Copyright IBM Corporation, 2006-2007
   5 * Copyright (C) 2006  Jon Mason <jdmason@kudzu.us>
   6 *
   7 * Author: Jon Mason <jdmason@kudzu.us>
   8 * Author: Muli Ben-Yehuda <muli@il.ibm.com>
   9
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  23 */
  24
  25#include <linux/kernel.h>
  26#include <linux/init.h>
  27#include <linux/types.h>
  28#include <linux/slab.h>
  29#include <linux/mm.h>
  30#include <linux/spinlock.h>
  31#include <linux/string.h>
  32#include <linux/dma-mapping.h>
  33#include <linux/init.h>
  34#include <linux/bitops.h>
  35#include <linux/pci_ids.h>
  36#include <linux/pci.h>
  37#include <linux/delay.h>
  38#include <linux/scatterlist.h>
  39#include <asm/gart.h>
  40#include <asm/calgary.h>
  41#include <asm/tce.h>
  42#include <asm/pci-direct.h>
  43#include <asm/system.h>
  44#include <asm/dma.h>
  45#include <asm/rio.h>
  46
  47#ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
  48int use_calgary __read_mostly = 1;
  49#else
  50int use_calgary __read_mostly = 0;
  51#endif /* CONFIG_CALGARY_DEFAULT_ENABLED */
  52
  53#define PCI_DEVICE_ID_IBM_CALGARY 0x02a1
  54#define PCI_DEVICE_ID_IBM_CALIOC2 0x0308
  55
  56/* register offsets inside the host bridge space */
  57#define CALGARY_CONFIG_REG      0x0108
  58#define PHB_CSR_OFFSET          0x0110 /* Channel Status */
  59#define PHB_PLSSR_OFFSET        0x0120
  60#define PHB_CONFIG_RW_OFFSET    0x0160
  61#define PHB_IOBASE_BAR_LOW      0x0170
  62#define PHB_IOBASE_BAR_HIGH     0x0180
  63#define PHB_MEM_1_LOW           0x0190
  64#define PHB_MEM_1_HIGH          0x01A0
  65#define PHB_IO_ADDR_SIZE        0x01B0
  66#define PHB_MEM_1_SIZE          0x01C0
  67#define PHB_MEM_ST_OFFSET       0x01D0
  68#define PHB_AER_OFFSET          0x0200
  69#define PHB_CONFIG_0_HIGH       0x0220
  70#define PHB_CONFIG_0_LOW        0x0230
  71#define PHB_CONFIG_0_END        0x0240
  72#define PHB_MEM_2_LOW           0x02B0
  73#define PHB_MEM_2_HIGH          0x02C0
  74#define PHB_MEM_2_SIZE_HIGH     0x02D0
  75#define PHB_MEM_2_SIZE_LOW      0x02E0
  76#define PHB_DOSHOLE_OFFSET      0x08E0
  77
  78/* CalIOC2 specific */
  79#define PHB_SAVIOR_L2           0x0DB0
  80#define PHB_PAGE_MIG_CTRL       0x0DA8
  81#define PHB_PAGE_MIG_DEBUG      0x0DA0
  82#define PHB_ROOT_COMPLEX_STATUS 0x0CB0
  83
  84/* PHB_CONFIG_RW */
  85#define PHB_TCE_ENABLE          0x20000000
  86#define PHB_SLOT_DISABLE        0x1C000000
  87#define PHB_DAC_DISABLE         0x01000000
  88#define PHB_MEM2_ENABLE         0x00400000
  89#define PHB_MCSR_ENABLE         0x00100000
  90/* TAR (Table Address Register) */
  91#define TAR_SW_BITS             0x0000ffffffff800fUL
  92#define TAR_VALID               0x0000000000000008UL
  93/* CSR (Channel/DMA Status Register) */
  94#define CSR_AGENT_MASK          0xffe0ffff
  95/* CCR (Calgary Configuration Register) */
  96#define CCR_2SEC_TIMEOUT        0x000000000000000EUL
  97/* PMCR/PMDR (Page Migration Control/Debug Registers */
  98#define PMR_SOFTSTOP            0x80000000
  99#define PMR_SOFTSTOPFAULT       0x40000000
 100#define PMR_HARDSTOP            0x20000000
 101
 102#define MAX_NUM_OF_PHBS         8 /* how many PHBs in total? */
 103#define MAX_NUM_CHASSIS         8 /* max number of chassis */
 104/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */
 105#define MAX_PHB_BUS_NUM         (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2)
 106#define PHBS_PER_CALGARY        4
 107
 108/* register offsets in Calgary's internal register space */
 109static const unsigned long tar_offsets[] = {
 110        0x0580 /* TAR0 */,
 111        0x0588 /* TAR1 */,
 112        0x0590 /* TAR2 */,
 113        0x0598 /* TAR3 */
 114};
 115
 116static const unsigned long split_queue_offsets[] = {
 117        0x4870 /* SPLIT QUEUE 0 */,
 118        0x5870 /* SPLIT QUEUE 1 */,
 119        0x6870 /* SPLIT QUEUE 2 */,
 120        0x7870 /* SPLIT QUEUE 3 */
 121};
 122
 123static const unsigned long phb_offsets[] = {
 124        0x8000 /* PHB0 */,
 125        0x9000 /* PHB1 */,
 126        0xA000 /* PHB2 */,
 127        0xB000 /* PHB3 */
 128};
 129
 130/* PHB debug registers */
 131
 132static const unsigned long phb_debug_offsets[] = {
 133        0x4000  /* PHB 0 DEBUG */,
 134        0x5000  /* PHB 1 DEBUG */,
 135        0x6000  /* PHB 2 DEBUG */,
 136        0x7000  /* PHB 3 DEBUG */
 137};
 138
 139/*
 140 * STUFF register for each debug PHB,
 141 * byte 1 = start bus number, byte 2 = end bus number
 142 */
 143
 144#define PHB_DEBUG_STUFF_OFFSET  0x0020
 145
 146#define EMERGENCY_PAGES 32 /* = 128KB */
 147
 148unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED;
 149static int translate_empty_slots __read_mostly = 0;
 150static int calgary_detected __read_mostly = 0;
 151
 152static struct rio_table_hdr     *rio_table_hdr __initdata;
 153static struct scal_detail       *scal_devs[MAX_NUMNODES] __initdata;
 154static struct rio_detail        *rio_devs[MAX_NUMNODES * 4] __initdata;
 155
 156struct calgary_bus_info {
 157        void *tce_space;
 158        unsigned char translation_disabled;
 159        signed char phbid;
 160        void __iomem *bbar;
 161};
 162
 163static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev);
 164static void calgary_tce_cache_blast(struct iommu_table *tbl);
 165static void calgary_dump_error_regs(struct iommu_table *tbl);
 166static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev);
 167static void calioc2_tce_cache_blast(struct iommu_table *tbl);
 168static void calioc2_dump_error_regs(struct iommu_table *tbl);
 169
 170static struct cal_chipset_ops calgary_chip_ops = {
 171        .handle_quirks = calgary_handle_quirks,
 172        .tce_cache_blast = calgary_tce_cache_blast,
 173        .dump_error_regs = calgary_dump_error_regs
 174};
 175
 176static struct cal_chipset_ops calioc2_chip_ops = {
 177        .handle_quirks = calioc2_handle_quirks,
 178        .tce_cache_blast = calioc2_tce_cache_blast,
 179        .dump_error_regs = calioc2_dump_error_regs
 180};
 181
 182static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, };
 183
 184/* enable this to stress test the chip's TCE cache */
 185#ifdef CONFIG_IOMMU_DEBUG
 186int debugging __read_mostly = 1;
 187
 188static inline unsigned long verify_bit_range(unsigned long* bitmap,
 189        int expected, unsigned long start, unsigned long end)
 190{
 191        unsigned long idx = start;
 192
 193        BUG_ON(start >= end);
 194
 195        while (idx < end) {
 196                if (!!test_bit(idx, bitmap) != expected)
 197                        return idx;
 198                ++idx;
 199        }
 200
 201        /* all bits have the expected value */
 202        return ~0UL;
 203}
 204#else /* debugging is disabled */
 205int debugging __read_mostly = 0;
 206
 207static inline unsigned long verify_bit_range(unsigned long* bitmap,
 208        int expected, unsigned long start, unsigned long end)
 209{
 210        return ~0UL;
 211}
 212
 213#endif /* CONFIG_IOMMU_DEBUG */
 214
 215static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
 216{
 217        unsigned int npages;
 218
 219        npages = PAGE_ALIGN(dma + dmalen) - (dma & PAGE_MASK);
 220        npages >>= PAGE_SHIFT;
 221
 222        return npages;
 223}
 224
 225static inline int translation_enabled(struct iommu_table *tbl)
 226{
 227        /* only PHBs with translation enabled have an IOMMU table */
 228        return (tbl != NULL);
 229}
 230
 231static void iommu_range_reserve(struct iommu_table *tbl,
 232        unsigned long start_addr, unsigned int npages)
 233{
 234        unsigned long index;
 235        unsigned long end;
 236        unsigned long badbit;
 237        unsigned long flags;
 238
 239        index = start_addr >> PAGE_SHIFT;
 240
 241        /* bail out if we're asked to reserve a region we don't cover */
 242        if (index >= tbl->it_size)
 243                return;
 244
 245        end = index + npages;
 246        if (end > tbl->it_size) /* don't go off the table */
 247                end = tbl->it_size;
 248
 249        spin_lock_irqsave(&tbl->it_lock, flags);
 250
 251        badbit = verify_bit_range(tbl->it_map, 0, index, end);
 252        if (badbit != ~0UL) {
 253                if (printk_ratelimit())
 254                        printk(KERN_ERR "Calgary: entry already allocated at "
 255                               "0x%lx tbl %p dma 0x%lx npages %u\n",
 256                               badbit, tbl, start_addr, npages);
 257        }
 258
 259        set_bit_string(tbl->it_map, index, npages);
 260
 261        spin_unlock_irqrestore(&tbl->it_lock, flags);
 262}
 263
 264static unsigned long iommu_range_alloc(struct iommu_table *tbl,
 265        unsigned int npages)
 266{
 267        unsigned long flags;
 268        unsigned long offset;
 269
 270        BUG_ON(npages == 0);
 271
 272        spin_lock_irqsave(&tbl->it_lock, flags);
 273
 274        offset = find_next_zero_string(tbl->it_map, tbl->it_hint,
 275                                       tbl->it_size, npages);
 276        if (offset == ~0UL) {
 277                tbl->chip_ops->tce_cache_blast(tbl);
 278                offset = find_next_zero_string(tbl->it_map, 0,
 279                                               tbl->it_size, npages);
 280                if (offset == ~0UL) {
 281                        printk(KERN_WARNING "Calgary: IOMMU full.\n");
 282                        spin_unlock_irqrestore(&tbl->it_lock, flags);
 283                        if (panic_on_overflow)
 284                                panic("Calgary: fix the allocator.\n");
 285                        else
 286                                return bad_dma_address;
 287                }
 288        }
 289
 290        set_bit_string(tbl->it_map, offset, npages);
 291        tbl->it_hint = offset + npages;
 292        BUG_ON(tbl->it_hint > tbl->it_size);
 293
 294        spin_unlock_irqrestore(&tbl->it_lock, flags);
 295
 296        return offset;
 297}
 298
 299static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *vaddr,
 300        unsigned int npages, int direction)
 301{
 302        unsigned long entry;
 303        dma_addr_t ret = bad_dma_address;
 304
 305        entry = iommu_range_alloc(tbl, npages);
 306
 307        if (unlikely(entry == bad_dma_address))
 308                goto error;
 309
 310        /* set the return dma address */
 311        ret = (entry << PAGE_SHIFT) | ((unsigned long)vaddr & ~PAGE_MASK);
 312
 313        /* put the TCEs in the HW table */
 314        tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK,
 315                  direction);
 316
 317        return ret;
 318
 319error:
 320        printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
 321               "iommu %p\n", npages, tbl);
 322        return bad_dma_address;
 323}
 324
 325static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
 326        unsigned int npages)
 327{
 328        unsigned long entry;
 329        unsigned long badbit;
 330        unsigned long badend;
 331        unsigned long flags;
 332
 333        /* were we called with bad_dma_address? */
 334        badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE);
 335        if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) {
 336                printk(KERN_ERR "Calgary: driver tried unmapping bad DMA "
 337                       "address 0x%Lx\n", dma_addr);
 338                WARN_ON(1);
 339                return;
 340        }
 341
 342        entry = dma_addr >> PAGE_SHIFT;
 343
 344        BUG_ON(entry + npages > tbl->it_size);
 345
 346        tce_free(tbl, entry, npages);
 347
 348        spin_lock_irqsave(&tbl->it_lock, flags);
 349
 350        badbit = verify_bit_range(tbl->it_map, 1, entry, entry + npages);
 351        if (badbit != ~0UL) {
 352                if (printk_ratelimit())
 353                        printk(KERN_ERR "Calgary: bit is off at 0x%lx "
 354                               "tbl %p dma 0x%Lx entry 0x%lx npages %u\n",
 355                               badbit, tbl, dma_addr, entry, npages);
 356        }
 357
 358        __clear_bit_string(tbl->it_map, entry, npages);
 359
 360        spin_unlock_irqrestore(&tbl->it_lock, flags);
 361}
 362
 363static inline struct iommu_table *find_iommu_table(struct device *dev)
 364{
 365        struct pci_dev *pdev;
 366        struct pci_bus *pbus;
 367        struct iommu_table *tbl;
 368
 369        pdev = to_pci_dev(dev);
 370
 371        pbus = pdev->bus;
 372
 373        /* is the device behind a bridge? Look for the root bus */
 374        while (pbus->parent)
 375                pbus = pbus->parent;
 376
 377        tbl = pci_iommu(pbus);
 378
 379        BUG_ON(tbl && (tbl->it_busno != pbus->number));
 380
 381        return tbl;
 382}
 383
 384static void calgary_unmap_sg(struct device *dev,
 385        struct scatterlist *sglist, int nelems, int direction)
 386{
 387        struct iommu_table *tbl = find_iommu_table(dev);
 388        struct scatterlist *s;
 389        int i;
 390
 391        if (!translation_enabled(tbl))
 392                return;
 393
 394        for_each_sg(sglist, s, nelems, i) {
 395                unsigned int npages;
 396                dma_addr_t dma = s->dma_address;
 397                unsigned int dmalen = s->dma_length;
 398
 399                if (dmalen == 0)
 400                        break;
 401
 402                npages = num_dma_pages(dma, dmalen);
 403                iommu_free(tbl, dma, npages);
 404        }
 405}
 406
 407static int calgary_nontranslate_map_sg(struct device* dev,
 408        struct scatterlist *sg, int nelems, int direction)
 409{
 410        struct scatterlist *s;
 411        int i;
 412
 413        for_each_sg(sg, s, nelems, i) {
 414                struct page *p = sg_page(s);
 415
 416                BUG_ON(!p);
 417                s->dma_address = virt_to_bus(sg_virt(s));
 418                s->dma_length = s->length;
 419        }
 420        return nelems;
 421}
 422
 423static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 424        int nelems, int direction)
 425{
 426        struct iommu_table *tbl = find_iommu_table(dev);
 427        struct scatterlist *s;
 428        unsigned long vaddr;
 429        unsigned int npages;
 430        unsigned long entry;
 431        int i;
 432
 433        if (!translation_enabled(tbl))
 434                return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 435
 436        for_each_sg(sg, s, nelems, i) {
 437                BUG_ON(!sg_page(s));
 438
 439                vaddr = (unsigned long) sg_virt(s);
 440                npages = num_dma_pages(vaddr, s->length);
 441
 442                entry = iommu_range_alloc(tbl, npages);
 443                if (entry == bad_dma_address) {
 444                        /* makes sure unmap knows to stop */
 445                        s->dma_length = 0;
 446                        goto error;
 447                }
 448
 449                s->dma_address = (entry << PAGE_SHIFT) | s->offset;
 450
 451                /* insert into HW table */
 452                tce_build(tbl, entry, npages, vaddr & PAGE_MASK,
 453                          direction);
 454
 455                s->dma_length = s->length;
 456        }
 457
 458        return nelems;
 459error:
 460        calgary_unmap_sg(dev, sg, nelems, direction);
 461        for_each_sg(sg, s, nelems, i) {
 462                sg->dma_address = bad_dma_address;
 463                sg->dma_length = 0;
 464        }
 465        return 0;
 466}
 467
 468static dma_addr_t calgary_map_single(struct device *dev, void *vaddr,
 469        size_t size, int direction)
 470{
 471        dma_addr_t dma_handle = bad_dma_address;
 472        unsigned long uaddr;
 473        unsigned int npages;
 474        struct iommu_table *tbl = find_iommu_table(dev);
 475
 476        uaddr = (unsigned long)vaddr;
 477        npages = num_dma_pages(uaddr, size);
 478
 479        if (translation_enabled(tbl))
 480                dma_handle = iommu_alloc(tbl, vaddr, npages, direction);
 481        else
 482                dma_handle = virt_to_bus(vaddr);
 483
 484        return dma_handle;
 485}
 486
 487static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
 488        size_t size, int direction)
 489{
 490        struct iommu_table *tbl = find_iommu_table(dev);
 491        unsigned int npages;
 492
 493        if (!translation_enabled(tbl))
 494                return;
 495
 496        npages = num_dma_pages(dma_handle, size);
 497        iommu_free(tbl, dma_handle, npages);
 498}
 499
 500static void* calgary_alloc_coherent(struct device *dev, size_t size,
 501        dma_addr_t *dma_handle, gfp_t flag)
 502{
 503        void *ret = NULL;
 504        dma_addr_t mapping;
 505        unsigned int npages, order;
 506        struct iommu_table *tbl = find_iommu_table(dev);
 507
 508        size = PAGE_ALIGN(size); /* size rounded up to full pages */
 509        npages = size >> PAGE_SHIFT;
 510        order = get_order(size);
 511
 512        /* alloc enough pages (and possibly more) */
 513        ret = (void *)__get_free_pages(flag, order);
 514        if (!ret)
 515                goto error;
 516        memset(ret, 0, size);
 517
 518        if (translation_enabled(tbl)) {
 519                /* set up tces to cover the allocated range */
 520                mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL);
 521                if (mapping == bad_dma_address)
 522                        goto free;
 523
 524                *dma_handle = mapping;
 525        } else /* non translated slot */
 526                *dma_handle = virt_to_bus(ret);
 527
 528        return ret;
 529
 530free:
 531        free_pages((unsigned long)ret, get_order(size));
 532        ret = NULL;
 533error:
 534        return ret;
 535}
 536
 537static const struct dma_mapping_ops calgary_dma_ops = {
 538        .alloc_coherent = calgary_alloc_coherent,
 539        .map_single = calgary_map_single,
 540        .unmap_single = calgary_unmap_single,
 541        .map_sg = calgary_map_sg,
 542        .unmap_sg = calgary_unmap_sg,
 543};
 544
 545static inline void __iomem * busno_to_bbar(unsigned char num)
 546{
 547        return bus_info[num].bbar;
 548}
 549
 550static inline int busno_to_phbid(unsigned char num)
 551{
 552        return bus_info[num].phbid;
 553}
 554
 555static inline unsigned long split_queue_offset(unsigned char num)
 556{
 557        size_t idx = busno_to_phbid(num);
 558
 559        return split_queue_offsets[idx];
 560}
 561
 562static inline unsigned long tar_offset(unsigned char num)
 563{
 564        size_t idx = busno_to_phbid(num);
 565
 566        return tar_offsets[idx];
 567}
 568
 569static inline unsigned long phb_offset(unsigned char num)
 570{
 571        size_t idx = busno_to_phbid(num);
 572
 573        return phb_offsets[idx];
 574}
 575
 576static inline void __iomem* calgary_reg(void __iomem *bar, unsigned long offset)
 577{
 578        unsigned long target = ((unsigned long)bar) | offset;
 579        return (void __iomem*)target;
 580}
 581
 582static inline int is_calioc2(unsigned short device)
 583{
 584        return (device == PCI_DEVICE_ID_IBM_CALIOC2);
 585}
 586
 587static inline int is_calgary(unsigned short device)
 588{
 589        return (device == PCI_DEVICE_ID_IBM_CALGARY);
 590}
 591
 592static inline int is_cal_pci_dev(unsigned short device)
 593{
 594        return (is_calgary(device) || is_calioc2(device));
 595}
 596
 597static void calgary_tce_cache_blast(struct iommu_table *tbl)
 598{
 599        u64 val;
 600        u32 aer;
 601        int i = 0;
 602        void __iomem *bbar = tbl->bbar;
 603        void __iomem *target;
 604
 605        /* disable arbitration on the bus */
 606        target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_AER_OFFSET);
 607        aer = readl(target);
 608        writel(0, target);
 609
 610        /* read plssr to ensure it got there */
 611        target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_PLSSR_OFFSET);
 612        val = readl(target);
 613
 614        /* poll split queues until all DMA activity is done */
 615        target = calgary_reg(bbar, split_queue_offset(tbl->it_busno));
 616        do {
 617                val = readq(target);
 618                i++;
 619        } while ((val & 0xff) != 0xff && i < 100);
 620        if (i == 100)
 621                printk(KERN_WARNING "Calgary: PCI bus not quiesced, "
 622                       "continuing anyway\n");
 623
 624        /* invalidate TCE cache */
 625        target = calgary_reg(bbar, tar_offset(tbl->it_busno));
 626        writeq(tbl->tar_val, target);
 627
 628        /* enable arbitration */
 629        target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_AER_OFFSET);
 630        writel(aer, target);
 631        (void)readl(target); /* flush */
 632}
 633
 634static void calioc2_tce_cache_blast(struct iommu_table *tbl)
 635{
 636        void __iomem *bbar = tbl->bbar;
 637        void __iomem *target;
 638        u64 val64;
 639        u32 val;
 640        int i = 0;
 641        int count = 1;
 642        unsigned char bus = tbl->it_busno;
 643
 644begin:
 645        printk(KERN_DEBUG "Calgary: CalIOC2 bus 0x%x entering tce cache blast "
 646               "sequence - count %d\n", bus, count);
 647
 648        /* 1. using the Page Migration Control reg set SoftStop */
 649        target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_CTRL);
 650        val = be32_to_cpu(readl(target));
 651        printk(KERN_DEBUG "1a. read 0x%x [LE] from %p\n", val, target);
 652        val |= PMR_SOFTSTOP;
 653        printk(KERN_DEBUG "1b. writing 0x%x [LE] to %p\n", val, target);
 654        writel(cpu_to_be32(val), target);
 655
 656        /* 2. poll split queues until all DMA activity is done */
 657        printk(KERN_DEBUG "2a. starting to poll split queues\n");
 658        target = calgary_reg(bbar, split_queue_offset(bus));
 659        do {
 660                val64 = readq(target);
 661                i++;
 662        } while ((val64 & 0xff) != 0xff && i < 100);
 663        if (i == 100)
 664                printk(KERN_WARNING "CalIOC2: PCI bus not quiesced, "
 665                       "continuing anyway\n");
 666
 667        /* 3. poll Page Migration DEBUG for SoftStopFault */
 668        target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_DEBUG);
 669        val = be32_to_cpu(readl(target));
 670        printk(KERN_DEBUG "3. read 0x%x [LE] from %p\n", val, target);
 671
 672        /* 4. if SoftStopFault - goto (1) */
 673        if (val & PMR_SOFTSTOPFAULT) {
 674                if (++count < 100)
 675                        goto begin;
 676                else {
 677                        printk(KERN_WARNING "CalIOC2: too many SoftStopFaults, "
 678                               "aborting TCE cache flush sequence!\n");
 679                        return; /* pray for the best */
 680                }
 681        }
 682
 683        /* 5. Slam into HardStop by reading PHB_PAGE_MIG_CTRL */
 684        target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_CTRL);
 685        printk(KERN_DEBUG "5a. slamming into HardStop by reading %p\n", target);
 686        val = be32_to_cpu(readl(target));
 687        printk(KERN_DEBUG "5b. read 0x%x [LE] from %p\n", val, target);
 688        target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_DEBUG);
 689        val = be32_to_cpu(readl(target));
 690        printk(KERN_DEBUG "5c. read 0x%x [LE] from %p (debug)\n", val, target);
 691
 692        /* 6. invalidate TCE cache */
 693        printk(KERN_DEBUG "6. invalidating TCE cache\n");
 694        target = calgary_reg(bbar, tar_offset(bus));
 695        writeq(tbl->tar_val, target);
 696
 697        /* 7. Re-read PMCR */
 698        printk(KERN_DEBUG "7a. Re-reading PMCR\n");
 699        target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_CTRL);
 700        val = be32_to_cpu(readl(target));
 701        printk(KERN_DEBUG "7b. read 0x%x [LE] from %p\n", val, target);
 702
 703        /* 8. Remove HardStop */
 704        printk(KERN_DEBUG "8a. removing HardStop from PMCR\n");
 705        target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_CTRL);
 706        val = 0;
 707        printk(KERN_DEBUG "8b. writing 0x%x [LE] to %p\n", val, target);
 708        writel(cpu_to_be32(val), target);
 709        val = be32_to_cpu(readl(target));
 710        printk(KERN_DEBUG "8c. read 0x%x [LE] from %p\n", val, target);
 711}
 712
 713static void __init calgary_reserve_mem_region(struct pci_dev *dev, u64 start,
 714        u64 limit)
 715{
 716        unsigned int numpages;
 717
 718        limit = limit | 0xfffff;
 719        limit++;
 720
 721        numpages = ((limit - start) >> PAGE_SHIFT);
 722        iommu_range_reserve(pci_iommu(dev->bus), start, numpages);
 723}
 724
 725static void __init calgary_reserve_peripheral_mem_1(struct pci_dev *dev)
 726{
 727        void __iomem *target;
 728        u64 low, high, sizelow;
 729        u64 start, limit;
 730        struct iommu_table *tbl = pci_iommu(dev->bus);
 731        unsigned char busnum = dev->bus->number;
 732        void __iomem *bbar = tbl->bbar;
 733
 734        /* peripheral MEM_1 region */
 735        target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_LOW);
 736        low = be32_to_cpu(readl(target));
 737        target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_HIGH);
 738        high = be32_to_cpu(readl(target));
 739        target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_SIZE);
 740        sizelow = be32_to_cpu(readl(target));
 741
 742        start = (high << 32) | low;
 743        limit = sizelow;
 744
 745        calgary_reserve_mem_region(dev, start, limit);
 746}
 747
 748static void __init calgary_reserve_peripheral_mem_2(struct pci_dev *dev)
 749{
 750        void __iomem *target;
 751        u32 val32;
 752        u64 low, high, sizelow, sizehigh;
 753        u64 start, limit;
 754        struct iommu_table *tbl = pci_iommu(dev->bus);
 755        unsigned char busnum = dev->bus->number;
 756        void __iomem *bbar = tbl->bbar;
 757
 758        /* is it enabled? */
 759        target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET);
 760        val32 = be32_to_cpu(readl(target));
 761        if (!(val32 & PHB_MEM2_ENABLE))
 762                return;
 763
 764        target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_LOW);
 765        low = be32_to_cpu(readl(target));
 766        target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_HIGH);
 767        high = be32_to_cpu(readl(target));
 768        target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_SIZE_LOW);
 769        sizelow = be32_to_cpu(readl(target));
 770        target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_SIZE_HIGH);
 771        sizehigh = be32_to_cpu(readl(target));
 772
 773        start = (high << 32) | low;
 774        limit = (sizehigh << 32) | sizelow;
 775
 776        calgary_reserve_mem_region(dev, start, limit);
 777}
 778
 779/*
 780 * some regions of the IO address space do not get translated, so we
 781 * must not give devices IO addresses in those regions. The regions
 782 * are the 640KB-1MB region and the two PCI peripheral memory holes.
 783 * Reserve all of them in the IOMMU bitmap to avoid giving them out
 784 * later.
 785 */
 786static void __init calgary_reserve_regions(struct pci_dev *dev)
 787{
 788        unsigned int npages;
 789        u64 start;
 790        struct iommu_table *tbl = pci_iommu(dev->bus);
 791
 792        /* reserve EMERGENCY_PAGES from bad_dma_address and up */
 793        iommu_range_reserve(tbl, bad_dma_address, EMERGENCY_PAGES);
 794
 795        /* avoid the BIOS/VGA first 640KB-1MB region */
 796        /* for CalIOC2 - avoid the entire first MB */
 797        if (is_calgary(dev->device)) {
 798                start = (640 * 1024);
 799                npages = ((1024 - 640) * 1024) >> PAGE_SHIFT;
 800        } else { /* calioc2 */
 801                start = 0;
 802                npages = (1 * 1024 * 1024) >> PAGE_SHIFT;
 803        }
 804        iommu_range_reserve(tbl, start, npages);
 805
 806        /* reserve the two PCI peripheral memory regions in IO space */
 807        calgary_reserve_peripheral_mem_1(dev);
 808        calgary_reserve_peripheral_mem_2(dev);
 809}
 810
 811static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
 812{
 813        u64 val64;
 814        u64 table_phys;
 815        void __iomem *target;
 816        int ret;
 817        struct iommu_table *tbl;
 818
 819        /* build TCE tables for each PHB */
 820        ret = build_tce_table(dev, bbar);
 821        if (ret)
 822                return ret;
 823
 824        tbl = pci_iommu(dev->bus);
 825        tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space;
 826        tce_free(tbl, 0, tbl->it_size);
 827
 828        if (is_calgary(dev->device))
 829                tbl->chip_ops = &calgary_chip_ops;
 830        else if (is_calioc2(dev->device))
 831                tbl->chip_ops = &calioc2_chip_ops;
 832        else
 833                BUG();
 834
 835        calgary_reserve_regions(dev);
 836
 837        /* set TARs for each PHB */
 838        target = calgary_reg(bbar, tar_offset(dev->bus->number));
 839        val64 = be64_to_cpu(readq(target));
 840
 841        /* zero out all TAR bits under sw control */
 842        val64 &= ~TAR_SW_BITS;
 843        table_phys = (u64)__pa(tbl->it_base);
 844
 845        val64 |= table_phys;
 846
 847        BUG_ON(specified_table_size > TCE_TABLE_SIZE_8M);
 848        val64 |= (u64) specified_table_size;
 849
 850        tbl->tar_val = cpu_to_be64(val64);
 851
 852        writeq(tbl->tar_val, target);
 853        readq(target); /* flush */
 854
 855        return 0;
 856}
 857
 858static void __init calgary_free_bus(struct pci_dev *dev)
 859{
 860        u64 val64;
 861        struct iommu_table *tbl = pci_iommu(dev->bus);
 862        void __iomem *target;
 863        unsigned int bitmapsz;
 864
 865        target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number));
 866        val64 = be64_to_cpu(readq(target));
 867        val64 &= ~TAR_SW_BITS;
 868        writeq(cpu_to_be64(val64), target);
 869        readq(target); /* flush */
 870
 871        bitmapsz = tbl->it_size / BITS_PER_BYTE;
 872        free_pages((unsigned long)tbl->it_map, get_order(bitmapsz));
 873        tbl->it_map = NULL;
 874
 875        kfree(tbl);
 876        
 877        set_pci_iommu(dev->bus, NULL);
 878
 879        /* Can't free bootmem allocated memory after system is up :-( */
 880        bus_info[dev->bus->number].tce_space = NULL;
 881}
 882
 883static void calgary_dump_error_regs(struct iommu_table *tbl)
 884{
 885        void __iomem *bbar = tbl->bbar;
 886        void __iomem *target;
 887        u32 csr, plssr;
 888
 889        target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_CSR_OFFSET);
 890        csr = be32_to_cpu(readl(target));
 891
 892        target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_PLSSR_OFFSET);
 893        plssr = be32_to_cpu(readl(target));
 894
 895        /* If no error, the agent ID in the CSR is not valid */
 896        printk(KERN_EMERG "Calgary: DMA error on Calgary PHB 0x%x, "
 897               "0x%08x@CSR 0x%08x@PLSSR\n", tbl->it_busno, csr, plssr);
 898}
 899
 900static void calioc2_dump_error_regs(struct iommu_table *tbl)
 901{
 902        void __iomem *bbar = tbl->bbar;
 903        u32 csr, csmr, plssr, mck, rcstat;
 904        void __iomem *target;
 905        unsigned long phboff = phb_offset(tbl->it_busno);
 906        unsigned long erroff;
 907        u32 errregs[7];
 908        int i;
 909
 910        /* dump CSR */
 911        target = calgary_reg(bbar, phboff | PHB_CSR_OFFSET);
 912        csr = be32_to_cpu(readl(target));
 913        /* dump PLSSR */
 914        target = calgary_reg(bbar, phboff | PHB_PLSSR_OFFSET);
 915        plssr = be32_to_cpu(readl(target));
 916        /* dump CSMR */
 917        target = calgary_reg(bbar, phboff | 0x290);
 918        csmr = be32_to_cpu(readl(target));
 919        /* dump mck */
 920        target = calgary_reg(bbar, phboff | 0x800);
 921        mck = be32_to_cpu(readl(target));
 922
 923        printk(KERN_EMERG "Calgary: DMA error on CalIOC2 PHB 0x%x\n",
 924               tbl->it_busno);
 925
 926        printk(KERN_EMERG "Calgary: 0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n",
 927               csr, plssr, csmr, mck);
 928
 929        /* dump rest of error regs */
 930        printk(KERN_EMERG "Calgary: ");
 931        for (i = 0; i < ARRAY_SIZE(errregs); i++) {
 932                /* err regs are at 0x810 - 0x870 */
 933                erroff = (0x810 + (i * 0x10));
 934                target = calgary_reg(bbar, phboff | erroff);
 935                errregs[i] = be32_to_cpu(readl(target));
 936                printk("0x%08x@0x%lx ", errregs[i], erroff);
 937        }
 938        printk("\n");
 939
 940        /* root complex status */
 941        target = calgary_reg(bbar, phboff | PHB_ROOT_COMPLEX_STATUS);
 942        rcstat = be32_to_cpu(readl(target));
 943        printk(KERN_EMERG "Calgary: 0x%08x@0x%x\n", rcstat,
 944               PHB_ROOT_COMPLEX_STATUS);
 945}
 946
 947static void calgary_watchdog(unsigned long data)
 948{
 949        struct pci_dev *dev = (struct pci_dev *)data;
 950        struct iommu_table *tbl = pci_iommu(dev->bus);
 951        void __iomem *bbar = tbl->bbar;
 952        u32 val32;
 953        void __iomem *target;
 954
 955        target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_CSR_OFFSET);
 956        val32 = be32_to_cpu(readl(target));
 957
 958        /* If no error, the agent ID in the CSR is not valid */
 959        if (val32 & CSR_AGENT_MASK) {
 960                tbl->chip_ops->dump_error_regs(tbl);
 961
 962                /* reset error */
 963                writel(0, target);
 964
 965                /* Disable bus that caused the error */
 966                target = calgary_reg(bbar, phb_offset(tbl->it_busno) |
 967                                     PHB_CONFIG_RW_OFFSET);
 968                val32 = be32_to_cpu(readl(target));
 969                val32 |= PHB_SLOT_DISABLE;
 970                writel(cpu_to_be32(val32), target);
 971                readl(target); /* flush */
 972        } else {
 973                /* Reset the timer */
 974                mod_timer(&tbl->watchdog_timer, jiffies + 2 * HZ);
 975        }
 976}
 977
 978static void __init calgary_set_split_completion_timeout(void __iomem *bbar,
 979        unsigned char busnum, unsigned long timeout)
 980{
 981        u64 val64;
 982        void __iomem *target;
 983        unsigned int phb_shift = ~0; /* silence gcc */
 984        u64 mask;
 985
 986        switch (busno_to_phbid(busnum)) {
 987        case 0: phb_shift = (63 - 19);
 988                break;
 989        case 1: phb_shift = (63 - 23);
 990                break;
 991        case 2: phb_shift = (63 - 27);
 992                break;
 993        case 3: phb_shift = (63 - 35);
 994                break;
 995        default:
 996                BUG_ON(busno_to_phbid(busnum));
 997        }
 998
 999        target = calgary_reg(bbar, CALGARY_CONFIG_REG);
1000        val64 = be64_to_cpu(readq(target));
1001
1002        /* zero out this PHB's timer bits */
1003        mask = ~(0xFUL << phb_shift);
1004        val64 &= mask;
1005        val64 |= (timeout << phb_shift);
1006        writeq(cpu_to_be64(val64), target);
1007        readq(target); /* flush */
1008}
1009
1010static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev)
1011{
1012        unsigned char busnum = dev->bus->number;
1013        void __iomem *bbar = tbl->bbar;
1014        void __iomem *target;
1015        u32 val;
1016
1017        /*
1018         * CalIOC2 designers recommend setting bit 8 in 0xnDB0 to 1
1019         */
1020        target = calgary_reg(bbar, phb_offset(busnum) | PHB_SAVIOR_L2);
1021        val = cpu_to_be32(readl(target));
1022        val |= 0x00800000;
1023        writel(cpu_to_be32(val), target);
1024}
1025
1026static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev)
1027{
1028        unsigned char busnum = dev->bus->number;
1029
1030        /*
1031         * Give split completion a longer timeout on bus 1 for aic94xx
1032         * http://bugzilla.kernel.org/show_bug.cgi?id=7180
1033         */
1034        if (is_calgary(dev->device) && (busnum == 1))
1035                calgary_set_split_completion_timeout(tbl->bbar, busnum,
1036                                                     CCR_2SEC_TIMEOUT);
1037}
1038
1039static void __init calgary_enable_translation(struct pci_dev *dev)
1040{
1041        u32 val32;
1042        unsigned char busnum;
1043        void __iomem *target;
1044        void __iomem *bbar;
1045        struct iommu_table *tbl;
1046
1047        busnum = dev->bus->number;
1048        tbl = pci_iommu(dev->bus);
1049        bbar = tbl->bbar;
1050
1051        /* enable TCE in PHB Config Register */
1052        target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET);
1053        val32 = be32_to_cpu(readl(target));
1054        val32 |= PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE;
1055
1056        printk(KERN_INFO "Calgary: enabling translation on %s PHB %#x\n",
1057               (dev->device == PCI_DEVICE_ID_IBM_CALGARY) ?
1058               "Calgary" : "CalIOC2", busnum);
1059        printk(KERN_INFO "Calgary: errant DMAs will now be prevented on this "
1060               "bus.\n");
1061
1062        writel(cpu_to_be32(val32), target);
1063        readl(target); /* flush */
1064
1065        init_timer(&tbl->watchdog_timer);
1066        tbl->watchdog_timer.function = &calgary_watchdog;
1067        tbl->watchdog_timer.data = (unsigned long)dev;
1068        mod_timer(&tbl->watchdog_timer, jiffies);
1069}
1070
1071static void __init calgary_disable_translation(struct pci_dev *dev)
1072{
1073        u32 val32;
1074        unsigned char busnum;
1075        void __iomem *target;
1076        void __iomem *bbar;
1077        struct iommu_table *tbl;
1078
1079        busnum = dev->bus->number;
1080        tbl = pci_iommu(dev->bus);
1081        bbar = tbl->bbar;
1082
1083        /* disable TCE in PHB Config Register */
1084        target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET);
1085        val32 = be32_to_cpu(readl(target));
1086        val32 &= ~(PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE);
1087
1088        printk(KERN_INFO "Calgary: disabling translation on PHB %#x!\n", busnum);
1089        writel(cpu_to_be32(val32), target);
1090        readl(target); /* flush */
1091
1092        del_timer_sync(&tbl->watchdog_timer);
1093}
1094
1095static void __init calgary_init_one_nontraslated(struct pci_dev *dev)
1096{
1097        pci_dev_get(dev);
1098        set_pci_iommu(dev->bus, NULL);
1099
1100        /* is the device behind a bridge? */
1101        if (dev->bus->parent)
1102                dev->bus->parent->self = dev;
1103        else
1104                dev->bus->self = dev;
1105}
1106
1107static int __init calgary_init_one(struct pci_dev *dev)
1108{
1109        void __iomem *bbar;
1110        struct iommu_table *tbl;
1111        int ret;
1112
1113        BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM);
1114
1115        bbar = busno_to_bbar(dev->bus->number);
1116        ret = calgary_setup_tar(dev, bbar);
1117        if (ret)
1118                goto done;
1119
1120        pci_dev_get(dev);
1121
1122        if (dev->bus->parent) {
1123                if (dev->bus->parent->self)
1124                        printk(KERN_WARNING "Calgary: IEEEE, dev %p has "
1125                               "bus->parent->self!\n", dev);
1126                dev->bus->parent->self = dev;
1127        } else
1128                dev->bus->self = dev;
1129
1130        tbl = pci_iommu(dev->bus);
1131        tbl->chip_ops->handle_quirks(tbl, dev);
1132
1133        calgary_enable_translation(dev);
1134
1135        return 0;
1136
1137done:
1138        return ret;
1139}
1140
1141static int __init calgary_locate_bbars(void)
1142{
1143        int ret;
1144        int rioidx, phb, bus;
1145        void __iomem *bbar;
1146        void __iomem *target;
1147        unsigned long offset;
1148        u8 start_bus, end_bus;
1149        u32 val;
1150
1151        ret = -ENODATA;
1152        for (rioidx = 0; rioidx < rio_table_hdr->num_rio_dev; rioidx++) {
1153                struct rio_detail *rio = rio_devs[rioidx];
1154
1155                if ((rio->type != COMPAT_CALGARY) && (rio->type != ALT_CALGARY))
1156                        continue;
1157
1158                /* map entire 1MB of Calgary config space */
1159                bbar = ioremap_nocache(rio->BBAR, 1024 * 1024);
1160                if (!bbar)
1161                        goto error;
1162
1163                for (phb = 0; phb < PHBS_PER_CALGARY; phb++) {
1164                        offset = phb_debug_offsets[phb] | PHB_DEBUG_STUFF_OFFSET;
1165                        target = calgary_reg(bbar, offset);
1166
1167                        val = be32_to_cpu(readl(target));
1168
1169                        start_bus = (u8)((val & 0x00FF0000) >> 16);
1170                        end_bus = (u8)((val & 0x0000FF00) >> 8);
1171
1172                        if (end_bus) {
1173                                for (bus = start_bus; bus <= end_bus; bus++) {
1174                                        bus_info[bus].bbar = bbar;
1175                                        bus_info[bus].phbid = phb;
1176                                }
1177                        } else {
1178                                bus_info[start_bus].bbar = bbar;
1179                                bus_info[start_bus].phbid = phb;
1180                        }
1181                }
1182        }
1183
1184        return 0;
1185
1186error:
1187        /* scan bus_info and iounmap any bbars we previously ioremap'd */
1188        for (bus = 0; bus < ARRAY_SIZE(bus_info); bus++)
1189                if (bus_info[bus].bbar)
1190                        iounmap(bus_info[bus].bbar);
1191
1192        return ret;
1193}
1194
1195static int __init calgary_init(void)
1196{
1197        int ret;
1198        struct pci_dev *dev = NULL;
1199        struct calgary_bus_info *info;
1200
1201        ret = calgary_locate_bbars();
1202        if (ret)
1203                return ret;
1204
1205        do {
1206                dev = pci_get_device(PCI_VENDOR_ID_IBM, PCI_ANY_ID, dev);
1207                if (!dev)
1208                        break;
1209                if (!is_cal_pci_dev(dev->device))
1210                        continue;
1211
1212                info = &bus_info[dev->bus->number];
1213                if (info->translation_disabled) {
1214                        calgary_init_one_nontraslated(dev);
1215                        continue;
1216                }
1217
1218                if (!info->tce_space && !translate_empty_slots)
1219                        continue;
1220
1221                ret = calgary_init_one(dev);
1222                if (ret)
1223                        goto error;
1224        } while (1);
1225
1226        return ret;
1227
1228error:
1229        do {
1230                dev = pci_get_device_reverse(PCI_VENDOR_ID_IBM,
1231                                             PCI_ANY_ID, dev);
1232                if (!dev)
1233                        break;
1234                if (!is_cal_pci_dev(dev->device))
1235                        continue;
1236
1237                info = &bus_info[dev->bus->number];
1238                if (info->translation_disabled) {
1239                        pci_dev_put(dev);
1240                        continue;
1241                }
1242                if (!info->tce_space && !translate_empty_slots)
1243                        continue;
1244
1245                calgary_disable_translation(dev);
1246                calgary_free_bus(dev);
1247                pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */
1248        } while (1);
1249
1250        return ret;
1251}
1252
1253static inline int __init determine_tce_table_size(u64 ram)
1254{
1255        int ret;
1256
1257        if (specified_table_size != TCE_TABLE_SIZE_UNSPECIFIED)
1258                return specified_table_size;
1259
1260        /*
1261         * Table sizes are from 0 to 7 (TCE_TABLE_SIZE_64K to
1262         * TCE_TABLE_SIZE_8M). Table size 0 has 8K entries and each
1263         * larger table size has twice as many entries, so shift the
1264         * max ram address by 13 to divide by 8K and then look at the
1265         * order of the result to choose between 0-7.
1266         */
1267        ret = get_order(ram >> 13);
1268        if (ret > TCE_TABLE_SIZE_8M)
1269                ret = TCE_TABLE_SIZE_8M;
1270
1271        return ret;
1272}
1273
1274static int __init build_detail_arrays(void)
1275{
1276        unsigned long ptr;
1277        int i, scal_detail_size, rio_detail_size;
1278
1279        if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){
1280                printk(KERN_WARNING
1281                        "Calgary: MAX_NUMNODES too low! Defined as %d, "
1282                        "but system has %d nodes.\n",
1283                        MAX_NUMNODES, rio_table_hdr->num_scal_dev);
1284                return -ENODEV;
1285        }
1286
1287        switch (rio_table_hdr->version){
1288        case 2:
1289                scal_detail_size = 11;
1290                rio_detail_size = 13;
1291                break;
1292        case 3:
1293                scal_detail_size = 12;
1294                rio_detail_size = 15;
1295                break;
1296        default:
1297                printk(KERN_WARNING
1298                       "Calgary: Invalid Rio Grande Table Version: %d\n",
1299                       rio_table_hdr->version);
1300                return -EPROTO;
1301        }
1302
1303        ptr = ((unsigned long)rio_table_hdr) + 3;
1304        for (i = 0; i < rio_table_hdr->num_scal_dev;
1305                    i++, ptr += scal_detail_size)
1306                scal_devs[i] = (struct scal_detail *)ptr;
1307
1308        for (i = 0; i < rio_table_hdr->num_rio_dev;
1309                    i++, ptr += rio_detail_size)
1310                rio_devs[i] = (struct rio_detail *)ptr;
1311
1312        return 0;
1313}
1314
1315static int __init calgary_bus_has_devices(int bus, unsigned short pci_dev)
1316{
1317        int dev;
1318        u32 val;
1319
1320        if (pci_dev == PCI_DEVICE_ID_IBM_CALIOC2) {
1321                /*
1322                 * FIXME: properly scan for devices accross the
1323                 * PCI-to-PCI bridge on every CalIOC2 port.
1324                 */
1325                return 1;
1326        }
1327
1328        for (dev = 1; dev < 8; dev++) {
1329                val = read_pci_config(bus, dev, 0, 0);
1330                if (val != 0xffffffff)
1331                        break;
1332        }
1333        return (val != 0xffffffff);
1334}
1335
1336void __init detect_calgary(void)
1337{
1338        int bus;
1339        void *tbl;
1340        int calgary_found = 0;
1341        unsigned long ptr;
1342        unsigned int offset, prev_offset;
1343        int ret;
1344
1345        /*
1346         * if the user specified iommu=off or iommu=soft or we found
1347         * another HW IOMMU already, bail out.
1348         */
1349        if (swiotlb || no_iommu || iommu_detected)
1350                return;
1351
1352        if (!use_calgary)
1353                return;
1354
1355        if (!early_pci_allowed())
1356                return;
1357
1358        printk(KERN_DEBUG "Calgary: detecting Calgary via BIOS EBDA area\n");
1359
1360        ptr = (unsigned long)phys_to_virt(get_bios_ebda());
1361
1362        rio_table_hdr = NULL;
1363        prev_offset = 0;
1364        offset = 0x180;
1365        /*
1366         * The next offset is stored in the 1st word.
1367         * Only parse up until the offset increases:
1368         */
1369        while (offset > prev_offset) {
1370                /* The block id is stored in the 2nd word */
1371                if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){
1372                        /* set the pointer past the offset & block id */
1373                        rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
1374                        break;
1375                }
1376                prev_offset = offset;
1377                offset = *((unsigned short *)(ptr + offset));
1378        }
1379        if (!rio_table_hdr) {
1380                printk(KERN_DEBUG "Calgary: Unable to locate Rio Grande table "
1381                       "in EBDA - bailing!\n");
1382                return;
1383        }
1384
1385        ret = build_detail_arrays();
1386        if (ret) {
1387                printk(KERN_DEBUG "Calgary: build_detail_arrays ret %d\n", ret);
1388                return;
1389        }
1390
1391        specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);
1392
1393        for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
1394                struct calgary_bus_info *info = &bus_info[bus];
1395                unsigned short pci_device;
1396                u32 val;
1397
1398                val = read_pci_config(bus, 0, 0, 0);
1399                pci_device = (val & 0xFFFF0000) >> 16;
1400
1401                if (!is_cal_pci_dev(pci_device))
1402                        continue;
1403
1404                if (info->translation_disabled)
1405                        continue;
1406
1407                if (calgary_bus_has_devices(bus, pci_device) ||
1408                    translate_empty_slots) {
1409                        tbl = alloc_tce_table();
1410                        if (!tbl)
1411                                goto cleanup;
1412                        info->tce_space = tbl;
1413                        calgary_found = 1;
1414                }
1415        }
1416
1417        printk(KERN_DEBUG "Calgary: finished detection, Calgary %s\n",
1418               calgary_found ? "found" : "not found");
1419
1420        if (calgary_found) {
1421                iommu_detected = 1;
1422                calgary_detected = 1;
1423                printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n");
1424                printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, "
1425                       "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size,
1426                       debugging ? "enabled" : "disabled");
1427        }
1428        return;
1429
1430cleanup:
1431        for (--bus; bus >= 0; --bus) {
1432                struct calgary_bus_info *info = &bus_info[bus];
1433
1434                if (info->tce_space)
1435                        free_tce_table(info->tce_space);
1436        }
1437}
1438
1439int __init calgary_iommu_init(void)
1440{
1441        int ret;
1442
1443        if (no_iommu || swiotlb)
1444                return -ENODEV;
1445
1446        if (!calgary_detected)
1447                return -ENODEV;
1448
1449        /* ok, we're trying to use Calgary - let's roll */
1450        printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
1451
1452        ret = calgary_init();
1453        if (ret) {
1454                printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
1455                       "falling back to no_iommu\n", ret);
1456                if (end_pfn > MAX_DMA32_PFN)
1457                        printk(KERN_ERR "WARNING more than 4GB of memory, "
1458                                        "32bit PCI may malfunction.\n");
1459                return ret;
1460        }
1461
1462        force_iommu = 1;
1463        bad_dma_address = 0x0;
1464        dma_ops = &calgary_dma_ops;
1465
1466        return 0;
1467}
1468
1469static int __init calgary_parse_options(char *p)
1470{
1471        unsigned int bridge;
1472        size_t len;
1473        char* endp;
1474
1475        while (*p) {
1476                if (!strncmp(p, "64k", 3))
1477                        specified_table_size = TCE_TABLE_SIZE_64K;
1478                else if (!strncmp(p, "128k", 4))
1479                        specified_table_size = TCE_TABLE_SIZE_128K;
1480                else if (!strncmp(p, "256k", 4))
1481                        specified_table_size = TCE_TABLE_SIZE_256K;
1482                else if (!strncmp(p, "512k", 4))
1483                        specified_table_size = TCE_TABLE_SIZE_512K;
1484                else if (!strncmp(p, "1M", 2))
1485                        specified_table_size = TCE_TABLE_SIZE_1M;
1486                else if (!strncmp(p, "2M", 2))
1487                        specified_table_size = TCE_TABLE_SIZE_2M;
1488                else if (!strncmp(p, "4M", 2))
1489                        specified_table_size = TCE_TABLE_SIZE_4M;
1490                else if (!strncmp(p, "8M", 2))
1491                        specified_table_size = TCE_TABLE_SIZE_8M;
1492
1493                len = strlen("translate_empty_slots");
1494                if (!strncmp(p, "translate_empty_slots", len))
1495                        translate_empty_slots = 1;
1496
1497                len = strlen("disable");
1498                if (!strncmp(p, "disable", len)) {
1499                        p += len;
1500                        if (*p == '=')
1501                                ++p;
1502                        if (*p == '\0')
1503                                break;
1504                        bridge = simple_strtol(p, &endp, 0);
1505                        if (p == endp)
1506                                break;
1507
1508                        if (bridge < MAX_PHB_BUS_NUM) {
1509                                printk(KERN_INFO "Calgary: disabling "
1510                                       "translation for PHB %#x\n", bridge);
1511                                bus_info[bridge].translation_disabled = 1;
1512                        }
1513                }
1514
1515                p = strpbrk(p, ",");
1516                if (!p)
1517                        break;
1518
1519                p++; /* skip ',' */
1520        }
1521        return 1;
1522}
1523__setup("calgary=", calgary_parse_options);
1524
1525static void __init calgary_fixup_one_tce_space(struct pci_dev *dev)
1526{
1527        struct iommu_table *tbl;
1528        unsigned int npages;
1529        int i;
1530
1531        tbl = pci_iommu(dev->bus);
1532
1533        for (i = 0; i < 4; i++) {
1534                struct resource *r = &dev->resource[PCI_BRIDGE_RESOURCES + i];
1535
1536                /* Don't give out TCEs that map MEM resources */
1537                if (!(r->flags & IORESOURCE_MEM))
1538                        continue;
1539
1540                /* 0-based? we reserve the whole 1st MB anyway */
1541                if (!r->start)
1542                        continue;
1543
1544                /* cover the whole region */
1545                npages = (r->end - r->start) >> PAGE_SHIFT;
1546                npages++;
1547
1548                iommu_range_reserve(tbl, r->start, npages);
1549        }
1550}
1551
1552static int __init calgary_fixup_tce_spaces(void)
1553{
1554        struct pci_dev *dev = NULL;
1555        struct calgary_bus_info *info;
1556
1557        if (no_iommu || swiotlb || !calgary_detected)
1558                return -ENODEV;
1559
1560        printk(KERN_DEBUG "Calgary: fixing up tce spaces\n");
1561
1562        do {
1563                dev = pci_get_device(PCI_VENDOR_ID_IBM, PCI_ANY_ID, dev);
1564                if (!dev)
1565                        break;
1566                if (!is_cal_pci_dev(dev->device))
1567                        continue;
1568
1569                info = &bus_info[dev->bus->number];
1570                if (info->translation_disabled)
1571                        continue;
1572
1573                if (!info->tce_space)
1574                        continue;
1575
1576                calgary_fixup_one_tce_space(dev);
1577
1578        } while (1);
1579
1580        return 0;
1581}
1582
1583/*
1584 * We need to be call after pcibios_assign_resources (fs_initcall level)
1585 * and before device_initcall.
1586 */
1587rootfs_initcall(calgary_fixup_tce_spaces);
1588