Staging: VME: move VME drivers out of staging

This moves the VME core, VME board drivers, and VME bridge drivers out
of the drivers/staging/vme/ area to drivers/vme/.

The VME device drivers have not moved out yet due to some API questions
they are still working through, that should happen soon, hopefully.

Cc: Martyn Welch <[email protected]>
Cc: Manohar Vanga <[email protected]>
Cc: Vincent Bossier <[email protected]>
Cc: "Emilio G. Cota" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
Greg Kroah-Hartman 2012-04-26 12:34:58 -07:00
commit db3b9e990e
26 changed files with 22 additions and 25 deletions

19
drivers/vme/Kconfig Normal file
View file

@ -0,0 +1,19 @@
#
# VME configuration.
#
menuconfig VME_BUS
tristate "VME bridge support"
depends on PCI
---help---
If you say Y here you get support for the VME bridge Framework.
if VME_BUS
source "drivers/vme/bridges/Kconfig"
source "drivers/vme/boards/Kconfig"
source "drivers/staging/vme/devices/Kconfig"
endif # VME

7
drivers/vme/Makefile Normal file
View file

@ -0,0 +1,7 @@
#
# Makefile for the VME bridge device drivers.
#
obj-$(CONFIG_VME_BUS) += vme.o
obj-y += bridges/
obj-y += boards/

View file

@ -0,0 +1,9 @@
comment "VME Board Drivers"
config VMIVME_7805
tristate "VMIVME-7805"
help
If you say Y here you get support for the VMIVME-7805 board.
This board has an additional control interface to the Universe II
chip. This driver has to be included if you want to access VME bus
with VMIVME-7805 board.

View file

@ -0,0 +1,5 @@
#
# Makefile for the VME board drivers.
#
obj-$(CONFIG_VMIVME_7805) += vme_vmivme7805.o

View file

