1/* 2 * Misc. support for HP zx1 chipset support 3 * 4 * Copyright (C) 2002 Hewlett-Packard Co 5 * Copyright (C) 2002 Alex Williamson <alex_williamson@hp.com> 6 * Copyright (C) 2002 Bjorn Helgaas <bjorn_helgaas@hp.com> 7 */ 8 9 10#include <linux/config.h> 11#include <linux/init.h> 12#include <linux/kernel.h> 13#include <linux/pci.h> 14#include <linux/acpi.h> 15#include <linux/efi.h> 16 17#include <asm/dma.h> 18#include <asm/iosapic.h> 19 20extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *, unsigned long *); 21 22#define PFX "hpzx1: " 23 24static int hpzx1_devices; 25 26struct fake_pci_dev { 27 unsigned long csr_base; 28 unsigned long csr_size; 29 unsigned long mapped_csrs; // ioremapped 30 int sizing; // in middle of BAR sizing operation? 31}; 32 33#define PCI_FAKE_DEV(dev) ((struct fake_pci_dev *) \ 34 PCI_CONTROLLER(dev)->platform_data) 35 36static struct pci_ops *orig_pci_ops; 37 38#define HP_CFG_RD(sz, bits, name) \ 39static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \ 40{ \ 41 struct fake_pci_dev *fake_dev; \ 42 if (!(fake_dev = PCI_FAKE_DEV(dev))) \ 43 return orig_pci_ops->name(dev, where, value); \ 44 \ 45 if (where == PCI_BASE_ADDRESS_0) { \ 46 if (fake_dev->sizing) \ 47 *value = ~(fake_dev->csr_size - 1); \ 48 else \ 49 *value = (fake_dev->csr_base & \ 50 PCI_BASE_ADDRESS_MEM_MASK) | \ 51 PCI_BASE_ADDRESS_SPACE_MEMORY; \ 52 fake_dev->sizing = 0; \ 53 return PCIBIOS_SUCCESSFUL; \ 54 } \ 55 *value = read##sz(fake_dev->mapped_csrs + where); \ 56 if (where == PCI_COMMAND) \ 57 *value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \ 58 return PCIBIOS_SUCCESSFUL; \ 59} 60 61#define HP_CFG_WR(sz, bits, name) \ 62static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \ 63{ \ 64 struct fake_pci_dev *fake_dev; \ 65 \ 66 if (!(fake_dev = PCI_FAKE_DEV(dev))) \ 67 return orig_pci_ops->name(dev, where, value); \ 68 \ 69 if (where == PCI_BASE_ADDRESS_0) { \ 70 if (value == (u##bits) ~0) \ 71 fake_dev->sizing = 1; \ 72 return PCIBIOS_SUCCESSFUL; \ 73 } else \ 74 write##sz(value, fake_dev->mapped_csrs + where); \ 75 return PCIBIOS_SUCCESSFUL; \ 76} 77 78HP_CFG_RD(b, 8, read_byte) 79HP_CFG_RD(w, 16, read_word) 80HP_CFG_RD(l, 32, read_dword) 81HP_CFG_WR(b, 8, write_byte) 82HP_CFG_WR(w, 16, write_word) 83HP_CFG_WR(l, 32, write_dword) 84 85static struct pci_ops hp_pci_conf = { 86 hp_cfg_readb, 87 hp_cfg_readw, 88 hp_cfg_readl, 89 hp_cfg_writeb, 90 hp_cfg_writew, 91 hp_cfg_writel, 92}; 93 94static void 95hpzx1_fake_pci_dev(char *name, unsigned int busnum, unsigned long addr, unsigned int size) 96{ 97 struct pci_controller *controller; 98 struct fake_pci_dev *fake; 99 int slot; 100 struct pci_dev *dev; 101 struct pci_bus *b, *bus = NULL; 102 u8 hdr; 103 104 controller = kmalloc(sizeof(*controller), GFP_KERNEL); 105 if (!controller) { 106 printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name, 107 (void *) addr); 108 return; 109 } 110 memset(controller, 0, sizeof(*controller)); 111 112 fake = kmalloc(sizeof(*fake), GFP_KERNEL); 113 if (!fake) { 114 printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name, 115 (void *) addr); 116 kfree(controller); 117 return; 118 } 119 120 memset(fake, 0, sizeof(*fake)); 121 fake->csr_base = addr; 122 fake->csr_size = size; 123 fake->mapped_csrs = (unsigned long) ioremap(addr, size); 124 fake->sizing = 0; 125 controller->platform_data = fake; 126 127 pci_for_each_bus(b) 128 if (busnum == b->number) { 129 bus = b; 130 break; 131 } 132 133 if (!bus) { 134 printk(KERN_ERR PFX "No host bus 0x%02x for %s (0x%p)\n", 135 busnum, name, (void *) addr); 136 kfree(fake); 137 kfree(controller); 138 return; 139 } 140 141 for (slot = 0x1e; slot; slot--) 142 if (!pci_find_slot(busnum, PCI_DEVFN(slot, 0))) 143 break; 144 145 if (slot < 0) { 146 printk(KERN_ERR PFX "No space for %s (0x%p) on bus 0x%02x\n", 147 name, (void *) addr, busnum); 148 kfree(fake); 149 kfree(controller); 150 return; 151 } 152 153 dev = kmalloc(sizeof(*dev), GFP_KERNEL); 154 if (!dev) { 155 printk(KERN_ERR PFX "No memory for %s (0x%p)\n", name, 156 (void *) addr); 157 kfree(fake); 158 kfree(controller); 159 return; 160 } 161 162 bus->ops = &hp_pci_conf; // replace pci ops for this bus 163 164 memset(dev, 0, sizeof(*dev)); 165 dev->bus = bus; 166 dev->sysdata = controller; 167 dev->devfn = PCI_DEVFN(slot, 0); 168 pci_read_config_word(dev, PCI_VENDOR_ID, &dev->vendor); 169 pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device); 170 pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr); 171 dev->hdr_type = hdr & 0x7f; 172 173 pci_setup_device(dev); 174 175 // pci_insert_device() without running /sbin/hotplug 176 list_add_tail(&dev->bus_list, &bus->devices); 177 list_add_tail(&dev->global_list, &pci_devices); 178 179 printk(KERN_INFO PFX "%s at 0x%lx; pci dev %s\n", name, addr, 180 dev->slot_name); 181 182 hpzx1_devices++; 183} 184 185static acpi_status 186hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret) 187{ 188 u64 csr_base = 0, csr_length = 0; 189 acpi_status status; 190 char *name = context; 191 char fullname[16]; 192 193 status = acpi_hp_csr_space(obj, &csr_base, &csr_length); 194 if (ACPI_FAILURE(status)) 195 return status; 196 197 /* 198 * Only SBA shows up in ACPI namespace, so its CSR space 199 * includes both SBA and IOC. Make SBA and IOC show up 200 * separately in PCI space. 201 */ 202 sprintf(fullname, "%s SBA", name); 203 hpzx1_fake_pci_dev(fullname, 0, csr_base, 0x1000); 204 sprintf(fullname, "%s IOC", name); 205 hpzx1_fake_pci_dev(fullname, 0, csr_base + 0x1000, 0x1000); 206 207 return AE_OK; 208} 209 210static acpi_status 211hpzx1_lba_probe(acpi_handle obj, u32 depth, void *context, void **ret) 212{ 213 u64 csr_base = 0, csr_length = 0; 214 acpi_status status; 215 NATIVE_UINT busnum; 216 char *name = context; 217 char fullname[32]; 218 219 status = acpi_hp_csr_space(obj, &csr_base, &csr_length); 220 if (ACPI_FAILURE(status)) 221 return status; 222 223 status = acpi_evaluate_integer(obj, METHOD_NAME__BBN, NULL, &busnum); 224 if (ACPI_FAILURE(status)) { 225 printk(KERN_WARNING PFX "evaluate _BBN fail=0x%x\n", status); 226 busnum = 0; // no _BBN; stick it on bus 0 227 } 228 229 sprintf(fullname, "%s _BBN 0x%02x", name, (unsigned int) busnum); 230 hpzx1_fake_pci_dev(fullname, busnum, csr_base, csr_length); 231 232 return AE_OK; 233} 234 235static void 236hpzx1_acpi_dev_init(void) 237{ 238 extern struct pci_ops *pci_root_ops; 239 240 orig_pci_ops = pci_root_ops; 241 242 /* 243 * Make fake PCI devices for the following hardware in the 244 * ACPI namespace. This makes it more convenient for drivers 245 * because they can claim these devices based on PCI 246 * information, rather than needing to know about ACPI. The 247 * 64-bit "HPA" space for this hardware is available as BAR 248 * 0/1. 249 * 250 * HWP0001: Single IOC SBA w/o IOC in namespace 251 * HWP0002: LBA device 252 * HWP0003: AGP LBA device 253 */ 254 acpi_get_devices("HWP0001", hpzx1_sba_probe, "HWP0001", NULL); 255#ifdef CONFIG_IA64_HP_PROTO 256 if (hpzx1_devices) { 257#endif 258 acpi_get_devices("HWP0002", hpzx1_lba_probe, "HWP0002 PCI LBA", NULL); 259 acpi_get_devices("HWP0003", hpzx1_lba_probe, "HWP0003 AGP LBA", NULL); 260 261#ifdef CONFIG_IA64_HP_PROTO 262 } 263 264#define ZX1_FUNC_ID_VALUE (PCI_DEVICE_ID_HP_ZX1_SBA << 16) | PCI_VENDOR_ID_HP 265 /* 266 * Early protos don't have bridges in the ACPI namespace, so 267 * if we didn't find anything, add the things we know are 268 * there. 269 */ 270 if (hpzx1_devices == 0) { 271 u64 hpa, csr_base; 272 273 csr_base = 0xfed00000UL; 274 hpa = (u64) ioremap(csr_base, 0x2000); 275 if (__raw_readl(hpa) == ZX1_FUNC_ID_VALUE) { 276 hpzx1_fake_pci_dev("HWP0001 SBA", 0, csr_base, 0x1000); 277 hpzx1_fake_pci_dev("HWP0001 IOC", 0, csr_base + 0x1000, 278 0x1000); 279 280 csr_base = 0xfed24000UL; 281 iounmap(hpa); 282 hpa = (u64) ioremap(csr_base, 0x1000); 283 hpzx1_fake_pci_dev("HWP0003 AGP LBA", 0x40, csr_base, 284 0x1000); 285 } 286 iounmap(hpa); 287 } 288#endif 289} 290 291extern void sba_init(void); 292 293void 294hpzx1_pci_fixup (int phase) 295{ 296 iosapic_pci_fixup(phase); 297 switch (phase) { 298 case 0: 299 /* zx1 has a hardware I/O TLB which lets us DMA from any device to any address */ 300 MAX_DMA_ADDRESS = ~0UL; 301 break; 302 303 case 1: 304 hpzx1_acpi_dev_init(); 305 sba_init(); 306 break; 307 } 308} 309