1 /* 2 * Copyright 2007, Michael Ellerman, IBM Corporation. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9 10 11 #include <linux/interrupt.h> 12 #include <linux/irq.h> 13 #include <linux/kernel.h> 14 #include <linux/pci.h> 15 #include <linux/msi.h> 16 #include <linux/reboot.h> 17 18 #include <asm/dcr.h> 19 #include <asm/machdep.h> 20 #include <asm/prom.h> 21 22 23 /* 24 * MSIC registers, specified as offsets from dcr_base 25 */ 26 #define MSIC_CTRL_REG 0x0 27 28 /* Base Address registers specify FIFO location in BE memory */ 29 #define MSIC_BASE_ADDR_HI_REG 0x3 30 #define MSIC_BASE_ADDR_LO_REG 0x4 31 32 /* Hold the read/write offsets into the FIFO */ 33 #define MSIC_READ_OFFSET_REG 0x5 34 #define MSIC_WRITE_OFFSET_REG 0x6 35 36 37 /* MSIC control register flags */ 38 #define MSIC_CTRL_ENABLE 0x0001 39 #define MSIC_CTRL_FIFO_FULL_ENABLE 0x0002 40 #define MSIC_CTRL_IRQ_ENABLE 0x0008 41 #define MSIC_CTRL_FULL_STOP_ENABLE 0x0010 42 43 /* 44 * The MSIC can be configured to use a FIFO of 32KB, 64KB, 128KB or 256KB. 45 * Currently we're using a 64KB FIFO size. 46 */ 47 #define MSIC_FIFO_SIZE_SHIFT 16 48 #define MSIC_FIFO_SIZE_BYTES (1 << MSIC_FIFO_SIZE_SHIFT) 49 50 /* 51 * To configure the FIFO size as (1 << n) bytes, we write (n - 15) into bits 52 * 8-9 of the MSIC control reg. 53 */ 54 #define MSIC_CTRL_FIFO_SIZE (((MSIC_FIFO_SIZE_SHIFT - 15) << 8) & 0x300) 55 56 /* 57 * We need to mask the read/write offsets to make sure they stay within 58 * the bounds of the FIFO. Also they should always be 16-byte aligned. 59 */ 60 #define MSIC_FIFO_SIZE_MASK ((MSIC_FIFO_SIZE_BYTES - 1) & ~0xFu) 61 62 /* Each entry in the FIFO is 16 bytes, the first 4 bytes hold the irq # */ 63 #define MSIC_FIFO_ENTRY_SIZE 0x10 64 65 66 struct axon_msic { 67 struct irq_host *irq_host; 68 __le32 *fifo; 69 dcr_host_t dcr_host; 70 struct list_head list; 71 u32 read_offset; 72 }; 73 74 static LIST_HEAD(axon_msic_list); 75 76 static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) 77 { 78 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); 79 80 dcr_write(msic->dcr_host, dcr_n, val); 81 } 82 83 static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) 84 { 85 struct axon_msic *msic = get_irq_data(irq); 86 u32 write_offset, msi; 87 int idx; 88 89 write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG); 90 pr_debug("axon_msi: original write_offset 0x%x\n", write_offset); 91 92 /* write_offset doesn't wrap properly, so we have to mask it */ 93 write_offset &= MSIC_FIFO_SIZE_MASK; 94 95 while (msic->read_offset != write_offset) { 96 idx = msic->read_offset / sizeof(__le32); 97 msi = le32_to_cpu(msic->fifo[idx]); 98 msi &= 0xFFFF; 99 100 pr_debug("axon_msi: woff %x roff %x msi %x\n", 101 write_offset, msic->read_offset, msi); 102 103 msic->read_offset += MSIC_FIFO_ENTRY_SIZE; 104 msic->read_offset &= MSIC_FIFO_SIZE_MASK; 105 106 if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host) 107 generic_handle_irq(msi); 108 else 109 pr_debug("axon_msi: invalid irq 0x%x!\n", msi); 110 } 111 112 desc->chip->eoi(irq); 113 } 114 115 static struct axon_msic *find_msi_translator(struct pci_dev *dev) 116 { 117 struct irq_host *irq_host; 118 struct device_node *dn, *tmp; 119 const phandle *ph; 120 struct axon_msic *msic = NULL; 121 122 dn = of_node_get(pci_device_to_OF_node(dev)); 123 if (!dn) { 124 dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); 125 return NULL; 126 } 127 128 for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) { 129 ph = of_get_property(dn, "msi-translator", NULL); 130 if (ph) 131 break; 132 } 133 134 if (!ph) { 135 dev_dbg(&dev->dev, 136 "axon_msi: no msi-translator property found\n"); 137 goto out_error; 138 } 139 140 tmp = dn; 141 dn = of_find_node_by_phandle(*ph); 142 if (!dn) { 143 dev_dbg(&dev->dev, 144 "axon_msi: msi-translator doesn't point to a node\n"); 145 goto out_error; 146 } 147 148 irq_host = irq_find_host(dn); 149 if (!irq_host) { 150 dev_dbg(&dev->dev, "axon_msi: no irq_host found for node %s\n", 151 dn->full_name); 152 goto out_error; 153 } 154 155 msic = irq_host->host_data; 156 157 out_error: 158 of_node_put(dn); 159 of_node_put(tmp); 160 161 return msic; 162 } 163 164 static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type) 165 { 166 if (!find_msi_translator(dev)) 167 return -ENODEV; 168 169 return 0; 170 } 171 172 static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg) 173 { 174 struct device_node *dn, *tmp; 175 struct msi_desc *entry; 176 int len; 177 const u32 *prop; 178 179 dn = of_node_get(pci_device_to_OF_node(dev)); 180 if (!dn) { 181 dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n"); 182 return -ENODEV; 183 } 184 185 entry = list_first_entry(&dev->msi_list, struct msi_desc, list); 186 187 for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) { 188 if (entry->msi_attrib.is_64) { 189 prop = of_get_property(dn, "msi-address-64", &len); 190 if (prop) 191 break; 192 } 193 194 prop = of_get_property(dn, "msi-address-32", &len); 195 if (prop) 196 break; 197 } 198 199 if (!prop) { 200 dev_dbg(&dev->dev, 201 "axon_msi: no msi-address-(32|64) properties found\n"); 202 return -ENOENT; 203 } 204 205 switch (len) { 206 case 8: 207 msg->address_hi = prop[0]; 208 msg->address_lo = prop[1]; 209 break; 210 case 4: 211 msg->address_hi = 0; 212 msg->address_lo = prop[0]; 213 break; 214 default: 215 dev_dbg(&dev->dev, 216 "axon_msi: malformed msi-address-(32|64) property\n"); 217 of_node_put(dn); 218 return -EINVAL; 219 } 220 221 of_node_put(dn); 222 223 return 0; 224 } 225 226 static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 227 { 228 unsigned int virq, rc; 229 struct msi_desc *entry; 230 struct msi_msg msg; 231 struct axon_msic *msic; 232 233 msic = find_msi_translator(dev); 234 if (!msic) 235 return -ENODEV; 236 237 rc = setup_msi_msg_address(dev, &msg); 238 if (rc) 239 return rc; 240 241 /* We rely on being able to stash a virq in a u16 */ 242 BUILD_BUG_ON(NR_IRQS > 65536); 243 244 list_for_each_entry(entry, &dev->msi_list, list) { 245 virq = irq_create_direct_mapping(msic->irq_host); 246 if (virq == NO_IRQ) { 247 dev_warn(&dev->dev, 248 "axon_msi: virq allocation failed!\n"); 249 return -1; 250 } 251 dev_dbg(&dev->dev, "axon_msi: allocated virq 0x%x\n", virq); 252 253 set_irq_msi(virq, entry); 254 msg.data = virq; 255 write_msi_msg(virq, &msg); 256 } 257 258 return 0; 259 } 260 261 static void axon_msi_teardown_msi_irqs(struct pci_dev *dev) 262 { 263 struct msi_desc *entry; 264 265 dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n"); 266 267 list_for_each_entry(entry, &dev->msi_list, list) { 268 if (entry->irq == NO_IRQ) 269 continue; 270 271 set_irq_msi(entry->irq, NULL); 272 irq_dispose_mapping(entry->irq); 273 } 274 } 275 276 static struct irq_chip msic_irq_chip = { 277 .mask = mask_msi_irq, 278 .unmask = unmask_msi_irq, 279 .shutdown = unmask_msi_irq, 280 .typename = "AXON-MSI", 281 }; 282 283 static int msic_host_map(struct irq_host *h, unsigned int virq, 284 irq_hw_number_t hw) 285 { 286 set_irq_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq); 287 288 return 0; 289 } 290 291 static struct irq_host_ops msic_host_ops = { 292 .map = msic_host_map, 293 }; 294 295 static int axon_msi_notify_reboot(struct notifier_block *nb, 296 unsigned long code, void *data) 297 { 298 struct axon_msic *msic; 299 u32 tmp; 300 301 list_for_each_entry(msic, &axon_msic_list, list) { 302 pr_debug("axon_msi: disabling %s\n", 303 msic->irq_host->of_node->full_name); 304 tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); 305 tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; 306 msic_dcr_write(msic, MSIC_CTRL_REG, tmp); 307 } 308 309 return 0; 310 } 311 312 static struct notifier_block axon_msi_reboot_notifier = { 313 .notifier_call = axon_msi_notify_reboot 314 }; 315 316 static int axon_msi_setup_one(struct device_node *dn) 317 { 318 struct page *page; 319 struct axon_msic *msic; 320 unsigned int virq; 321 int dcr_base, dcr_len; 322 323 pr_debug("axon_msi: setting up dn %s\n", dn->full_name); 324 325 msic = kzalloc(sizeof(struct axon_msic), GFP_KERNEL); 326 if (!msic) { 327 printk(KERN_ERR "axon_msi: couldn't allocate msic for %s\n", 328 dn->full_name); 329 goto out; 330 } 331 332 dcr_base = dcr_resource_start(dn, 0); 333 dcr_len = dcr_resource_len(dn, 0); 334 335 if (dcr_base == 0 || dcr_len == 0) { 336 printk(KERN_ERR 337 "axon_msi: couldn't parse dcr properties on %s\n", 338 dn->full_name); 339 goto out; 340 } 341 342 msic->dcr_host = dcr_map(dn, dcr_base, dcr_len); 343 if (!DCR_MAP_OK(msic->dcr_host)) { 344 printk(KERN_ERR "axon_msi: dcr_map failed for %s\n", 345 dn->full_name); 346 goto out_free_msic; 347 } 348 349 page = alloc_pages_node(of_node_to_nid(dn), GFP_KERNEL, 350 get_order(MSIC_FIFO_SIZE_BYTES)); 351 if (!page) { 352 printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n", 353 dn->full_name); 354 goto out_free_msic; 355 } 356 357 msic->fifo = page_address(page); 358 359 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP, 360 NR_IRQS, &msic_host_ops, 0); 361 if (!msic->irq_host) { 362 printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n", 363 dn->full_name); 364 goto out_free_fifo; 365 } 366 367 msic->irq_host->host_data = msic; 368 369 virq = irq_of_parse_and_map(dn, 0); 370 if (virq == NO_IRQ) { 371 printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n", 372 dn->full_name); 373 goto out_free_host; 374 } 375 376 set_irq_data(virq, msic); 377 set_irq_chained_handler(virq, axon_msi_cascade); 378 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq); 379 380 /* Enable the MSIC hardware */ 381 msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, (u64)msic->fifo >> 32); 382 msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG, 383 (u64)msic->fifo & 0xFFFFFFFF); 384 msic_dcr_write(msic, MSIC_CTRL_REG, 385 MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE | 386 MSIC_CTRL_FIFO_SIZE); 387 388 list_add(&msic->list, &axon_msic_list); 389 390 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); 391 392 return 0; 393 394 out_free_host: 395 kfree(msic->irq_host); 396 out_free_fifo: 397 __free_pages(virt_to_page(msic->fifo), get_order(MSIC_FIFO_SIZE_BYTES)); 398 out_free_msic: 399 kfree(msic); 400 out: 401 402 return -1; 403 } 404 405 static int axon_msi_init(void) 406 { 407 struct device_node *dn; 408 int found = 0; 409 410 pr_debug("axon_msi: initialising ...\n"); 411 412 for_each_compatible_node(dn, NULL, "ibm,axon-msic") { 413 if (axon_msi_setup_one(dn) == 0) 414 found++; 415 } 416 417 if (found) { 418 ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; 419 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; 420 ppc_md.msi_check_device = axon_msi_check_device; 421 422 register_reboot_notifier(&axon_msi_reboot_notifier); 423 424 pr_debug("axon_msi: registered callbacks!\n"); 425 } 426 427 return 0; 428 } 429 arch_initcall(axon_msi_init); 430