@ -0,0 +1,123 @@
/*
* Support for the VMIVME-7805 board access to the Universe II bridge.
*
* Author: Arthur Benilov <arthur.benilov@iba-group.com>
* Copyright 2010 Ion Beam Application, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/poll.h>
#include <linux/io.h>
#include "vme_vmivme7805.h"
static int __init vmic_init(void);
static int vmic_probe(struct pci_dev *, const struct pci_device_id *);
static void vmic_remove(struct pci_dev *);
static void __exit vmic_exit(void);
/** Base address to access FPGA register */
static void *vmic_base;
static const char driver_name[] = "vmivme_7805";
static DEFINE_PCI_DEVICE_TABLE(vmic_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) },
{ },
};
static struct pci_driver vmic_driver = {
.name = driver_name,
.id_table = vmic_ids,
.probe = vmic_probe,
.remove = vmic_remove,
};
static int __init vmic_init(void)
{
return pci_register_driver(&vmic_driver);
}
static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int retval;
u32 data;
/* Enable the device */
retval = pci_enable_device(pdev);
if (retval) {
dev_err(&pdev->dev, "Unable to enable device\n");
goto err;
}
/* Map Registers */
retval = pci_request_regions(pdev, driver_name);
if (retval) {
dev_err(&pdev->dev, "Unable to reserve resources\n");
goto err_resource;
}
/* Map registers in BAR 0 */
vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16);
if (!vmic_base) {
dev_err(&pdev->dev, "Unable to remap CRG region\n");
retval = -EIO;
goto err_remap;
}
/* Clear the FPGA VME IF contents */
iowrite32(0, vmic_base + VME_CONTROL);
/* Clear any initial BERR */
data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
data |= BM_VME_CONTROL_BERRST;
iowrite32(data, vmic_base + VME_CONTROL);
/* Enable the vme interface and byte swapping */
data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
data = data | BM_VME_CONTROL_MASTER_ENDIAN |
BM_VME_CONTROL_SLAVE_ENDIAN |
BM_VME_CONTROL_ABLE |
BM_VME_CONTROL_BERRI |
BM_VME_CONTROL_BPENA |
BM_VME_CONTROL_VBENA;
iowrite32(data, vmic_base + VME_CONTROL);
return 0;
err_remap:
pci_release_regions(pdev);
err_resource:
pci_disable_device(pdev);
err:
return retval;
}
static void vmic_remove(struct pci_dev *pdev)
{
iounmap(vmic_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
}
static void __exit vmic_exit(void)
{
pci_unregister_driver(&vmic_driver);
}
MODULE_DESCRIPTION("VMIVME-7805 board support driver");
MODULE_AUTHOR("Arthur Benilov <[email protected]>");
MODULE_LICENSE("GPL");
module_init(vmic_init);
module_exit(vmic_exit);

View file

@ -0,0 +1,37 @@
/*
* vmivme_7805.h
*
* Support for the VMIVME-7805 board access to the Universe II bridge.
*
* Author: Arthur Benilov <arthur.benilov@iba-group.com>
* Copyright 2010 Ion Beam Application, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef _VMIVME_7805_H
#define _VMIVME_7805_H
#ifndef PCI_VENDOR_ID_VMIC
#define PCI_VENDOR_ID_VMIC 0x114A
#endif
#ifndef PCI_DEVICE_ID_VTIMR
#define PCI_DEVICE_ID_VTIMR 0x0004
#endif
#define VME_CONTROL 0x0000
#define BM_VME_CONTROL_MASTER_ENDIAN 0x0001
#define BM_VME_CONTROL_SLAVE_ENDIAN 0x0002
#define BM_VME_CONTROL_ABLE 0x0004
#define BM_VME_CONTROL_BERRI 0x0040
#define BM_VME_CONTROL_BERRST 0x0080
#define BM_VME_CONTROL_BPENA 0x0400
#define BM_VME_CONTROL_VBENA 0x0800
#endif /* _VMIVME_7805_H */

View file

@ -0,0 +1,15 @@
comment "VME Bridge Drivers"
config VME_CA91CX42
tristate "Universe II"
depends on VIRT_TO_BUS
help
If you say Y here you get support for the Tundra CA91C142
(Universe II) VME bridge chip.
config VME_TSI148
tristate "Tempe"
depends on VIRT_TO_BUS
help
If you say Y here you get support for the Tundra TSI148 VME bridge
chip.

View file

@ -0,0 +1,2 @@
obj-$(CONFIG_VME_CA91CX42) += vme_ca91cx42.o
obj-$(CONFIG_VME_TSI148) += vme_tsi148.o

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,583 @@
/*
* ca91c042.h
*
* Support for the Tundra Universe 1 and Universe II VME bridge chips
*
* Author: Tom Armistead
* Updated by Ajit Prem
* Copyright 2004 Motorola Inc.
*
* Further updated by Martyn Welch <martyn.welch@ge.com>
* Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
*
* Derived from ca91c042.h by Michael Wyrick
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef _CA91CX42_H
#define _CA91CX42_H
#ifndef PCI_VENDOR_ID_TUNDRA
#define PCI_VENDOR_ID_TUNDRA 0x10e3
#endif
#ifndef PCI_DEVICE_ID_TUNDRA_CA91C142
#define PCI_DEVICE_ID_TUNDRA_CA91C142 0x0000
#endif
/*
* Define the number of each that the CA91C142 supports.
*/
#define CA91C142_MAX_MASTER 8 /* Max Master Windows */
#define CA91C142_MAX_SLAVE 8 /* Max Slave Windows */
#define CA91C142_MAX_DMA 1 /* Max DMA Controllers */
#define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */
/* Structure used to hold driver specific information */
struct ca91cx42_driver {
void __iomem *base; /* Base Address of device registers */
wait_queue_head_t dma_queue;
wait_queue_head_t iack_queue;
wait_queue_head_t mbox_queue;
void (*lm_callback[4])(int); /* Called in interrupt handler */
void *crcsr_kernel;
dma_addr_t crcsr_bus;
struct mutex vme_rmw; /* Only one RMW cycle at a time */
struct mutex vme_int; /*
* Only one VME interrupt can be
* generated at a time, provide locking
*/
};
/* See Page 2-77 in the Universe User Manual */
struct ca91cx42_dma_descriptor {
unsigned int dctl; /* DMA Control */
unsigned int dtbc; /* Transfer Byte Count */
unsigned int dla; /* PCI Address */
unsigned int res1; /* Reserved */
unsigned int dva; /* Vme Address */
unsigned int res2; /* Reserved */
unsigned int dcpp; /* Pointer to Numed Cmd Packet with rPN */
unsigned int res3; /* Reserved */
};
struct ca91cx42_dma_entry {
struct ca91cx42_dma_descriptor descriptor;
struct list_head list;
};
/* Universe Register Offsets */
/* general PCI configuration registers */
#define CA91CX42_PCI_ID 0x000
#define CA91CX42_PCI_CSR 0x004
#define CA91CX42_PCI_CLASS 0x008
#define CA91CX42_PCI_MISC0 0x00C
#define CA91CX42_PCI_BS 0x010
#define CA91CX42_PCI_MISC1 0x03C
#define LSI0_CTL 0x0100
#define LSI0_BS 0x0104
#define LSI0_BD 0x0108
#define LSI0_TO 0x010C
#define LSI1_CTL 0x0114
#define LSI1_BS 0x0118
#define LSI1_BD 0x011C
#define LSI1_TO 0x0120
#define LSI2_CTL 0x0128
#define LSI2_BS 0x012C
#define LSI2_BD 0x0130
#define LSI2_TO 0x0134
#define LSI3_CTL 0x013C
#define LSI3_BS 0x0140
#define LSI3_BD 0x0144
#define LSI3_TO 0x0148
#define LSI4_CTL 0x01A0
#define LSI4_BS 0x01A4
#define LSI4_BD 0x01A8
#define LSI4_TO 0x01AC
#define LSI5_CTL 0x01B4
#define LSI5_BS 0x01B8
#define LSI5_BD 0x01BC
#define LSI5_TO 0x01C0
#define LSI6_CTL 0x01C8
#define LSI6_BS 0x01CC
#define LSI6_BD 0x01D0
#define LSI6_TO 0x01D4
#define LSI7_CTL 0x01DC
#define LSI7_BS 0x01E0
#define LSI7_BD 0x01E4
#define LSI7_TO 0x01E8
static const int CA91CX42_LSI_CTL[] = { LSI0_CTL, LSI1_CTL, LSI2_CTL, LSI3_CTL,
LSI4_CTL, LSI5_CTL, LSI6_CTL, LSI7_CTL };
static const int CA91CX42_LSI_BS[] = { LSI0_BS, LSI1_BS, LSI2_BS, LSI3_BS,
LSI4_BS, LSI5_BS, LSI6_BS, LSI7_BS };
static const int CA91CX42_LSI_BD[] = { LSI0_BD, LSI1_BD, LSI2_BD, LSI3_BD,
LSI4_BD, LSI5_BD, LSI6_BD, LSI7_BD };
static const int CA91CX42_LSI_TO[] = { LSI0_TO, LSI1_TO, LSI2_TO, LSI3_TO,
LSI4_TO, LSI5_TO, LSI6_TO, LSI7_TO };
#define SCYC_CTL 0x0170
#define SCYC_ADDR 0x0174
#define SCYC_EN 0x0178
#define SCYC_CMP 0x017C
#define SCYC_SWP 0x0180
#define LMISC 0x0184
#define SLSI 0x0188
#define L_CMDERR 0x018C
#define LAERR 0x0190
#define DCTL 0x0200
#define DTBC 0x0204
#define DLA 0x0208
#define DVA 0x0210
#define DCPP 0x0218
#define DGCS 0x0220
#define D_LLUE 0x0224
#define LINT_EN 0x0300
#define LINT_STAT 0x0304
#define LINT_MAP0 0x0308
#define LINT_MAP1 0x030C
#define VINT_EN 0x0310
#define VINT_STAT 0x0314
#define VINT_MAP0 0x0318
#define VINT_MAP1 0x031C
#define STATID 0x0320
#define V1_STATID 0x0324
#define V2_STATID 0x0328
#define V3_STATID 0x032C
#define V4_STATID 0x0330
#define V5_STATID 0x0334
#define V6_STATID 0x0338
#define V7_STATID 0x033C
static const int CA91CX42_V_STATID[8] = { 0, V1_STATID, V2_STATID, V3_STATID,
V4_STATID, V5_STATID, V6_STATID,
V7_STATID };
#define LINT_MAP2 0x0340
#define VINT_MAP2 0x0344
#define MBOX0 0x0348
#define MBOX1 0x034C
#define MBOX2 0x0350
#define MBOX3 0x0354
#define SEMA0 0x0358
#define SEMA1 0x035C
#define MAST_CTL 0x0400
#define MISC_CTL 0x0404
#define MISC_STAT 0x0408
#define USER_AM 0x040C
#define VSI0_CTL 0x0F00
#define VSI0_BS 0x0F04
#define VSI0_BD 0x0F08
#define VSI0_TO 0x0F0C
#define VSI1_CTL 0x0F14
#define VSI1_BS 0x0F18
#define VSI1_BD 0x0F1C
#define VSI1_TO 0x0F20
#define VSI2_CTL 0x0F28
#define VSI2_BS 0x0F2C
#define VSI2_BD 0x0F30
#define VSI2_TO 0x0F34
#define VSI3_CTL 0x0F3C
#define VSI3_BS 0x0F40
#define VSI3_BD 0x0F44
#define VSI3_TO 0x0F48
#define LM_CTL 0x0F64
#define LM_BS 0x0F68
#define VRAI_CTL 0x0F70
#define VRAI_BS 0x0F74
#define VCSR_CTL 0x0F80
#define VCSR_TO 0x0F84
#define V_AMERR 0x0F88
#define VAERR 0x0F8C
#define VSI4_CTL 0x0F90
#define VSI4_BS 0x0F94
#define VSI4_BD 0x0F98
#define VSI4_TO 0x0F9C
#define VSI5_CTL 0x0FA4
#define VSI5_BS 0x0FA8
#define VSI5_BD 0x0FAC
#define VSI5_TO 0x0FB0
#define VSI6_CTL 0x0FB8
#define VSI6_BS 0x0FBC
#define VSI6_BD 0x0FC0
#define VSI6_TO 0x0FC4
#define VSI7_CTL 0x0FCC
#define VSI7_BS 0x0FD0
#define VSI7_BD 0x0FD4
#define VSI7_TO 0x0FD8
static const int CA91CX42_VSI_CTL[] = { VSI0_CTL, VSI1_CTL, VSI2_CTL, VSI3_CTL,
VSI4_CTL, VSI5_CTL, VSI6_CTL, VSI7_CTL };
static const int CA91CX42_VSI_BS[] = { VSI0_BS, VSI1_BS, VSI2_BS, VSI3_BS,
VSI4_BS, VSI5_BS, VSI6_BS, VSI7_BS };
static const int CA91CX42_VSI_BD[] = { VSI0_BD, VSI1_BD, VSI2_BD, VSI3_BD,
VSI4_BD, VSI5_BD, VSI6_BD, VSI7_BD };
static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
VSI4_TO, VSI5_TO, VSI6_TO, VSI7_TO };
#define VCSR_CLR 0x0FF4
#define VCSR_SET 0x0FF8
#define VCSR_BS 0x0FFC
/*
* PCI Class Register
* offset 008
*/
#define CA91CX42_BM_PCI_CLASS_BASE 0xFF000000
#define CA91CX42_OF_PCI_CLASS_BASE 24
#define CA91CX42_BM_PCI_CLASS_SUB 0x00FF0000
#define CA91CX42_OF_PCI_CLASS_SUB 16
#define CA91CX42_BM_PCI_CLASS_PROG 0x0000FF00
#define CA91CX42_OF_PCI_CLASS_PROG 8
#define CA91CX42_BM_PCI_CLASS_RID 0x000000FF
#define CA91CX42_OF_PCI_CLASS_RID 0
#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_I 0
#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_II 1
/*
* PCI Misc Register
* offset 00C
*/
#define CA91CX42_BM_PCI_MISC0_BISTC 0x80000000
#define CA91CX42_BM_PCI_MISC0_SBIST 0x60000000
#define CA91CX42_BM_PCI_MISC0_CCODE 0x0F000000
#define CA91CX42_BM_PCI_MISC0_MFUNCT 0x00800000
#define CA91CX42_BM_PCI_MISC0_LAYOUT 0x007F0000
#define CA91CX42_BM_PCI_MISC0_LTIMER 0x0000FF00
#define CA91CX42_OF_PCI_MISC0_LTIMER 8
/*
* LSI Control Register
* offset 100
*/
#define CA91CX42_LSI_CTL_EN (1<<31)
#define CA91CX42_LSI_CTL_PWEN (1<<30)
#define CA91CX42_LSI_CTL_VDW_M (3<<22)
#define CA91CX42_LSI_CTL_VDW_D8 0
#define CA91CX42_LSI_CTL_VDW_D16 (1<<22)
#define CA91CX42_LSI_CTL_VDW_D32 (1<<23)
#define CA91CX42_LSI_CTL_VDW_D64 (3<<22)
#define CA91CX42_LSI_CTL_VAS_M (7<<16)
#define CA91CX42_LSI_CTL_VAS_A16 0
#define CA91CX42_LSI_CTL_VAS_A24 (1<<16)
#define CA91CX42_LSI_CTL_VAS_A32 (1<<17)
#define CA91CX42_LSI_CTL_VAS_CRCSR (5<<16)
#define CA91CX42_LSI_CTL_VAS_USER1 (3<<17)
#define CA91CX42_LSI_CTL_VAS_USER2 (7<<16)
#define CA91CX42_LSI_CTL_PGM_M (1<<14)
#define CA91CX42_LSI_CTL_PGM_DATA 0
#define CA91CX42_LSI_CTL_PGM_PGM (1<<14)
#define CA91CX42_LSI_CTL_SUPER_M (1<<12)
#define CA91CX42_LSI_CTL_SUPER_NPRIV 0
#define CA91CX42_LSI_CTL_SUPER_SUPR (1<<12)
#define CA91CX42_LSI_CTL_VCT_M (1<<8)
#define CA91CX42_LSI_CTL_VCT_BLT (1<<8)
#define CA91CX42_LSI_CTL_VCT_MBLT (1<<8)
#define CA91CX42_LSI_CTL_LAS (1<<0)
/*
* SCYC_CTL Register
* offset 178
*/
#define CA91CX42_SCYC_CTL_LAS_PCIMEM 0
#define CA91CX42_SCYC_CTL_LAS_PCIIO (1<<2)
#define CA91CX42_SCYC_CTL_CYC_M (3<<0)
#define CA91CX42_SCYC_CTL_CYC_RMW (1<<0)
#define CA91CX42_SCYC_CTL_CYC_ADOH (1<<1)
/*
* LMISC Register
* offset 184
*/
#define CA91CX42_BM_LMISC_CRT 0xF0000000
#define CA91CX42_OF_LMISC_CRT 28
#define CA91CX42_BM_LMISC_CWT 0x0F000000
#define CA91CX42_OF_LMISC_CWT 24
/*
* SLSI Register
* offset 188
*/
#define CA91CX42_BM_SLSI_EN 0x80000000
#define CA91CX42_BM_SLSI_PWEN 0x40000000
#define CA91CX42_BM_SLSI_VDW 0x00F00000
#define CA91CX42_OF_SLSI_VDW 20
#define CA91CX42_BM_SLSI_PGM 0x0000F000
#define CA91CX42_OF_SLSI_PGM 12
#define CA91CX42_BM_SLSI_SUPER 0x00000F00
#define CA91CX42_OF_SLSI_SUPER 8
#define CA91CX42_BM_SLSI_BS 0x000000F6
#define CA91CX42_OF_SLSI_BS 2
#define CA91CX42_BM_SLSI_LAS 0x00000003
#define CA91CX42_OF_SLSI_LAS 0
#define CA91CX42_BM_SLSI_RESERVED 0x3F0F0000
/*
* DCTL Register
* offset 200
*/
#define CA91CX42_DCTL_L2V (1<<31)
#define CA91CX42_DCTL_VDW_M (3<<22)
#define CA91CX42_DCTL_VDW_M (3<<22)
#define CA91CX42_DCTL_VDW_D8 0
#define CA91CX42_DCTL_VDW_D16 (1<<22)
#define CA91CX42_DCTL_VDW_D32 (1<<23)
#define CA91CX42_DCTL_VDW_D64 (3<<22)
#define CA91CX42_DCTL_VAS_M (7<<16)
#define CA91CX42_DCTL_VAS_A16 0
#define CA91CX42_DCTL_VAS_A24 (1<<16)
#define CA91CX42_DCTL_VAS_A32 (1<<17)
#define CA91CX42_DCTL_VAS_USER1 (3<<17)
#define CA91CX42_DCTL_VAS_USER2 (7<<16)
#define CA91CX42_DCTL_PGM_M (1<<14)
#define CA91CX42_DCTL_PGM_DATA 0
#define CA91CX42_DCTL_PGM_PGM (1<<14)
#define CA91CX42_DCTL_SUPER_M (1<<12)
#define CA91CX42_DCTL_SUPER_NPRIV 0
#define CA91CX42_DCTL_SUPER_SUPR (1<<12)
#define CA91CX42_DCTL_VCT_M (1<<8)
#define CA91CX42_DCTL_VCT_BLT (1<<8)
#define CA91CX42_DCTL_LD64EN (1<<7)
/*
* DCPP Register
* offset 218
*/
#define CA91CX42_DCPP_M 0xf
#define CA91CX42_DCPP_NULL (1<<0)
/*
* DMA General Control/Status Register (DGCS)
* offset 220
*/
#define CA91CX42_DGCS_GO (1<<31)
#define CA91CX42_DGCS_STOP_REQ (1<<30)
#define CA91CX42_DGCS_HALT_REQ (1<<29)
#define CA91CX42_DGCS_CHAIN (1<<27)
#define CA91CX42_DGCS_VON_M (7<<20)
#define CA91CX42_DGCS_VOFF_M (0xf<<16)
#define CA91CX42_DGCS_ACT (1<<15)
#define CA91CX42_DGCS_STOP (1<<14)
#define CA91CX42_DGCS_HALT (1<<13)
#define CA91CX42_DGCS_DONE (1<<11)
#define CA91CX42_DGCS_LERR (1<<10)
#define CA91CX42_DGCS_VERR (1<<9)
#define CA91CX42_DGCS_PERR (1<<8)
#define CA91CX42_DGCS_INT_STOP (1<<6)
#define CA91CX42_DGCS_INT_HALT (1<<5)
#define CA91CX42_DGCS_INT_DONE (1<<3)
#define CA91CX42_DGCS_INT_LERR (1<<2)
#define CA91CX42_DGCS_INT_VERR (1<<1)
#define CA91CX42_DGCS_INT_PERR (1<<0)
/*
* PCI Interrupt Enable Register
* offset 300
*/
#define CA91CX42_LINT_LM3 0x00800000
#define CA91CX42_LINT_LM2 0x00400000
#define CA91CX42_LINT_LM1 0x00200000
#define CA91CX42_LINT_LM0 0x00100000
#define CA91CX42_LINT_MBOX3 0x00080000
#define CA91CX42_LINT_MBOX2 0x00040000
#define CA91CX42_LINT_MBOX1 0x00020000
#define CA91CX42_LINT_MBOX0 0x00010000
#define CA91CX42_LINT_ACFAIL 0x00008000
#define CA91CX42_LINT_SYSFAIL 0x00004000
#define CA91CX42_LINT_SW_INT 0x00002000
#define CA91CX42_LINT_SW_IACK 0x00001000
#define CA91CX42_LINT_VERR 0x00000400
#define CA91CX42_LINT_LERR 0x00000200
#define CA91CX42_LINT_DMA 0x00000100
#define CA91CX42_LINT_VIRQ7 0x00000080
#define CA91CX42_LINT_VIRQ6 0x00000040
#define CA91CX42_LINT_VIRQ5 0x00000020
#define CA91CX42_LINT_VIRQ4 0x00000010
#define CA91CX42_LINT_VIRQ3 0x00000008
#define CA91CX42_LINT_VIRQ2 0x00000004
#define CA91CX42_LINT_VIRQ1 0x00000002
#define CA91CX42_LINT_VOWN 0x00000001
static const int CA91CX42_LINT_VIRQ[] = { 0, CA91CX42_LINT_VIRQ1,
CA91CX42_LINT_VIRQ2, CA91CX42_LINT_VIRQ3,
CA91CX42_LINT_VIRQ4, CA91CX42_LINT_VIRQ5,
CA91CX42_LINT_VIRQ6, CA91CX42_LINT_VIRQ7 };
#define CA91CX42_LINT_MBOX 0x000F0000
static const int CA91CX42_LINT_LM[] = { CA91CX42_LINT_LM0, CA91CX42_LINT_LM1,
CA91CX42_LINT_LM2, CA91CX42_LINT_LM3 };
/*
* MAST_CTL Register
* offset 400
*/
#define CA91CX42_BM_MAST_CTL_MAXRTRY 0xF0000000
#define CA91CX42_OF_MAST_CTL_MAXRTRY 28
#define CA91CX42_BM_MAST_CTL_PWON 0x0F000000
#define CA91CX42_OF_MAST_CTL_PWON 24
#define CA91CX42_BM_MAST_CTL_VRL 0x00C00000
#define CA91CX42_OF_MAST_CTL_VRL 22
#define CA91CX42_BM_MAST_CTL_VRM 0x00200000
#define CA91CX42_BM_MAST_CTL_VREL 0x00100000
#define CA91CX42_BM_MAST_CTL_VOWN 0x00080000
#define CA91CX42_BM_MAST_CTL_VOWN_ACK 0x00040000
#define CA91CX42_BM_MAST_CTL_PABS 0x00001000
#define CA91CX42_BM_MAST_CTL_BUS_NO 0x0000000F
#define CA91CX42_OF_MAST_CTL_BUS_NO 0
/*
* MISC_CTL Register
* offset 404
*/
#define CA91CX42_MISC_CTL_VBTO 0xF0000000
#define CA91CX42_MISC_CTL_VARB 0x04000000
#define CA91CX42_MISC_CTL_VARBTO 0x03000000
#define CA91CX42_MISC_CTL_SW_LRST 0x00800000
#define CA91CX42_MISC_CTL_SW_SRST 0x00400000
#define CA91CX42_MISC_CTL_BI 0x00100000
#define CA91CX42_MISC_CTL_ENGBI 0x00080000
#define CA91CX42_MISC_CTL_RESCIND 0x00040000
#define CA91CX42_MISC_CTL_SYSCON 0x00020000
#define CA91CX42_MISC_CTL_V64AUTO 0x00010000
#define CA91CX42_MISC_CTL_RESERVED 0x0820FFFF
#define CA91CX42_OF_MISC_CTL_VARBTO 24
#define CA91CX42_OF_MISC_CTL_VBTO 28
/*
* MISC_STAT Register
* offset 408
*/
#define CA91CX42_BM_MISC_STAT_ENDIAN 0x80000000
#define CA91CX42_BM_MISC_STAT_LCLSIZE 0x40000000
#define CA91CX42_BM_MISC_STAT_DY4AUTO 0x08000000
#define CA91CX42_BM_MISC_STAT_MYBBSY 0x00200000
#define CA91CX42_BM_MISC_STAT_DY4DONE 0x00080000
#define CA91CX42_BM_MISC_STAT_TXFE 0x00040000
#define CA91CX42_BM_MISC_STAT_RXFE 0x00020000
#define CA91CX42_BM_MISC_STAT_DY4AUTOID 0x0000FF00
#define CA91CX42_OF_MISC_STAT_DY4AUTOID 8
/*
* VSI Control Register
* offset F00
*/
#define CA91CX42_VSI_CTL_EN (1<<31)
#define CA91CX42_VSI_CTL_PWEN (1<<30)
#define CA91CX42_VSI_CTL_PREN (1<<29)
#define CA91CX42_VSI_CTL_PGM_M (3<<22)
#define CA91CX42_VSI_CTL_PGM_DATA (1<<22)
#define CA91CX42_VSI_CTL_PGM_PGM (1<<23)
#define CA91CX42_VSI_CTL_SUPER_M (3<<20)
#define CA91CX42_VSI_CTL_SUPER_NPRIV (1<<20)
#define CA91CX42_VSI_CTL_SUPER_SUPR (1<<21)
#define CA91CX42_VSI_CTL_VAS_M (7<<16)
#define CA91CX42_VSI_CTL_VAS_A16 0
#define CA91CX42_VSI_CTL_VAS_A24 (1<<16)
#define CA91CX42_VSI_CTL_VAS_A32 (1<<17)
#define CA91CX42_VSI_CTL_VAS_USER1 (3<<17)
#define CA91CX42_VSI_CTL_VAS_USER2 (7<<16)
#define CA91CX42_VSI_CTL_LD64EN (1<<7)
#define CA91CX42_VSI_CTL_LLRMW (1<<6)
#define CA91CX42_VSI_CTL_LAS_M (3<<0)
#define CA91CX42_VSI_CTL_LAS_PCI_MS 0
#define CA91CX42_VSI_CTL_LAS_PCI_IO (1<<0)
#define CA91CX42_VSI_CTL_LAS_PCI_CONF (1<<1)
/* LM_CTL Register
* offset F64
*/
#define CA91CX42_LM_CTL_EN (1<<31)
#define CA91CX42_LM_CTL_PGM (1<<23)
#define CA91CX42_LM_CTL_DATA (1<<22)
#define CA91CX42_LM_CTL_SUPR (1<<21)
#define CA91CX42_LM_CTL_NPRIV (1<<20)
#define CA91CX42_LM_CTL_AS_M (5<<16)
#define CA91CX42_LM_CTL_AS_A16 0
#define CA91CX42_LM_CTL_AS_A24 (1<<16)
#define CA91CX42_LM_CTL_AS_A32 (1<<17)
/*
* VRAI_CTL Register
* offset F70
*/
#define CA91CX42_BM_VRAI_CTL_EN 0x80000000
#define CA91CX42_BM_VRAI_CTL_PGM 0x00C00000
#define CA91CX42_OF_VRAI_CTL_PGM 22
#define CA91CX42_BM_VRAI_CTL_SUPER 0x00300000
#define CA91CX42_OF_VRAI_CTL_SUPER 20
#define CA91CX42_BM_VRAI_CTL_VAS 0x00030000
#define CA91CX42_OF_VRAI_CTL_VAS 16
/* VCSR_CTL Register
* offset F80
*/
#define CA91CX42_VCSR_CTL_EN (1<<31)
#define CA91CX42_VCSR_CTL_LAS_M (3<<0)
#define CA91CX42_VCSR_CTL_LAS_PCI_MS 0
#define CA91CX42_VCSR_CTL_LAS_PCI_IO (1<<0)
#define CA91CX42_VCSR_CTL_LAS_PCI_CONF (1<<1)
/* VCSR_BS Register
* offset FFC
*/
#define CA91CX42_VCSR_BS_SLOT_M (0x1F<<27)
#endif /* _CA91CX42_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1517
drivers/vme/vme.c Normal file

