19c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/* 29c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * This file is subject to the terms and conditions of the GNU General Public 39c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * License. See the file "COPYING" in the main directory of this archive 49c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * for more details. 59c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 69c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Copyright (C) 2003-2005 Silicon Graphics, Inc. All Rights Reserved. 79c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 89c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 99c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule#include <linux/types.h> 109c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule#include <linux/interrupt.h> 119c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule#include <linux/pci.h> 1281f6527bd322ef1f3a58c2c438b9ded3bd8f606aAkinobu Mita#include <linux/bitmap.h> 135a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 14bd3ff1943509e641a34f2d8dd1d41ed12a4476c1Paul Gortmaker#include <linux/export.h> 159c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule#include <asm/sn/sn_sal.h> 169c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule#include <asm/sn/addrs.h> 171fa92957282e4595727c1a21bf6687ea5a2d612fTony Luck#include <asm/sn/io.h> 189c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule#include <asm/sn/pcidev.h> 199c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule#include <asm/sn/pcibus_provider_defs.h> 209c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule#include <asm/sn/tioca_provider.h> 219c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2253493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargavau32 tioca_gart_found; 239c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark MauleEXPORT_SYMBOL(tioca_gart_found); /* used by agp-sgi */ 249c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 259c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark MauleLIST_HEAD(tioca_list); 269c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark MauleEXPORT_SYMBOL(tioca_list); /* used by agp-sgi */ 279c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 289c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maulestatic int tioca_gart_init(struct tioca_kernel *); 299c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 309c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 319c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_gart_init - Initialize SGI TIOCA GART 329c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @tioca_common: ptr to common prom/kernel struct identifying the 339c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 349c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * If the indicated tioca has devices present, initialize its associated 359c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * GART MMR's and kernel memory. 369c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 379c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maulestatic int 389c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Mauletioca_gart_init(struct tioca_kernel *tioca_kern) 399c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 4053493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u64 ap_reg; 4153493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u64 offset; 429c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct page *tmp; 439c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_common *tioca_common; 44b3e5b5b2277f9c047082dcb309f665fe8b5706c1Al Viro struct tioca __iomem *ca_base; 459c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 469c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_common = tioca_kern->ca_common; 47b3e5b5b2277f9c047082dcb309f665fe8b5706c1Al Viro ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base; 489c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 499c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (list_empty(tioca_kern->ca_devices)) 509c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return 0; 519c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 529c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg = 0; 539c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 549c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 559c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Validate aperature size 569c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 579c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 589c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule switch (CA_APERATURE_SIZE >> 20) { 599c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 4: 609c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x3ff << CA_GART_AP_SIZE_SHFT); /* 4MB */ 619c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 629c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 8: 639c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x3fe << CA_GART_AP_SIZE_SHFT); /* 8MB */ 649c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 659c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 16: 669c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x3fc << CA_GART_AP_SIZE_SHFT); /* 16MB */ 679c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 689c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 32: 699c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x3f8 << CA_GART_AP_SIZE_SHFT); /* 32 MB */ 709c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 719c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 64: 729c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x3f0 << CA_GART_AP_SIZE_SHFT); /* 64 MB */ 739c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 749c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 128: 759c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x3e0 << CA_GART_AP_SIZE_SHFT); /* 128 MB */ 769c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 779c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 256: 789c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x3c0 << CA_GART_AP_SIZE_SHFT); /* 256 MB */ 799c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 809c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 512: 819c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x380 << CA_GART_AP_SIZE_SHFT); /* 512 MB */ 829c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 839c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 1024: 849c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x300 << CA_GART_AP_SIZE_SHFT); /* 1GB */ 859c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 869c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 2048: 879c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x200 << CA_GART_AP_SIZE_SHFT); /* 2GB */ 889c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 899c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule case 4096: 909c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (0x000 << CA_GART_AP_SIZE_SHFT); /* 4 GB */ 919c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 929c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule default: 939c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule printk(KERN_ERR "%s: Invalid CA_APERATURE_SIZE " 94d4ed80841ad4a1d59decccfbe2d010558568c5fbHarvey Harrison "0x%lx\n", __func__, (ulong) CA_APERATURE_SIZE); 959c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return -1; 969c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 979c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 989c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 999c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Set up other aperature parameters 1009c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 1019c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1029c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (PAGE_SIZE >= 16384) { 1039c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_ap_pagesize = 16384; 1049c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= CA_GART_PAGE_SIZE; 1059c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } else { 1069c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_ap_pagesize = 4096; 1079c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 1089c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1099c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_ap_size = CA_APERATURE_SIZE; 1109c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_ap_bus_base = CA_APERATURE_BASE; 1119c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gart_entries = 1129c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_ap_size / tioca_kern->ca_ap_pagesize; 1139c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1149c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= (CA_GART_AP_ENB_AGP | CA_GART_AP_ENB_PCI); 1159c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ap_reg |= tioca_kern->ca_ap_bus_base; 1169c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1179c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 1189c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Allocate and set up the GART 1199c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 1209c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1219c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gart_size = tioca_kern->ca_gart_entries * sizeof(u64); 1229c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tmp = 1239c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule alloc_pages_node(tioca_kern->ca_closest_node, 1249c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule GFP_KERNEL | __GFP_ZERO, 1259c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule get_order(tioca_kern->ca_gart_size)); 1269c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1279c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!tmp) { 1289c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule printk(KERN_ERR "%s: Could not allocate " 129e088a4ad7fa53c3dc3c29f930025f41ccf01953eMatthew Wilcox "%llu bytes (order %d) for GART\n", 130d4ed80841ad4a1d59decccfbe2d010558568c5fbHarvey Harrison __func__, 1319c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gart_size, 1329c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule get_order(tioca_kern->ca_gart_size)); 1339c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return -ENOMEM; 1349c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 1359c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1369c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gart = page_address(tmp); 1379c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gart_coretalk_addr = 1389c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule PHYS_TO_TIODMA(virt_to_phys(tioca_kern->ca_gart)); 1399c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1409c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 1419c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Compute PCI/AGP convenience fields 1429c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 1439c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1449c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule offset = CA_PCI32_MAPPED_BASE - CA_APERATURE_BASE; 1459c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pciap_base = CA_PCI32_MAPPED_BASE; 1469c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pciap_size = CA_PCI32_MAPPED_SIZE; 1479c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pcigart_start = offset / tioca_kern->ca_ap_pagesize; 1489c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pcigart_base = 1499c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gart_coretalk_addr + offset; 1509c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pcigart = 1519c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule &tioca_kern->ca_gart[tioca_kern->ca_pcigart_start]; 1529c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pcigart_entries = 1539c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pciap_size / tioca_kern->ca_ap_pagesize; 1549c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pcigart_pagemap = 155f96cb1f0580324b95b7219466312a376a59a796fPekka Enberg kzalloc(tioca_kern->ca_pcigart_entries / 8, GFP_KERNEL); 1569c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!tioca_kern->ca_pcigart_pagemap) { 1579c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule free_pages((unsigned long)tioca_kern->ca_gart, 1589c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule get_order(tioca_kern->ca_gart_size)); 1599c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return -1; 1609c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 1619c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1629c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule offset = CA_AGP_MAPPED_BASE - CA_APERATURE_BASE; 1639c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gfxap_base = CA_AGP_MAPPED_BASE; 1649c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gfxap_size = CA_AGP_MAPPED_SIZE; 1659c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gfxgart_start = offset / tioca_kern->ca_ap_pagesize; 1669c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gfxgart_base = 1679c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gart_coretalk_addr + offset; 1689c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gfxgart = 1699c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule &tioca_kern->ca_gart[tioca_kern->ca_gfxgart_start]; 1709c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gfxgart_entries = 1719c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gfxap_size / tioca_kern->ca_ap_pagesize; 1729c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1739c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 1749c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * various control settings: 1759c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * use agp op-combining 1769c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * use GET semantics to fetch memory 1779c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * participate in coherency domain 1784628d7cada7a19166ba8fe57f5ef0f0009694e1eMark Maule * DISABLE GART PREFETCHING due to hw bug tracked in SGI PV930029 1799c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 1809c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1815fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule __sn_setq_relaxed(&ca_base->ca_control1, 1825fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule CA_AGPDMA_OP_ENB_COMBDELAY); /* PV895469 ? */ 1835fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM); 1845fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule __sn_setq_relaxed(&ca_base->ca_control2, 1855fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule (0x2ull << CA_GART_MEM_PARAM_SHFT)); 1869c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_gart_iscoherent = 1; 1875fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule __sn_clrq_relaxed(&ca_base->ca_control2, 1885fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule (CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB)); 1899c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1909c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 1919c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Unmask GART fetch error interrupts. Clear residual errors first. 1929c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 1939c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1945fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule writeq(CA_GART_FETCH_ERR, &ca_base->ca_int_status_alias); 1955fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule writeq(CA_GART_FETCH_ERR, &ca_base->ca_mult_error_alias); 1965fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule __sn_clrq_relaxed(&ca_base->ca_int_mask, CA_GART_FETCH_ERR); 1979c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 1989c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 1999c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Program the aperature and gart registers in TIOCA 2009c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 2019c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2025fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule writeq(ap_reg, &ca_base->ca_gart_aperature); 2035fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule writeq(tioca_kern->ca_gart_coretalk_addr|1, &ca_base->ca_gart_ptr_table); 2049c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2059c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return 0; 2069c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 2079c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2089c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 2099c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_fastwrite_enable - enable AGP FW for a tioca and its functions 2109c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @tioca_kernel: structure representing the CA 2119c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 2129c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Given a CA, scan all attached functions making sure they all support 2139c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * FastWrite. If so, enable FastWrite for all functions and the CA itself. 2149c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 2159c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2169c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maulevoid 2179c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Mauletioca_fastwrite_enable(struct tioca_kernel *tioca_kern) 2189c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 2199c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule int cap_ptr; 22053493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u32 reg; 221b3e5b5b2277f9c047082dcb309f665fe8b5706c1Al Viro struct tioca __iomem *tioca_base; 2229c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct pci_dev *pdev; 2239c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_common *common; 2249c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2259c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule common = tioca_kern->ca_common; 2269c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2279c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 2289c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Scan all vga controllers on this bus making sure they all 22972fdbdce3d52282f8ea95f512e871791256754e6Simon Arlott * support FW. If not, return. 2309c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 2319c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2329c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) { 2339c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8)) 2349c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule continue; 2359c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2369c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); 2379c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!cap_ptr) 2389c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return; /* no AGP CAP means no FW */ 2399c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2409c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule pci_read_config_dword(pdev, cap_ptr + PCI_AGP_STATUS, ®); 2419c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!(reg & PCI_AGP_STATUS_FW)) 2429c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return; /* function doesn't support FW */ 2439c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 2449c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2459c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 2469c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Set fw for all vga fn's 2479c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 2489c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2499c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) { 2509c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8)) 2519c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule continue; 2529c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2539c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); 2549c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule pci_read_config_dword(pdev, cap_ptr + PCI_AGP_COMMAND, ®); 2559c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule reg |= PCI_AGP_COMMAND_FW; 2569c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule pci_write_config_dword(pdev, cap_ptr + PCI_AGP_COMMAND, reg); 2579c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 2589c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2599c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 2609c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Set ca's fw to match 2619c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 2629c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 263b3e5b5b2277f9c047082dcb309f665fe8b5706c1Al Viro tioca_base = (struct tioca __iomem*)common->ca_common.bs_base; 2645fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE); 2659c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 2669c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2679c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark MauleEXPORT_SYMBOL(tioca_fastwrite_enable); /* used by agp-sgi */ 2689c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2699c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 2709c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_dma_d64 - create a DMA mapping using 64-bit direct mode 2719c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @paddr: system physical address 2729c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 2739c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Map @paddr into 64-bit CA bus space. No device context is necessary. 2749c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Bits 53:0 come from the coretalk address. We just need to mask in the 2759c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * following optional bits of the 64-bit pci address: 2769c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 2779c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 63:60 - Coretalk Packet Type - 0x1 for Mem Get/Put (coherent) 2789c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 0x2 for PIO (non-coherent) 2799c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * We will always use 0x1 2809c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 55:55 - Swap bytes Currently unused 2819c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 28253493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargavastatic u64 2839c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Mauletioca_dma_d64(unsigned long paddr) 2849c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 2859c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule dma_addr_t bus_addr; 2869c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2879c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule bus_addr = PHYS_TO_TIODMA(paddr); 2889c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2899c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule BUG_ON(!bus_addr); 2909c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule BUG_ON(bus_addr >> 54); 2919c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2929c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* Set upper nibble to Cache Coherent Memory op */ 2939c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule bus_addr |= (1UL << 60); 2949c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2959c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return bus_addr; 2969c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 2979c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 2989c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 2999c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_dma_d48 - create a DMA mapping using 48-bit direct mode 3009c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @pdev: linux pci_dev representing the function 3019c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @paddr: system physical address 3029c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 3039c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Map @paddr into 64-bit bus space of the CA associated with @pcidev_info. 3049c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 3059c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * The CA agp 48 bit direct address falls out as follows: 3069c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 3079c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * When direct mapping AGP addresses, the 48 bit AGP address is 3089c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * constructed as follows: 3099c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 3109c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * [47:40] - Low 8 bits of the page Node ID extracted from coretalk 3119c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * address [47:40]. The upper 8 node bits are fixed 3129c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * and come from the xxx register bits [5:0] 3139c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * [39:38] - Chiplet ID extracted from coretalk address [39:38] 3149c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * [37:00] - node offset extracted from coretalk address [37:00] 3159c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 3169c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Since the node id in general will be non-zero, and the chiplet id 3179c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * will always be non-zero, it follows that the device must support 3189c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * a dma mask of at least 0xffffffffff (40 bits) to target node 0 3199c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * and in general should be 0xffffffffffff (48 bits) to target nodes 3209c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * up to 255. Nodes above 255 need the support of the xxx register, 3219c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * and so a given CA can only directly target nodes in the range 3229c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * xxx - xxx+255. 3239c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 32453493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargavastatic u64 32553493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargavatioca_dma_d48(struct pci_dev *pdev, u64 paddr) 3269c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 3279c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_common *tioca_common; 328b3e5b5b2277f9c047082dcb309f665fe8b5706c1Al Viro struct tioca __iomem *ca_base; 32953493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u64 ct_addr; 3309c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule dma_addr_t bus_addr; 33153493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u32 node_upper; 33253493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u64 agp_dma_extn; 3339c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev); 3349c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3359c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; 336b3e5b5b2277f9c047082dcb309f665fe8b5706c1Al Viro ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base; 3379c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3389c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ct_addr = PHYS_TO_TIODMA(paddr); 3399c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!ct_addr) 3409c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return 0; 3419c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 34292a582ed2757456ca9599f8b4ea2064f2154eb02Prarit Bhargava bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL); 3439c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule node_upper = ct_addr >> 48; 3449c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3459c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (node_upper > 64) { 3469c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule printk(KERN_ERR "%s: coretalk addr 0x%p node id out " 347d4ed80841ad4a1d59decccfbe2d010558568c5fbHarvey Harrison "of range\n", __func__, (void *)ct_addr); 3489c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return 0; 3499c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 3509c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3515fbcf9a5c6904bd563f584d12d1f4d3f68a19d7dMark Maule agp_dma_extn = __sn_readq_relaxed(&ca_base->ca_agp_dma_addr_extn); 3529c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) { 3539c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule printk(KERN_ERR "%s: coretalk upper node (%u) " 354e088a4ad7fa53c3dc3c29f930025f41ccf01953eMatthew Wilcox "mismatch with ca_agp_dma_addr_extn (%llu)\n", 355d4ed80841ad4a1d59decccfbe2d010558568c5fbHarvey Harrison __func__, 3569c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule node_upper, (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)); 3579c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return 0; 3589c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 3599c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3609c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return bus_addr; 3619c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 3629c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3639c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 3649c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_dma_mapped - create a DMA mapping using a CA GART 3659c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @pdev: linux pci_dev representing the function 3669c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @paddr: host physical address to map 3679c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @req_size: len (bytes) to map 3689c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 3699c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Map @paddr into CA address space using the GART mechanism. The mapped 37072fdbdce3d52282f8ea95f512e871791256754e6Simon Arlott * dma_addr_t is guaranteed to be contiguous in CA bus space. 3719c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 3729c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maulestatic dma_addr_t 373e088a4ad7fa53c3dc3c29f930025f41ccf01953eMatthew Wilcoxtioca_dma_mapped(struct pci_dev *pdev, unsigned long paddr, size_t req_size) 3749c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 37581f6527bd322ef1f3a58c2c438b9ded3bd8f606aAkinobu Mita int ps, ps_shift, entry, entries, mapsize; 37653493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u64 xio_addr, end_xio_addr; 3779c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_common *tioca_common; 3789c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_kernel *tioca_kern; 3799c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule dma_addr_t bus_addr = 0; 3809c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_dmamap *ca_dmamap; 3819c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule void *map; 3829c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule unsigned long flags; 38353b3531bbbf70ac7551b32d1acc229d94de52658Alexey Dobriyan struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev); 3849c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3859c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; 3869c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private; 3879c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3889c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule xio_addr = PHYS_TO_TIODMA(paddr); 3899c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!xio_addr) 3909c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return 0; 3919c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3929c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule spin_lock_irqsave(&tioca_kern->ca_lock, flags); 3939c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 3949c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 3959c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * allocate a map struct 3969c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 3979c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 398f96cb1f0580324b95b7219466312a376a59a796fPekka Enberg ca_dmamap = kzalloc(sizeof(struct tioca_dmamap), GFP_ATOMIC); 3999c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!ca_dmamap) 4009c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule goto map_return; 4019c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4029c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 4039c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Locate free entries that can hold req_size. Account for 4049c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * unaligned start/length when allocating. 4059c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 4069c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4079c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ps = tioca_kern->ca_ap_pagesize; /* will be power of 2 */ 4089c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ps_shift = ffs(ps) - 1; 4099c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule end_xio_addr = xio_addr + req_size - 1; 4109c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4119c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule entries = (end_xio_addr >> ps_shift) - (xio_addr >> ps_shift) + 1; 4129c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4139c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule map = tioca_kern->ca_pcigart_pagemap; 4149c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule mapsize = tioca_kern->ca_pcigart_entries; 4159c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 41681f6527bd322ef1f3a58c2c438b9ded3bd8f606aAkinobu Mita entry = bitmap_find_next_zero_area(map, mapsize, 0, entries, 0); 41781f6527bd322ef1f3a58c2c438b9ded3bd8f606aAkinobu Mita if (entry >= mapsize) { 4186bf6a1a49377c32a02939ec835553703994f3e41Julia Lawall kfree(ca_dmamap); 4199c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule goto map_return; 4206bf6a1a49377c32a02939ec835553703994f3e41Julia Lawall } 4219c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 42281f6527bd322ef1f3a58c2c438b9ded3bd8f606aAkinobu Mita bitmap_set(map, entry, entries); 4239c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4249c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule bus_addr = tioca_kern->ca_pciap_base + (entry * ps); 4259c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4269c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ca_dmamap->cad_dma_addr = bus_addr; 4279c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ca_dmamap->cad_gart_size = entries; 4289c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ca_dmamap->cad_gart_entry = entry; 4293ea8b477b4b9d3e75b5e9b8aea41259f45031823Mark Maule list_add(&ca_dmamap->cad_list, &tioca_kern->ca_dmamaps); 4309c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4319c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (xio_addr % ps) { 4329c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr); 4339c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule bus_addr += xio_addr & (ps - 1); 4349c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule xio_addr &= ~(ps - 1); 4359c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule xio_addr += ps; 4369c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule entry++; 4379c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 4389c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4399c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule while (xio_addr < end_xio_addr) { 4409c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr); 4419c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule xio_addr += ps; 4429c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule entry++; 4439c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 4449c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4459c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_tlbflush(tioca_kern); 4469c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4479c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maulemap_return: 4489c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule spin_unlock_irqrestore(&tioca_kern->ca_lock, flags); 4499c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return bus_addr; 4509c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 4519c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4529c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 4539c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_dma_unmap - release CA mapping resources 4549c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @pdev: linux pci_dev representing the function 4559c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @bus_addr: bus address returned by an earlier tioca_dma_map 4569c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @dir: mapping direction (unused) 4579c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 4589c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Locate mapping resources associated with @bus_addr and release them. 4599c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * For mappings created using the direct modes (64 or 48) there are no 4609c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * resources to release. 4619c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 46292a582ed2757456ca9599f8b4ea2064f2154eb02Prarit Bhargavastatic void 4639c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Mauletioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) 4649c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 4659c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule int i, entry; 4669c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_common *tioca_common; 4679c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_kernel *tioca_kern; 4689c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_dmamap *map; 4699c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev); 4709c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule unsigned long flags; 4719c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4729c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; 4739c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private; 4749c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4759c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* return straight away if this isn't be a mapped address */ 4769c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4779c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (bus_addr < tioca_kern->ca_pciap_base || 4789c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule bus_addr >= (tioca_kern->ca_pciap_base + tioca_kern->ca_pciap_size)) 4799c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return; 4809c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4819c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule spin_lock_irqsave(&tioca_kern->ca_lock, flags); 4829c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4839c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule list_for_each_entry(map, &tioca_kern->ca_dmamaps, cad_list) 4849c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (map->cad_dma_addr == bus_addr) 4859c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule break; 4869c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4879c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule BUG_ON(map == NULL); 4889c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4899c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule entry = map->cad_gart_entry; 4909c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4919c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule for (i = 0; i < map->cad_gart_size; i++, entry++) { 4929c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule clear_bit(entry, tioca_kern->ca_pcigart_pagemap); 4939c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_pcigart[entry] = 0; 4949c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 4959c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_tlbflush(tioca_kern); 4969c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 4979c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule list_del(&map->cad_list); 4989c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule spin_unlock_irqrestore(&tioca_kern->ca_lock, flags); 4999c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule kfree(map); 5009c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 5019c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5029c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 5039c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_dma_map - map pages for PCI DMA 5049c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @pdev: linux pci_dev representing the function 5059c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @paddr: host physical address to map 5069c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @byte_count: bytes to map 5079c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 5089c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * This is the main wrapper for mapping host physical pages to CA PCI space. 5099c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * The mapping mode used is based on the devices dma_mask. As a last resort 5109c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * use the GART mapped mode. 5119c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 51253493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargavastatic u64 513b4a6b3436531f6c5256e6d60d388c3c28ff1a0e9Jeff Mahoneytioca_dma_map(struct pci_dev *pdev, unsigned long paddr, size_t byte_count, int dma_flags) 5149c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 51553493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u64 mapaddr; 5169c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5179c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 51883821d3f558dc651e555d62182ed0c95651f41a6Mark Maule * Not supported for now ... 51983821d3f558dc651e555d62182ed0c95651f41a6Mark Maule */ 52083821d3f558dc651e555d62182ed0c95651f41a6Mark Maule if (dma_flags & SN_DMA_MSI) 52183821d3f558dc651e555d62182ed0c95651f41a6Mark Maule return 0; 52283821d3f558dc651e555d62182ed0c95651f41a6Mark Maule 52383821d3f558dc651e555d62182ed0c95651f41a6Mark Maule /* 52472fdbdce3d52282f8ea95f512e871791256754e6Simon Arlott * If card is 64 or 48 bit addressable, use a direct mapping. 32 5259c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * bit direct is so restrictive w.r.t. where the memory resides that 5269c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * we don't use it even though CA has some support. 5279c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 5289c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5299c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (pdev->dma_mask == ~0UL) 5309c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule mapaddr = tioca_dma_d64(paddr); 5319c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule else if (pdev->dma_mask == 0xffffffffffffUL) 5329c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule mapaddr = tioca_dma_d48(pdev, paddr); 5339c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule else 5349c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule mapaddr = 0; 5359c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5369c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* Last resort ... use PCI portion of CA GART */ 5379c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5389c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (mapaddr == 0) 5399c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule mapaddr = tioca_dma_mapped(pdev, paddr, byte_count); 5409c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5419c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return mapaddr; 5429c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 5439c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5449c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 5459c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_error_intr_handler - SGI TIO CA error interrupt handler 5469c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @irq: unused 5479c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @arg: pointer to tioca_common struct for the given CA 5489c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 5499c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Handle a CA error interrupt. Simply a wrapper around a SAL call which 5509c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * defers processing to the SGI prom. 5519c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 5529c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maulestatic irqreturn_t 5537d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellstioca_error_intr_handler(int irq, void *arg) 5549c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 5559c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_common *soft = arg; 5569c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct ia64_sal_retval ret_stuff; 55753493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u64 segment; 55853493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava u64 busnum; 5599c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ret_stuff.status = 0; 5609c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule ret_stuff.v0 = 0; 5619c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 562674c6479b7bdc78528ea83dd43897e3161558b8bColin Ngam segment = soft->ca_common.bs_persist_segment; 5639c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule busnum = soft->ca_common.bs_persist_busnum; 5649c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5659c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule SAL_CALL_NOLOCK(ret_stuff, 5669c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule (u64) SN_SAL_IOIF_ERROR_INTERRUPT, 5679c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule segment, busnum, 0, 0, 0, 0, 0); 5689c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5699c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return IRQ_HANDLED; 5709c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 5719c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5729c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 5739c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_bus_fixup - perform final PCI fixup for a TIO CA bus 5749c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * @prom_bussoft: Common prom/kernel struct representing the bus 5759c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 5769c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Replicates the tioca_common pointed to by @prom_bussoft in kernel 5779c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * space. Allocates and initializes a kernel-only area for a given CA, 5789c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * and sets up an irq for handling CA error interrupts. 5799c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * 5809c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * On successful setup, returns the kernel version of tioca_common back to 5819c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * the caller. 5829c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 58392a582ed2757456ca9599f8b4ea2064f2154eb02Prarit Bhargavastatic void * 5847c2a6c62c013a4ea57243536fc7f3987e4ba04bcChristoph Lametertioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) 5859c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 5869c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_common *tioca_common; 5879c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct tioca_kernel *tioca_kern; 5889c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule struct pci_bus *bus; 5899c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5909c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* sanity check prom rev */ 5919c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 592d3e5e1a1b4f43bcfa1a34516e233911487c67307Aaron Young if (is_shub1() && sn_sal_rev() < 0x0406) { 5939c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule printk 5949c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule (KERN_ERR "%s: SGI prom rev 4.06 or greater required " 595d4ed80841ad4a1d59decccfbe2d010558568c5fbHarvey Harrison "for tioca support\n", __func__); 5969c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return NULL; 5979c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 5989c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 5999c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* 6009c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * Allocate kernel bus soft and copy from prom. 6019c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 6029c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 603ac0d1a48d8b18c4808ab73d990b83bb032f21c25Thomas Meyer tioca_common = kmemdup(prom_bussoft, sizeof(struct tioca_common), 604ac0d1a48d8b18c4808ab73d990b83bb032f21c25Thomas Meyer GFP_KERNEL); 6059c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!tioca_common) 6069c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return NULL; 6079c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6081ee27a4eedf3cc08245d395936c1bfaf80c074ccJes Sorensen tioca_common->ca_common.bs_base = (unsigned long) 6091ee27a4eedf3cc08245d395936c1bfaf80c074ccJes Sorensen ioremap(REGION_OFFSET(tioca_common->ca_common.bs_base), 6101ee27a4eedf3cc08245d395936c1bfaf80c074ccJes Sorensen sizeof(struct tioca_common)); 6119c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6129c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* init kernel-private area */ 6139c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 614f96cb1f0580324b95b7219466312a376a59a796fPekka Enberg tioca_kern = kzalloc(sizeof(struct tioca_kernel), GFP_KERNEL); 6159c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (!tioca_kern) { 6169c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule kfree(tioca_common); 6179c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return NULL; 6189c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 6199c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6209c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_common = tioca_common; 6219c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule spin_lock_init(&tioca_kern->ca_lock); 6229c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule INIT_LIST_HEAD(&tioca_kern->ca_dmamaps); 6239c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_closest_node = 6249c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule nasid_to_cnodeid(tioca_common->ca_closest_nasid); 62553493dcf6e9e27cc9379cbf8962642986927aea9Prarit Bhargava tioca_common->ca_kernel_private = (u64) tioca_kern; 6269c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 627674c6479b7bdc78528ea83dd43897e3161558b8bColin Ngam bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment, 628674c6479b7bdc78528ea83dd43897e3161558b8bColin Ngam tioca_common->ca_common.bs_persist_busnum); 6299c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule BUG_ON(!bus); 6309c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_kern->ca_devices = &bus->devices; 6319c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6329c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule /* init GART */ 6339c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6349c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (tioca_gart_init(tioca_kern) < 0) { 6359c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule kfree(tioca_kern); 6369c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule kfree(tioca_common); 6379c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return NULL; 6389c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule } 6399c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6409c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_gart_found++; 6419c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule list_add(&tioca_kern->ca_list, &tioca_list); 6429c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6439c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule if (request_irq(SGI_TIOCA_ERROR, 6449c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule tioca_error_intr_handler, 645121a4226e89aae6654d667d58ab72df740b97b92Thomas Gleixner IRQF_SHARED, "TIOCA error", (void *)tioca_common)) 6469c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule printk(KERN_WARNING 6479c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule "%s: Unable to get irq %d. " 6489c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule "Error interrupts won't be routed for TIOCA bus %d\n", 649d4ed80841ad4a1d59decccfbe2d010558568c5fbHarvey Harrison __func__, SGI_TIOCA_ERROR, 6509c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule (int)tioca_common->ca_common.bs_persist_busnum); 6519c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 65248e30fa0738be3688f655632d917498464019e60Dimitri Sivanich irq_set_handler(SGI_TIOCA_ERROR, handle_level_irq); 6536e9de18120988388cdae5097c09e774416d58745John Keller sn_set_err_irq_affinity(SGI_TIOCA_ERROR); 6546e9de18120988388cdae5097c09e774416d58745John Keller 6557c2a6c62c013a4ea57243536fc7f3987e4ba04bcChristoph Lameter /* Setup locality information */ 6567c2a6c62c013a4ea57243536fc7f3987e4ba04bcChristoph Lameter controller->node = tioca_kern->ca_closest_node; 6579c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return tioca_common; 6589c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 6599c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6609c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maulestatic struct sn_pcibus_provider tioca_pci_interfaces = { 6619c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule .dma_map = tioca_dma_map, 6629c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule .dma_map_consistent = tioca_dma_map, 6639c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule .dma_unmap = tioca_dma_unmap, 6649c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule .bus_fixup = tioca_bus_fixup, 6658409668b561fbe464f7a392e8dc77eca225d27acMark Maule .force_interrupt = NULL, 6668409668b561fbe464f7a392e8dc77eca225d27acMark Maule .target_interrupt = NULL 6679c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule}; 6689c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule 6699c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule/** 6709c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule * tioca_init_provider - init SN PCI provider ops for TIO CA 6719c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule */ 6729c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Mauleint 6739c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Mauletioca_init_provider(void) 6749c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule{ 6759c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule sn_pci_provider[PCIIO_ASIC_TYPE_TIOCA] = &tioca_pci_interfaces; 6769c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule return 0; 6779c90bdde77f7b7a42f7ebb900275d459ce2bac05Mark Maule} 678