vme_ca91cx42.c revision c813f592a5e65cfd9321f51c95a6977e9518dde6
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/module.h> 1960479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/mm.h> 2060479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/types.h> 2160479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/errno.h> 2260479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/pci.h> 2360479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/dma-mapping.h> 2460479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/poll.h> 2560479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/interrupt.h> 2660479690af6d559d4202bed139db90323386bd2bMartyn Welch#include <linux/spinlock.h> 276af783c8ba3418a8ffc50f1266d9b1e35a3322dbGreg Kroah-Hartman#include <linux/sched.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 */ 5660479690af6d559d4202bed139db90323386bd2bMartyn Welch 573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic char driver_name[] = "vme_ca91cx42"; 5860479690af6d559d4202bed139db90323386bd2bMartyn Welch 593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic struct pci_device_id ca91cx42_ids[] = { 603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, 613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch { }, 6260479690af6d559d4202bed139db90323386bd2bMartyn Welch}; 6360479690af6d559d4202bed139db90323386bd2bMartyn Welch 643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic struct pci_driver ca91cx42_driver = { 653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch .name = driver_name, 663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch .id_table = ca91cx42_ids, 673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch .probe = ca91cx42_probe, 683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch .remove = ca91cx42_remove, 6960479690af6d559d4202bed139db90323386bd2bMartyn Welch}; 7060479690af6d559d4202bed139db90323386bd2bMartyn Welch 713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_DMA_irqhandler(void) 7260479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wake_up(&dma_queue); 7460479690af6d559d4202bed139db90323386bd2bMartyn Welch 753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_DMA; 763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 7760479690af6d559d4202bed139db90323386bd2bMartyn Welch 783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_LM_irqhandler(u32 stat) 793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int i; 813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 serviced = 0; 8260479690af6d559d4202bed139db90323386bd2bMartyn Welch 833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (i = 0; i < 4; i++) { 843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_LM[i]) { 853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* We only enable interrupts if the callback is set */ 863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm_callback[i](i); 873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= CA91CX42_LINT_LM[i]; 8860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 8960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 9060479690af6d559d4202bed139db90323386bd2bMartyn Welch 913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return serviced; 923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 9360479690af6d559d4202bed139db90323386bd2bMartyn Welch 943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX This needs to be split into 4 queues */ 953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_MB_irqhandler(int mbox_mask) 963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wake_up(&mbox_queue); 9860479690af6d559d4202bed139db90323386bd2bMartyn Welch 993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_MBOX; 1003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 10160479690af6d559d4202bed139db90323386bd2bMartyn Welch 1023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_IACK_irqhandler(void) 1033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 1043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wake_up(&iack_queue); 10560479690af6d559d4202bed139db90323386bd2bMartyn Welch 1063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_SW_IACK; 10760479690af6d559d4202bed139db90323386bd2bMartyn Welch} 10860479690af6d559d4202bed139db90323386bd2bMartyn Welch 1093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 1103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_bus_error_chk(int clrflag) 11160479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 11260479690af6d559d4202bed139db90323386bd2bMartyn Welch int tmp; 1133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + PCI_COMMAND); 1143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (tmp & 0x08000000) { /* S_TA is Set */ 11560479690af6d559d4202bed139db90323386bd2bMartyn Welch if (clrflag) 1163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp | 0x08000000, 1173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->base + PCI_COMMAND); 1183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 1; 11960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 1203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 12160479690af6d559d4202bed139db90323386bd2bMartyn Welch} 1223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 12360479690af6d559d4202bed139db90323386bd2bMartyn Welch 1243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_VERR_irqhandler(void) 12560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 12660479690af6d559d4202bed139db90323386bd2bMartyn Welch int val; 12760479690af6d559d4202bed139db90323386bd2bMartyn Welch 1283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DGCS); 12960479690af6d559d4202bed139db90323386bd2bMartyn Welch 13060479690af6d559d4202bed139db90323386bd2bMartyn Welch if (!(val & 0x00000800)) { 1313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read " 1323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "Error DGCS=%08X\n", val); 13360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 1343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_VERR; 13660479690af6d559d4202bed139db90323386bd2bMartyn Welch} 13760479690af6d559d4202bed139db90323386bd2bMartyn Welch 1383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_LERR_irqhandler(void) 13960479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 14060479690af6d559d4202bed139db90323386bd2bMartyn Welch int val; 14160479690af6d559d4202bed139db90323386bd2bMartyn Welch 1423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DGCS); 14360479690af6d559d4202bed139db90323386bd2bMartyn Welch 14460479690af6d559d4202bed139db90323386bd2bMartyn Welch if (!(val & 0x00000800)) { 1453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read " 1463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "Error DGCS=%08X\n", val); 14760479690af6d559d4202bed139db90323386bd2bMartyn Welch 14860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 14960479690af6d559d4202bed139db90323386bd2bMartyn Welch 1503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return CA91CX42_LINT_LERR; 15160479690af6d559d4202bed139db90323386bd2bMartyn Welch} 15260479690af6d559d4202bed139db90323386bd2bMartyn Welch 1533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic u32 ca91cx42_VIRQ_irqhandler(int stat) 15560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 1563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int vec, i, serviced = 0; 15760479690af6d559d4202bed139db90323386bd2bMartyn Welch 15860479690af6d559d4202bed139db90323386bd2bMartyn Welch for (i = 7; i > 0; i--) { 1593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & (1 << i)) { 1603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vec = ioread32(ca91cx42_bridge->base + 1613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_V_STATID[i]) & 0xff; 1623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 163c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch vme_irq_handler(ca91cx42_bridge, i, vec); 1643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= (1 << i); 16660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 16760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 1683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return serviced; 17060479690af6d559d4202bed139db90323386bd2bMartyn Welch} 17160479690af6d559d4202bed139db90323386bd2bMartyn Welch 1723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id) 17360479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 1743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 stat, enable, serviced = 0; 17560479690af6d559d4202bed139db90323386bd2bMartyn Welch 1763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (dev_id != ca91cx42_bridge->base) 17760479690af6d559d4202bed139db90323386bd2bMartyn Welch return IRQ_NONE; 17860479690af6d559d4202bed139db90323386bd2bMartyn Welch 1793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch enable = ioread32(ca91cx42_bridge->base + LINT_EN); 1803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch stat = ioread32(ca91cx42_bridge->base + LINT_STAT); 18160479690af6d559d4202bed139db90323386bd2bMartyn Welch 1823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Only look at unmasked interrupts */ 1833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch stat &= enable; 1843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (unlikely(!stat)) 1863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return IRQ_NONE; 1873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 1883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_DMA) 1893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_DMA_irqhandler(); 1903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | 1913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_LM3)) 1923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_LM_irqhandler(stat); 1933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_MBOX) 1943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_MB_irqhandler(stat); 1953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_SW_IACK) 1963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_IACK_irqhandler(); 1973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_VERR) 1983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_VERR_irqhandler(); 1993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & CA91CX42_LINT_LERR) 2003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_LERR_irqhandler(); 2013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 | 2023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 | 2033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 | 2043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_VIRQ7)) 2053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch serviced |= ca91cx42_VIRQ_irqhandler(stat); 2063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Clear serviced interrupts */ 2083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(stat, ca91cx42_bridge->base + LINT_STAT); 20960479690af6d559d4202bed139db90323386bd2bMartyn Welch 21060479690af6d559d4202bed139db90323386bd2bMartyn Welch return IRQ_HANDLED; 21160479690af6d559d4202bed139db90323386bd2bMartyn Welch} 21260479690af6d559d4202bed139db90323386bd2bMartyn Welch 2133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_irq_init(struct vme_bridge *bridge) 21460479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 2153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int result, tmp; 2163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct pci_dev *pdev; 21760479690af6d559d4202bed139db90323386bd2bMartyn Welch 2183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Need pdev */ 2193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pdev = container_of(bridge->parent, struct pci_dev, dev); 22060479690af6d559d4202bed139db90323386bd2bMartyn Welch 2213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Initialise list for VME bus errors */ 2223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(bridge->vme_errors)); 22360479690af6d559d4202bed139db90323386bd2bMartyn Welch 224c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch mutex_init(&(bridge->irq_mtx)); 225c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch 2263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable interrupts from PCI to VME */ 2273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + VINT_EN); 22860479690af6d559d4202bed139db90323386bd2bMartyn Welch 2293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable PCI interrupts */ 2303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + LINT_EN); 2313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Clear Any Pending PCI Interrupts */ 2323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); 23360479690af6d559d4202bed139db90323386bd2bMartyn Welch 2343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED, 2353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch driver_name, pdev); 2363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (result) { 2373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", 2383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pdev->irq); 2393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return result; 24060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 24160479690af6d559d4202bed139db90323386bd2bMartyn Welch 2423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Ensure all interrupts are mapped to PCI Interrupt 0 */ 2433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + LINT_MAP0); 2443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + LINT_MAP1); 2453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, bridge->base + LINT_MAP2); 2463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Enable DMA, mailbox & LM Interrupts */ 2483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = CA91CX42_LINT_MBOX3 | CA91CX42_LINT_MBOX2 | CA91CX42_LINT_MBOX1 | 2493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_MBOX0 | CA91CX42_LINT_SW_IACK | 2503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LINT_VERR | CA91CX42_LINT_LERR | CA91CX42_LINT_DMA; 2513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, bridge->base + LINT_EN); 25360479690af6d559d4202bed139db90323386bd2bMartyn Welch 2543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 25560479690af6d559d4202bed139db90323386bd2bMartyn Welch} 25660479690af6d559d4202bed139db90323386bd2bMartyn Welch 2573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void ca91cx42_irq_exit(struct pci_dev *pdev) 25860479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 2593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable interrupts from PCI to VME */ 2603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + VINT_EN); 26160479690af6d559d4202bed139db90323386bd2bMartyn Welch 2623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable PCI interrupts */ 2633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + LINT_EN); 2643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Clear Any Pending PCI Interrupts */ 2653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00FFFFFF, ca91cx42_bridge->base + LINT_STAT); 26660479690af6d559d4202bed139db90323386bd2bMartyn Welch 2673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch free_irq(pdev->irq, pdev); 2683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 26960479690af6d559d4202bed139db90323386bd2bMartyn Welch 2703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 2713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Set up an VME interrupt 2723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 273c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welchvoid ca91cx42_irq_set(int level, int state, int sync) 274c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch 2753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 276c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch struct pci_dev *pdev; 2773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 tmp; 27860479690af6d559d4202bed139db90323386bd2bMartyn Welch 2793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Enable IRQ level */ 2803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + LINT_EN); 2813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 282c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch if (state == 0) 2833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp &= ~CA91CX42_LINT_VIRQ[level]; 284c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch else 285c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch tmp |= CA91CX42_LINT_VIRQ[level]; 28660479690af6d559d4202bed139db90323386bd2bMartyn Welch 287c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + LINT_EN); 288c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch 289c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch if ((state == 0) && (sync != 0)) { 2903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, 2913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev); 2923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 2933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch synchronize_irq(pdev->irq); 29460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 29560479690af6d559d4202bed139db90323386bd2bMartyn Welch} 29660479690af6d559d4202bed139db90323386bd2bMartyn Welch 297c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welchint ca91cx42_irq_generate(int level, int statid) 29860479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 2993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 tmp; 30060479690af6d559d4202bed139db90323386bd2bMartyn Welch 3013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Universe can only generate even vectors */ 3023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (statid & 1) 3033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 30460479690af6d559d4202bed139db90323386bd2bMartyn Welch 3053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_lock(&(vme_int)); 30660479690af6d559d4202bed139db90323386bd2bMartyn Welch 3073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + VINT_EN); 30860479690af6d559d4202bed139db90323386bd2bMartyn Welch 3093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Set Status/ID */ 3103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(statid << 24, ca91cx42_bridge->base + STATID); 3113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Assert VMEbus IRQ */ 3133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = tmp | (1 << (level + 24)); 3143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + VINT_EN); 31560479690af6d559d4202bed139db90323386bd2bMartyn Welch 3163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Wait for IACK */ 3173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wait_event_interruptible(iack_queue, 0); 3183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Return interrupt to low state */ 3203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + VINT_EN); 3213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = tmp & ~(1 << (level + 24)); 3223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + VINT_EN); 3233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_unlock(&(vme_int)); 3253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 32760479690af6d559d4202bed139db90323386bd2bMartyn Welch} 32860479690af6d559d4202bed139db90323386bd2bMartyn Welch 3293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, 3303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long vme_base, unsigned long long size, 3313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle) 33260479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 3333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int i, addr = 0, granularity = 0; 3343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int temp_ctl = 0; 3353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int vme_bound, pci_offset; 33660479690af6d559d4202bed139db90323386bd2bMartyn Welch 3373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch i = image->number; 33860479690af6d559d4202bed139db90323386bd2bMartyn Welch 3393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (aspace) { 3403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A16: 3413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_A16; 3423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A24: 3443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_A24; 3453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A32: 3473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_A32; 3483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER1: 3503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_USER1; 3513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER2: 3533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch addr |= CA91CX42_VSI_CTL_VAS_USER2; 3543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 3553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A64: 3563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_CRCSR: 3573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER3: 3583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER4: 3593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch default: 3603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid address space\n"); 3613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 3623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 36360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 36460479690af6d559d4202bed139db90323386bd2bMartyn Welch 3653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* 3663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Bound address is a valid address for the window, adjust 3673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * accordingly 3683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 3693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_bound = vme_base + size - granularity; 3703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_offset = pci_base - vme_base; 3713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* XXX Need to check that vme_base, vme_bound and pci_offset aren't 3733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * too big for registers 3743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 3753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((i == 0) || (i == 4)) 3773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch granularity = 0x1000; 3783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 3793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch granularity = 0x10000; 3803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 3813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vme_base & (granularity - 1)) { 3823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid VME base alignment\n"); 3833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 3843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 3853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vme_bound & (granularity - 1)) { 3863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid VME bound alignment\n"); 3873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 3883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 3893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (pci_offset & (granularity - 1)) { 3903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid PCI Offset alignment\n"); 3913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 39260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 39360479690af6d559d4202bed139db90323386bd2bMartyn Welch 3943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable while we are mucking around */ 3953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 3963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_VSI_CTL_EN; 3973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 39860479690af6d559d4202bed139db90323386bd2bMartyn Welch 3993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup mapping */ 4003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vme_base, ca91cx42_bridge->base + CA91CX42_VSI_BS[i]); 4013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vme_bound, ca91cx42_bridge->base + CA91CX42_VSI_BD[i]); 4023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(pci_offset, ca91cx42_bridge->base + CA91CX42_VSI_TO[i]); 4033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX Prefetch stuff currently unsupported */ 4053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 4063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeIn->wrPostEnable) 4073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_PWEN; 4083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeIn->prefetchEnable) 4093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_PREN; 4103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeIn->rmwLock) 4113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_LLRMW; 4123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeIn->data64BitCapable) 4133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_LD64EN; 4143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 4153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup address space */ 4173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M; 4183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= addr; 4193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup cycle types */ 4213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~(CA91CX42_VSI_CTL_PGM_M | CA91CX42_VSI_CTL_SUPER_M); 4223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_SUPER) 4233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_SUPER_SUPR; 4243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_USER) 4253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_SUPER_NPRIV; 4263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_PROG) 4273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_PGM_PGM; 4283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_DATA) 4293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA; 4303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Write ctl reg without enable */ 4323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 4333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (enabled) 4353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_VSI_CTL_EN; 4363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 4383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 44060479690af6d559d4202bed139db90323386bd2bMartyn Welch} 44160479690af6d559d4202bed139db90323386bd2bMartyn Welch 4423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, 4433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long *vme_base, unsigned long long *size, 4443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle) 44560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 4463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int i, granularity = 0, ctl = 0; 4473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long vme_bound, pci_offset; 4483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch i = image->number; 45060479690af6d559d4202bed139db90323386bd2bMartyn Welch 4513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((i == 0) || (i == 4)) 4523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch granularity = 0x1000; 4533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 4543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch granularity = 0x10000; 4553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Read Registers */ 4573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 4583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *vme_base = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BS[i]); 4603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_bound = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BD[i]); 4613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_offset = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_TO[i]); 4623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *pci_base = (dma_addr_t)vme_base + pci_offset; 4643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *size = (unsigned long long)((vme_bound - *vme_base) + granularity); 4653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *enabled = 0; 4673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = 0; 4683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle = 0; 4693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_EN) 4713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *enabled = 1; 4723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A16) 4743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A16; 4753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A24) 4763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A24; 4773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A32) 4783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A32; 4793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER1) 4803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_USER1; 4813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER2) 4823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_USER2; 4833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_SUPER_SUPR) 4853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_SUPER; 4863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_SUPER_NPRIV) 4873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_USER; 4883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_PGM_PGM) 4893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_PROG; 4903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_VSI_CTL_PGM_DATA) 4913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_DATA; 4923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 4943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 4953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 4973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Allocate and map PCI Resource 4983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 4993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_alloc_resource(struct vme_master_resource *image, 5003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long size) 5013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 5023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long existing_size; 5033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval = 0; 5043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct pci_dev *pdev; 5053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Find pci_dev container of dev */ 5073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ca91cx42_bridge->parent == NULL) { 5083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Dev entry NULL\n"); 5093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 5103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 5113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); 5123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch existing_size = (unsigned long long)(image->pci_resource.end - 5143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.start); 5153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* If the existing size is OK, return */ 5173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (existing_size == (size - 1)) 5183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 5193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (existing_size != 0) { 5213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(image->kern_base); 5223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->kern_base = NULL; 5233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (image->pci_resource.name != NULL) 5243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(image->pci_resource.name); 5253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch release_resource(&(image->pci_resource)); 5263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(&(image->pci_resource), 0, sizeof(struct resource)); 5273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 5283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (image->pci_resource.name == NULL) { 5303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); 5313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (image->pci_resource.name == NULL) { 5323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Unable to allocate memory for resource" 5333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch " name\n"); 5343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 5353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_name; 5363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 53760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 5383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch sprintf((char *)image->pci_resource.name, "%s.%d", 5403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->name, image->number); 5413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.start = 0; 5433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.end = (unsigned long)size; 5443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.flags = IORESOURCE_MEM; 5453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = pci_bus_alloc_resource(pdev->bus, 5473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &(image->pci_resource), size, size, PCIBIOS_MIN_MEM, 5483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 0, NULL, NULL); 5493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval) { 5503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Failed to allocate mem resource for " 5513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "window %d size 0x%lx start 0x%lx\n", 5523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->number, (unsigned long)size, 5533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch (unsigned long)image->pci_resource.start); 5543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_resource; 55560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 5563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->kern_base = ioremap_nocache( 5583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->pci_resource.start, size); 5593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (image->kern_base == NULL) { 5603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Failed to remap resource\n"); 5613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 5623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_remap; 56360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 56460479690af6d559d4202bed139db90323386bd2bMartyn Welch 5653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 5663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(image->kern_base); 5683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->kern_base = NULL; 5693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_remap: 5703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch release_resource(&(image->pci_resource)); 5713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_resource: 5723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(image->pci_resource.name); 5733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(&(image->pci_resource), 0, sizeof(struct resource)); 5743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_name: 5753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 5763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 5773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 5793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * * Free and unmap PCI Resource 5803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * */ 5813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void ca91cx42_free_resource(struct vme_master_resource *image) 5823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 5833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(image->kern_base); 5843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch image->kern_base = NULL; 5853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch release_resource(&(image->pci_resource)); 5863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(image->pci_resource.name); 5873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(&(image->pci_resource), 0, sizeof(struct resource)); 5883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 5893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 5913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_master_set(struct vme_master_resource *image, int enabled, 5923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long vme_base, unsigned long long size, 5933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) 5943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 5953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval = 0; 5963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int i; 5973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int temp_ctl = 0; 5983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long pci_bound, vme_offset, pci_base; 5993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Verify input data */ 6013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vme_base & 0xFFF) { 6023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid VME Window alignment\n"); 6033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 6043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_window; 6053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 6063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (size & 0xFFF) { 6073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid VME Window alignment\n"); 6083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 6093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_window; 6103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 6113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock(&(image->lock)); 6133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* XXX We should do this much later, so that we can exit without 6153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * needing to redo the mapping... 6163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 6173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* 6183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Let's allocate the resource here rather than further up the stack as 6193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * it avoids pushing loads of bus dependant stuff up the stack 6203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 6213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = ca91cx42_alloc_resource(image, size); 6223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval) { 6233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 6243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Unable to allocate memory for resource " 6253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "name\n"); 6263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 6273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_res; 6283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 6293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_base = (unsigned long long)image->pci_resource.start; 6313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* 6333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Bound address is a valid address for the window, adjust 6343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * according to window granularity. 6353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 6363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_bound = pci_base + (size - 0x1000); 6373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_offset = vme_base - pci_base; 6383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch i = image->number; 6403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable while we are mucking around */ 6423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 6433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_LSI_CTL_EN; 6443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 6453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX Prefetch stuff currently unsupported */ 6473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 6483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeOut->wrPostEnable) 6493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x40000000; 6503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 6513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup cycle types */ 6533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M; 6543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_BLT) 6553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VCT_BLT; 6563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_MBLT) 6573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VCT_MBLT; 6583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup data width */ 6603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_LSI_CTL_VDW_M; 6613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (dwidth) { 6623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_D8: 6633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VDW_D8; 6643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 6653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_D16: 6663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VDW_D16; 6673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 6683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_D32: 6693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VDW_D32; 6703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 6713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_D64: 6723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VDW_D64; 6733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 6743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch default: 6753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 6763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid data width\n"); 6773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 6783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_dwidth; 6793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 68060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 6813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 6823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup address space */ 6833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~CA91CX42_LSI_CTL_VAS_M; 6843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (aspace) { 68560479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A16: 6863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_A16; 68760479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 68860479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A24: 6893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_A24; 69060479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 69160479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A32: 6923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_A32; 6933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 6943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_CRCSR: 6953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_CRCSR; 69660479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 69760479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER1: 6983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_USER1; 69960479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 70060479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER2: 7013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_VAS_USER2; 7023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A64: 7043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER3: 7053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER4: 7063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch default: 7073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 7083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Invalid address space\n"); 7093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 7103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_aspace; 71160479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 71260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 71360479690af6d559d4202bed139db90323386bd2bMartyn Welch 7143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= ~(CA91CX42_LSI_CTL_PGM_M | CA91CX42_LSI_CTL_SUPER_M); 7153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_SUPER) 7163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_SUPER_SUPR; 7173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (cycle & VME_PROG) 7183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM; 71960479690af6d559d4202bed139db90323386bd2bMartyn Welch 7203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup mapping */ 7213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(pci_base, ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); 7223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(pci_bound, ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); 7233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vme_offset, ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); 7243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Write ctl reg without enable */ 7263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 7273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (enabled) 7293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= CA91CX42_LSI_CTL_EN; 7303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 7323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 7343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 7353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_aspace: 7373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_dwidth: 7383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_free_resource(image); 7393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_res: 7403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_window: 7413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 7423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 7433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint __ca91cx42_master_get(struct vme_master_resource *image, int *enabled, 7453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long *vme_base, unsigned long long *size, 7463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) 7473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 7483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int i, ctl; 7493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long pci_base, pci_bound, vme_offset; 7503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch i = image->number; 7523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 7543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_base = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); 7563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_offset = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); 7573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_bound = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); 7583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *vme_base = pci_base + vme_offset; 7603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *size = (pci_bound - pci_base) + 0x1000; 7613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *enabled = 0; 7633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = 0; 7643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle = 0; 7653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = 0; 7663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_LSI_CTL_EN) 7683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *enabled = 1; 7693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup address space */ 7713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (ctl & CA91CX42_LSI_CTL_VAS_M) { 7723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_A16: 7733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A16; 7743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_A24: 7763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A24; 7773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_A32: 7793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_A32; 7803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_CRCSR: 7823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_CRCSR; 7833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_USER1: 7853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_USER1; 7863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VAS_USER2: 7883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *aspace = VME_USER2; 7893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 7903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 7913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* XXX Not sure howto check for MBLT */ 7933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup cycle types */ 7943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_LSI_CTL_VCT_BLT) 7953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_BLT; 7963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 7973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_SCT; 7983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 7993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_LSI_CTL_SUPER_SUPR) 8003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_SUPER; 8013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 8023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle |= VME_USER; 8033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & CA91CX42_LSI_CTL_PGM_PGM) 8053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle = VME_PROG; 8063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 8073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *cycle = VME_DATA; 8083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup data width */ 8103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (ctl & CA91CX42_LSI_CTL_VDW_M) { 8113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VDW_D8: 8123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = VME_D8; 8133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VDW_D16: 8153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = VME_D16; 8163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VDW_D32: 8183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = VME_D32; 8193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case CA91CX42_LSI_CTL_VDW_D64: 8213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *dwidth = VME_D64; 8223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 8233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 8243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX Prefetch stuff currently unsupported */ 8263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 8273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ctl & 0x40000000) 8283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeOut->wrPostEnable = 1; 8293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 8303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 8323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 8333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_master_get(struct vme_master_resource *image, int *enabled, 8353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long long *vme_base, unsigned long long *size, 8363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) 8373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 8383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval; 8393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock(&(image->lock)); 8413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = __ca91cx42_master_get(image, enabled, vme_base, size, aspace, 8433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch cycle, dwidth); 8443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 8463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 8483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 8493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf, 8513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch size_t count, loff_t offset) 8523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 8533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval; 85460479690af6d559d4202bed139db90323386bd2bMartyn Welch 8553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock(&(image->lock)); 85660479690af6d559d4202bed139db90323386bd2bMartyn Welch 8573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count); 8583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = count; 85960479690af6d559d4202bed139db90323386bd2bMartyn Welch 8603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 8613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 86360479690af6d559d4202bed139db90323386bd2bMartyn Welch} 86460479690af6d559d4202bed139db90323386bd2bMartyn Welch 8653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf, 8663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch size_t count, loff_t offset) 86760479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 8683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval = 0; 86960479690af6d559d4202bed139db90323386bd2bMartyn Welch 8703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock(&(image->lock)); 87160479690af6d559d4202bed139db90323386bd2bMartyn Welch 8723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memcpy_toio(image->kern_base + offset, buf, (unsigned int)count); 8733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = count; 8743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock(&(image->lock)); 8763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 87860479690af6d559d4202bed139db90323386bd2bMartyn Welch} 87960479690af6d559d4202bed139db90323386bd2bMartyn Welch 8803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_slot_get(void) 88160479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 8823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 slot = 0; 88360479690af6d559d4202bed139db90323386bd2bMartyn Welch 8843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slot = ioread32(ca91cx42_bridge->base + VCSR_BS); 8853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27); 8863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return (int)slot; 8873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 8893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int __init ca91cx42_init(void) 8913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 8923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return pci_register_driver(&ca91cx42_driver); 8933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 8943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 8953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* 8963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Configure CR/CSR space 8973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * 8983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Access to the CR/CSR can be configured at power-up. The location of the 8993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * CR/CSR registers in the CR/CSR address space is determined by the boards 9003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * Auto-ID or Geographic address. This function ensures that the window is 9013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * enabled at an offset consistent with the boards geopgraphic address. 9023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 9033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_crcsr_init(struct pci_dev *pdev) 9043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 9053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned int crcsr_addr; 9063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int tmp, slot; 9073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/* XXX We may need to set this somehow as the Universe II does not support 9093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * geographical addressing. 9103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 9113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 9123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vme_slotnum != -1) 9133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vme_slotnum << 27, ca91cx42_bridge->base + VCSR_BS); 9143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 9153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slot = ca91cx42_slot_get(); 9163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot); 9173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (slot == 0) { 9183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Slot number is unset, not configuring " 9193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "CR/CSR space\n"); 9203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 92160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 9223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Allocate mem for CR/CSR image */ 9243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, 9253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &crcsr_bus); 9263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (crcsr_kernel == NULL) { 9273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " 9283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "image\n"); 9293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -ENOMEM; 93060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 93160479690af6d559d4202bed139db90323386bd2bMartyn Welch 9323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); 93360479690af6d559d4202bed139db90323386bd2bMartyn Welch 9343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch crcsr_addr = slot * (512 * 1024); 9353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(crcsr_bus - crcsr_addr, ca91cx42_bridge->base + VCSR_TO); 93660479690af6d559d4202bed139db90323386bd2bMartyn Welch 9373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL); 9383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp |= CA91CX42_VCSR_CTL_EN; 9393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL); 94060479690af6d559d4202bed139db90323386bd2bMartyn Welch 9413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 94260479690af6d559d4202bed139db90323386bd2bMartyn Welch} 94360479690af6d559d4202bed139db90323386bd2bMartyn Welch 9443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void ca91cx42_crcsr_exit(struct pci_dev *pdev) 94560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 9463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 tmp; 94760479690af6d559d4202bed139db90323386bd2bMartyn Welch 9483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Turn off CR/CSR space */ 9493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL); 9503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tmp &= ~CA91CX42_VCSR_CTL_EN; 9513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL); 95260479690af6d559d4202bed139db90323386bd2bMartyn Welch 9533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Free image */ 9543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + VCSR_TO); 95560479690af6d559d4202bed139db90323386bd2bMartyn Welch 9563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus); 9573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 95860479690af6d559d4202bed139db90323386bd2bMartyn Welch 9593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) 9603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 9613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int retval, i; 9623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch u32 data; 9633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct list_head *pos = NULL; 9643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_master_resource *master_image; 9653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_slave_resource *slave_image; 9663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 9673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_dma_resource *dma_ctrlr; 9683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 9693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_lm_resource *lm; 9703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* We want to support more than one of each bridge so we need to 9723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * dynamically allocate the bridge structure 9733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 9743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge = kmalloc(sizeof(struct vme_bridge), GFP_KERNEL); 9753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ca91cx42_bridge == NULL) { 9773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for device " 9783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "structure\n"); 9793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 9803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_struct; 9813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 9823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge)); 9843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Enable the device */ 9863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = pci_enable_device(pdev); 9873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval) { 9883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Unable to enable device\n"); 9893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_enable; 9903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 9913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Map Registers */ 9933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = pci_request_regions(pdev, driver_name); 9943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval) { 9953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Unable to reserve resources\n"); 9963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_resource; 9973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 9983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 9993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* map registers in BAR 0 */ 10003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), 10013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 4096); 10023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (!ca91cx42_bridge->base) { 10033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Unable to remap CRG region\n"); 10043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EIO; 10053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_remap; 10063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Check to see if the mapping worked out */ 10093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch data = ioread32(ca91cx42_bridge->base + CA91CX42_PCI_ID) & 0x0000FFFF; 10103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (data != PCI_VENDOR_ID_TUNDRA) { 10113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "PCI_ID check failed\n"); 10123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EIO; 10133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_test; 10143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Initialize wait queues & mutual exclusion flags */ 10173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* XXX These need to be moved to the vme_bridge structure */ 10183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch init_waitqueue_head(&dma_queue); 10193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch init_waitqueue_head(&iack_queue); 10203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(vme_int)); 10213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(vme_rmw)); 10223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->parent = &(pdev->dev); 10243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch strcpy(ca91cx42_bridge->name, driver_name); 10253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup IRQ */ 10273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = ca91cx42_irq_init(ca91cx42_bridge); 10283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval != 0) { 10293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Chip Initialization failed.\n"); 10303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_irq; 10313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Add master windows to list */ 10343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(ca91cx42_bridge->master_resources)); 10353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (i = 0; i < CA91C142_MAX_MASTER; i++) { 10363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image = kmalloc(sizeof(struct vme_master_resource), 10373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch GFP_KERNEL); 10383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (master_image == NULL) { 10393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for " 10403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "master resource structure\n"); 10413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 10423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_master; 10433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->parent = ca91cx42_bridge; 10453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock_init(&(master_image->lock)); 10463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->locked = 0; 10473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->number = i; 10483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | 10493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch VME_CRCSR | VME_USER1 | VME_USER2; 10503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | 10513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch VME_SUPER | VME_USER | VME_PROG | VME_DATA; 10523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64; 10533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch memset(&(master_image->pci_resource), 0, 10543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch sizeof(struct resource)); 10553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image->kern_base = NULL; 10563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_add_tail(&(master_image->list), 10573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &(ca91cx42_bridge->master_resources)); 10583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Add slave windows to list */ 10613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(ca91cx42_bridge->slave_resources)); 10623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (i = 0; i < CA91C142_MAX_SLAVE; i++) { 10633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image = kmalloc(sizeof(struct vme_slave_resource), 10643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch GFP_KERNEL); 10653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (slave_image == NULL) { 10663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for " 10673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "slave resource structure\n"); 10683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 10693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_slave; 10703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->parent = ca91cx42_bridge; 10723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(slave_image->mtx)); 10733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->locked = 0; 10743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->number = i; 10753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->address_attr = VME_A24 | VME_A32 | VME_USER1 | 10763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch VME_USER2; 10773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Only windows 0 and 4 support A16 */ 10793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (i == 0 || i == 4) 10803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->address_attr |= VME_A16; 10813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 10823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | 10833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch VME_SUPER | VME_USER | VME_PROG | VME_DATA; 10843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_add_tail(&(slave_image->list), 10853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &(ca91cx42_bridge->slave_resources)); 10863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 10883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Add dma engines to list */ 10893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources)); 10903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (i = 0; i < CA91C142_MAX_DMA; i++) { 10913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), 10923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch GFP_KERNEL); 10933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (dma_ctrlr == NULL) { 10943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for " 10953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "dma resource structure\n"); 10963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 10973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_dma; 10983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 10993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr->parent = ca91cx42_bridge; 11003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(dma_ctrlr->mtx)); 11013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr->locked = 0; 11023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr->number = i; 11033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(dma_ctrlr->pending)); 11043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(dma_ctrlr->running)); 11053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_add_tail(&(dma_ctrlr->list), 11063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch &(ca91cx42_bridge->dma_resources)); 11073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 11093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Add location monitor to list */ 11103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources)); 11113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); 11123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (lm == NULL) { 11133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Failed to allocate memory for " 11143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch "location monitor resource structure\n"); 11153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -ENOMEM; 11163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_lm; 11173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm->parent = ca91cx42_bridge; 11193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch mutex_init(&(lm->mtx)); 11203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm->locked = 0; 11213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm->number = 1; 11223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm->monitors = 4; 11233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_add_tail(&(lm->list), &(ca91cx42_bridge->lm_resources)); 11243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->slave_get = ca91cx42_slave_get; 11263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->slave_set = ca91cx42_slave_set; 11273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_get = ca91cx42_master_get; 11283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_set = ca91cx42_master_set; 11293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_read = ca91cx42_master_read; 11303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_write = ca91cx42_master_write; 11313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 11323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->master_rmw = ca91cx42_master_rmw; 11333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add; 11343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec; 11353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty; 11363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 1137c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch ca91cx42_bridge->irq_set = ca91cx42_irq_set; 1138c813f592a5e65cfd9321f51c95a6977e9518dde6Martyn Welch ca91cx42_bridge->irq_generate = ca91cx42_irq_generate; 11393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 11403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->lm_set = ca91cx42_lm_set; 11413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->lm_get = ca91cx42_lm_get; 11423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->lm_attach = ca91cx42_lm_attach; 11433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->lm_detach = ca91cx42_lm_detach; 11443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 11453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_bridge->slot_get = ca91cx42_slot_get; 11463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch data = ioread32(ca91cx42_bridge->base + MISC_CTL); 11483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_info(&pdev->dev, "Board is%s the VME system controller\n", 11493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch (data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not"); 11503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_info(&pdev->dev, "Slot ID is %d\n", ca91cx42_slot_get()); 11513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (ca91cx42_crcsr_init(pdev)) { 11533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); 11543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = -EINVAL; 11553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 11563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_crcsr; 11573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 115860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 115960479690af6d559d4202bed139db90323386bd2bMartyn Welch 11603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Need to save ca91cx42_bridge pointer locally in link list for use in 11613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * ca91cx42_remove() 11623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch */ 11633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch retval = vme_register_bridge(ca91cx42_bridge); 11643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (retval != 0) { 11653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dev_err(&pdev->dev, "Chip Registration failed.\n"); 11663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch goto err_reg; 11673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 11703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 11713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_unregister_bridge(ca91cx42_bridge); 11723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_reg: 11733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_crcsr_exit(pdev); 11743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_crcsr: 11753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_lm: 11763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 11773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { 11783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm = list_entry(pos, struct vme_lm_resource, list); 11793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 11803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(lm); 11813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 11833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_dma: 11843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 11853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->dma_resources)) { 11863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); 11873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 11883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(dma_ctrlr); 118960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 11903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 11913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_slave: 11923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 11933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->slave_resources)) { 11943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image = list_entry(pos, struct vme_slave_resource, list); 11953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 11963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(slave_image); 11973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 11983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_master: 11993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->master_resources)) { 12013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image = list_entry(pos, struct vme_master_resource, 12023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list); 12033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(master_image); 12053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 12063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_irq_exit(pdev); 12083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_irq: 12093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_test: 12103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(ca91cx42_bridge->base); 12113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_remap: 12123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_release_regions(pdev); 12133d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_resource: 12143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_disable_device(pdev); 12153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_enable: 12163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(ca91cx42_bridge); 12173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welcherr_struct: 12183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return retval; 121960479690af6d559d4202bed139db90323386bd2bMartyn Welch 122060479690af6d559d4202bed139db90323386bd2bMartyn Welch} 122160479690af6d559d4202bed139db90323386bd2bMartyn Welch 12223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchvoid ca91cx42_remove(struct pci_dev *pdev) 122360479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 12243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct list_head *pos = NULL; 12253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_master_resource *master_image; 12263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_slave_resource *slave_image; 12273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_dma_resource *dma_ctrlr; 12283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch struct vme_lm_resource *lm; 12293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int i; 123060479690af6d559d4202bed139db90323386bd2bMartyn Welch 12313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Turn off Ints */ 12323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + LINT_EN); 12333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Turn off the windows */ 12353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI0_CTL); 12363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI1_CTL); 12373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI2_CTL); 12383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI3_CTL); 12393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI4_CTL); 12403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI5_CTL); 12413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI6_CTL); 12423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00800000, ca91cx42_bridge->base + LSI7_CTL); 12433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI0_CTL); 12443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI1_CTL); 12453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI2_CTL); 12463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI3_CTL); 12473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI4_CTL); 12483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI5_CTL); 12493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI6_CTL); 12503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00F00000, ca91cx42_bridge->base + VSI7_CTL); 12513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vme_unregister_bridge(ca91cx42_bridge); 12533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 12543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_crcsr_exit(pdev); 12553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 12563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { 12583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch lm = list_entry(pos, struct vme_lm_resource, list); 12593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(lm); 126160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 12623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->dma_resources)) { 12653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); 12663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(dma_ctrlr); 126860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 126960479690af6d559d4202bed139db90323386bd2bMartyn Welch 12703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->slave_resources)) { 12723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch slave_image = list_entry(pos, struct vme_slave_resource, list); 12733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(slave_image); 12753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 127660479690af6d559d4202bed139db90323386bd2bMartyn Welch 12773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* resources are stored in link list */ 12783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_for_each(pos, &(ca91cx42_bridge->master_resources)) { 12793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch master_image = list_entry(pos, struct vme_master_resource, 12803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list); 12813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch list_del(pos); 12823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(master_image); 12833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 128460479690af6d559d4202bed139db90323386bd2bMartyn Welch 12853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_irq_exit(pdev); 128660479690af6d559d4202bed139db90323386bd2bMartyn Welch 12873d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iounmap(ca91cx42_bridge->base); 128860479690af6d559d4202bed139db90323386bd2bMartyn Welch 12893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_release_regions(pdev); 129060479690af6d559d4202bed139db90323386bd2bMartyn Welch 12913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_disable_device(pdev); 12923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 12933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch kfree(ca91cx42_bridge); 129460479690af6d559d4202bed139db90323386bd2bMartyn Welch} 129560479690af6d559d4202bed139db90323386bd2bMartyn Welch 12963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchstatic void __exit ca91cx42_exit(void) 129760479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 12983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch pci_unregister_driver(&ca91cx42_driver); 12993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 130060479690af6d559d4202bed139db90323386bd2bMartyn Welch 13013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn WelchMODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge"); 13023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn WelchMODULE_LICENSE("GPL"); 130360479690af6d559d4202bed139db90323386bd2bMartyn Welch 13043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchmodule_init(ca91cx42_init); 13053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchmodule_exit(ca91cx42_exit); 130660479690af6d559d4202bed139db90323386bd2bMartyn Welch 13073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch/*---------------------------------------------------------------------------- 13083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch * STAGING 13093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch *--------------------------------------------------------------------------*/ 13103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 13113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#if 0 131260479690af6d559d4202bed139db90323386bd2bMartyn Welch#define SWIZZLE(X) ( ((X & 0xFF000000) >> 24) | ((X & 0x00FF0000) >> 8) | ((X & 0x0000FF00) << 8) | ((X & 0x000000FF) << 24)) 131360479690af6d559d4202bed139db90323386bd2bMartyn Welch 13143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_master_rmw(vmeRmwCfg_t *vmeRmw) 131560479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 131660479690af6d559d4202bed139db90323386bd2bMartyn Welch int temp_ctl = 0; 131760479690af6d559d4202bed139db90323386bd2bMartyn Welch int tempBS = 0; 131860479690af6d559d4202bed139db90323386bd2bMartyn Welch int tempBD = 0; 131960479690af6d559d4202bed139db90323386bd2bMartyn Welch int tempTO = 0; 132060479690af6d559d4202bed139db90323386bd2bMartyn Welch int vmeBS = 0; 132160479690af6d559d4202bed139db90323386bd2bMartyn Welch int vmeBD = 0; 132260479690af6d559d4202bed139db90323386bd2bMartyn Welch int *rmw_pci_data_ptr = NULL; 132360479690af6d559d4202bed139db90323386bd2bMartyn Welch int *vaDataPtr = NULL; 132460479690af6d559d4202bed139db90323386bd2bMartyn Welch int i; 132560479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeOutWindowCfg_t vmeOut; 132660479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeRmw->maxAttempts < 1) { 13273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 132860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 132960479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeRmw->targetAddrU) { 13303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 133160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 13323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Find the PCI address that maps to the desired VME address */ 133360479690af6d559d4202bed139db90323386bd2bMartyn Welch for (i = 0; i < 8; i++) { 13343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + 13353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch CA91CX42_LSI_CTL[i]); 133660479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((temp_ctl & 0x80000000) == 0) { 133760479690af6d559d4202bed139db90323386bd2bMartyn Welch continue; 133860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 133960479690af6d559d4202bed139db90323386bd2bMartyn Welch memset(&vmeOut, 0, sizeof(vmeOut)); 134060479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeOut.windowNbr = i; 13413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_get_out_bound(&vmeOut); 134260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeOut.addrSpace != vmeRmw->addrSpace) { 134360479690af6d559d4202bed139db90323386bd2bMartyn Welch continue; 134460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 13453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tempBS = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); 13463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tempBD = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); 13473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch tempTO = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); 134860479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeBS = tempBS + tempTO; 134960479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeBD = tempBD + tempTO; 135060479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((vmeRmw->targetAddr >= vmeBS) && 135160479690af6d559d4202bed139db90323386bd2bMartyn Welch (vmeRmw->targetAddr < vmeBD)) { 135260479690af6d559d4202bed139db90323386bd2bMartyn Welch rmw_pci_data_ptr = 135360479690af6d559d4202bed139db90323386bd2bMartyn Welch (int *)(tempBS + (vmeRmw->targetAddr - vmeBS)); 135460479690af6d559d4202bed139db90323386bd2bMartyn Welch vaDataPtr = 135560479690af6d559d4202bed139db90323386bd2bMartyn Welch (int *)(out_image_va[i] + 135660479690af6d559d4202bed139db90323386bd2bMartyn Welch (vmeRmw->targetAddr - vmeBS)); 135760479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 135860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 135960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 136060479690af6d559d4202bed139db90323386bd2bMartyn Welch 13613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* If no window - fail. */ 136260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (rmw_pci_data_ptr == NULL) { 13633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 13643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } 13653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup the RMW registers. */ 13663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + SCYC_CTL); 13673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(SWIZZLE(vmeRmw->enableMask), ca91cx42_bridge->base + SCYC_EN); 13683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(SWIZZLE(vmeRmw->compareData), ca91cx42_bridge->base + 13693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch SCYC_CMP); 13703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(SWIZZLE(vmeRmw->swapData), ca91cx42_bridge->base + SCYC_SWP); 13713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32((int)rmw_pci_data_ptr, ca91cx42_bridge->base + SCYC_ADDR); 13723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(1, ca91cx42_bridge->base + SCYC_CTL); 13733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 13743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Run the RMW cycle until either success or max attempts. */ 137560479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeRmw->numAttempts = 1; 137660479690af6d559d4202bed139db90323386bd2bMartyn Welch while (vmeRmw->numAttempts <= vmeRmw->maxAttempts) { 137760479690af6d559d4202bed139db90323386bd2bMartyn Welch 13783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if ((ioread32(vaDataPtr) & vmeRmw->enableMask) == 137960479690af6d559d4202bed139db90323386bd2bMartyn Welch (vmeRmw->swapData & vmeRmw->enableMask)) { 138060479690af6d559d4202bed139db90323386bd2bMartyn Welch 13813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + SCYC_CTL); 138260479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 138360479690af6d559d4202bed139db90323386bd2bMartyn Welch 138460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 138560479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeRmw->numAttempts++; 138660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 138760479690af6d559d4202bed139db90323386bd2bMartyn Welch 13883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* If no success, set num Attempts to be greater than max attempts */ 138960479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeRmw->numAttempts > vmeRmw->maxAttempts) { 139060479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeRmw->numAttempts = vmeRmw->maxAttempts + 1; 139160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 139260479690af6d559d4202bed139db90323386bd2bMartyn Welch 13933d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 139460479690af6d559d4202bed139db90323386bd2bMartyn Welch} 139560479690af6d559d4202bed139db90323386bd2bMartyn Welch 139660479690af6d559d4202bed139db90323386bd2bMartyn Welchint uniSetupDctlReg(vmeDmaPacket_t * vmeDma, int *dctlregreturn) 139760479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 139860479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dctlreg = 0x80; 139960479690af6d559d4202bed139db90323386bd2bMartyn Welch struct vmeAttr *vmeAttr; 140060479690af6d559d4202bed139db90323386bd2bMartyn Welch 140160479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeDma->srcBus == VME_DMA_VME) { 140260479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg = 0; 140360479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeAttr = &vmeDma->srcVmeAttr; 140460479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 140560479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg = 0x80000000; 140660479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeAttr = &vmeDma->dstVmeAttr; 140760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 140860479690af6d559d4202bed139db90323386bd2bMartyn Welch 140960479690af6d559d4202bed139db90323386bd2bMartyn Welch switch (vmeAttr->maxDataWidth) { 141060479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_D8: 141160479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 141260479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_D16: 141360479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00400000; 141460479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 141560479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_D32: 141660479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00800000; 141760479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 141860479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_D64: 141960479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00C00000; 142060479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 142160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 142260479690af6d559d4202bed139db90323386bd2bMartyn Welch 142360479690af6d559d4202bed139db90323386bd2bMartyn Welch switch (vmeAttr->addrSpace) { 142460479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A16: 142560479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 142660479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A24: 142760479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00010000; 142860479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 142960479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_A32: 143060479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00020000; 143160479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 143260479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER1: 143360479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00060000; 143460479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 143560479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER2: 143660479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00070000; 143760479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 143860479690af6d559d4202bed139db90323386bd2bMartyn Welch 14393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A64: /* not supported in Universe DMA */ 144060479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_CRCSR: 144160479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER3: 144260479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_USER4: 14433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 144460479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 144560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 144660479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeAttr->userAccessType == VME_PROG) { 144760479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00004000; 144860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 144960479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeAttr->dataAccessType == VME_SUPER) { 145060479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00001000; 145160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 145260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeAttr->xferProtocol != VME_SCT) { 145360479690af6d559d4202bed139db90323386bd2bMartyn Welch dctlreg |= 0x00000100; 145460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 145560479690af6d559d4202bed139db90323386bd2bMartyn Welch *dctlregreturn = dctlreg; 14563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 145760479690af6d559d4202bed139db90323386bd2bMartyn Welch} 145860479690af6d559d4202bed139db90323386bd2bMartyn Welch 145960479690af6d559d4202bed139db90323386bd2bMartyn Welchunsigned int 14603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchca91cx42_start_dma(int channel, unsigned int dgcsreg, TDMA_Cmd_Packet *vmeLL) 146160479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 146260479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int val; 146360479690af6d559d4202bed139db90323386bd2bMartyn Welch 14643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup registers as needed for direct or chained. */ 146560479690af6d559d4202bed139db90323386bd2bMartyn Welch if (dgcsreg & 0x8000000) { 14663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + DTBC); 14673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32((unsigned int)vmeLL, ca91cx42_bridge->base + DCPP); 146860479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 146960479690af6d559d4202bed139db90323386bd2bMartyn Welch#if 0 14703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DGCS = %08x\n", dgcsreg); 14713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DVA = %08x\n", 14723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(&vmeLL->dva)); 14733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DLV = %08x\n", 14743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(&vmeLL->dlv)); 14753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DTBC = %08x\n", 14763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(&vmeLL->dtbc)); 14773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "Starting: DCTL = %08x\n", 14783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(&vmeLL->dctl)); 147960479690af6d559d4202bed139db90323386bd2bMartyn Welch#endif 14803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Write registers */ 14813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(ioread32(&vmeLL->dva), ca91cx42_bridge->base + DVA); 14823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(ioread32(&vmeLL->dlv), ca91cx42_bridge->base + DLA); 14833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(ioread32(&vmeLL->dtbc), ca91cx42_bridge->base + DTBC); 14843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(ioread32(&vmeLL->dctl), ca91cx42_bridge->base + DCTL); 14853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0, ca91cx42_bridge->base + DCPP); 148660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 148760479690af6d559d4202bed139db90323386bd2bMartyn Welch 14883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Start the operation */ 14893d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(dgcsreg, ca91cx42_bridge->base + DGCS); 149060479690af6d559d4202bed139db90323386bd2bMartyn Welch val = get_tbl(); 14913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(dgcsreg | 0x8000000F, ca91cx42_bridge->base + DGCS); 14923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return val; 149360479690af6d559d4202bed139db90323386bd2bMartyn Welch} 149460479690af6d559d4202bed139db90323386bd2bMartyn Welch 14953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn WelchTDMA_Cmd_Packet *ca91cx42_setup_dma(vmeDmaPacket_t * vmeDma) 149660479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 149760479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDmaPacket_t *vmeCur; 149860479690af6d559d4202bed139db90323386bd2bMartyn Welch int maxPerPage; 149960479690af6d559d4202bed139db90323386bd2bMartyn Welch int currentLLcount; 150060479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *startLL; 150160479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *currentLL; 150260479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *nextLL; 150360479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dctlreg = 0; 150460479690af6d559d4202bed139db90323386bd2bMartyn Welch 150560479690af6d559d4202bed139db90323386bd2bMartyn Welch maxPerPage = PAGESIZE / sizeof(TDMA_Cmd_Packet) - 1; 150660479690af6d559d4202bed139db90323386bd2bMartyn Welch startLL = (TDMA_Cmd_Packet *) __get_free_pages(GFP_KERNEL, 0); 150760479690af6d559d4202bed139db90323386bd2bMartyn Welch if (startLL == 0) { 15083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return startLL; 150960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 15103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* First allocate pages for descriptors and create linked list */ 151160479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeCur = vmeDma; 151260479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 151360479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLLcount = 0; 151460479690af6d559d4202bed139db90323386bd2bMartyn Welch while (vmeCur != 0) { 151560479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeCur->pNextPacket != 0) { 151660479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = (unsigned int)(currentLL + 1); 151760479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLLcount++; 151860479690af6d559d4202bed139db90323386bd2bMartyn Welch if (currentLLcount >= maxPerPage) { 151960479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = 152060479690af6d559d4202bed139db90323386bd2bMartyn Welch __get_free_pages(GFP_KERNEL, 0); 152160479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLLcount = 0; 152260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 152360479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 152460479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 152560479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = (unsigned int)0; 152660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 152760479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeCur = vmeCur->pNextPacket; 152860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 152960479690af6d559d4202bed139db90323386bd2bMartyn Welch 15303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Next fill in information for each descriptor */ 153160479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeCur = vmeDma; 153260479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 153360479690af6d559d4202bed139db90323386bd2bMartyn Welch while (vmeCur != 0) { 153460479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeCur->srcBus == VME_DMA_VME) { 15353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->srcAddr, ¤tLL->dva); 15363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->dstAddr, ¤tLL->dlv); 153760479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 15383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->srcAddr, ¤tLL->dlv); 15393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->dstAddr, ¤tLL->dva); 154060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 154160479690af6d559d4202bed139db90323386bd2bMartyn Welch uniSetupDctlReg(vmeCur, &dctlreg); 15423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(dctlreg, ¤tLL->dctl); 15433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeCur->byteCount, ¤tLL->dtbc); 154460479690af6d559d4202bed139db90323386bd2bMartyn Welch 154560479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 154660479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeCur = vmeCur->pNextPacket; 154760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 154860479690af6d559d4202bed139db90323386bd2bMartyn Welch 15493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Convert Links to PCI addresses. */ 155060479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 155160479690af6d559d4202bed139db90323386bd2bMartyn Welch while (currentLL != 0) { 155260479690af6d559d4202bed139db90323386bd2bMartyn Welch nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 155360479690af6d559d4202bed139db90323386bd2bMartyn Welch if (nextLL == 0) { 15543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(1, ¤tLL->dcpp); 155560479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 15563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32((unsigned int)virt_to_bus(nextLL), 155760479690af6d559d4202bed139db90323386bd2bMartyn Welch ¤tLL->dcpp); 155860479690af6d559d4202bed139db90323386bd2bMartyn Welch } 155960479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = nextLL; 156060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 156160479690af6d559d4202bed139db90323386bd2bMartyn Welch 15623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Return pointer to descriptors list */ 15633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return startLL; 156460479690af6d559d4202bed139db90323386bd2bMartyn Welch} 156560479690af6d559d4202bed139db90323386bd2bMartyn Welch 15663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_free_dma(TDMA_Cmd_Packet *startLL) 156760479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 156860479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *currentLL; 156960479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *prevLL; 157060479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *nextLL; 157160479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dcppreg; 157260479690af6d559d4202bed139db90323386bd2bMartyn Welch 15733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Convert Links to virtual addresses. */ 157460479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 157560479690af6d559d4202bed139db90323386bd2bMartyn Welch while (currentLL != 0) { 15763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dcppreg = ioread32(¤tLL->dcpp); 157760479690af6d559d4202bed139db90323386bd2bMartyn Welch dcppreg &= ~6; 157860479690af6d559d4202bed139db90323386bd2bMartyn Welch if (dcppreg & 1) { 157960479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = 0; 158060479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 158160479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL->dcpp = (unsigned int)bus_to_virt(dcppreg); 158260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 158360479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 158460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 158560479690af6d559d4202bed139db90323386bd2bMartyn Welch 15863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Free all pages associated with the descriptors. */ 158760479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = startLL; 158860479690af6d559d4202bed139db90323386bd2bMartyn Welch prevLL = currentLL; 158960479690af6d559d4202bed139db90323386bd2bMartyn Welch while (currentLL != 0) { 159060479690af6d559d4202bed139db90323386bd2bMartyn Welch nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp; 159160479690af6d559d4202bed139db90323386bd2bMartyn Welch if (currentLL + 1 != nextLL) { 159260479690af6d559d4202bed139db90323386bd2bMartyn Welch free_pages((int)prevLL, 0); 159360479690af6d559d4202bed139db90323386bd2bMartyn Welch prevLL = nextLL; 159460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 159560479690af6d559d4202bed139db90323386bd2bMartyn Welch currentLL = nextLL; 159660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 159760479690af6d559d4202bed139db90323386bd2bMartyn Welch 15983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Return pointer to descriptors list */ 15993d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 160060479690af6d559d4202bed139db90323386bd2bMartyn Welch} 160160479690af6d559d4202bed139db90323386bd2bMartyn Welch 16023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_do_dma(vmeDmaPacket_t *vmeDma) 160360479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 160460479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dgcsreg = 0; 160560479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int dctlreg = 0; 160660479690af6d559d4202bed139db90323386bd2bMartyn Welch int val; 160760479690af6d559d4202bed139db90323386bd2bMartyn Welch int channel, x; 160860479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDmaPacket_t *curDma; 160960479690af6d559d4202bed139db90323386bd2bMartyn Welch TDMA_Cmd_Packet *dmaLL; 161060479690af6d559d4202bed139db90323386bd2bMartyn Welch 16113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Sanity check the VME chain. */ 161260479690af6d559d4202bed139db90323386bd2bMartyn Welch channel = vmeDma->channel_number; 161360479690af6d559d4202bed139db90323386bd2bMartyn Welch if (channel > 0) { 16143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 161560479690af6d559d4202bed139db90323386bd2bMartyn Welch } 161660479690af6d559d4202bed139db90323386bd2bMartyn Welch curDma = vmeDma; 161760479690af6d559d4202bed139db90323386bd2bMartyn Welch while (curDma != 0) { 161860479690af6d559d4202bed139db90323386bd2bMartyn Welch if (curDma->byteCount == 0) { 16193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 162060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 162160479690af6d559d4202bed139db90323386bd2bMartyn Welch if (curDma->byteCount >= 0x1000000) { 16223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 162360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 162460479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((curDma->srcAddr & 7) != (curDma->dstAddr & 7)) { 16253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 162660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 162760479690af6d559d4202bed139db90323386bd2bMartyn Welch switch (curDma->srcBus) { 162860479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_DMA_PCI: 162960479690af6d559d4202bed139db90323386bd2bMartyn Welch if (curDma->dstBus != VME_DMA_VME) { 16303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 163160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 163260479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 163360479690af6d559d4202bed139db90323386bd2bMartyn Welch case VME_DMA_VME: 163460479690af6d559d4202bed139db90323386bd2bMartyn Welch if (curDma->dstBus != VME_DMA_PCI) { 16353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 163660479690af6d559d4202bed139db90323386bd2bMartyn Welch } 163760479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 163860479690af6d559d4202bed139db90323386bd2bMartyn Welch default: 16393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 164060479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 164160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 164260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (uniSetupDctlReg(curDma, &dctlreg) < 0) { 16433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 164460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 164560479690af6d559d4202bed139db90323386bd2bMartyn Welch 164660479690af6d559d4202bed139db90323386bd2bMartyn Welch curDma = curDma->pNextPacket; 16473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (curDma == vmeDma) { /* Endless Loop! */ 16483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 164960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 165060479690af6d559d4202bed139db90323386bd2bMartyn Welch } 165160479690af6d559d4202bed139db90323386bd2bMartyn Welch 16523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* calculate control register */ 165360479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeDma->pNextPacket != 0) { 165460479690af6d559d4202bed139db90323386bd2bMartyn Welch dgcsreg = 0x8000000; 165560479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 165660479690af6d559d4202bed139db90323386bd2bMartyn Welch dgcsreg = 0; 165760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 165860479690af6d559d4202bed139db90323386bd2bMartyn Welch 16593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (x = 0; x < 8; x++) { /* vme block size */ 166060479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((256 << x) >= vmeDma->maxVmeBlockSize) { 166160479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 166260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 166360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 166460479690af6d559d4202bed139db90323386bd2bMartyn Welch if (x == 8) 166560479690af6d559d4202bed139db90323386bd2bMartyn Welch x = 7; 166660479690af6d559d4202bed139db90323386bd2bMartyn Welch dgcsreg |= (x << 20); 166760479690af6d559d4202bed139db90323386bd2bMartyn Welch 166860479690af6d559d4202bed139db90323386bd2bMartyn Welch if (vmeDma->vmeBackOffTimer) { 16693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch for (x = 1; x < 8; x++) { /* vme timer */ 167060479690af6d559d4202bed139db90323386bd2bMartyn Welch if ((16 << (x - 1)) >= vmeDma->vmeBackOffTimer) { 167160479690af6d559d4202bed139db90323386bd2bMartyn Welch break; 167260479690af6d559d4202bed139db90323386bd2bMartyn Welch } 167360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 167460479690af6d559d4202bed139db90323386bd2bMartyn Welch if (x == 8) 167560479690af6d559d4202bed139db90323386bd2bMartyn Welch x = 7; 167660479690af6d559d4202bed139db90323386bd2bMartyn Welch dgcsreg |= (x << 16); 167760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 16783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /*` Setup the dma chain */ 16793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch dmaLL = ca91cx42_setup_dma(vmeDma); 168060479690af6d559d4202bed139db90323386bd2bMartyn Welch 16813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Start the DMA */ 168260479690af6d559d4202bed139db90323386bd2bMartyn Welch if (dgcsreg & 0x8000000) { 168360479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDma->vmeDmaStartTick = 16843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_start_dma(channel, dgcsreg, 168560479690af6d559d4202bed139db90323386bd2bMartyn Welch (TDMA_Cmd_Packet *) virt_to_phys(dmaLL)); 168660479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 168760479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDma->vmeDmaStartTick = 16883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_start_dma(channel, dgcsreg, dmaLL); 168960479690af6d559d4202bed139db90323386bd2bMartyn Welch } 169060479690af6d559d4202bed139db90323386bd2bMartyn Welch 16913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch wait_event_interruptible(dma_queue, 16923d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ioread32(ca91cx42_bridge->base + DGCS) & 0x800); 169360479690af6d559d4202bed139db90323386bd2bMartyn Welch 16943d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DGCS); 16953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(val | 0xF00, ca91cx42_bridge->base + DGCS); 169660479690af6d559d4202bed139db90323386bd2bMartyn Welch 169760479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDma->vmeDmaStatus = 0; 169860479690af6d559d4202bed139db90323386bd2bMartyn Welch 169960479690af6d559d4202bed139db90323386bd2bMartyn Welch if (!(val & 0x00000800)) { 170060479690af6d559d4202bed139db90323386bd2bMartyn Welch vmeDma->vmeDmaStatus = val & 0x700; 17013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch printk(KERN_ERR "ca91c042: DMA Error in ca91cx42_DMA_irqhandler" 17023d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch " DGCS=%08X\n", val); 17033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DCPP); 170460479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DCPP=%08X\n", val); 17053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DCTL); 170660479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DCTL=%08X\n", val); 17073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DTBC); 170860479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DTBC=%08X\n", val); 17093d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DLA); 171060479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DLA=%08X\n", val); 17113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch val = ioread32(ca91cx42_bridge->base + DVA); 171260479690af6d559d4202bed139db90323386bd2bMartyn Welch printk(KERN_ERR "ca91c042: DVA=%08X\n", val); 171360479690af6d559d4202bed139db90323386bd2bMartyn Welch 171460479690af6d559d4202bed139db90323386bd2bMartyn Welch } 17153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Free the dma chain */ 17163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch ca91cx42_free_dma(dmaLL); 171760479690af6d559d4202bed139db90323386bd2bMartyn Welch 17183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 171960479690af6d559d4202bed139db90323386bd2bMartyn Welch} 172060479690af6d559d4202bed139db90323386bd2bMartyn Welch 17213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_lm_set(vmeLmCfg_t *vmeLm) 172260479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 17233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 17243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->addrU) 17263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 17273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch switch (vmeLm->addrSpace) { 17293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A64: 17303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER3: 17313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER4: 17323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 17333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A16: 17343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00000; 17353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A24: 17373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x10000; 17383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_A32: 17403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x20000; 17413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_CRCSR: 17433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x50000; 17443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER1: 17463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x60000; 17473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 17483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch case VME_USER2: 17493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x70000; 17503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch break; 175160479690af6d559d4202bed139db90323386bd2bMartyn Welch } 17523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Disable while we are mucking around */ 17543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL); 17553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(vmeLm->addr, ca91cx42_bridge->base + LM_BS); 17573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Setup CTL register. */ 17593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->userAccessType & VME_SUPER) 17603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00200000; 17613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->userAccessType & VME_USER) 17623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00100000; 17633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->dataAccessType & VME_PROG) 17643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00800000; 17653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->dataAccessType & VME_DATA) 17663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 0x00400000; 17673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch /* Write ctl reg and enable */ 17703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x80000000 | temp_ctl, ca91cx42_bridge->base + LM_CTL); 17713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + LM_CTL); 17723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 177460479690af6d559d4202bed139db90323386bd2bMartyn Welch} 177560479690af6d559d4202bed139db90323386bd2bMartyn Welch 17763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_wait_lm(vmeLmCfg_t *vmeLm) 177760479690af6d559d4202bed139db90323386bd2bMartyn Welch{ 17783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch unsigned long flags; 177960479690af6d559d4202bed139db90323386bd2bMartyn Welch unsigned int tmp; 17803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 17813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_lock_irqsave(&lm_lock, flags); 17823d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch spin_unlock_irqrestore(&lm_lock, flags); 17833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (tmp == 0) { 17843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeLm->lmWait < 10) 17853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeLm->lmWait = 10; 17863d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch interruptible_sleep_on_timeout(&lm_queue, vmeLm->lmWait); 178760479690af6d559d4202bed139db90323386bd2bMartyn Welch } 17883d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL); 178960479690af6d559d4202bed139db90323386bd2bMartyn Welch 17903d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 17913d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 179260479690af6d559d4202bed139db90323386bd2bMartyn Welch 179360479690af6d559d4202bed139db90323386bd2bMartyn Welch 179460479690af6d559d4202bed139db90323386bd2bMartyn Welch 17953d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_set_arbiter(vmeArbiterCfg_t *vmeArb) 17963d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 17973d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 17983d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int vbto = 0; 179960479690af6d559d4202bed139db90323386bd2bMartyn Welch 18003d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL); 18013d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= 0x00FFFFFF; 180260479690af6d559d4202bed139db90323386bd2bMartyn Welch 18033d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) { 18043d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto = 7; 18053d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } else if (vmeArb->globalTimeoutTimer > 1024) { 18063d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return -EINVAL; 18073d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch } else if (vmeArb->globalTimeoutTimer == 0) { 18083d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto = 0; 180960479690af6d559d4202bed139db90323386bd2bMartyn Welch } else { 18103d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto = 1; 18113d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch while ((16 * (1 << (vbto - 1))) < vmeArb->globalTimeoutTimer) 18123d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto += 1; 181360479690af6d559d4202bed139db90323386bd2bMartyn Welch } 18143d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= (vbto << 28); 18153d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18163d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeArb->arbiterMode == VME_PRIORITY_MODE) 18173d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 1 << 26; 18183d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18193d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeArb->arbiterTimeoutFlag) 18203d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= 2 << 24; 18213d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18223d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + MISC_CTL); 18233d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 18243d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 18253d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18263d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_get_arbiter(vmeArbiterCfg_t *vmeArb) 18273d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 18283d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 18293d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int vbto = 0; 18303d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18313d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL); 18323d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18333d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vbto = (temp_ctl >> 28) & 0xF; 18343d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vbto != 0) 18353d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeArb->globalTimeoutTimer = (16 * (1 << (vbto - 1))); 18363d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18373d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (temp_ctl & (1 << 26)) 18383d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeArb->arbiterMode = VME_PRIORITY_MODE; 18393d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch else 18403d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeArb->arbiterMode = VME_R_ROBIN_MODE; 18413d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18423d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (temp_ctl & (3 << 24)) 18433d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeArb->arbiterTimeoutFlag = 1; 18443d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18453d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 18463d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 18473d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18483d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_set_requestor(vmeRequesterCfg_t *vmeReq) 18493d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 18503d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 18513d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18523d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL); 18533d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl &= 0xFF0FFFFF; 18543d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18553d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeReq->releaseMode == 1) 18563d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= (1 << 20); 18573d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18583d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (vmeReq->fairMode == 1) 18593d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= (1 << 21); 18603d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18613d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl |= (vmeReq->requestLevel << 22); 18623d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18633d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch iowrite32(temp_ctl, ca91cx42_bridge->base + MAST_CTL); 18643d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 18653d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch} 18663d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18673d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welchint ca91cx42_get_requestor(vmeRequesterCfg_t *vmeReq) 18683d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch{ 18693d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch int temp_ctl = 0; 18703d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18713d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL); 18723d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18733d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (temp_ctl & (1 << 20)) 18743d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeReq->releaseMode = 1; 18753d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18763d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch if (temp_ctl & (1 << 21)) 18773d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeReq->fairMode = 1; 18783d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18793d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch vmeReq->requestLevel = (temp_ctl & 0xC00000) >> 22; 18803d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18813d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch return 0; 188260479690af6d559d4202bed139db90323386bd2bMartyn Welch} 18833d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18843d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch 18853d0f8bc7517718a4846de6f538ad67a4f7f83239Martyn Welch#endif 1886