File diff suppressed because it is too large Load diff

396
drivers/vme/vme_api.txt Normal file
View file

@ -0,0 +1,396 @@
VME Device Driver API
=====================
Driver registration
===================
As with other subsystems within the Linux kernel, VME device drivers register
with the VME subsystem, typically called from the devices init routine. This is
achieved via a call to the following function:
int vme_register_driver (struct vme_driver *driver);
If driver registration is successful this function returns zero, if an error
occurred a negative error code will be returned.
A pointer to a structure of type 'vme_driver' must be provided to the
registration function. The structure is as follows:
struct vme_driver {
struct list_head node;
const char *name;
int (*match)(struct vme_dev *);
int (*probe)(struct vme_dev *);
int (*remove)(struct vme_dev *);
void (*shutdown)(void);
struct device_driver driver;
struct list_head devices;
unsigned int ndev;
};
At the minimum, the '.name', '.match' and '.probe' elements of this structure
should be correctly set. The '.name' element is a pointer to a string holding
the device driver's name.
The '.match' function allows controlling the number of devices that need to
be registered. The match function should return 1 if a device should be
probed and 0 otherwise. This example match function (from vme_user.c) limits
the number of devices probed to one:
#define USER_BUS_MAX 1
...
static int vme_user_match(struct vme_dev *vdev)
{
if (vdev->id.num >= USER_BUS_MAX)
return 0;
return 1;
}
The '.probe' element should contain a pointer to the probe routine. The
probe routine is passed a 'struct vme_dev' pointer as an argument. The
'struct vme_dev' structure looks like the following:
struct vme_dev {
int num;
struct vme_bridge *bridge;
struct device dev;
struct list_head drv_list;
struct list_head bridge_list;
};
Here, the 'num' field refers to the sequential device ID for this specific
driver. The bridge number (or bus number) can be accessed using
dev->bridge->num.
A function is also provided to unregister the driver from the VME core and is
usually called from the device driver's exit routine:
void vme_unregister_driver (struct vme_driver *driver);
Resource management
===================
Once a driver has registered with the VME core the provided match routine will
be called the number of times specified during the registration. If a match
succeeds, a non-zero value should be returned. A zero return value indicates
failure. For all successful matches, the probe routine of the corresponding
driver is called. The probe routine is passed a pointer to the devices
device structure. This pointer should be saved, it will be required for
requesting VME resources.
The driver can request ownership of one or more master windows, slave windows
and/or dma channels. Rather than allowing the device driver to request a
specific window or DMA channel (which may be used by a different driver) this
driver allows a resource to be assigned based on the required attributes of the
driver in question:
struct vme_resource * vme_master_request(struct vme_dev *dev,
u32 aspace, u32 cycle, u32 width);
struct vme_resource * vme_slave_request(struct vme_dev *dev, u32 aspace,
u32 cycle);
struct vme_resource *vme_dma_request(struct vme_dev *dev, u32 route);
For slave windows these attributes are split into the VME address spaces that
need to be accessed in 'aspace' and VME bus cycle types required in 'cycle'.
Master windows add a further set of attributes in 'width' specifying the
required data transfer widths. These attributes are defined as bitmasks and as
such any combination of the attributes can be requested for a single window,
the core will assign a window that meets the requirements, returning a pointer
of type vme_resource that should be used to identify the allocated resource
when it is used. For DMA controllers, the request function requires the
potential direction of any transfers to be provided in the route attributes.
This is typically VME-to-MEM and/or MEM-to-VME, though some hardware can
support VME-to-VME and MEM-to-MEM transfers as well as test pattern generation.
If an unallocated window fitting the requirements can not be found a NULL
pointer will be returned.
Functions are also provided to free window allocations once they are no longer
required. These functions should be passed the pointer to the resource provided
during resource allocation:
void vme_master_free(struct vme_resource *res);
void vme_slave_free(struct vme_resource *res);
void vme_dma_free(struct vme_resource *res);
Master windows
==============
Master windows provide access from the local processor[s] out onto the VME bus.
The number of windows available and the available access modes is dependent on
the underlying chipset. A window must be configured before it can be used.
Master window configuration
---------------------------
Once a master window has been assigned the following functions can be used to
configure it and retrieve the current settings:
int vme_master_set (struct vme_resource *res, int enabled,
unsigned long long base, unsigned long long size, u32 aspace,
u32 cycle, u32 width);
int vme_master_get (struct vme_resource *res, int *enabled,
unsigned long long *base, unsigned long long *size, u32 *aspace,
u32 *cycle, u32 *width);
The address spaces, transfer widths and cycle types are the same as described
under resource management, however some of the options are mutually exclusive.
For example, only one address space may be specified.
These functions return 0 on success or an error code should the call fail.
Master window access
--------------------
The following functions can be used to read from and write to configured master
windows. These functions return the number of bytes copied:
ssize_t vme_master_read(struct vme_resource *res, void *buf,
size_t count, loff_t offset);
ssize_t vme_master_write(struct vme_resource *res, void *buf,
size_t count, loff_t offset);
In addition to simple reads and writes, a function is provided to do a
read-modify-write transaction. This function returns the original value of the
VME bus location :
unsigned int vme_master_rmw (struct vme_resource *res,
unsigned int mask, unsigned int compare, unsigned int swap,
loff_t offset);
This functions by reading the offset, applying the mask. If the bits selected in
the mask match with the values of the corresponding bits in the compare field,
the value of swap is written the specified offset.
Slave windows
=============
Slave windows provide devices on the VME bus access into mapped portions of the
local memory. The number of windows available and the access modes that can be
used is dependent on the underlying chipset. A window must be configured before
it can be used.
Slave window configuration
--------------------------
Once a slave window has been assigned the following functions can be used to
configure it and retrieve the current settings:
int vme_slave_set (struct vme_resource *res, int enabled,
unsigned long long base, unsigned long long size,
dma_addr_t mem, u32 aspace, u32 cycle);
int vme_slave_get (struct vme_resource *res, int *enabled,
unsigned long long *base, unsigned long long *size,
dma_addr_t *mem, u32 *aspace, u32 *cycle);
The address spaces, transfer widths and cycle types are the same as described
under resource management, however some of the options are mutually exclusive.
For example, only one address space may be specified.
These functions return 0 on success or an error code should the call fail.
Slave window buffer allocation
------------------------------
Functions are provided to allow the user to allocate and free a contiguous
buffers which will be accessible by the VME bridge. These functions do not have
to be used, other methods can be used to allocate a buffer, though care must be
taken to ensure that they are contiguous and accessible by the VME bridge:
void * vme_alloc_consistent(struct vme_resource *res, size_t size,
dma_addr_t *mem);
void vme_free_consistent(struct vme_resource *res, size_t size,
void *virt, dma_addr_t mem);
Slave window access
-------------------
Slave windows map local memory onto the VME bus, the standard methods for
accessing memory should be used.
DMA channels
============
The VME DMA transfer provides the ability to run link-list DMA transfers. The
API introduces the concept of DMA lists. Each DMA list is a link-list which can
be passed to a DMA controller. Multiple lists can be created, extended,
executed, reused and destroyed.
List Management
---------------
The following functions are provided to create and destroy DMA lists. Execution
of a list will not automatically destroy the list, thus enabling a list to be
reused for repetitive tasks:
struct vme_dma_list *vme_new_dma_list(struct vme_resource *res);
int vme_dma_list_free(struct vme_dma_list *list);
List Population
---------------
An item can be added to a list using the following function ( the source and
destination attributes need to be created before calling this function, this is
covered under "Transfer Attributes"):
int vme_dma_list_add(struct vme_dma_list *list,
struct vme_dma_attr *src, struct vme_dma_attr *dest,
size_t count);
NOTE: The detailed attributes of the transfers source and destination
are not checked until an entry is added to a DMA list, the request
for a DMA channel purely checks the directions in which the
controller is expected to transfer data. As a result it is
possible for this call to return an error, for example if the
source or destination is in an unsupported VME address space.
Transfer Attributes
-------------------
The attributes for the source and destination are handled separately from adding
an item to a list. This is due to the diverse attributes required for each type
of source and destination. There are functions to create attributes for PCI, VME
and pattern sources and destinations (where appropriate):
Pattern source:
struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type);
PCI source or destination:
struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem);
VME source or destination:
struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base,
u32 aspace, u32 cycle, u32 width);
The following function should be used to free an attribute:
void vme_dma_free_attribute(struct vme_dma_attr *attr);
List Execution
--------------
The following function queues a list for execution. The function will return
once the list has been executed:
int vme_dma_list_exec(struct vme_dma_list *list);
Interrupts
==========
The VME API provides functions to attach and detach callbacks to specific VME
level and status ID combinations and for the generation of VME interrupts with
specific VME level and status IDs.
Attaching Interrupt Handlers
----------------------------
The following functions can be used to attach and free a specific VME level and
status ID combination. Any given combination can only be assigned a single
callback function. A void pointer parameter is provided, the value of which is
passed to the callback function, the use of this pointer is user undefined:
int vme_irq_request(struct vme_dev *dev, int level, int statid,
void (*callback)(int, int, void *), void *priv);
void vme_irq_free(struct vme_dev *dev, int level, int statid);
The callback parameters are as follows. Care must be taken in writing a callback
function, callback functions run in interrupt context:
void callback(int level, int statid, void *priv);
Interrupt Generation
--------------------
The following function can be used to generate a VME interrupt at a given VME
level and VME status ID:
int vme_irq_generate(struct vme_dev *dev, int level, int statid);
Location monitors
=================
The VME API provides the following functionality to configure the location
monitor.
Location Monitor Management
---------------------------
The following functions are provided to request the use of a block of location
monitors and to free them after they are no longer required:
struct vme_resource * vme_lm_request(struct vme_dev *dev);
void vme_lm_free(struct vme_resource * res);
Each block may provide a number of location monitors, monitoring adjacent
locations. The following function can be used to determine how many locations
are provided:
int vme_lm_count(struct vme_resource * res);
Location Monitor Configuration
------------------------------
Once a bank of location monitors has been allocated, the following functions
are provided to configure the location and mode of the location monitor:
int vme_lm_set(struct vme_resource *res, unsigned long long base,
u32 aspace, u32 cycle);
int vme_lm_get(struct vme_resource *res, unsigned long long *base,
u32 *aspace, u32 *cycle);
Location Monitor Use
--------------------
The following functions allow a callback to be attached and detached from each
location monitor location. Each location monitor can monitor a number of
adjacent locations:
int vme_lm_attach(struct vme_resource *res, int num,
void (*callback)(int));
int vme_lm_detach(struct vme_resource *res, int num);
The callback function is declared as follows.
void callback(int num);
Slot Detection
==============
This function returns the slot ID of the provided bridge.
int vme_slot_get(struct vme_dev *dev);

