vme_ca91cx42.c revision 3d0f8bc7517718a4846de6f538ad67a4f7f83239
160479690af6d559d4202bed139db90323386bd2bMartyn Welch/* 260479690af6d559d4202bed139db90323386bd2bMartyn Welch * Support for the Tundra Universe I/II VME-PCI Bridge Chips 360479690af6d559d4202bed139db90323386bd2bMartyn Welch * 460479690af6d559d4202bed139db90323386bd2bMartyn Welch * Author: Martyn Welch <martyn.welch@gefanuc.com> 560479690af6d559d4202bed139db90323386bd2bMartyn Welch * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. 660479690af6d559d4202bed139db90323386bd2bMartyn Welch * 760479690af6d559d4202bed139db90323386bd2bMartyn Welch * Based on work by Tom Armistead and Ajit Prem 860479690af6d559d4202bed139db90323386bd2bMartyn Welch * Copyright 2004 Motorola Inc. 960479690af6d559d4202bed139db90323386bd2bMartyn Welch * 1060479690af6d559d4202bed139db90323386bd2bMartyn Welch * Derived from ca91c042.c by Michael Wyrick 1160479690af6d559d4202bed139db90323386bd2bMartyn Welch * 1260479690af6d559d4202bed139db90323386bd2bMartyn Welch * This program is free software; you can redistribute it and/or modify it 1360479690af6d559d4202bed139db90323386bd2bMartyn Welch * under the terms of the GNU General Public License as published by the 1460479690af6d559d4202bed139db90323386bd2bMartyn Welch * Free Software Foundation; either version 2 of the License, or (at your 1560479690af6d559d4202bed139db90323386bd2bMartyn Welch * option) any later version. 1660479690af6d559d4202bed139db90323386bd2bMartyn Welch */ 1760479690af6d559d4202bed139db90323386bd2bMartyn Welch 1860479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/version.h> 1960479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/module.h> 2060479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/mm.h> 2160479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/types.h> 2260479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/errno.h> 2360479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/pci.h> 2460479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/dma-mapping.h> 2560479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/poll.h> 2660479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/interrupt.h> 2760479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/spinlock.h> 2860479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <asm/time.h> 2960479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <asm/io.h> 3060479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <asm/uaccess.h> 3160479690af6d559d4202bed139db90323386bd2bMartyn Welch 3260479690af6d559d4202bed139db90323386bd2bMartyn Welch#include "../vme.h" 3360479690af6d559d4202bed139db90323386bd2bMartyn Welch#include "../vme_bridge.h" 3460479690af6d559d4202bed139db90323386bd2bMartyn Welch#include "vme_ca91cx42.h" 3560479690af6d559d4202bed139db90323386bd2bMartyn Welch 363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int __init ca91cx42_init(void); 373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *); 383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void ca91cx42_remove(struct pci_dev *); 393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void __exit ca91cx42_exit(void); 4060479690af6d559d4202bed139db90323386bd2bMartyn Welch 413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstruct vme_bridge *ca91cx42_bridge; 423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchwait_queue_head_t dma_queue; 433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchwait_queue_head_t iack_queue; 443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchwait_queue_head_t lm_queue; 453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchwait_queue_head_t mbox_queue; 4660479690af6d559d4202bed139db90323386bd2bMartyn Welch 473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchvoid (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */ 483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchvoid *crcsr_kernel; 493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchdma_addr_t crcsr_bus; 5060479690af6d559d4202bed139db90323386bd2bMartyn Welch 513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstruct mutex vme_rmw; /* Only one RMW cycle at a time */ 523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstruct mutex vme_int; /* 533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Only one VME interrupt can be 543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * generated at a time, provide locking 553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstruct mutex vme_irq; /* Locking for VME irq callback configuration */ 5760479690af6d559d4202bed139db90323386bd2bMartyn Welch 5860479690af6d559d4202bed139db90323386bd2bMartyn Welch 5960479690af6d559d4202bed139db90323386bd2bMartyn Welch 603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic char driver_name[] = "vme_ca91cx42"; 6160479690af6d559d4202bed139db90323386bd2bMartyn Welch 623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic struct pci_device_id ca91cx42_ids[] = { 633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, 643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch { }, 6560479690af6d559d4202bed139db90323386bd2bMartyn Welch}; 6660479690af6d559d4202bed139db90323386bd2bMartyn Welch 673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic struct pci_driver ca91cx42_driver = { 683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch .name = driver_name, 693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch .id_table = ca91cx42_ids, 703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch .probe = ca91cx42_probe, 713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch .remove = ca91cx42_remove, 7260479690af6d559d4202bed139db90323386bd2bMartyn Welch}; 7360479690af6d559d4202bed139db90323386bd2bMartyn Welch 743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_DMA_irqhandler(void) 7560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wake_up(&dma_queue); 7760479690af6d559d4202bed139db90323386bd2bMartyn Welch 783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_DMA; 793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 8060479690af6d559d4202bed139db90323386bd2bMartyn Welch 813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_LM_irqhandler(u32 stat) 823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int i; 843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 serviced = 0; 8560479690af6d559d4202bed139db90323386bd2bMartyn Welch 863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (i = 0; i < 4; i++) { 873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_LM[i]) { 883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* We only enable interrupts if the callback is set */ 893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm_callback[i](i); 903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= CA91CX42_LINT_LM[i]; 9160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 9260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 9360479690af6d559d4202bed139db90323386bd2bMartyn Welch 943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return serviced; 953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 9660479690af6d559d4202bed139db90323386bd2bMartyn Welch 973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX This needs to be split into 4 queues */ 983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_MB_irqhandler(int mbox_mask) 993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 1003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wake_up(&mbox_queue); 10160479690af6d559d4202bed139db90323386bd2bMartyn Welch 1023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_MBOX; 1033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 10460479690af6d559d4202bed139db90323386bd2bMartyn Welch 1053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_IACK_irqhandler(void) 1063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 1073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wake_up(&iack_queue); 10860479690af6d559d4202bed139db90323386bd2bMartyn Welch 1093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_SW_IACK; 11060479690af6d559d4202bed139db90323386bd2bMartyn Welch} 11160479690af6d559d4202bed139db90323386bd2bMartyn Welch 1123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 1133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_bus_error_chk(int clrflag) 11460479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 11560479690af6d559d4202bed139db90323386bd2bMartyn Welch int tmp; 1163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + PCI_COMMAND); 1173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (tmp & 0x08000000) { /* S_TA is Set */ 11860479690af6d559d4202bed139db90323386bd2bMartyn Welch if (clrflag) 1193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp | 0x08000000, 1203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->base + PCI_COMMAND); 1213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 1; 12260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 1233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 12460479690af6d559d4202bed139db90323386bd2bMartyn Welch} 1253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 12660479690af6d559d4202bed139db90323386bd2bMartyn Welch 1273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_VERR_irqhandler(void) 12860479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 12960479690af6d559d4202bed139db90323386bd2bMartyn Welch int val; 13060479690af6d559d4202bed139db90323386bd2bMartyn Welch 1313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DGCS); 13260479690af6d559d4202bed139db90323386bd2bMartyn Welch 13360479690af6d559d4202bed139db90323386bd2bMartyn Welch if (!(val & 0x00000800)) { 1343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read " 1353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "Error DGCS=%08X\n", val); 13660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 1373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_VERR; 13960479690af6d559d4202bed139db90323386bd2bMartyn Welch} 14060479690af6d559d4202bed139db90323386bd2bMartyn Welch 1413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_LERR_irqhandler(void) 14260479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 14360479690af6d559d4202bed139db90323386bd2bMartyn Welch int val; 14460479690af6d559d4202bed139db90323386bd2bMartyn Welch 1453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DGCS); 14660479690af6d559d4202bed139db90323386bd2bMartyn Welch 14760479690af6d559d4202bed139db90323386bd2bMartyn Welch if (!(val & 0x00000800)) { 1483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read " 1493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "Error DGCS=%08X\n", val); 15060479690af6d559d4202bed139db90323386bd2bMartyn Welch 15160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 15260479690af6d559d4202bed139db90323386bd2bMartyn Welch 1533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_LERR; 15460479690af6d559d4202bed139db90323386bd2bMartyn Welch} 15560479690af6d559d4202bed139db90323386bd2bMartyn Welch 1563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_VIRQ_irqhandler(int stat) 15860479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 1593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int vec, i, serviced = 0; 1603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch void (*call)(int, int, void *); 1613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch void *priv_data; 16260479690af6d559d4202bed139db90323386bd2bMartyn Welch 16360479690af6d559d4202bed139db90323386bd2bMartyn Welch for (i = 7; i > 0; i--) { 1643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & (1 << i)) { 1653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vec = ioread32(ca91cx42_bridge->base + 1663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_V_STATID[i]) & 0xff; 1673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch call = ca91cx42_bridge->irq[i - 1].callback[vec].func; 1693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch priv_data = 1703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->irq[i - 1].callback[vec].priv_data; 1713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (call != NULL) 1733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch call(i, vec, priv_data); 1743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 1753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk("Spurilous VME interrupt, level:%x, " 1763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "vector:%x\n", i, vec); 1773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= (1 << i); 17960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 18060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 1813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return serviced; 18360479690af6d559d4202bed139db90323386bd2bMartyn Welch} 18460479690af6d559d4202bed139db90323386bd2bMartyn Welch 1853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id) 18660479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 1873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 stat, enable, serviced = 0; 18860479690af6d559d4202bed139db90323386bd2bMartyn Welch 1893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (dev_id != ca91cx42_bridge->base) 19060479690af6d559d4202bed139db90323386bd2bMartyn Welch return IRQ_NONE; 19160479690af6d559d4202bed139db90323386bd2bMartyn Welch 1923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch enable = ioread32(ca91cx42_bridge->base + LINT_EN); 1933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch stat = ioread32(ca91cx42_bridge->base + LINT_STAT); 19460479690af6d559d4202bed139db90323386bd2bMartyn Welch 1953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Only look at unmasked interrupts */ 1963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch stat &= enable; 1973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (unlikely(!stat)) 1993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return IRQ_NONE; 2003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_DMA) 2023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_DMA_irqhandler(); 2033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | 2043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_LM3)) 2053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_LM_irqhandler(stat); 2063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_MBOX) 2073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_MB_irqhandler(stat); 2083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_SW_IACK) 2093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_IACK_irqhandler(); 2103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_VERR) 2113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_VERR_irqhandler(); 2123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_LERR) 2133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_LERR_irqhandler(); 2143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 | 2153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 | 2163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 | 2173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_VIRQ7)) 2183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_VIRQ_irqhandler(stat); 2193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Clear serviced interrupts */ 2213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(stat, ca91cx42_bridge->base + LINT_STAT); 22260479690af6d559d4202bed139db90323386bd2bMartyn Welch 22360479690af6d559d4202bed139db90323386bd2bMartyn Welch return IRQ_HANDLED; 22460479690af6d559d4202bed139db90323386bd2bMartyn Welch} 22560479690af6d559d4202bed139db90323386bd2bMartyn Welch 2263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_irq_init(struct vme_bridge *bridge) 22760479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 2283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int result, tmp; 2293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct pci_dev *pdev; 23060479690af6d559d4202bed139db90323386bd2bMartyn Welch 2313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Need pdev */ 2323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pdev = container_of(bridge->parent, struct pci_dev, dev); 23360479690af6d559d4202bed139db90323386bd2bMartyn Welch 2343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Initialise list for VME bus errors */ 2353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(bridge->vme_errors)); 23660479690af6d559d4202bed139db90323386bd2bMartyn Welch 2373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable interrupts from PCI to VME */ 2383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + VINT_EN); 23960479690af6d559d4202bed139db90323386bd2bMartyn Welch 2403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable PCI interrupts */ 2413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + LINT_EN); 2423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Clear Any Pending PCI Interrupts */ 2433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); 24460479690af6d559d4202bed139db90323386bd2bMartyn Welch 2453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED, 2463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch driver_name, pdev); 2473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (result) { 2483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", 2493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pdev->irq); 2503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return result; 25160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 25260479690af6d559d4202bed139db90323386bd2bMartyn Welch 2533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Ensure all interrupts are mapped to PCI Interrupt 0 */ 2543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + LINT_MAP0); 2553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + LINT_MAP1); 2563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + LINT_MAP2); 2573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Enable DMA, mailbox & LM Interrupts */ 2593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = CA91CX42_LINT_MBOX3 | CA91CX42_LINT_MBOX2 | CA91CX42_LINT_MBOX1 | 2603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_MBOX0 | CA91CX42_LINT_SW_IACK | 2613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_VERR | CA91CX42_LINT_LERR | CA91CX42_LINT_DMA; 2623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, bridge->base + LINT_EN); 26460479690af6d559d4202bed139db90323386bd2bMartyn Welch 2653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 26660479690af6d559d4202bed139db90323386bd2bMartyn Welch} 26760479690af6d559d4202bed139db90323386bd2bMartyn Welch 2683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void ca91cx42_irq_exit(struct pci_dev *pdev) 26960479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 2703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable interrupts from PCI to VME */ 2713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + VINT_EN); 27260479690af6d559d4202bed139db90323386bd2bMartyn Welch 2733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable PCI interrupts */ 2743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + LINT_EN); 2753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Clear Any Pending PCI Interrupts */ 2763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00FFFFFF, ca91cx42_bridge->base + LINT_STAT); 27760479690af6d559d4202bed139db90323386bd2bMartyn Welch 2783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch free_irq(pdev->irq, pdev); 2793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 28060479690af6d559d4202bed139db90323386bd2bMartyn Welch 2813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 2823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Set up an VME interrupt 2833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 2843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_request_irq(int level, int statid, 2853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch void (*callback)(int level, int vector, void *priv_data), 2863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch void *priv_data) 2873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 2883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 tmp; 28960479690af6d559d4202bed139db90323386bd2bMartyn Welch 2903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_lock(&(vme_irq)); 2913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ca91cx42_bridge->irq[level - 1].callback[statid].func) { 2933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_unlock(&(vme_irq)); 2943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk("VME Interrupt already taken\n"); 2953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EBUSY; 29660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 29760479690af6d559d4202bed139db90323386bd2bMartyn Welch 2983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->irq[level - 1].count++; 3003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->irq[level - 1].callback[statid].priv_data = priv_data; 3013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->irq[level - 1].callback[statid].func = callback; 3023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Enable IRQ level */ 3043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + LINT_EN); 3053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp |= CA91CX42_LINT_VIRQ[level]; 3063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + LINT_EN); 3073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_unlock(&(vme_irq)); 3093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 31160479690af6d559d4202bed139db90323386bd2bMartyn Welch} 31260479690af6d559d4202bed139db90323386bd2bMartyn Welch 3133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 3143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Free VME interrupt 3153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 3163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchvoid ca91cx42_free_irq(int level, int statid) 31760479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 3183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 tmp; 3193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct pci_dev *pdev; 32060479690af6d559d4202bed139db90323386bd2bMartyn Welch 3213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_lock(&(vme_irq)); 32260479690af6d559d4202bed139db90323386bd2bMartyn Welch 3233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->irq[level - 1].count--; 32460479690af6d559d4202bed139db90323386bd2bMartyn Welch 3253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable IRQ level if no more interrupts attached at this level*/ 3263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ca91cx42_bridge->irq[level - 1].count == 0) { 3273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + LINT_EN); 3283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp &= ~CA91CX42_LINT_VIRQ[level]; 3293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + LINT_EN); 33060479690af6d559d4202bed139db90323386bd2bMartyn Welch 3313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, 3323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev); 3333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch synchronize_irq(pdev->irq); 33560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 3363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->irq[level - 1].callback[statid].func = NULL; 3383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->irq[level - 1].callback[statid].priv_data = NULL; 3393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_unlock(&(vme_irq)); 34160479690af6d559d4202bed139db90323386bd2bMartyn Welch} 34260479690af6d559d4202bed139db90323386bd2bMartyn Welch 3433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_generate_irq(int level, int statid) 34460479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 3453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 tmp; 34660479690af6d559d4202bed139db90323386bd2bMartyn Welch 3473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Universe can only generate even vectors */ 3483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (statid & 1) 3493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 35060479690af6d559d4202bed139db90323386bd2bMartyn Welch 3513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_lock(&(vme_int)); 35260479690af6d559d4202bed139db90323386bd2bMartyn Welch 3533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + VINT_EN); 35460479690af6d559d4202bed139db90323386bd2bMartyn Welch 3553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Set Status/ID */ 3563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(statid << 24, ca91cx42_bridge->base + STATID); 3573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Assert VMEbus IRQ */ 3593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = tmp | (1 << (level + 24)); 3603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + VINT_EN); 36160479690af6d559d4202bed139db90323386bd2bMartyn Welch 3623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Wait for IACK */ 3633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wait_event_interruptible(iack_queue, 0); 3643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Return interrupt to low state */ 3663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + VINT_EN); 3673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = tmp & ~(1 << (level + 24)); 3683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + VINT_EN); 3693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_unlock(&(vme_int)); 3713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 37360479690af6d559d4202bed139db90323386bd2bMartyn Welch} 37460479690af6d559d4202bed139db90323386bd2bMartyn Welch 3753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, 3763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long vme_base, unsigned long long size, 3773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle) 37860479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 3793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int i, addr = 0, granularity = 0; 3803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int temp_ctl = 0; 3813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int vme_bound, pci_offset; 38260479690af6d559d4202bed139db90323386bd2bMartyn Welch 3833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch i = image->number; 38460479690af6d559d4202bed139db90323386bd2bMartyn Welch 3853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (aspace) { 3863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A16: 3873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_A16; 3883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A24: 3903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_A24; 3913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A32: 3933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_A32; 3943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER1: 3963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_USER1; 3973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER2: 3993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_USER2; 4003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 4013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A64: 4023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_CRCSR: 4033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER3: 4043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER4: 4053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch default: 4063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid address space\n"); 4073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 4083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 40960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 41060479690af6d559d4202bed139db90323386bd2bMartyn Welch 4113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* 4123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Bound address is a valid address for the window, adjust 4133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * accordingly 4143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 4153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_bound = vme_base + size - granularity; 4163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_offset = pci_base - vme_base; 4173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* XXX Need to check that vme_base, vme_bound and pci_offset aren't 4193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * too big for registers 4203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 4213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((i == 0) || (i == 4)) 4233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch granularity = 0x1000; 4243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 4253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch granularity = 0x10000; 4263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vme_base & (granularity - 1)) { 4283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid VME base alignment\n"); 4293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 4303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 4313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vme_bound & (granularity - 1)) { 4323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid VME bound alignment\n"); 4333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 4343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 4353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (pci_offset & (granularity - 1)) { 4363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid PCI Offset alignment\n"); 4373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 43860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 43960479690af6d559d4202bed139db90323386bd2bMartyn Welch 4403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable while we are mucking around */ 4413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 4423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_VSI_CTL_EN; 4433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 44460479690af6d559d4202bed139db90323386bd2bMartyn Welch 4453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup mapping */ 4463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vme_base, ca91cx42_bridge->base + CA91CX42_VSI_BS[i]); 4473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vme_bound, ca91cx42_bridge->base + CA91CX42_VSI_BD[i]); 4483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(pci_offset, ca91cx42_bridge->base + CA91CX42_VSI_TO[i]); 4493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX Prefetch stuff currently unsupported */ 4513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 4523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeIn->wrPostEnable) 4533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_PWEN; 4543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeIn->prefetchEnable) 4553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_PREN; 4563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeIn->rmwLock) 4573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_LLRMW; 4583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeIn->data64BitCapable) 4593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_LD64EN; 4603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 4613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup address space */ 4633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M; 4643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= addr; 4653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup cycle types */ 4673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~(CA91CX42_VSI_CTL_PGM_M | CA91CX42_VSI_CTL_SUPER_M); 4683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_SUPER) 4693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_SUPER_SUPR; 4703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_USER) 4713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_SUPER_NPRIV; 4723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_PROG) 4733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_PGM_PGM; 4743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_DATA) 4753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA; 4763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Write ctl reg without enable */ 4783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 4793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (enabled) 4813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_EN; 4823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 4843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 48660479690af6d559d4202bed139db90323386bd2bMartyn Welch} 48760479690af6d559d4202bed139db90323386bd2bMartyn Welch 4883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, 4893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long *vme_base, unsigned long long *size, 4903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle) 49160479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 4923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int i, granularity = 0, ctl = 0; 4933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long vme_bound, pci_offset; 4943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch i = image->number; 49660479690af6d559d4202bed139db90323386bd2bMartyn Welch 4973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((i == 0) || (i == 4)) 4983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch granularity = 0x1000; 4993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 5003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch granularity = 0x10000; 5013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Read Registers */ 5033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 5043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *vme_base = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BS[i]); 5063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_bound = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BD[i]); 5073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_offset = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_TO[i]); 5083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *pci_base = (dma_addr_t)vme_base + pci_offset; 5103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *size = (unsigned long long)((vme_bound - *vme_base) + granularity); 5113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *enabled = 0; 5133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = 0; 5143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle = 0; 5153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_EN) 5173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *enabled = 1; 5183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A16) 5203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A16; 5213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A24) 5223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A24; 5233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A32) 5243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A32; 5253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER1) 5263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_USER1; 5273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER2) 5283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_USER2; 5293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_SUPER_SUPR) 5313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_SUPER; 5323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_SUPER_NPRIV) 5333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_USER; 5343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_PGM_PGM) 5353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_PROG; 5363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_PGM_DATA) 5373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_DATA; 5383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 5403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 5413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 5433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Allocate and map PCI Resource 5443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 5453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_alloc_resource(struct vme_master_resource *image, 5463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long size) 5473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 5483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long existing_size; 5493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval = 0; 5503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct pci_dev *pdev; 5513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Find pci_dev container of dev */ 5533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ca91cx42_bridge->parent == NULL) { 5543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Dev entry NULL\n"); 5553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 5563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 5573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); 5583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch existing_size = (unsigned long long)(image->pci_resource.end - 5603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.start); 5613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* If the existing size is OK, return */ 5633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (existing_size == (size - 1)) 5643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 5653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (existing_size != 0) { 5673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(image->kern_base); 5683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->kern_base = NULL; 5693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (image->pci_resource.name != NULL) 5703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(image->pci_resource.name); 5713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch release_resource(&(image->pci_resource)); 5723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(&(image->pci_resource), 0, sizeof(struct resource)); 5733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 5743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (image->pci_resource.name == NULL) { 5763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); 5773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (image->pci_resource.name == NULL) { 5783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Unable to allocate memory for resource" 5793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch " name\n"); 5803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 5813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_name; 5823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 58360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 5843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch sprintf((char *)image->pci_resource.name, "%s.%d", 5863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->name, image->number); 5873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.start = 0; 5893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.end = (unsigned long)size; 5903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.flags = IORESOURCE_MEM; 5913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = pci_bus_alloc_resource(pdev->bus, 5933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &(image->pci_resource), size, size, PCIBIOS_MIN_MEM, 5943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 0, NULL, NULL); 5953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval) { 5963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Failed to allocate mem resource for " 5973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "window %d size 0x%lx start 0x%lx\n", 5983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->number, (unsigned long)size, 5993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch (unsigned long)image->pci_resource.start); 6003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_resource; 60160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 6023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->kern_base = ioremap_nocache( 6043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.start, size); 6053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (image->kern_base == NULL) { 6063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Failed to remap resource\n"); 6073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 6083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_remap; 60960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 61060479690af6d559d4202bed139db90323386bd2bMartyn Welch 6113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 6123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(image->kern_base); 6143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->kern_base = NULL; 6153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_remap: 6163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch release_resource(&(image->pci_resource)); 6173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_resource: 6183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(image->pci_resource.name); 6193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(&(image->pci_resource), 0, sizeof(struct resource)); 6203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_name: 6213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 6223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 6233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 6253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * * Free and unmap PCI Resource 6263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * */ 6273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void ca91cx42_free_resource(struct vme_master_resource *image) 6283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 6293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(image->kern_base); 6303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->kern_base = NULL; 6313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch release_resource(&(image->pci_resource)); 6323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(image->pci_resource.name); 6333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(&(image->pci_resource), 0, sizeof(struct resource)); 6343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 6353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_master_set(struct vme_master_resource *image, int enabled, 6383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long vme_base, unsigned long long size, 6393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) 6403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 6413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval = 0; 6423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int i; 6433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int temp_ctl = 0; 6443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long pci_bound, vme_offset, pci_base; 6453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Verify input data */ 6473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vme_base & 0xFFF) { 6483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid VME Window alignment\n"); 6493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 6503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_window; 6513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 6523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (size & 0xFFF) { 6533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid VME Window alignment\n"); 6543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 6553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_window; 6563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 6573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock(&(image->lock)); 6593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* XXX We should do this much later, so that we can exit without 6613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * needing to redo the mapping... 6623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 6633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* 6643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Let's allocate the resource here rather than further up the stack as 6653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * it avoids pushing loads of bus dependant stuff up the stack 6663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 6673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = ca91cx42_alloc_resource(image, size); 6683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval) { 6693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 6703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Unable to allocate memory for resource " 6713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "name\n"); 6723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 6733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_res; 6743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 6753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_base = (unsigned long long)image->pci_resource.start; 6773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* 6793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Bound address is a valid address for the window, adjust 6803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * according to window granularity. 6813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 6823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_bound = pci_base + (size - 0x1000); 6833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_offset = vme_base - pci_base; 6843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch i = image->number; 6863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable while we are mucking around */ 6883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 6893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_LSI_CTL_EN; 6903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 6913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX Prefetch stuff currently unsupported */ 6933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 6943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeOut->wrPostEnable) 6953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x40000000; 6963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 6973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup cycle types */ 6993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M; 7003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_BLT) 7013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VCT_BLT; 7023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_MBLT) 7033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VCT_MBLT; 7043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup data width */ 7063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_LSI_CTL_VDW_M; 7073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (dwidth) { 7083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_D8: 7093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VDW_D8; 7103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_D16: 7123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VDW_D16; 7133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_D32: 7153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VDW_D32; 7163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_D64: 7183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VDW_D64; 7193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch default: 7213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 7223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid data width\n"); 7233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 7243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_dwidth; 7253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 72660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 7273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup address space */ 7293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_LSI_CTL_VAS_M; 7303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (aspace) { 73160479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A16: 7323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_A16; 73360479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 73460479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A24: 7353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_A24; 73660479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 73760479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A32: 7383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_A32; 7393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_CRCSR: 7413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_CRCSR; 74260479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 74360479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER1: 7443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_USER1; 74560479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 74660479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER2: 7473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_USER2; 7483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A64: 7503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER3: 7513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER4: 7523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch default: 7533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 7543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid address space\n"); 7553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 7563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_aspace; 75760479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 75860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 75960479690af6d559d4202bed139db90323386bd2bMartyn Welch 7603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~(CA91CX42_LSI_CTL_PGM_M | CA91CX42_LSI_CTL_SUPER_M); 7613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_SUPER) 7623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_SUPER_SUPR; 7633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_PROG) 7643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM; 76560479690af6d559d4202bed139db90323386bd2bMartyn Welch 7663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup mapping */ 7673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(pci_base, ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); 7683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(pci_bound, ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); 7693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vme_offset, ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); 7703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Write ctl reg without enable */ 7723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 7733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (enabled) 7753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_EN; 7763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 7783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 7803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 7813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_aspace: 7833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_dwidth: 7843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_free_resource(image); 7853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_res: 7863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_window: 7873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 7883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 7893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint __ca91cx42_master_get(struct vme_master_resource *image, int *enabled, 7913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long *vme_base, unsigned long long *size, 7923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) 7933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 7943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int i, ctl; 7953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long pci_base, pci_bound, vme_offset; 7963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch i = image->number; 7983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 8003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_base = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); 8023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_offset = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); 8033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_bound = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); 8043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *vme_base = pci_base + vme_offset; 8063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *size = (pci_bound - pci_base) + 0x1000; 8073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *enabled = 0; 8093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = 0; 8103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle = 0; 8113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = 0; 8123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_LSI_CTL_EN) 8143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *enabled = 1; 8153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup address space */ 8173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (ctl & CA91CX42_LSI_CTL_VAS_M) { 8183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_A16: 8193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A16; 8203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_A24: 8223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A24; 8233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_A32: 8253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A32; 8263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_CRCSR: 8283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_CRCSR; 8293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_USER1: 8313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_USER1; 8323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_USER2: 8343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_USER2; 8353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 8373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* XXX Not sure howto check for MBLT */ 8393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup cycle types */ 8403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_LSI_CTL_VCT_BLT) 8413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_BLT; 8423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 8433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_SCT; 8443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_LSI_CTL_SUPER_SUPR) 8463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_SUPER; 8473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 8483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_USER; 8493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_LSI_CTL_PGM_PGM) 8513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle = VME_PROG; 8523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 8533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle = VME_DATA; 8543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup data width */ 8563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (ctl & CA91CX42_LSI_CTL_VDW_M) { 8573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VDW_D8: 8583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = VME_D8; 8593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VDW_D16: 8613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = VME_D16; 8623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VDW_D32: 8643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = VME_D32; 8653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VDW_D64: 8673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = VME_D64; 8683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 8703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX Prefetch stuff currently unsupported */ 8723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 8733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & 0x40000000) 8743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeOut->wrPostEnable = 1; 8753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 8763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 8783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 8793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_master_get(struct vme_master_resource *image, int *enabled, 8813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long *vme_base, unsigned long long *size, 8823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) 8833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 8843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval; 8853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock(&(image->lock)); 8873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = __ca91cx42_master_get(image, enabled, vme_base, size, aspace, 8893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch cycle, dwidth); 8903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 8923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 8943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 8953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf, 8973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch size_t count, loff_t offset) 8983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 8993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval; 90060479690af6d559d4202bed139db90323386bd2bMartyn Welch 9013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock(&(image->lock)); 90260479690af6d559d4202bed139db90323386bd2bMartyn Welch 9033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count); 9043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = count; 90560479690af6d559d4202bed139db90323386bd2bMartyn Welch 9063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 9073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 90960479690af6d559d4202bed139db90323386bd2bMartyn Welch} 91060479690af6d559d4202bed139db90323386bd2bMartyn Welch 9113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf, 9123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch size_t count, loff_t offset) 91360479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 9143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval = 0; 91560479690af6d559d4202bed139db90323386bd2bMartyn Welch 9163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock(&(image->lock)); 91760479690af6d559d4202bed139db90323386bd2bMartyn Welch 9183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memcpy_toio(image->kern_base + offset, buf, (unsigned int)count); 9193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = count; 9203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 9223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 92460479690af6d559d4202bed139db90323386bd2bMartyn Welch} 92560479690af6d559d4202bed139db90323386bd2bMartyn Welch 9263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_slot_get(void) 92760479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 9283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 slot = 0; 92960479690af6d559d4202bed139db90323386bd2bMartyn Welch 9303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slot = ioread32(ca91cx42_bridge->base + VCSR_BS); 9313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27); 9323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return (int)slot; 9333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 9353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int __init ca91cx42_init(void) 9373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 9383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return pci_register_driver(&ca91cx42_driver); 9393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 9403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 9423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Configure CR/CSR space 9433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * 9443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Access to the CR/CSR can be configured at power-up. The location of the 9453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * CR/CSR registers in the CR/CSR address space is determined by the boards 9463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Auto-ID or Geographic address. This function ensures that the window is 9473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * enabled at an offset consistent with the boards geopgraphic address. 9483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 9493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_crcsr_init(struct pci_dev *pdev) 9503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 9513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int crcsr_addr; 9523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int tmp, slot; 9533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX We may need to set this somehow as the Universe II does not support 9553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * geographical addressing. 9563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 9573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 9583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vme_slotnum != -1) 9593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vme_slotnum << 27, ca91cx42_bridge->base + VCSR_BS); 9603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 9613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slot = ca91cx42_slot_get(); 9623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot); 9633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (slot == 0) { 9643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Slot number is unset, not configuring " 9653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "CR/CSR space\n"); 9663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 96760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 9683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Allocate mem for CR/CSR image */ 9703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, 9713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &crcsr_bus); 9723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (crcsr_kernel == NULL) { 9733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " 9743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "image\n"); 9753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -ENOMEM; 97660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 97760479690af6d559d4202bed139db90323386bd2bMartyn Welch 9783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); 97960479690af6d559d4202bed139db90323386bd2bMartyn Welch 9803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch crcsr_addr = slot * (512 * 1024); 9813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(crcsr_bus - crcsr_addr, ca91cx42_bridge->base + VCSR_TO); 98260479690af6d559d4202bed139db90323386bd2bMartyn Welch 9833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL); 9843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp |= CA91CX42_VCSR_CTL_EN; 9853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL); 98660479690af6d559d4202bed139db90323386bd2bMartyn Welch 9873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 98860479690af6d559d4202bed139db90323386bd2bMartyn Welch} 98960479690af6d559d4202bed139db90323386bd2bMartyn Welch 9903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void ca91cx42_crcsr_exit(struct pci_dev *pdev) 99160479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 9923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 tmp; 99360479690af6d559d4202bed139db90323386bd2bMartyn Welch 9943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Turn off CR/CSR space */ 9953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL); 9963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp &= ~CA91CX42_VCSR_CTL_EN; 9973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL); 99860479690af6d559d4202bed139db90323386bd2bMartyn Welch 9993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Free image */ 10003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + VCSR_TO); 100160479690af6d559d4202bed139db90323386bd2bMartyn Welch 10023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus); 10033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 100460479690af6d559d4202bed139db90323386bd2bMartyn Welch 10053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) 10063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 10073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval, i; 10083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 data; 10093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct list_head *pos = NULL; 10103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_master_resource *master_image; 10113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_slave_resource *slave_image; 10123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 10133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_dma_resource *dma_ctrlr; 10143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 10153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_lm_resource *lm; 10163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* We want to support more than one of each bridge so we need to 10183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * dynamically allocate the bridge structure 10193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 10203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge = kmalloc(sizeof(struct vme_bridge), GFP_KERNEL); 10213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ca91cx42_bridge == NULL) { 10233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for device " 10243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "structure\n"); 10253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 10263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_struct; 10273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge)); 10303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Enable the device */ 10323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = pci_enable_device(pdev); 10333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval) { 10343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Unable to enable device\n"); 10353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_enable; 10363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Map Registers */ 10393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = pci_request_regions(pdev, driver_name); 10403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval) { 10413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Unable to reserve resources\n"); 10423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_resource; 10433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* map registers in BAR 0 */ 10463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), 10473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4096); 10483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (!ca91cx42_bridge->base) { 10493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Unable to remap CRG region\n"); 10503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EIO; 10513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_remap; 10523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Check to see if the mapping worked out */ 10553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch data = ioread32(ca91cx42_bridge->base + CA91CX42_PCI_ID) & 0x0000FFFF; 10563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (data != PCI_VENDOR_ID_TUNDRA) { 10573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "PCI_ID check failed\n"); 10583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EIO; 10593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_test; 10603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Initialize wait queues & mutual exclusion flags */ 10633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* XXX These need to be moved to the vme_bridge structure */ 10643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch init_waitqueue_head(&dma_queue); 10653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch init_waitqueue_head(&iack_queue); 10663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(vme_int)); 10673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(vme_irq)); 10683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(vme_rmw)); 10693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->parent = &(pdev->dev); 10713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch strcpy(ca91cx42_bridge->name, driver_name); 10723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup IRQ */ 10743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = ca91cx42_irq_init(ca91cx42_bridge); 10753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval != 0) { 10763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Chip Initialization failed.\n"); 10773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_irq; 10783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Add master windows to list */ 10813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(ca91cx42_bridge->master_resources)); 10823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (i = 0; i < CA91C142_MAX_MASTER; i++) { 10833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image = kmalloc(sizeof(struct vme_master_resource), 10843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch GFP_KERNEL); 10853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (master_image == NULL) { 10863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for " 10873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "master resource structure\n"); 10883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 10893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_master; 10903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->parent = ca91cx42_bridge; 10923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock_init(&(master_image->lock)); 10933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->locked = 0; 10943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->number = i; 10953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | 10963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch VME_CRCSR | VME_USER1 | VME_USER2; 10973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | 10983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch VME_SUPER | VME_USER | VME_PROG | VME_DATA; 10993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64; 11003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(&(master_image->pci_resource), 0, 11013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch sizeof(struct resource)); 11023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->kern_base = NULL; 11033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_add_tail(&(master_image->list), 11043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &(ca91cx42_bridge->master_resources)); 11053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Add slave windows to list */ 11083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(ca91cx42_bridge->slave_resources)); 11093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (i = 0; i < CA91C142_MAX_SLAVE; i++) { 11103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image = kmalloc(sizeof(struct vme_slave_resource), 11113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch GFP_KERNEL); 11123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (slave_image == NULL) { 11133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for " 11143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "slave resource structure\n"); 11153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 11163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_slave; 11173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->parent = ca91cx42_bridge; 11193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(slave_image->mtx)); 11203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->locked = 0; 11213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->number = i; 11223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->address_attr = VME_A24 | VME_A32 | VME_USER1 | 11233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch VME_USER2; 11243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Only windows 0 and 4 support A16 */ 11263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (i == 0 || i == 4) 11273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->address_attr |= VME_A16; 11283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | 11303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch VME_SUPER | VME_USER | VME_PROG | VME_DATA; 11313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_add_tail(&(slave_image->list), 11323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &(ca91cx42_bridge->slave_resources)); 11333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 11353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Add dma engines to list */ 11363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources)); 11373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (i = 0; i < CA91C142_MAX_DMA; i++) { 11383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), 11393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch GFP_KERNEL); 11403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (dma_ctrlr == NULL) { 11413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for " 11423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "dma resource structure\n"); 11433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 11443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_dma; 11453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr->parent = ca91cx42_bridge; 11473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(dma_ctrlr->mtx)); 11483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr->locked = 0; 11493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr->number = i; 11503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(dma_ctrlr->pending)); 11513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(dma_ctrlr->running)); 11523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_add_tail(&(dma_ctrlr->list), 11533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &(ca91cx42_bridge->dma_resources)); 11543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 11563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Add location monitor to list */ 11573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources)); 11583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); 11593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (lm == NULL) { 11603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for " 11613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "location monitor resource structure\n"); 11623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 11633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_lm; 11643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm->parent = ca91cx42_bridge; 11663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(lm->mtx)); 11673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm->locked = 0; 11683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm->number = 1; 11693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm->monitors = 4; 11703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_add_tail(&(lm->list), &(ca91cx42_bridge->lm_resources)); 11713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->slave_get = ca91cx42_slave_get; 11733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->slave_set = ca91cx42_slave_set; 11743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_get = ca91cx42_master_get; 11753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_set = ca91cx42_master_set; 11763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_read = ca91cx42_master_read; 11773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_write = ca91cx42_master_write; 11783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 11793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_rmw = ca91cx42_master_rmw; 11803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add; 11813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec; 11823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty; 11833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 11843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->request_irq = ca91cx42_request_irq; 11853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->free_irq = ca91cx42_free_irq; 11863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->generate_irq = ca91cx42_generate_irq; 11873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 11883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->lm_set = ca91cx42_lm_set; 11893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->lm_get = ca91cx42_lm_get; 11903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->lm_attach = ca91cx42_lm_attach; 11913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->lm_detach = ca91cx42_lm_detach; 11923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 11933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->slot_get = ca91cx42_slot_get; 11943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch data = ioread32(ca91cx42_bridge->base + MISC_CTL); 11963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_info(&pdev->dev, "Board is%s the VME system controller\n", 11973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch (data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not"); 11983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_info(&pdev->dev, "Slot ID is %d\n", ca91cx42_slot_get()); 11993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ca91cx42_crcsr_init(pdev)) { 12013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); 12023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 12033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 12043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_crcsr; 12053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 120660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 120760479690af6d559d4202bed139db90323386bd2bMartyn Welch 12083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Need to save ca91cx42_bridge pointer locally in link list for use in 12093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * ca91cx42_remove() 12103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 12113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = vme_register_bridge(ca91cx42_bridge); 12123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval != 0) { 12133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Chip Registration failed.\n"); 12143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_reg; 12153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 12163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 12183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_unregister_bridge(ca91cx42_bridge); 12203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_reg: 12213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_crcsr_exit(pdev); 12223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_crcsr: 12233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_lm: 12243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { 12263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm = list_entry(pos, struct vme_lm_resource, list); 12273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(lm); 12293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 12303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 12313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_dma: 12323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->dma_resources)) { 12343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); 12353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(dma_ctrlr); 123760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 12383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 12393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_slave: 12403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->slave_resources)) { 12423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image = list_entry(pos, struct vme_slave_resource, list); 12433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(slave_image); 12453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 12463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_master: 12473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->master_resources)) { 12493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image = list_entry(pos, struct vme_master_resource, 12503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list); 12513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(master_image); 12533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 12543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_irq_exit(pdev); 12563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_irq: 12573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_test: 12583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(ca91cx42_bridge->base); 12593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_remap: 12603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_release_regions(pdev); 12613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_resource: 12623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_disable_device(pdev); 12633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_enable: 12643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(ca91cx42_bridge); 12653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_struct: 12663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 126760479690af6d559d4202bed139db90323386bd2bMartyn Welch 126860479690af6d559d4202bed139db90323386bd2bMartyn Welch} 126960479690af6d559d4202bed139db90323386bd2bMartyn Welch 12703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchvoid ca91cx42_remove(struct pci_dev *pdev) 127160479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 12723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct list_head *pos = NULL; 12733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_master_resource *master_image; 12743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_slave_resource *slave_image; 12753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_dma_resource *dma_ctrlr; 12763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_lm_resource *lm; 12773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int i; 127860479690af6d559d4202bed139db90323386bd2bMartyn Welch 12793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Turn off Ints */ 12803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + LINT_EN); 12813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Turn off the windows */ 12833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI0_CTL); 12843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI1_CTL); 12853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI2_CTL); 12863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI3_CTL); 12873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI4_CTL); 12883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI5_CTL); 12893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI6_CTL); 12903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI7_CTL); 12913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI0_CTL); 12923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI1_CTL); 12933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI2_CTL); 12943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI3_CTL); 12953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI4_CTL); 12963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI5_CTL); 12973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI6_CTL); 12983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI7_CTL); 12993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 13003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_unregister_bridge(ca91cx42_bridge); 13013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 13023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_crcsr_exit(pdev); 13033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 13043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 13053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { 13063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm = list_entry(pos, struct vme_lm_resource, list); 13073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 13083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(lm); 130960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 13103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 13113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 13123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->dma_resources)) { 13133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); 13143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 13153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(dma_ctrlr); 131660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 131760479690af6d559d4202bed139db90323386bd2bMartyn Welch 13183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 13193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->slave_resources)) { 13203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image = list_entry(pos, struct vme_slave_resource, list); 13213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 13223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(slave_image); 13233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 132460479690af6d559d4202bed139db90323386bd2bMartyn Welch 13253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 13263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->master_resources)) { 13273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image = list_entry(pos, struct vme_master_resource, 13283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list); 13293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 13303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(master_image); 13313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 133260479690af6d559d4202bed139db90323386bd2bMartyn Welch 13333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_irq_exit(pdev); 133460479690af6d559d4202bed139db90323386bd2bMartyn Welch 13353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(ca91cx42_bridge->base); 133660479690af6d559d4202bed139db90323386bd2bMartyn Welch 13373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_release_regions(pdev); 133860479690af6d559d4202bed139db90323386bd2bMartyn Welch 13393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_disable_device(pdev); 13403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 13413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(ca91cx42_bridge); 134260479690af6d559d4202bed139db90323386bd2bMartyn Welch} 134360479690af6d559d4202bed139db90323386bd2bMartyn Welch 13443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void __exit ca91cx42_exit(void) 134560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 13463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_unregister_driver(&ca91cx42_driver); 13473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 134860479690af6d559d4202bed139db90323386bd2bMartyn Welch 13493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn WelchMODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge"); 13503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn WelchMODULE_LICENSE("GPL"); 135160479690af6d559d4202bed139db90323386bd2bMartyn Welch 13523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchmodule_init(ca91cx42_init); 13533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchmodule_exit(ca91cx42_exit); 135460479690af6d559d4202bed139db90323386bd2bMartyn Welch 13553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/*---------------------------------------------------------------------------- 13563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * STAGING 13573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *--------------------------------------------------------------------------*/ 13583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 13593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 136060479690af6d559d4202bed139db90323386bd2bMartyn Welch#define SWIZZLE(X) ( ((X & 0xFF000000) >> 24) | ((X & 0x00FF0000) >> 8) | ((X & 0x0000FF00) << 8) | ((X & 0x000000FF) << 24)) 136160479690af6d559d4202bed139db90323386bd2bMartyn Welch 13623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_master_rmw(vmeRmwCfg_t *vmeRmw) 136360479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 136460479690af6d559d4202bed139db90323386bd2bMartyn Welch int temp_ctl = 0; 136560479690af6d559d4202bed139db90323386bd2bMartyn Welch int tempBS = 0; 136660479690af6d559d4202bed139db90323386bd2bMartyn Welch int tempBD = 0; 136760479690af6d559d4202bed139db90323386bd2bMartyn Welch int tempTO = 0; 136860479690af6d559d4202bed139db90323386bd2bMartyn Welch int vmeBS = 0; 136960479690af6d559d4202bed139db90323386bd2bMartyn Welch int vmeBD = 0; 137060479690af6d559d4202bed139db90323386bd2bMartyn Welch int *rmw_pci_data_ptr = NULL; 137160479690af6d559d4202bed139db90323386bd2bMartyn Welch int *vaDataPtr = NULL; 137260479690af6d559d4202bed139db90323386bd2bMartyn Welch int i; 137360479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeOutWindowCfg_t vmeOut; 137460479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeRmw->maxAttempts < 1) { 13753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 137660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 137760479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeRmw->targetAddrU) { 13783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 137960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 13803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Find the PCI address that maps to the desired VME address */ 138160479690af6d559d4202bed139db90323386bd2bMartyn Welch for (i = 0; i < 8; i++) { 13823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + 13833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LSI_CTL[i]); 138460479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((temp_ctl & 0x80000000) == 0) { 138560479690af6d559d4202bed139db90323386bd2bMartyn Welch continue; 138660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 138760479690af6d559d4202bed139db90323386bd2bMartyn Welch memset(&vmeOut, 0, sizeof(vmeOut)); 138860479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeOut.windowNbr = i; 13893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_get_out_bound(&vmeOut); 139060479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeOut.addrSpace != vmeRmw->addrSpace) { 139160479690af6d559d4202bed139db90323386bd2bMartyn Welch continue; 139260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 13933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tempBS = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); 13943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tempBD = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); 13953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tempTO = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); 139660479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeBS = tempBS + tempTO; 139760479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeBD = tempBD + tempTO; 139860479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((vmeRmw->targetAddr >= vmeBS) && 139960479690af6d559d4202bed139db90323386bd2bMartyn Welch (vmeRmw->targetAddr < vmeBD)) { 140060479690af6d559d4202bed139db90323386bd2bMartyn Welch rmw_pci_data_ptr = 140160479690af6d559d4202bed139db90323386bd2bMartyn Welch (int *)(tempBS + (vmeRmw->targetAddr - vmeBS)); 140260479690af6d559d4202bed139db90323386bd2bMartyn Welch vaDataPtr = 140360479690af6d559d4202bed139db90323386bd2bMartyn Welch (int *)(out_image_va[i] + 140460479690af6d559d4202bed139db90323386bd2bMartyn Welch (vmeRmw->targetAddr - vmeBS)); 140560479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 140660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 140760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 140860479690af6d559d4202bed139db90323386bd2bMartyn Welch 14093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* If no window - fail. */ 141060479690af6d559d4202bed139db90323386bd2bMartyn Welch if (rmw_pci_data_ptr == NULL) { 14113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 14123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 14133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup the RMW registers. */ 14143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + SCYC_CTL); 14153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(SWIZZLE(vmeRmw->enableMask), ca91cx42_bridge->base + SCYC_EN); 14163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(SWIZZLE(vmeRmw->compareData), ca91cx42_bridge->base + 14173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch SCYC_CMP); 14183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(SWIZZLE(vmeRmw->swapData), ca91cx42_bridge->base + SCYC_SWP); 14193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32((int)rmw_pci_data_ptr, ca91cx42_bridge->base + SCYC_ADDR); 14203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(1, ca91cx42_bridge->base + SCYC_CTL); 14213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 14223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Run the RMW cycle until either success or max attempts. */ 142360479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeRmw->numAttempts = 1; 142460479690af6d559d4202bed139db90323386bd2bMartyn Welch while (vmeRmw->numAttempts <= vmeRmw->maxAttempts) { 142560479690af6d559d4202bed139db90323386bd2bMartyn Welch 14263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ioread32(vaDataPtr) & vmeRmw->enableMask) == 142760479690af6d559d4202bed139db90323386bd2bMartyn Welch (vmeRmw->swapData & vmeRmw->enableMask)) { 142860479690af6d559d4202bed139db90323386bd2bMartyn Welch 14293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + SCYC_CTL); 143060479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 143160479690af6d559d4202bed139db90323386bd2bMartyn Welch 143260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 143360479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeRmw->numAttempts++; 143460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 143560479690af6d559d4202bed139db90323386bd2bMartyn Welch 14363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* If no success, set num Attempts to be greater than max attempts */ 143760479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeRmw->numAttempts > vmeRmw->maxAttempts) { 143860479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeRmw->numAttempts = vmeRmw->maxAttempts + 1; 143960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 144060479690af6d559d4202bed139db90323386bd2bMartyn Welch 14413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 144260479690af6d559d4202bed139db90323386bd2bMartyn Welch} 144360479690af6d559d4202bed139db90323386bd2bMartyn Welch 144460479690af6d559d4202bed139db90323386bd2bMartyn Welchint uniSetupDctlReg(vmeDmaPacket_t * vmeDma, int *dctlregreturn) 144560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 144660479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dctlreg = 0x80; 144760479690af6d559d4202bed139db90323386bd2bMartyn Welch struct vmeAttr *vmeAttr; 144860479690af6d559d4202bed139db90323386bd2bMartyn Welch 144960479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeDma->srcBus == VME_DMA_VME) { 145060479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg = 0; 145160479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeAttr = &vmeDma->srcVmeAttr; 145260479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 145360479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg = 0x80000000; 145460479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeAttr = &vmeDma->dstVmeAttr; 145560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 145660479690af6d559d4202bed139db90323386bd2bMartyn Welch 145760479690af6d559d4202bed139db90323386bd2bMartyn Welch switch (vmeAttr->maxDataWidth) { 145860479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_D8: 145960479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 146060479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_D16: 146160479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00400000; 146260479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 146360479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_D32: 146460479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00800000; 146560479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 146660479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_D64: 146760479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00C00000; 146860479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 146960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 147060479690af6d559d4202bed139db90323386bd2bMartyn Welch 147160479690af6d559d4202bed139db90323386bd2bMartyn Welch switch (vmeAttr->addrSpace) { 147260479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A16: 147360479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 147460479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A24: 147560479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00010000; 147660479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 147760479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A32: 147860479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00020000; 147960479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 148060479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER1: 148160479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00060000; 148260479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 148360479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER2: 148460479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00070000; 148560479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 148660479690af6d559d4202bed139db90323386bd2bMartyn Welch 14873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A64: /* not supported in Universe DMA */ 148860479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_CRCSR: 148960479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER3: 149060479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER4: 14913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 149260479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 149360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 149460479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeAttr->userAccessType == VME_PROG) { 149560479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00004000; 149660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 149760479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeAttr->dataAccessType == VME_SUPER) { 149860479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00001000; 149960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 150060479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeAttr->xferProtocol != VME_SCT) { 150160479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00000100; 150260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 150360479690af6d559d4202bed139db90323386bd2bMartyn Welch *dctlregreturn = dctlreg; 15043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 150560479690af6d559d4202bed139db90323386bd2bMartyn Welch} 150660479690af6d559d4202bed139db90323386bd2bMartyn Welch 150760479690af6d559d4202bed139db90323386bd2bMartyn Welchunsigned int 15083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchca91cx42_start_dma(int channel, unsigned int dgcsreg, TDMA_Cmd_Packet *vmeLL) 150960479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 151060479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int val; 151160479690af6d559d4202bed139db90323386bd2bMartyn Welch 15123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup registers as needed for direct or chained. */ 151360479690af6d559d4202bed139db90323386bd2bMartyn Welch if (dgcsreg & 0x8000000) { 15143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + DTBC); 15153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32((unsigned int)vmeLL, ca91cx42_bridge->base + DCPP); 151660479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 151760479690af6d559d4202bed139db90323386bd2bMartyn Welch#if 0 15183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DGCS = %08x\n", dgcsreg); 15193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DVA = %08x\n", 15203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(&vmeLL->dva)); 15213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DLV = %08x\n", 15223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(&vmeLL->dlv)); 15233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DTBC = %08x\n", 15243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(&vmeLL->dtbc)); 15253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DCTL = %08x\n", 15263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(&vmeLL->dctl)); 152760479690af6d559d4202bed139db90323386bd2bMartyn Welch#endif 15283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Write registers */ 15293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(ioread32(&vmeLL->dva), ca91cx42_bridge->base + DVA); 15303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(ioread32(&vmeLL->dlv), ca91cx42_bridge->base + DLA); 15313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(ioread32(&vmeLL->dtbc), ca91cx42_bridge->base + DTBC); 15323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(ioread32(&vmeLL->dctl), ca91cx42_bridge->base + DCTL); 15333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + DCPP); 153460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 153560479690af6d559d4202bed139db90323386bd2bMartyn Welch 15363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Start the operation */ 15373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(dgcsreg, ca91cx42_bridge->base + DGCS); 153860479690af6d559d4202bed139db90323386bd2bMartyn Welch val = get_tbl(); 15393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(dgcsreg | 0x8000000F, ca91cx42_bridge->base + DGCS); 15403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return val; 154160479690af6d559d4202bed139db90323386bd2bMartyn Welch} 154260479690af6d559d4202bed139db90323386bd2bMartyn Welch 15433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn WelchTDMA_Cmd_Packet *ca91cx42_setup_dma(vmeDmaPacket_t * vmeDma) 154460479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 154560479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDmaPacket_t *vmeCur; 154660479690af6d559d4202bed139db90323386bd2bMartyn Welch int maxPerPage; 154760479690af6d559d4202bed139db90323386bd2bMartyn Welch int currentLLcount; 154860479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *startLL; 154960479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *currentLL; 155060479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *nextLL; 155160479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dctlreg = 0; 155260479690af6d559d4202bed139db90323386bd2bMartyn Welch 155360479690af6d559d4202bed139db90323386bd2bMartyn Welch maxPerPage = PAGESIZE / sizeof(TDMA_Cmd_Packet) - 1; 155460479690af6d559d4202bed139db90323386bd2bMartyn Welch startLL = (TDMA_Cmd_Packet *) __get_free_pages(GFP_KERNEL, 0); 155560479690af6d559d4202bed139db90323386bd2bMartyn Welch if (startLL == 0) { 15563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return startLL; 155760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 15583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* First allocate pages for descriptors and create linked list */ 155960479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeCur = vmeDma; 156060479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 156160479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLLcount = 0; 156260479690af6d559d4202bed139db90323386bd2bMartyn Welch while (vmeCur != 0) { 156360479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeCur->pNextPacket != 0) { 156460479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = (unsigned int)(currentLL + 1); 156560479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLLcount++; 156660479690af6d559d4202bed139db90323386bd2bMartyn Welch if (currentLLcount >= maxPerPage) { 156760479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = 156860479690af6d559d4202bed139db90323386bd2bMartyn Welch __get_free_pages(GFP_KERNEL, 0); 156960479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLLcount = 0; 157060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 157160479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 157260479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 157360479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = (unsigned int)0; 157460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 157560479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeCur = vmeCur->pNextPacket; 157660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 157760479690af6d559d4202bed139db90323386bd2bMartyn Welch 15783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Next fill in information for each descriptor */ 157960479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeCur = vmeDma; 158060479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 158160479690af6d559d4202bed139db90323386bd2bMartyn Welch while (vmeCur != 0) { 158260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeCur->srcBus == VME_DMA_VME) { 15833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->srcAddr, ¤tLL->dva); 15843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->dstAddr, ¤tLL->dlv); 158560479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 15863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->srcAddr, ¤tLL->dlv); 15873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->dstAddr, ¤tLL->dva); 158860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 158960479690af6d559d4202bed139db90323386bd2bMartyn Welch uniSetupDctlReg(vmeCur, &dctlreg); 15903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(dctlreg, ¤tLL->dctl); 15913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->byteCount, ¤tLL->dtbc); 159260479690af6d559d4202bed139db90323386bd2bMartyn Welch 159360479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 159460479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeCur = vmeCur->pNextPacket; 159560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 159660479690af6d559d4202bed139db90323386bd2bMartyn Welch 15973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Convert Links to PCI addresses. */ 159860479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 159960479690af6d559d4202bed139db90323386bd2bMartyn Welch while (currentLL != 0) { 160060479690af6d559d4202bed139db90323386bd2bMartyn Welch nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 160160479690af6d559d4202bed139db90323386bd2bMartyn Welch if (nextLL == 0) { 16023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(1, ¤tLL->dcpp); 160360479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 16043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32((unsigned int)virt_to_bus(nextLL), 160560479690af6d559d4202bed139db90323386bd2bMartyn Welch ¤tLL->dcpp); 160660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 160760479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = nextLL; 160860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 160960479690af6d559d4202bed139db90323386bd2bMartyn Welch 16103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Return pointer to descriptors list */ 16113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return startLL; 161260479690af6d559d4202bed139db90323386bd2bMartyn Welch} 161360479690af6d559d4202bed139db90323386bd2bMartyn Welch 16143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_free_dma(TDMA_Cmd_Packet *startLL) 161560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 161660479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *currentLL; 161760479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *prevLL; 161860479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *nextLL; 161960479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dcppreg; 162060479690af6d559d4202bed139db90323386bd2bMartyn Welch 16213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Convert Links to virtual addresses. */ 162260479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 162360479690af6d559d4202bed139db90323386bd2bMartyn Welch while (currentLL != 0) { 16243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dcppreg = ioread32(¤tLL->dcpp); 162560479690af6d559d4202bed139db90323386bd2bMartyn Welch dcppreg &= ~6; 162660479690af6d559d4202bed139db90323386bd2bMartyn Welch if (dcppreg & 1) { 162760479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = 0; 162860479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 162960479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = (unsigned int)bus_to_virt(dcppreg); 163060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 163160479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 163260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 163360479690af6d559d4202bed139db90323386bd2bMartyn Welch 16343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Free all pages associated with the descriptors. */ 163560479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 163660479690af6d559d4202bed139db90323386bd2bMartyn Welch prevLL = currentLL; 163760479690af6d559d4202bed139db90323386bd2bMartyn Welch while (currentLL != 0) { 163860479690af6d559d4202bed139db90323386bd2bMartyn Welch nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 163960479690af6d559d4202bed139db90323386bd2bMartyn Welch if (currentLL + 1 != nextLL) { 164060479690af6d559d4202bed139db90323386bd2bMartyn Welch free_pages((int)prevLL, 0); 164160479690af6d559d4202bed139db90323386bd2bMartyn Welch prevLL = nextLL; 164260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 164360479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = nextLL; 164460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 164560479690af6d559d4202bed139db90323386bd2bMartyn Welch 16463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Return pointer to descriptors list */ 16473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 164860479690af6d559d4202bed139db90323386bd2bMartyn Welch} 164960479690af6d559d4202bed139db90323386bd2bMartyn Welch 16503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_do_dma(vmeDmaPacket_t *vmeDma) 165160479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 165260479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dgcsreg = 0; 165360479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dctlreg = 0; 165460479690af6d559d4202bed139db90323386bd2bMartyn Welch int val; 165560479690af6d559d4202bed139db90323386bd2bMartyn Welch int channel, x; 165660479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDmaPacket_t *curDma; 165760479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *dmaLL; 165860479690af6d559d4202bed139db90323386bd2bMartyn Welch 16593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Sanity check the VME chain. */ 166060479690af6d559d4202bed139db90323386bd2bMartyn Welch channel = vmeDma->channel_number; 166160479690af6d559d4202bed139db90323386bd2bMartyn Welch if (channel > 0) { 16623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 166360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 166460479690af6d559d4202bed139db90323386bd2bMartyn Welch curDma = vmeDma; 166560479690af6d559d4202bed139db90323386bd2bMartyn Welch while (curDma != 0) { 166660479690af6d559d4202bed139db90323386bd2bMartyn Welch if (curDma->byteCount == 0) { 16673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 166860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 166960479690af6d559d4202bed139db90323386bd2bMartyn Welch if (curDma->byteCount >= 0x1000000) { 16703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 167160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 167260479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((curDma->srcAddr & 7) != (curDma->dstAddr & 7)) { 16733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 167460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 167560479690af6d559d4202bed139db90323386bd2bMartyn Welch switch (curDma->srcBus) { 167660479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_DMA_PCI: 167760479690af6d559d4202bed139db90323386bd2bMartyn Welch if (curDma->dstBus != VME_DMA_VME) { 16783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 167960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 168060479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 168160479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_DMA_VME: 168260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (curDma->dstBus != VME_DMA_PCI) { 16833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 168460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 168560479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 168660479690af6d559d4202bed139db90323386bd2bMartyn Welch default: 16873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 168860479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 168960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 169060479690af6d559d4202bed139db90323386bd2bMartyn Welch if (uniSetupDctlReg(curDma, &dctlreg) < 0) { 16913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 169260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 169360479690af6d559d4202bed139db90323386bd2bMartyn Welch 169460479690af6d559d4202bed139db90323386bd2bMartyn Welch curDma = curDma->pNextPacket; 16953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (curDma == vmeDma) { /* Endless Loop! */ 16963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 169760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 169860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 169960479690af6d559d4202bed139db90323386bd2bMartyn Welch 17003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* calculate control register */ 170160479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeDma->pNextPacket != 0) { 170260479690af6d559d4202bed139db90323386bd2bMartyn Welch dgcsreg = 0x8000000; 170360479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 170460479690af6d559d4202bed139db90323386bd2bMartyn Welch dgcsreg = 0; 170560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 170660479690af6d559d4202bed139db90323386bd2bMartyn Welch 17073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (x = 0; x < 8; x++) { /* vme block size */ 170860479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((256 << x) >= vmeDma->maxVmeBlockSize) { 170960479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 171060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 171160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 171260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (x == 8) 171360479690af6d559d4202bed139db90323386bd2bMartyn Welch x = 7; 171460479690af6d559d4202bed139db90323386bd2bMartyn Welch dgcsreg |= (x << 20); 171560479690af6d559d4202bed139db90323386bd2bMartyn Welch 171660479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeDma->vmeBackOffTimer) { 17173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (x = 1; x < 8; x++) { /* vme timer */ 171860479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((16 << (x - 1)) >= vmeDma->vmeBackOffTimer) { 171960479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 172060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 172160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 172260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (x == 8) 172360479690af6d559d4202bed139db90323386bd2bMartyn Welch x = 7; 172460479690af6d559d4202bed139db90323386bd2bMartyn Welch dgcsreg |= (x << 16); 172560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 17263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /*` Setup the dma chain */ 17273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dmaLL = ca91cx42_setup_dma(vmeDma); 172860479690af6d559d4202bed139db90323386bd2bMartyn Welch 17293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Start the DMA */ 173060479690af6d559d4202bed139db90323386bd2bMartyn Welch if (dgcsreg & 0x8000000) { 173160479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDma->vmeDmaStartTick = 17323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_start_dma(channel, dgcsreg, 173360479690af6d559d4202bed139db90323386bd2bMartyn Welch (TDMA_Cmd_Packet *) virt_to_phys(dmaLL)); 173460479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 173560479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDma->vmeDmaStartTick = 17363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_start_dma(channel, dgcsreg, dmaLL); 173760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 173860479690af6d559d4202bed139db90323386bd2bMartyn Welch 17393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wait_event_interruptible(dma_queue, 17403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(ca91cx42_bridge->base + DGCS) & 0x800); 174160479690af6d559d4202bed139db90323386bd2bMartyn Welch 17423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DGCS); 17433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(val | 0xF00, ca91cx42_bridge->base + DGCS); 174460479690af6d559d4202bed139db90323386bd2bMartyn Welch 174560479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDma->vmeDmaStatus = 0; 174660479690af6d559d4202bed139db90323386bd2bMartyn Welch 174760479690af6d559d4202bed139db90323386bd2bMartyn Welch if (!(val & 0x00000800)) { 174860479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDma->vmeDmaStatus = val & 0x700; 17493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "ca91c042: DMA Error in ca91cx42_DMA_irqhandler" 17503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch " DGCS=%08X\n", val); 17513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DCPP); 175260479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DCPP=%08X\n", val); 17533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DCTL); 175460479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DCTL=%08X\n", val); 17553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DTBC); 175660479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DTBC=%08X\n", val); 17573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DLA); 175860479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DLA=%08X\n", val); 17593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DVA); 176060479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DVA=%08X\n", val); 176160479690af6d559d4202bed139db90323386bd2bMartyn Welch 176260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 17633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Free the dma chain */ 17643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_free_dma(dmaLL); 176560479690af6d559d4202bed139db90323386bd2bMartyn Welch 17663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 176760479690af6d559d4202bed139db90323386bd2bMartyn Welch} 176860479690af6d559d4202bed139db90323386bd2bMartyn Welch 17693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_lm_set(vmeLmCfg_t *vmeLm) 177060479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 17713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 17723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->addrU) 17743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 17753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (vmeLm->addrSpace) { 17773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A64: 17783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER3: 17793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER4: 17803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 17813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A16: 17823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00000; 17833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A24: 17853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x10000; 17863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A32: 17883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x20000; 17893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_CRCSR: 17913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x50000; 17923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER1: 17943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x60000; 17953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER2: 17973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x70000; 17983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 179960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 18003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable while we are mucking around */ 18023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL); 18033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeLm->addr, ca91cx42_bridge->base + LM_BS); 18053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup CTL register. */ 18073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->userAccessType & VME_SUPER) 18083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00200000; 18093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->userAccessType & VME_USER) 18103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00100000; 18113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->dataAccessType & VME_PROG) 18123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00800000; 18133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->dataAccessType & VME_DATA) 18143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00400000; 18153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Write ctl reg and enable */ 18183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x80000000 | temp_ctl, ca91cx42_bridge->base + LM_CTL); 18193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + LM_CTL); 18203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 182260479690af6d559d4202bed139db90323386bd2bMartyn Welch} 182360479690af6d559d4202bed139db90323386bd2bMartyn Welch 18243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_wait_lm(vmeLmCfg_t *vmeLm) 182560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 18263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long flags; 182760479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int tmp; 18283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock_irqsave(&lm_lock, flags); 18303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock_irqrestore(&lm_lock, flags); 18313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (tmp == 0) { 18323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->lmWait < 10) 18333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeLm->lmWait = 10; 18343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch interruptible_sleep_on_timeout(&lm_queue, vmeLm->lmWait); 183560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 18363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL); 183760479690af6d559d4202bed139db90323386bd2bMartyn Welch 18383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 18393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 184060479690af6d559d4202bed139db90323386bd2bMartyn Welch 184160479690af6d559d4202bed139db90323386bd2bMartyn Welch 184260479690af6d559d4202bed139db90323386bd2bMartyn Welch 18433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_set_arbiter(vmeArbiterCfg_t *vmeArb) 18443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 18453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 18463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int vbto = 0; 184760479690af6d559d4202bed139db90323386bd2bMartyn Welch 18483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL); 18493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= 0x00FFFFFF; 185060479690af6d559d4202bed139db90323386bd2bMartyn Welch 18513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) { 18523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto = 7; 18533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } else if (vmeArb->globalTimeoutTimer > 1024) { 18543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 18553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } else if (vmeArb->globalTimeoutTimer == 0) { 18563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto = 0; 185760479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 18583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto = 1; 18593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch while ((16 * (1 << (vbto - 1))) < vmeArb->globalTimeoutTimer) 18603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto += 1; 186160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 18623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= (vbto << 28); 18633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeArb->arbiterMode == VME_PRIORITY_MODE) 18653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 1 << 26; 18663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeArb->arbiterTimeoutFlag) 18683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 2 << 24; 18693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + MISC_CTL); 18713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 18723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 18733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_get_arbiter(vmeArbiterCfg_t *vmeArb) 18753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 18763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 18773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int vbto = 0; 18783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL); 18803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto = (temp_ctl >> 28) & 0xF; 18823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vbto != 0) 18833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeArb->globalTimeoutTimer = (16 * (1 << (vbto - 1))); 18843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (temp_ctl & (1 << 26)) 18863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeArb->arbiterMode = VME_PRIORITY_MODE; 18873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 18883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeArb->arbiterMode = VME_R_ROBIN_MODE; 18893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (temp_ctl & (3 << 24)) 18913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeArb->arbiterTimeoutFlag = 1; 18923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 18943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 18953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_set_requestor(vmeRequesterCfg_t *vmeReq) 18973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 18983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 18993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL); 19013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= 0xFF0FFFFF; 19023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeReq->releaseMode == 1) 19043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= (1 << 20); 19053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeReq->fairMode == 1) 19073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= (1 << 21); 19083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= (vmeReq->requestLevel << 22); 19103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + MAST_CTL); 19123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 19133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 19143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_get_requestor(vmeRequesterCfg_t *vmeReq) 19163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 19173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 19183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL); 19203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (temp_ctl & (1 << 20)) 19223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeReq->releaseMode = 1; 19233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (temp_ctl & (1 << 21)) 19253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeReq->fairMode = 1; 19263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeReq->requestLevel = (temp_ctl & 0xC00000) >> 22; 19283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 193060479690af6d559d4202bed139db90323386bd2bMartyn Welch} 19313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 19333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 1934