174
drivers/vme/vme_bridge.h Normal file
View file

@ -0,0 +1,174 @@
#ifndef _VME_BRIDGE_H_
#define _VME_BRIDGE_H_
#define VME_CRCSR_BUF_SIZE (508*1024)
/*
* Resource structures
*/
struct vme_master_resource {
struct list_head list;
struct vme_bridge *parent;
/*
* We are likely to need to access the VME bus in interrupt context, so
* protect master routines with a spinlock rather than a mutex.
*/
spinlock_t lock;
int locked;
int number;
u32 address_attr;
u32 cycle_attr;
u32 width_attr;
struct resource bus_resource;
void __iomem *kern_base;
};
struct vme_slave_resource {
struct list_head list;
struct vme_bridge *parent;
struct mutex mtx;
int locked;
int number;
u32 address_attr;
u32 cycle_attr;
};
struct vme_dma_pattern {
u32 pattern;
u32 type;
};
struct vme_dma_pci {
dma_addr_t address;
};
struct vme_dma_vme {
unsigned long long address;
u32 aspace;
u32 cycle;
u32 dwidth;
};
struct vme_dma_list {
struct list_head list;
struct vme_dma_resource *parent;
struct list_head entries;
struct mutex mtx;
};
struct vme_dma_resource {
struct list_head list;
struct vme_bridge *parent;
struct mutex mtx;
int locked;
int number;
struct list_head pending;
struct list_head running;
u32 route_attr;
};
struct vme_lm_resource {
struct list_head list;
struct vme_bridge *parent;
struct mutex mtx;
int locked;
int number;
int monitors;
};
struct vme_bus_error {
struct list_head list;
unsigned long long address;
u32 attributes;
};
struct vme_callback {
void (*func)(int, int, void*);
void *priv_data;
};
struct vme_irq {
int count;
struct vme_callback callback[255];
};
/* Allow 16 characters for name (including null character) */
#define VMENAMSIZ 16
/* This structure stores all the information about one bridge
* The structure should be dynamically allocated by the driver and one instance
* of the structure should be present for each VME chip present in the system.
*/
struct vme_bridge {
char name[VMENAMSIZ];
int num;
struct list_head master_resources;
struct list_head slave_resources;
struct list_head dma_resources;
struct list_head lm_resources;
struct list_head vme_errors; /* List for errors generated on VME */
struct list_head devices; /* List of devices on this bridge */
/* Bridge Info - XXX Move to private structure? */
struct device *parent; /* Parent device (eg. pdev->dev for PCI) */
void *driver_priv; /* Private pointer for the bridge driver */
struct list_head bus_list; /* list of VME buses */
/* Interrupt callbacks */
struct vme_irq irq[7];
/* Locking for VME irq callback configuration */
struct mutex irq_mtx;
/* Slave Functions */
int (*slave_get) (struct vme_slave_resource *, int *,
unsigned long long *, unsigned long long *, dma_addr_t *,
u32 *, u32 *);
int (*slave_set) (struct vme_slave_resource *, int, unsigned long long,
unsigned long long, dma_addr_t, u32, u32);
/* Master Functions */
int (*master_get) (struct vme_master_resource *, int *,
unsigned long long *, unsigned long long *, u32 *, u32 *,
u32 *);
int (*master_set) (struct vme_master_resource *, int,
unsigned long long, unsigned long long, u32, u32, u32);
ssize_t (*master_read) (struct vme_master_resource *, void *, size_t,
loff_t);
ssize_t (*master_write) (struct vme_master_resource *, void *, size_t,
loff_t);
unsigned int (*master_rmw) (struct vme_master_resource *, unsigned int,
unsigned int, unsigned int, loff_t);
/* DMA Functions */
int (*dma_list_add) (struct vme_dma_list *, struct vme_dma_attr *,
struct vme_dma_attr *, size_t);
int (*dma_list_exec) (struct vme_dma_list *);
int (*dma_list_empty) (struct vme_dma_list *);
/* Interrupt Functions */
void (*irq_set) (struct vme_bridge *, int, int, int);
int (*irq_generate) (struct vme_bridge *, int, int);
/* Location monitor functions */
int (*lm_set) (struct vme_lm_resource *, unsigned long long, u32, u32);
int (*lm_get) (struct vme_lm_resource *, unsigned long long *, u32 *,
u32 *);
int (*lm_attach) (struct vme_lm_resource *, int, void (*callback)(int));
int (*lm_detach) (struct vme_lm_resource *, int);
/* CR/CSR space functions */
int (*slot_get) (struct vme_bridge *);
/* Bridge parent interface */
void *(*alloc_consistent)(struct device *dev, size_t size,
dma_addr_t *dma);
void (*free_consistent)(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma);
};
void vme_irq_handler(struct vme_bridge *, int, int);
int vme_register_bridge(struct vme_bridge *);
void vme_unregister_bridge(struct vme_bridge *);
#endif /* _VME_BRIDGE_H_ */