File indexing completed on 2025-05-11 08:23:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #include <rtems.h>
0049 #include <inttypes.h>
0050 #include <stdio.h>
0051 #include <stdarg.h>
0052 #include <bsp/irq.h>
0053 #include <stdlib.h>
0054 #include <rtems/bspIo.h> /* printk */
0055 #include <rtems/error.h> /* printk */
0056 #include <rtems/irq.h>
0057 #include <rtems/pci.h>
0058 #include <rtems/score/sysstate.h>
0059 #include <bsp.h>
0060 #include <libcpu/byteorder.h>
0061 #include <libcpu/io.h>
0062
0063 #define __INSIDE_RTEMS_BSP__
0064 #define _VME_TSI148_DECLARE_SHOW_ROUTINES
0065
0066 #include <bsp/vmeTsi148.h>
0067 #include <bsp/VMEDMA.h>
0068 #include <bsp/vmeTsi148DMA.h>
0069 #include "bspVmeDmaListP.h"
0070
0071
0072 #define DEBUG
0073
0074 #ifdef DEBUG
0075 #define STATIC
0076 #else
0077 #define STATIC static
0078 #endif
0079
0080
0081
0082 #define TSI_NUM_WIRES 4
0083
0084 #define TSI148_NUM_OPORTS 8
0085 #define TSI148_NUM_IPORTS 8
0086
0087 #define NUM_TSI_DEVS 2
0088
0089 #define PCI_VENDOR_TUNDRA 0x10e3
0090 #define PCI_DEVICE_TSI148 0x0148
0091
0092 #define TSI_OTSAU_SPACING 0x020
0093
0094 #define TSI_OTSAU0_REG 0x100
0095 #define TSI_OTSAL0_REG 0x104
0096 #define TSI_OTEAU0_REG 0x108
0097 #define TSI_OTEAL0_REG 0x10c
0098 #define TSI_OTOFU0_REG 0x110
0099 #define TSI_OTOFL0_REG 0x114
0100 #define TSI_OTBS0_REG 0x118
0101 #define TSI_OTAT0_REG 0x11c
0102 #define TSI_OTSAU_REG(port) (TSI_OTSAU0_REG + ((port)<<5))
0103 #define TSI_OTSAL_REG(port) (TSI_OTSAL0_REG + ((port)<<5))
0104 #define TSI_OTEAU_REG(port) (TSI_OTEAU0_REG + ((port)<<5))
0105 #define TSI_OTEAL_REG(port) (TSI_OTEAL0_REG + ((port)<<5))
0106 #define TSI_OTOFU_REG(port) (TSI_OTOFU0_REG + ((port)<<5))
0107 #define TSI_OTOFL_REG(port) (TSI_OTOFL0_REG + ((port)<<5))
0108 #define TSI_OTBS_REG(port) (TSI_OTBS0_REG + ((port)<<5))
0109 #define TSI_OTAT_REG(port) (TSI_OTAT0_REG + ((port)<<5))
0110 # define TSI_OTAT_EN (1<<31)
0111 # define TSI_OTAT_MRPFD (1<<18)
0112 # define TSI_OTAT_PFS(x) (((x)&3)<<16)
0113 # define TSI_OTAT_2eSSTM(x) (((x)&7)<<11)
0114 # define TSI_OTAT_2eSSTM_160 TSI_OTAT_2eSSTM(0)
0115 # define TSI_OTAT_2eSSTM_267 TSI_OTAT_2eSSTM(1)
0116 # define TSI_OTAT_2eSSTM_320 TSI_OTAT_2eSSTM(2)
0117 # define TSI_OTAT_TM(x) (((x)&7)<<8)
0118 # define TSI_TM_SCT_IDX 0
0119 # define TSI_TM_BLT_IDX 1
0120 # define TSI_TM_MBLT_IDX 2
0121 # define TSI_TM_2eVME_IDX 3
0122 # define TSI_TM_2eSST_IDX 4
0123 # define TSI_TM_2eSSTB_IDX 5
0124 # define TSI_OTAT_DBW(x) (((x)&3)<<6)
0125 # define TSI_OTAT_SUP (1<<5)
0126 # define TSI_OTAT_PGM (1<<4)
0127 # define TSI_OTAT_ADMODE(x) (((x)&0xf))
0128 # define TSI_OTAT_ADMODE_A16 0
0129 # define TSI_OTAT_ADMODE_A24 1
0130 # define TSI_OTAT_ADMODE_A32 2
0131 # define TSI_OTAT_ADMODE_A64 4
0132 # define TSI_OTAT_ADMODE_CSR 5
0133 # define TSI_OTAT_ADMODE_USR1 8
0134 # define TSI_OTAT_ADMODE_USR2 9
0135 # define TSI_OTAT_ADMODE_USR3 0xa
0136 # define TSI_OTAT_ADMODE_USR4 0xb
0137
0138 #define TSI_VIACK_1_REG 0x204
0139
0140 #define TSI_VMCTRL_REG 0x234
0141 # define TSI_VMCTRL_VSA (1<<27)
0142 # define TSI_VMCTRL_VS (1<<26)
0143 # define TSI_VMCTRL_DHB (1<<25)
0144 # define TSI_VMCTRL_DWB (1<<24)
0145 # define TSI_VMCTRL_RMWEN (1<<20)
0146 # define TSI_VMCTRL_A64DS (1<<16)
0147 # define TSI_VMCTRL_VTOFF_MSK (7<<12)
0148 # define TSI_VMCTRL_VTOFF_0us (0<<12)
0149 # define TSI_VMCTRL_VTOFF_1us (1<<12)
0150 # define TSI_VMCTRL_VTOFF_2us (2<<12)
0151 # define TSI_VMCTRL_VTOFF_4us (3<<12)
0152 # define TSI_VMCTRL_VTOFF_8us (4<<12)
0153 # define TSI_VMCTRL_VTOFF_16us (5<<12)
0154 # define TSI_VMCTRL_VTOFF_32us (6<<12)
0155 # define TSI_VMCTRL_VTOFF_64us (7<<12)
0156 # define TSI_VMCTRL_VTON_MSK (7<< 8)
0157 # define TSI_VMCTRL_VTON_4us (0<< 8)
0158 # define TSI_VMCTRL_VTON_8us (1<< 8)
0159 # define TSI_VMCTRL_VTON_16us (2<< 8)
0160 # define TSI_VMCTRL_VTON_32us (3<< 8)
0161 # define TSI_VMCTRL_VTON_64us (4<< 8)
0162 # define TSI_VMCTRL_VTON_128us (5<< 8)
0163 # define TSI_VMCTRL_VTON_256us (6<< 8)
0164 # define TSI_VMCTRL_VTON_512us (7<< 8)
0165 # define TSI_VMCTRL_VREL_MSK (3<< 3)
0166 # define TSI_VMCTRL_VREL_TON_or_DONE (0<< 3)
0167 # define TSI_VMCTRL_VREL_TONandREQ_or_DONE (1<< 3)
0168 # define TSI_VMCTRL_VREL_TONandBCLR_or_DONE (2<< 3)
0169 # define TSI_VMCTRL_VREL_TONorDONE_and_REQ (3<< 3)
0170 # define TSI_VMCTRL_VFAIR (1<< 2)
0171 # define TSI_VMCTRL_VREQL_MSK (3<< 0)
0172 # define TSI_VMCTRL_VREQL(x) ((x)&3)
0173
0174 #define TSI_VCTRL_REG 0x238
0175 #define TSI_VCTRL_DLT_MSK (0xf<<24)
0176 #define TSI_VCTRL_NELBB (1<<20)
0177 #define TSI_VCTRL_SRESET (1<<17)
0178 #define TSI_VCTRL_LRESET (1<<16)
0179 #define TSI_VCTRL_SFAILAI (1<<15)
0180 #define TSI_VCTRL_BID_MSK (0x1f<<8)
0181 #define TSI_VCTRL_ATOEN (1<< 7)
0182 #define TSI_VCTRL_ROBIN (1<< 6)
0183 #define TSI_VCTRL_GTO_MSK (7<< 0)
0184
0185
0186 #define TSI_VSTAT_REG 0x23c
0187 # define TSI_VSTAT_CPURST (1<<15)
0188 # define TSI_VSTAT_BDFAIL (1<<14)
0189 # define TSI_VSTAT_PURSTS (1<<12)
0190 # define TSI_VSTAT_BDFAILS (1<<11)
0191 # define TSI_VSTAT_SYSFLS (1<<10)
0192 # define TSI_VSTAT_ACFAILS (1<< 9)
0193 # define TSI_VSTAT_SCONS (1<< 8)
0194 # define TSI_VSTAT_GAP (1<< 5)
0195 # define TSI_VSTAT_GA_MSK (0x1f)
0196
0197 #define TSI_VEAU_REG 0x260
0198 #define TSI_VEAL_REG 0x264
0199 #define TSI_VEAT_REG 0x268
0200
0201 #define TSI_ITSAU_SPACING 0x020
0202
0203 #define TSI_ITSAU0_REG 0x300
0204 #define TSI_ITSAL0_REG 0x304
0205 #define TSI_ITEAU0_REG 0x308
0206 #define TSI_ITEAL0_REG 0x30c
0207 #define TSI_ITOFU0_REG 0x310
0208 #define TSI_ITOFL0_REG 0x314
0209 #define TSI_ITAT0_REG 0x318
0210 #define TSI_ITSAU_REG(port) (TSI_ITSAU0_REG + ((port)<<5))
0211 #define TSI_ITSAL_REG(port) (TSI_ITSAL0_REG + ((port)<<5))
0212 #define TSI_ITEAU_REG(port) (TSI_ITEAU0_REG + ((port)<<5))
0213 #define TSI_ITEAL_REG(port) (TSI_ITEAL0_REG + ((port)<<5))
0214 #define TSI_ITOFU_REG(port) (TSI_ITOFU0_REG + ((port)<<5))
0215 #define TSI_ITOFL_REG(port) (TSI_ITOFL0_REG + ((port)<<5))
0216 #define TSI_ITAT_REG(port) (TSI_ITAT0_REG + ((port)<<5))
0217
0218 # define TSI_ITAT_EN (1<<31)
0219 # define TSI_ITAT_TH (1<<18)
0220 # define TSI_ITAT_VFS(x) (((x)&3)<<16)
0221 # define TSI_ITAT_2eSSTM(x) (((x)&7)<<12)
0222 # define TSI_ITAT_2eSSTM_160 TSI_ITAT_2eSSTM(0)
0223 # define TSI_ITAT_2eSSTM_267 TSI_ITAT_2eSSTM(1)
0224 # define TSI_ITAT_2eSSTM_320 TSI_ITAT_2eSSTM(2)
0225 # define TSI_ITAT_2eSSTB (1<<11)
0226 # define TSI_ITAT_2eSST (1<<10)
0227 # define TSI_ITAT_2eVME (1<<9)
0228 # define TSI_ITAT_MBLT (1<<8)
0229 # define TSI_ITAT_BLT (1<<7)
0230 # define TSI_ITAT_AS(x) (((x)&7)<<4)
0231 # define TSI_ITAT_ADMODE_A16 (0<<4)
0232 # define TSI_ITAT_ADMODE_A24 (1<<4)
0233 # define TSI_ITAT_ADMODE_A32 (2<<4)
0234 # define TSI_ITAT_ADMODE_A64 (4<<4)
0235 # define TSI_ITAT_SUP (1<<3)
0236 # define TSI_ITAT_USR (1<<2)
0237 # define TSI_ITAT_PGM (1<<1)
0238 # define TSI_ITAT_DATA (1<<0)
0239
0240 #define TSI_CBAU_REG 0x40c
0241 #define TSI_CBAL_REG 0x410
0242 #define TSI_CRGAT_REG 0x414
0243 # define TSI_CRGAT_EN (1<<7)
0244 # define TSI_CRGAT_AS_MSK (7<<4)
0245 # define TSI_CRGAT_A16 (0<<4)
0246 # define TSI_CRGAT_A24 (1<<4)
0247 # define TSI_CRGAT_A32 (2<<4)
0248 # define TSI_CRGAT_A64 (4<<4)
0249 # define TSI_CRGAT_SUP (1<<3)
0250 # define TSI_CRGAT_USR (1<<2)
0251 # define TSI_CRGAT_PGM (1<<1)
0252 # define TSI_CRGAT_DATA (1<<0)
0253
0254 #define TSI_VICR_REG 0x440
0255 # define TSI_VICR_CNTS(v) (((v)&3)<<30)
0256 # define TSI_VICR_CNTS_DIS (0<<30)
0257 # define TSI_VICR_CNTS_IRQ1 (1<<30)
0258 # define TSI_VICR_CNTS_IRQ2 (2<<30)
0259 # define TSI_VICR_EDGIS(v) (((v)&3)<<28)
0260 # define TSI_VICR_EDGIS_DIS (0<<28)
0261 # define TSI_VICR_EDGIS_IRQ1 (1<<28)
0262 # define TSI_VICR_EDGIS_IRQ2 (2<<28)
0263 # define TSI_VICR_IRQ1F(v) (((v)&3)<<26)
0264 # define TSI_VICR_IRQ1F_NORML (0<<26)
0265 # define TSI_VICR_IRQ1F_PULSE (1<<26)
0266 # define TSI_VICR_IRQ1F_CLOCK (2<<26)
0267 # define TSI_VICR_IRQ1F_1MHZ (3<<26)
0268 # define TSI_VICR_IRQ2F(v) (((v)&3)<<24)
0269 # define TSI_VICR_IRQ2F_NORML (0<<24)
0270 # define TSI_VICR_IRQ2F_PULSE (1<<24)
0271 # define TSI_VICR_IRQ2F_CLOCK (2<<24)
0272 # define TSI_VICR_IRQ2F_1MHZ (3<<24)
0273 # define TSI_VICR_BIP (1<<23)
0274 # define TSI_VICR_BIPS (1<<22)
0275 # define TSI_VICR_IRQC (1<<15)
0276 # define TSI_VICR_IRQLS(v) (((v)&7)<<12)
0277 # define TSI_VICR_IRQS (1<<11)
0278 # define TSI_VICR_IRQL(v) (((v)&7)<<8)
0279 # define TSI_VICR_STID(v) ((v)&0xff)
0280 #define TSI_INTEN_REG 0x448
0281 #define TSI_INTEO_REG 0x44c
0282 #define TSI_INTS_REG 0x450
0283 # define TSI_INTS_IRQ1S (1<<1)
0284 # define TSI_INTS_IRQ2S (1<<2)
0285 # define TSI_INTS_IRQ3S (1<<3)
0286 # define TSI_INTS_IRQ4S (1<<4)
0287 # define TSI_INTS_IRQ5S (1<<5)
0288 # define TSI_INTS_IRQ6S (1<<6)
0289 # define TSI_INTS_IRQ7S (1<<7)
0290 # define TSI_INTS_ACFLS (1<<8)
0291 # define TSI_INTS_SYSFLS (1<<9)
0292 # define TSI_INTS_IACKS (1<<10)
0293 # define TSI_INTS_VIES (1<<11)
0294 # define TSI_INTS_VERRS (1<<12)
0295 # define TSI_INTS_PERRS (1<<13)
0296 # define TSI_INTS_MB0S (1<<16)
0297 # define TSI_INTS_MB1S (1<<17)
0298 # define TSI_INTS_MB2S (1<<18)
0299 # define TSI_INTS_MB3S (1<<19)
0300 # define TSI_INTS_LM0S (1<<20)
0301 # define TSI_INTS_LM1S (1<<21)
0302 # define TSI_INTS_LM2S (1<<22)
0303 # define TSI_INTS_LM3S (1<<23)
0304 # define TSI_INTS_DMA0S (1<<24)
0305 # define TSI_INTS_DMA1S (1<<25)
0306 #define TSI_INTC_REG 0x454
0307 # define TSI_INTC_ACFLC (1<<8)
0308 # define TSI_INTC_SYSFLC (1<<9)
0309 # define TSI_INTC_IACKC (1<<10)
0310 # define TSI_INTC_VIEC (1<<11)
0311 # define TSI_INTC_VERRC (1<<12)
0312 # define TSI_INTC_PERRC (1<<13)
0313 # define TSI_INTC_MB0C (1<<16)
0314 # define TSI_INTC_MB1C (1<<17)
0315 # define TSI_INTC_MB2C (1<<18)
0316 # define TSI_INTC_MB3C (1<<19)
0317 # define TSI_INTC_LM0C (1<<20)
0318 # define TSI_INTC_LM1C (1<<21)
0319 # define TSI_INTC_LM2C (1<<22)
0320 # define TSI_INTC_LM3C (1<<23)
0321 # define TSI_INTC_DMA0C (1<<24)
0322 # define TSI_INTC_DMA1C (1<<25)
0323 #define TSI_INTM1_REG 0x458
0324 #define TSI_INTM2_REG 0x45c
0325
0326 #define TSI_CBAR_REG 0xffc
0327
0328 #define TSI_CSR_OFFSET 0x7f000
0329
0330 #define TSI_CRG_SIZE (1<<12)
0331
0332
0333 #define TSI_RD(base, reg) in_be32((volatile uint32_t *)((base) + (reg)/sizeof(*base)))
0334 #define TSI_RD16(base, reg) in_be16((volatile uint16_t *)(base) + (reg)/sizeof(uint16_t))
0335 #define TSI_LE_RD16(base, reg) in_le16((volatile uint16_t *)(base) + (reg)/sizeof(uint16_t))
0336 #define TSI_LE_RD32(base, reg) in_le32((volatile uint32_t *)(base) + (reg)/sizeof(*base))
0337 #define TSI_RD8(base, reg) in_8((volatile uint8_t *)(base) + (reg))
0338 #define TSI_WR(base, reg, val) out_be32((volatile uint32_t *)((base) + (reg)/sizeof(*base)), val)
0339
0340 #define UNIV_SCTL_AM_MASK (UNIV_CTL_VAS | UNIV_SCTL_PGM | UNIV_SCTL_DAT | UNIV_SCTL_USER | UNIV_SCTL_SUPER)
0341
0342
0343
0344 #ifndef BSP_PCI_FIND_DEVICE
0345 #define BSP_PCI_FIND_DEVICE pci_find_device
0346 #endif
0347 #ifndef BSP_PCI_CONFIG_IN_LONG
0348 #define BSP_PCI_CONFIG_IN_LONG pci_read_config_dword
0349 #endif
0350 #ifndef BSP_PCI_CONFIG_IN_SHORT
0351 #define BSP_PCI_CONFIG_IN_SHORT pci_read_config_word
0352 #endif
0353 #ifndef BSP_PCI_CONFIG_OUT_SHORT
0354 #define BSP_PCI_CONFIG_OUT_SHORT pci_write_config_word
0355 #endif
0356 #ifndef BSP_PCI_CONFIG_IN_BYTE
0357 #define BSP_PCI_CONFIG_IN_BYTE pci_read_config_byte
0358 #endif
0359
0360 typedef uint32_t pci_ulong;
0361
0362 #ifdef __BIG_ENDIAN__
0363 static inline void st_be32( uint32_t *a, uint32_t v)
0364 {
0365 *a = v;
0366 }
0367 static inline uint32_t ld_be32( uint32_t *a )
0368 {
0369 return *a;
0370 }
0371 #elif defined(__LITTLE_ENDIAN__)
0372 #error "You need to implement st_be32/ld_be32"
0373 #else
0374 #error "Undefined endianness??"
0375 #endif
0376
0377 #ifndef BSP_LOCAL2PCI_ADDR
0378
0379 #ifndef PCI_DRAM_OFFSET
0380 #define PCI_DRAM_OFFSET 0
0381 #endif
0382 #define BSP_LOCAL2PCI_ADDR(l) (((uint32_t)l)+PCI_DRAM_OFFSET)
0383 #endif
0384
0385
0386
0387
0388 #ifndef BSP_PCI2LOCAL_ADDR
0389 #ifndef PCI_MEM_BASE
0390 #define PCI_MEM_BASE 0
0391 #endif
0392 #define BSP_PCI2LOCAL_ADDR(memaddr) ((unsigned long)(memaddr) + PCI_MEM_BASE)
0393 #endif
0394
0395 typedef uint32_t BEValue;
0396
0397 typedef struct {
0398 BERegister *base;
0399 int irqLine;
0400 int pic_pin[TSI_NUM_WIRES];
0401 } Tsi148Dev;
0402
0403 static Tsi148Dev devs[NUM_TSI_DEVS] = {{0}};
0404
0405 #define THEBASE (devs[0].base)
0406
0407
0408 extern int vmeTsi148RegPort;
0409 extern int vmeTsi148RegCSR;
0410
0411
0412
0413
0414
0415
0416
0417 static void
0418 uprintf(FILE *f, char *fmt, ...)
0419 {
0420 va_list ap;
0421 va_start(ap, fmt);
0422 if (!f || !_System_state_Is_up(_System_state_Get())) {
0423
0424
0425
0426 vprintk(fmt,ap);
0427 } else
0428 {
0429 vfprintf(f,fmt,ap);
0430 }
0431 va_end(ap);
0432 }
0433
0434 #define CHECK_BASE(base,quiet,rval) \
0435 do { \
0436 if ( !base ) { \
0437 if ( !quiet ) { \
0438 uprintf(stderr,"Tsi148: Driver not initialized\n"); \
0439 } \
0440 return rval; \
0441 } \
0442 } while (0)
0443
0444 int
0445 vmeTsi148FindPciBase(
0446 int instance,
0447 BERegister **pbase
0448 )
0449 {
0450 int bus,dev,fun;
0451 pci_ulong busaddr;
0452 unsigned char irqline;
0453 unsigned short wrd;
0454
0455 if (BSP_PCI_FIND_DEVICE(
0456 PCI_VENDOR_TUNDRA,
0457 PCI_DEVICE_TSI148,
0458 instance,
0459 &bus,
0460 &dev,
0461 &fun))
0462 return -1;
0463 if (BSP_PCI_CONFIG_IN_LONG(bus,dev,fun,PCI_BASE_ADDRESS_0,&busaddr))
0464 return -1;
0465
0466
0467 *pbase=(BERegister*)(((pci_ulong)BSP_PCI2LOCAL_ADDR(busaddr)) & ~0xff);
0468
0469 if (BSP_PCI_CONFIG_IN_BYTE(bus,dev,fun,PCI_INTERRUPT_LINE,&irqline))
0470 return -1;
0471
0472
0473 BSP_PCI_CONFIG_IN_SHORT(bus, dev, fun, PCI_COMMAND, &wrd);
0474 BSP_PCI_CONFIG_OUT_SHORT(bus, dev, fun, PCI_COMMAND, wrd | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
0475
0476 return irqline;
0477 }
0478
0479 int
0480 vmeTsi148InitInstance(unsigned instance)
0481 {
0482 int irq;
0483 BERegister *base;
0484
0485 if ( instance >= NUM_TSI_DEVS )
0486 return -1;
0487 if ( devs[instance].base )
0488 return -1;
0489
0490 if ((irq=vmeTsi148FindPciBase(instance,&base)) < 0) {
0491 uprintf(stderr,"unable to find a Tsi148 in pci config space\n");
0492 } else {
0493 uprintf(stderr,"Tundra Tsi148 PCI-VME bridge detected at 0x%08x, IRQ %d\n",
0494 (unsigned int)base, irq);
0495 }
0496 devs[0].base = base;
0497 devs[0].irqLine = irq;
0498
0499 return irq < 0 ? -1 : 0;
0500 }
0501
0502 int
0503 vmeTsi148Init(void)
0504 {
0505 return vmeTsi148InitInstance(0);
0506 }
0507
0508
0509 void
0510 vmeTsi148ResetXX(BERegister *base)
0511 {
0512 int port;
0513 uint32_t v;
0514
0515 CHECK_BASE(base,0, );
0516
0517 vmeTsi148DisableAllOutboundPortsXX(base);
0518 for ( port=0; port < TSI148_NUM_OPORTS; port++ )
0519 TSI_WR(base, TSI_OTBS_REG(port), 0);
0520 TSI_WR(base, TSI_INTEO_REG, 0);
0521 TSI_WR(base, TSI_INTEN_REG, 0);
0522 TSI_WR(base, TSI_INTC_REG, 0xffffffff);
0523 TSI_WR(base, TSI_INTM1_REG, 0);
0524 TSI_WR(base, TSI_INTM2_REG, 0);
0525 TSI_WR(base, TSI_VICR_REG, 0);
0526 TSI_WR(base, TSI_VEAT_REG, TSI_VEAT_VESCL);
0527
0528 # define TSI_VSTAT_BDFAIL (1<<14)
0529 TSI_WR(base, TSI_VSTAT_REG, TSI_RD(base, TSI_VSTAT_REG) & ~TSI_VSTAT_BDFAIL);
0530
0531
0532
0533
0534
0535
0536 v = TSI_RD(base, TSI_VMCTRL_REG);
0537 v &= ~( TSI_VMCTRL_VTON_MSK | TSI_VMCTRL_VREL_MSK );
0538 v |= (TSI_VMCTRL_VTON_512us | TSI_VMCTRL_VREL_TONorDONE_and_REQ );
0539 TSI_WR(base, TSI_VMCTRL_REG, v);
0540 }
0541
0542 void
0543 vmeTsi148Reset(void)
0544 {
0545 vmeTsi148ResetXX(THEBASE);
0546 }
0547
0548 RTEMS_INTERRUPT_LOCK_DEFINE( static, vmeTsi148_lock, "vmeTsi148_lock" )
0549 void
0550 vmeTsi148ResetBusXX(BERegister *base)
0551 {
0552 uint32_t v;
0553 rtems_interrupt_lock_context lock_context;
0554
0555 rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
0556 v = TSI_RD(base, TSI_VCTRL_REG);
0557 TSI_WR(base, TSI_VCTRL_REG, v | TSI_VCTRL_SRESET);
0558 rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
0559 }
0560
0561 void
0562 vmeTsi148ResetBus(void)
0563 {
0564 vmeTsi148ResetBusXX(THEBASE);
0565 }
0566
0567
0568
0569
0570
0571
0572 static unsigned long ck2esst(unsigned long am)
0573 {
0574 if ( VME_AM_IS_2eSST(am) ) {
0575
0576 am &= ~VME_AM_MASK;
0577 am |= VME_AM_2eVME_6U;
0578 }
0579 return am;
0580 }
0581
0582 static int
0583 am2omode(unsigned long address_space, unsigned long *pmode)
0584 {
0585 unsigned long mode = 0;
0586 unsigned long tm = TSI_TM_SCT_IDX;
0587
0588 switch ( VME_MODE_DBW_MSK & address_space ) {
0589 case VME_MODE_DBW8:
0590 return -1;
0591
0592 case VME_MODE_DBW16:
0593 break;
0594
0595 default:
0596 case VME_MODE_DBW32:
0597 mode |= TSI_OTAT_DBW(1);
0598 break;
0599 }
0600
0601 if ( ! (VME_MODE_PREFETCH_ENABLE & address_space) )
0602 mode |= TSI_OTAT_MRPFD;
0603 else {
0604 mode |= TSI_OTAT_PFS(address_space>>_LD_VME_MODE_PREFETCHSZ);
0605 }
0606
0607 address_space = ck2esst(address_space);
0608
0609 switch (address_space & VME_AM_MASK) {
0610 case VME_AM_STD_SUP_PGM:
0611 case VME_AM_STD_USR_PGM:
0612
0613 mode |= TSI_OTAT_PGM;
0614
0615
0616 case VME_AM_STD_SUP_BLT:
0617 case VME_AM_STD_SUP_MBLT:
0618
0619 case VME_AM_STD_USR_BLT:
0620 case VME_AM_STD_USR_MBLT:
0621 switch ( address_space & 3 ) {
0622 case 0: tm = TSI_TM_MBLT_IDX; break;
0623 case 3: tm = TSI_TM_BLT_IDX; break;
0624 default: break;
0625 }
0626
0627 case VME_AM_STD_SUP_DATA:
0628 case VME_AM_STD_USR_DATA:
0629
0630 mode |= TSI_OTAT_ADMODE_A24;
0631 break;
0632
0633 case VME_AM_EXT_SUP_PGM:
0634 case VME_AM_EXT_USR_PGM:
0635 mode |= TSI_OTAT_PGM;
0636
0637
0638 case VME_AM_EXT_SUP_BLT:
0639 case VME_AM_EXT_SUP_MBLT:
0640
0641 case VME_AM_EXT_USR_BLT:
0642 case VME_AM_EXT_USR_MBLT:
0643 switch ( address_space & 3 ) {
0644 case 0: tm = TSI_TM_MBLT_IDX; break;
0645 case 3: tm = TSI_TM_BLT_IDX; break;
0646 default: break;
0647 }
0648
0649 case VME_AM_EXT_SUP_DATA:
0650 case VME_AM_EXT_USR_DATA:
0651
0652 mode |= TSI_OTAT_ADMODE_A32;
0653 break;
0654
0655 case VME_AM_SUP_SHORT_IO:
0656 case VME_AM_USR_SHORT_IO:
0657 mode |= TSI_OTAT_ADMODE_A16;
0658 break;
0659
0660 case VME_AM_CSR:
0661 mode |= TSI_OTAT_ADMODE_CSR;
0662 break;
0663
0664 case VME_AM_2eVME_6U:
0665 case VME_AM_2eVME_3U:
0666 mode |= TSI_OTAT_ADMODE_A32;
0667 if ( VME_AM_IS_2eSST(address_space) ) {
0668 tm = ( VME_AM_2eSST_BCST & address_space ) ?
0669 TSI_TM_2eSSTB_IDX : TSI_TM_2eSST_IDX;
0670 switch ( VME_AM_IS_2eSST(address_space) ) {
0671 default:
0672 case VME_AM_2eSST_LO: mode |= TSI_OTAT_2eSSTM_160; break;
0673 case VME_AM_2eSST_MID: mode |= TSI_OTAT_2eSSTM_267; break;
0674 case VME_AM_2eSST_HI: mode |= TSI_OTAT_2eSSTM_320; break;
0675 }
0676 } else {
0677 tm = TSI_TM_2eVME_IDX;
0678 }
0679 break;
0680
0681 case 0:
0682 break;
0683
0684 default:
0685 return -1;
0686 }
0687
0688 mode |= TSI_OTAT_TM(tm);
0689
0690 if ( VME_AM_IS_SUP(address_space) )
0691 mode |= TSI_OTAT_SUP;
0692 *pmode = mode;
0693 return 0;
0694 }
0695
0696 static int
0697 am2imode(unsigned long address_space, unsigned long *pmode)
0698 {
0699 unsigned long mode=0;
0700 unsigned long pgm = 0;
0701
0702 mode |= TSI_ITAT_VFS(address_space>>_LD_VME_MODE_PREFETCHSZ);
0703
0704 if ( VME_AM_IS_2eSST(address_space) ) {
0705 mode |= TSI_ITAT_2eSST;
0706 if ( VME_AM_2eSST_BCST & address_space )
0707 mode |= TSI_ITAT_2eSSTB;
0708 switch ( VME_AM_IS_2eSST(address_space) ) {
0709 default:
0710 case VME_AM_2eSST_LO: mode |= TSI_ITAT_2eSSTM_160; break;
0711 case VME_AM_2eSST_MID: mode |= TSI_ITAT_2eSSTM_267; break;
0712 case VME_AM_2eSST_HI: mode |= TSI_ITAT_2eSSTM_320; break;
0713 }
0714 address_space = ck2esst(address_space);
0715 }
0716
0717 mode |= TSI_ITAT_BLT;
0718 mode |= TSI_ITAT_MBLT;
0719
0720 mode |= TSI_ITAT_PGM;
0721 mode |= TSI_ITAT_USR;
0722
0723 switch (address_space & VME_AM_MASK) {
0724 case VME_AM_STD_SUP_PGM:
0725 case VME_AM_STD_USR_PGM:
0726
0727 pgm = 1;
0728
0729
0730 case VME_AM_STD_SUP_BLT:
0731 case VME_AM_STD_SUP_MBLT:
0732 case VME_AM_STD_USR_BLT:
0733 case VME_AM_STD_USR_MBLT:
0734 case VME_AM_STD_SUP_DATA:
0735 case VME_AM_STD_USR_DATA:
0736
0737 mode |= TSI_ITAT_ADMODE_A24;
0738 break;
0739
0740 case VME_AM_EXT_SUP_PGM:
0741 case VME_AM_EXT_USR_PGM:
0742 pgm = 1;
0743
0744
0745 case VME_AM_2eVME_6U:
0746 case VME_AM_2eVME_3U:
0747 case VME_AM_EXT_SUP_BLT:
0748 case VME_AM_EXT_SUP_MBLT:
0749 case VME_AM_EXT_USR_BLT:
0750 case VME_AM_EXT_USR_MBLT:
0751 case VME_AM_EXT_SUP_DATA:
0752 case VME_AM_EXT_USR_DATA:
0753 mode |= TSI_ITAT_ADMODE_A32;
0754 break;
0755
0756 case VME_AM_SUP_SHORT_IO:
0757 case VME_AM_USR_SHORT_IO:
0758 mode |= TSI_ITAT_ADMODE_A16;
0759 break;
0760
0761 case 0:
0762 *pmode = 0;
0763 return 0;
0764
0765 default:
0766 return -1;
0767 }
0768
0769 if ( VME_AM_IS_SUP(address_space) )
0770 mode |= TSI_ITAT_SUP;
0771
0772 if ( !pgm )
0773 mode |= TSI_ITAT_DATA;
0774
0775 *pmode = mode;
0776 return 0;
0777 }
0778
0779 static void
0780 readTriple(
0781 BERegister *base,
0782 unsigned reg,
0783 unsigned long long *ps,
0784 unsigned long long *pl,
0785 unsigned long long *po)
0786 {
0787 *ps = TSI_RD(base, reg);
0788 *ps = (*ps<<32) | (TSI_RD(base, (reg+4)) & 0xffff0000);
0789 *pl = TSI_RD(base, (reg+8));
0790 *pl = (*pl<<32) | (TSI_RD(base, (reg+0xc)) & 0xffff0000);
0791 *po = TSI_RD(base, (reg+0x10));
0792 *po = (*po<<32) | (TSI_RD(base, (reg+0x14)) & 0xffff0000);
0793 }
0794
0795
0796 static unsigned long
0797 inboundGranularity(unsigned long itat)
0798 {
0799 switch ( itat & TSI_ITAT_AS(-1) ) {
0800 case TSI_ITAT_ADMODE_A16: return 0xf;
0801 case TSI_ITAT_ADMODE_A24: return 0xfff;
0802 default:
0803 break;
0804 }
0805 return 0xffff;
0806 }
0807
0808 static int
0809 configTsiPort(
0810 BERegister *base,
0811 int isout,
0812 unsigned long port,
0813 unsigned long address_space,
0814 unsigned long vme_address,
0815 unsigned long pci_address,
0816 unsigned long length)
0817 {
0818 unsigned long long start, limit, offst;
0819 unsigned long mode, mask, tat_reg, tsau_reg;
0820 char *name = (isout ? "Outbound" : "Inbound");
0821 int i,s,l;
0822
0823 CHECK_BASE(base,0,-1);
0824
0825 mode = 0;
0826
0827 if ( port >= (isout ? TSI148_NUM_OPORTS : TSI148_NUM_IPORTS) ) {
0828 uprintf(stderr,"Tsi148 %s Port Cfg: invalid port\n", name);
0829 return -1;
0830 }
0831
0832 if ( base == THEBASE && isout && vmeTsi148RegPort == port ) {
0833 uprintf(stderr,"Tsi148 %s Port Cfg: invalid port; reserved by the interrupt manager for CRG\n", name);
0834 return -1;
0835 }
0836
0837 if ( length && (isout ? am2omode(address_space, &mode) : am2imode(address_space, &mode)) ) {
0838 uprintf(stderr,"Tsi148 %s Port Cfg: invalid address space / mode flags\n",name);
0839 return -1;
0840 }
0841
0842
0843 if ( isout ) {
0844 start = pci_address;
0845 offst = (unsigned long long)vme_address - start;
0846 mask = 0xffff;
0847 tat_reg = TSI_OTAT_REG(port);
0848 tsau_reg = TSI_OTSAU_REG(port);
0849 mode |= TSI_OTAT_EN;
0850
0851
0852 for ( i = 0; i < TSI148_NUM_OPORTS; i++ ) {
0853
0854 if ( i == port || ! (TSI_OTAT_EN & TSI_RD(base, TSI_OTAT_REG(i))) )
0855 continue;
0856
0857
0858 s = TSI_RD(base, TSI_OTSAU_REG(i) + 0x04);
0859 l = TSI_RD(base, TSI_OTSAU_REG(i) + 0x0c);
0860 if ( ! ( start + length <= s || start > s + l ) ) {
0861 uprintf(stderr,"Tsi148 Outbound Port Cfg: PCI address range overlaps with port %i (0x%08x..0x%08x)\n", i, s, l);
0862 return -1;
0863 }
0864 }
0865 } else {
0866 start = vme_address;
0867 offst = (unsigned long long)pci_address - start;
0868 mask = inboundGranularity(mode);
0869 tat_reg = TSI_ITAT_REG(port);
0870 tsau_reg = TSI_ITSAU_REG(port);
0871 mode |= TSI_ITAT_EN;
0872
0873
0874 for ( i = 0; i < TSI148_NUM_IPORTS; i++ ) {
0875
0876 if ( i == port || ! (TSI_ITAT_EN & (s=TSI_RD(base, TSI_ITAT_REG(i)))) )
0877 continue;
0878
0879 if ( (TSI_ITAT_AS(-1) & s) != (TSI_ITAT_AS(-1) & mode) ) {
0880
0881 continue;
0882 }
0883
0884 if ( ! (mode & s & (TSI_ITAT_SUP | TSI_ITAT_USR | TSI_ITAT_PGM | TSI_ITAT_DATA)) ) {
0885
0886 continue;
0887 }
0888
0889
0890 s = TSI_RD(base, TSI_ITSAU_REG(i) + 0x04);
0891 l = TSI_RD(base, TSI_ITSAU_REG(i) + 0x0c);
0892 if ( ! ( start + length <= s || start > s + l ) ) {
0893 uprintf(stderr,"Tsi148 Inbound Port Cfg: VME address range overlaps with port %i (0x%08x..0x%08x)\n", i, s, l);
0894 return -1;
0895 }
0896 }
0897 }
0898
0899
0900 if ( 0 == length ) {
0901 TSI_WR(base, tat_reg, TSI_RD(base, tat_reg) & ~(isout ? TSI_OTAT_EN : TSI_ITAT_EN));
0902 return 0;
0903 }
0904
0905
0906 if ( (vme_address & mask)
0907 || (pci_address & mask)
0908 || (length & mask) ) {
0909 uprintf(stderr,"Tsi148 %s Port Cfg: invalid address/length; must be multiple of 0x%x\n",
0910 name,
0911 mask+1);
0912 return -1;
0913 }
0914
0915 limit = start + length - 1;
0916
0917 if ( limit >= (unsigned long long)1<<32 ) {
0918 uprintf(stderr,"Tsi148 %s Port Cfg: invalid address/length; must be < 1<<32\n", name);
0919 return -1;
0920 }
0921
0922
0923 TSI_WR(base, tat_reg, 0);
0924
0925
0926 TSI_WR(base, tsau_reg , 0);
0927 TSI_WR(base, tsau_reg + 0x04, (uint32_t)start);
0928 TSI_WR(base, tsau_reg + 0x08, 0);
0929 TSI_WR(base, tsau_reg + 0x0c, (uint32_t)limit);
0930 TSI_WR(base, tsau_reg + 0x10, (uint32_t)(offst>>32));
0931 TSI_WR(base, tsau_reg + 0x14, (uint32_t)offst);
0932
0933
0934
0935
0936 TSI_WR(base, tat_reg, mode);
0937 return 0;
0938 }
0939
0940 static int
0941 disableTsiPort(
0942 BERegister *base,
0943 int isout,
0944 unsigned long port)
0945 {
0946 return configTsiPort(base, isout, port, 0, 0, 0, 0);
0947 }
0948
0949 int
0950 vmeTsi148InboundPortCfgXX(
0951 BERegister *base,
0952 unsigned long port,
0953 unsigned long address_space,
0954 unsigned long vme_address,
0955 unsigned long pci_address,
0956 unsigned long length)
0957 {
0958 return configTsiPort(base, 0, port, address_space, vme_address, pci_address, length);
0959 }
0960
0961 int
0962 vmeTsi148InboundPortCfg(
0963 unsigned long port,
0964 unsigned long address_space,
0965 unsigned long vme_address,
0966 unsigned long pci_address,
0967 unsigned long length)
0968 {
0969 return configTsiPort(THEBASE, 0, port, address_space, vme_address, pci_address, length);
0970 }
0971
0972
0973 int
0974 vmeTsi148OutboundPortCfgXX(
0975 BERegister *base,
0976 unsigned long port,
0977 unsigned long address_space,
0978 unsigned long vme_address,
0979 unsigned long pci_address,
0980 unsigned long length)
0981 {
0982 return configTsiPort(base, 1, port, address_space, vme_address, pci_address, length);
0983 }
0984
0985 int
0986 vmeTsi148OutboundPortCfg(
0987 unsigned long port,
0988 unsigned long address_space,
0989 unsigned long vme_address,
0990 unsigned long pci_address,
0991 unsigned long length)
0992 {
0993 return configTsiPort(THEBASE, 1, port, address_space, vme_address, pci_address, length);
0994 }
0995
0996
0997 static int
0998 xlateFindPort(
0999 BERegister *base,
1000 int outbound,
1001 int reverse,
1002 unsigned long as,
1003 unsigned long aIn,
1004 unsigned long *paOut
1005 )
1006 {
1007 unsigned long mode, mode_msk;
1008 int port;
1009 unsigned long long start, limit, offst, a;
1010 unsigned long tsau_reg, tat_reg, gran, skip;
1011
1012 CHECK_BASE(base,0,-1);
1013
1014 mode = 0;
1015
1016 switch ( as & VME_MODE_MATCH_MASK ) {
1017 case VME_MODE_EXACT_MATCH:
1018 mode_msk = ~0;
1019 break;
1020
1021 case VME_MODE_AS_MATCH:
1022 if ( outbound )
1023 mode_msk = TSI_OTAT_ADMODE(-1) | TSI_OTAT_EN;
1024 else
1025 mode_msk = TSI_ITAT_AS(-1) | TSI_ITAT_EN;
1026 break;
1027
1028 default:
1029 if ( outbound )
1030 mode_msk = TSI_OTAT_PGM | TSI_OTAT_SUP | TSI_OTAT_ADMODE(-1) | TSI_OTAT_EN;
1031 else
1032 mode_msk = TSI_ITAT_PGM | TSI_ITAT_DATA | TSI_ITAT_SUP | TSI_ITAT_USR | TSI_ITAT_AS(-1) | TSI_ITAT_EN;
1033 break;
1034 }
1035
1036 as &= ~VME_MODE_MATCH_MASK;
1037
1038 if ( outbound ? am2omode(as,&mode) : am2imode(as,&mode) ) {
1039 uprintf(stderr, "vmeTsi148XlateAddr: invalid address space/mode argument");
1040 return -2;
1041 }
1042
1043 if (outbound ) {
1044 tsau_reg = TSI_OTSAU_REG(0);
1045 tat_reg = TSI_OTAT_REG(0);
1046 skip = TSI_OTSAU_SPACING;
1047 mode |= TSI_OTAT_EN;
1048 gran = 0x10000;
1049 } else {
1050 tsau_reg = TSI_ITSAU_REG(0);
1051 tat_reg = TSI_ITAT_REG(0);
1052 skip = TSI_ITSAU_SPACING;
1053 mode |= TSI_ITAT_EN;
1054 gran = inboundGranularity(mode) + 1;
1055 }
1056
1057 for ( port = 0; port < TSI148_NUM_OPORTS; port++, tsau_reg += skip, tat_reg += skip ) {
1058
1059 if ( (mode & mode_msk) == (TSI_RD(base, tat_reg) & mode_msk) ) {
1060
1061
1062 readTriple(base, tsau_reg, &start, &limit, &offst);
1063 limit += gran;
1064
1065 if ( !reverse ) {
1066 start += offst;
1067 limit += offst;
1068 offst = -offst;
1069 }
1070 a = aIn;
1071 if ( aIn >= start && aIn <= limit ) {
1072
1073 *paOut = (unsigned long)(a + offst);
1074 return port;
1075 }
1076 }
1077 }
1078
1079 uprintf(stderr, "vmeTsi148XlateAddr: no matching mapping found\n");
1080 return -1;
1081 }
1082
1083 int
1084 vmeTsi148XlateAddrXX(
1085 BERegister *base,
1086 int outbound,
1087 int reverse,
1088 unsigned long as,
1089 unsigned long aIn,
1090 unsigned long *paOut
1091 )
1092 {
1093 int port = xlateFindPort( base, outbound, reverse, as, aIn, paOut );
1094 return port < 0 ? -1 : 0;
1095 }
1096
1097 int
1098 vmeTsi148XlateAddr(
1099 int outbound,
1100 int reverse,
1101 unsigned long as,
1102 unsigned long aIn,
1103 unsigned long *paOut
1104 )
1105 {
1106 return vmeTsi148XlateAddrXX(THEBASE, outbound, reverse, as, aIn, paOut);
1107 }
1108
1109
1110 static void uprintfllx(FILE *f, unsigned long long v)
1111 {
1112 uprintf(f,"0x%08llx ", v);
1113 }
1114
1115 void
1116 vmeTsi148OutboundPortsShowXX(BERegister *base, FILE *f)
1117 {
1118 int port;
1119 unsigned long mode;
1120 char tit = 0;
1121
1122 unsigned long long start, limit, offst;
1123
1124 CHECK_BASE(base,0, );
1125
1126 if (!f) f=stdout;
1127 uprintf(f,"Tsi148 Outbound Ports:\n");
1128
1129 for ( port = 0; port < TSI148_NUM_OPORTS; port++ ) {
1130 mode = TSI_RD(base, TSI_OTAT_REG(port));
1131 if ( ! (TSI_OTAT_EN & mode) )
1132 continue;
1133
1134 readTriple(base, TSI_OTSAU_REG(port), &start, &limit, &offst);
1135
1136
1137 limit = limit-start+0x10000;
1138 if ( !tit ) {
1139 uprintf(f,"Port VME-Addr Size PCI-Adrs Mode:\n");
1140 tit = 1;
1141 }
1142 uprintf(f,"%d: ", port);
1143 uprintfllx(f,start+offst);
1144 uprintfllx(f,limit);
1145 uprintfllx(f,start);
1146 switch( mode & TSI_OTAT_ADMODE(-1) ) {
1147 case TSI_OTAT_ADMODE_A16: uprintf(f,"A16"); break;
1148 case TSI_OTAT_ADMODE_A24: uprintf(f,"A24"); break;
1149 case TSI_OTAT_ADMODE_A32: uprintf(f,"A32"); break;
1150 case TSI_OTAT_ADMODE_A64: uprintf(f,"A64"); break;
1151 case TSI_OTAT_ADMODE_CSR: uprintf(f,"CSR"); break;
1152 default: uprintf(f,"A??"); break;
1153 }
1154
1155 if ( mode & TSI_OTAT_PGM ) uprintf(f,", PGM");
1156 if ( mode & TSI_OTAT_SUP ) uprintf(f,", SUP");
1157 if ( ! (TSI_OTAT_MRPFD & mode) ) uprintf(f,", PREFETCH");
1158
1159 switch ( mode & TSI_OTAT_DBW(-1) ) {
1160 case TSI_OTAT_DBW(0): uprintf(f,", D16"); break;
1161 case TSI_OTAT_DBW(1): uprintf(f,", D32"); break;
1162 default: uprintf(f,", D??"); break;
1163 }
1164
1165 switch( mode & TSI_OTAT_TM(-1) ) {
1166 case TSI_OTAT_TM(0): uprintf(f,", SCT"); break;
1167 case TSI_OTAT_TM(1): uprintf(f,", BLT"); break;
1168 case TSI_OTAT_TM(2): uprintf(f,", MBLT"); break;
1169 case TSI_OTAT_TM(3): uprintf(f,", 2eVME"); break;
1170 case TSI_OTAT_TM(4): uprintf(f,", 2eSST"); break;
1171 case TSI_OTAT_TM(5): uprintf(f,", 2eSST_BCST"); break;
1172 default: uprintf(f," TM??"); break;
1173 }
1174
1175 uprintf(f,"\n");
1176 }
1177 }
1178
1179 void
1180 vmeTsi148OutboundPortsShow(FILE *f)
1181 {
1182 vmeTsi148OutboundPortsShowXX(THEBASE, f);
1183 }
1184
1185 void
1186 vmeTsi148InboundPortsShowXX(BERegister *base, FILE *f)
1187 {
1188 int port;
1189 unsigned long mode;
1190 char tit = 0;
1191
1192 unsigned long long start, limit, offst;
1193
1194 CHECK_BASE(base,0, );
1195
1196 if (!f) f=stdout;
1197 uprintf(f,"Tsi148 Inbound Ports:\n");
1198
1199 for ( port = 0; port < TSI148_NUM_IPORTS; port++ ) {
1200 mode = TSI_RD(base, TSI_ITAT_REG(port));
1201 if ( ! (TSI_ITAT_EN & mode) )
1202 continue;
1203
1204 readTriple(base, TSI_ITSAU_REG(port), &start, &limit, &offst);
1205
1206
1207 limit = limit - start + inboundGranularity(mode) + 1;
1208 if ( !tit ) {
1209 uprintf(f,"Port VME-Addr Size PCI-Adrs Mode:\n");
1210 tit = 1;
1211 }
1212 uprintf(f,"%d: ", port);
1213 uprintfllx(f,start);
1214 uprintfllx(f,limit);
1215 uprintfllx(f,start+offst);
1216 switch( mode & TSI_ITAT_AS(-1) ) {
1217 case TSI_ITAT_ADMODE_A16: uprintf(f,"A16"); break;
1218 case TSI_ITAT_ADMODE_A24: uprintf(f,"A24"); break;
1219 case TSI_ITAT_ADMODE_A32: uprintf(f,"A32"); break;
1220 case TSI_ITAT_ADMODE_A64: uprintf(f,"A64"); break;
1221 default: uprintf(f,"A??"); break;
1222 }
1223
1224 if ( mode & TSI_ITAT_PGM ) uprintf(f,", PGM");
1225 if ( mode & TSI_ITAT_DATA ) uprintf(f,", DAT");
1226 if ( mode & TSI_ITAT_SUP ) uprintf(f,", SUP");
1227 if ( mode & TSI_ITAT_USR ) uprintf(f,", USR");
1228
1229 if ( mode & TSI_ITAT_2eSSTB ) uprintf(f,", 2eSSTB");
1230 if ( mode & TSI_ITAT_2eSST ) uprintf(f,", 2eSST");
1231 if ( mode & TSI_ITAT_2eVME ) uprintf(f,", 2eVME");
1232 if ( mode & TSI_ITAT_MBLT ) uprintf(f,", MBLT");
1233 if ( mode & TSI_ITAT_BLT ) uprintf(f,", BLT");
1234
1235 uprintf(f,"\n");
1236 }
1237 }
1238
1239 void
1240 vmeTsi148InboundPortsShow(FILE *f)
1241 {
1242 vmeTsi148InboundPortsShowXX(THEBASE, f);
1243 }
1244
1245
1246 void
1247 vmeTsi148DisableAllInboundPortsXX(BERegister *base)
1248 {
1249 int port;
1250
1251 for ( port = 0; port < TSI148_NUM_IPORTS; port++ )
1252 if ( disableTsiPort(base, 0, port) )
1253 break;
1254 }
1255
1256 void
1257 vmeTsi148DisableAllInboundPorts(void)
1258 {
1259 vmeTsi148DisableAllInboundPortsXX(THEBASE);
1260 }
1261
1262 void
1263 vmeTsi148DisableAllOutboundPortsXX(BERegister *base)
1264 {
1265 int port;
1266
1267 for ( port = 0; port < TSI148_NUM_IPORTS; port++ )
1268 if ( disableTsiPort(base, 1, port) )
1269 break;
1270 }
1271
1272 void
1273 vmeTsi148DisableAllOutboundPorts(void)
1274 {
1275 vmeTsi148DisableAllOutboundPortsXX(THEBASE);
1276 }
1277
1278
1279
1280
1281 int
1282 vmeTsi148MapCRGXX(BERegister *b, uint32_t vme_base, uint32_t as )
1283 {
1284 uint32_t mode;
1285
1286 CHECK_BASE( b, 0, -1 );
1287
1288 if ( vmeTsi148RegPort > -1 && ! vmeTsi148RegCSR ) {
1289 uprintf(stderr,"vmeTsi148: CRG already mapped and in use by interrupt manager\n");
1290 return -1;
1291 }
1292
1293
1294 mode = TSI_CRGAT_EN | TSI_CRGAT_SUP | TSI_CRGAT_USR | TSI_CRGAT_PGM | TSI_CRGAT_DATA;
1295
1296 if ( VME_AM_IS_SHORT(as) ) {
1297 mode |= TSI_CRGAT_A16;
1298 } else
1299 if ( VME_AM_IS_STD(as) ) {
1300 mode |= TSI_CRGAT_A24;
1301 } else
1302 if ( VME_AM_IS_EXT(as) ) {
1303 mode |= TSI_CRGAT_A32;
1304 } else {
1305 return -2;
1306 }
1307
1308
1309 TSI_WR( b, TSI_CBAL_REG, (vme_base & ~(TSI_CRG_SIZE-1)));
1310 TSI_WR( b, TSI_CRGAT_REG, mode );
1311
1312 return 0;
1313 }
1314
1315 int
1316 vmeTsi148MapCRG(uint32_t vme_base, uint32_t as )
1317 {
1318 return vmeTsi148MapCRGXX( THEBASE, vme_base, as );
1319 }
1320
1321
1322
1323 typedef struct
1324 IRQEntryRec_ {
1325 VmeTsi148ISR isr;
1326 void *usrData;
1327 } IRQEntryRec, *IRQEntry;
1328
1329 static IRQEntry irqHdlTbl[TSI_NUM_INT_VECS]={0};
1330
1331 int vmeTsi148IrqMgrInstalled = 0;
1332 int vmeTsi148RegPort = -1;
1333 int vmeTsi148RegCSR = 0;
1334 BERegister *vmeTsi148RegBase = 0;
1335
1336 static volatile unsigned long wire_mask[TSI_NUM_WIRES] = {0};
1337
1338 static int tsi_wire[TSI_NUM_WIRES] = {0};
1339
1340
1341 static unsigned char tsi_iack_width[7] = {
1342 1,1,1,1,1,1,1
1343 };
1344
1345
1346 static int uni2tsi_vec_map[TSI_NUM_INT_VECS-256] = {
1347 -1,
1348 256 + 24 - 8,
1349 256 + 13 - 8,
1350 256 + 12 - 8,
1351 -1,
1352 256 + 10 - 8,
1353 -1,
1354 256 + 9 - 8,
1355 256 + 8 - 8,
1356 256 + 16 - 8,
1357 256 + 17 - 8,
1358 256 + 18 - 8,
1359 256 + 19 - 8,
1360 256 + 20 - 8,
1361 256 + 21 - 8,
1362 256 + 22 - 8,
1363 256 + 23 - 8,
1364
1365 256 + 11 - 8,
1366 256 + 25 - 8,
1367 };
1368
1369
1370 static int tsi2uni_vec_map[TSI_NUM_INT_VECS - 256] = {
1371 TSI_ACFAIL_INT_VEC,
1372 TSI_SYSFAIL_INT_VEC,
1373 TSI_VME_SW_IACK_INT_VEC,
1374 TSI_VIES_INT_VEC,
1375 TSI_VERR_INT_VEC,
1376 TSI_LERR_INT_VEC,
1377 -1,
1378 -1,
1379 TSI_MBOX0_INT_VEC,
1380 TSI_MBOX1_INT_VEC,
1381 TSI_MBOX2_INT_VEC,
1382 TSI_MBOX3_INT_VEC,
1383 TSI_LM0_INT_VEC,
1384 TSI_LM1_INT_VEC,
1385 TSI_LM2_INT_VEC,
1386 TSI_LM3_INT_VEC,
1387 TSI_DMA_INT_VEC,
1388 TSI_DMA1_INT_VEC,
1389 -1,
1390 };
1391
1392 static inline int
1393 uni2tsivec(int v)
1394 {
1395 if ( v < 0 || v >= TSI_NUM_INT_VECS )
1396 return -1;
1397 return v < 256 ? v : uni2tsi_vec_map[v-256];
1398 }
1399
1400 static int
1401 lvl2bitno(unsigned int level)
1402 {
1403 if ( level >= 256 )
1404 return uni2tsivec(level) + 8 - 256;
1405 else if ( level < 8 && level > 0 )
1406 return level;
1407 return -1;
1408 }
1409
1410 int
1411 vmeTsi148IntRoute(unsigned int level, unsigned int pin)
1412 {
1413 int i;
1414 unsigned long mask, shift, mapreg, wire;
1415 rtems_interrupt_lock_context lock_context;
1416
1417 if ( pin >= TSI_NUM_WIRES || ! tsi_wire[pin] || !vmeTsi148IrqMgrInstalled )
1418 return -1;
1419
1420 if ( level >= 256 ) {
1421 if ( (i = uni2tsivec(level)) < 0 )
1422 return -1;
1423 shift = 8 + (i-256);
1424 } else if ( 1 <= level && level <=7 ) {
1425 shift = level;
1426 } else {
1427 return -1;
1428 }
1429
1430 mask = 1<<shift;
1431
1432
1433 if ( shift < 16 ) {
1434 mapreg = TSI_INTM2_REG;
1435 } else if ( shift < 32 ) {
1436 shift -= 16;
1437 mapreg = TSI_INTM1_REG;
1438 } else {
1439 return -1;
1440 }
1441
1442 shift <<=1;
1443
1444
1445 wire = (tsi_wire[pin]-1) << shift;
1446
1447 rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
1448 for ( i = 0; i<TSI_NUM_WIRES; i++ ) {
1449 wire_mask[i] &= ~mask;
1450 }
1451 wire_mask[pin] |= mask;
1452
1453 mask = TSI_RD(THEBASE, mapreg) & ~ (0x3<<shift);
1454 mask |= wire;
1455 TSI_WR( THEBASE, mapreg, mask );
1456
1457 rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
1458 return 0;
1459 }
1460
1461 VmeTsi148ISR
1462 vmeTsi148ISRGet(unsigned long vector, void **parg)
1463 {
1464 VmeTsi148ISR rval = 0;
1465 volatile IRQEntry *p;
1466 int v = uni2tsivec(vector);
1467 rtems_interrupt_lock_context lock_context;
1468
1469
1470 if ( v < 0 )
1471 return rval;
1472
1473 p = irqHdlTbl + v;
1474
1475 rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
1476 if ( *p ) {
1477 if ( parg )
1478 *parg = (*p)->usrData;
1479 rval = (*p)->isr;
1480 }
1481 rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
1482
1483 return rval;
1484 }
1485
1486 static void
1487 tsiVMEISR(rtems_irq_hdl_param arg)
1488 {
1489 int pin = (int)arg;
1490 BERegister *b = THEBASE;
1491 IRQEntry ip;
1492 unsigned long msk,lintstat,vector, vecarg;
1493 int lvl;
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505 while ( (lintstat = (TSI_RD(vmeTsi148RegBase, TSI_INTS_REG) & wire_mask[pin])) ) {
1506
1507
1508
1509 do {
1510
1511 #ifdef __PPC__
1512 asm volatile("cntlzw %0, %1":"=r"(lvl):"r"(lintstat));
1513 lvl = 31-lvl;
1514 msk = 1<<lvl;
1515 #else
1516 { static unsigned long m[] = {
1517 0xffff0000, 0xff00ff00, 0xf0f0f0f0, 0xcccccccc, 0xaaaaaaaa
1518 };
1519 int i;
1520 unsigned tmp;
1521
1522
1523
1524
1525
1526
1527 for ( i=0, lvl=0, msk = lintstat; i<5; i++ ) {
1528 lvl <<= 1;
1529 if ( (tmp = msk & m[i]) ) {
1530 lvl++;
1531 msk = tmp;
1532 } else
1533 msk = msk & ~m[i];
1534 }
1535 }
1536 #endif
1537
1538 if ( lvl > 7 ) {
1539
1540 TSI_WR(b, TSI_INTC_REG, msk);
1541 vector = 256 + lvl - 8;
1542 vecarg = tsi2uni_vec_map[lvl-8];
1543 } else {
1544
1545 switch ( tsi_iack_width[lvl-1] ) {
1546 default:
1547 case 1:
1548 vector = TSI_RD8(b, TSI_VIACK_1_REG - 4 + (lvl<<2) + 3);
1549 break;
1550
1551 case 2:
1552 vector = TSI_RD16(b, TSI_VIACK_1_REG - 4 + (lvl<<2) + 2);
1553 break;
1554
1555 case 4:
1556 vector = TSI_RD(b, TSI_VIACK_1_REG - 4 + (lvl<<2));
1557 break;
1558 }
1559 vecarg = vector;
1560 }
1561
1562 if ( !(ip=irqHdlTbl[vector])) {
1563
1564 vmeTsi148IntDisable(lvl);
1565 printk("vmeTsi148 ISR: ERROR: no handler registered (level %i) IACK 0x%08lx -- DISABLING level %i\n",
1566 lvl, vector, lvl);
1567 } else {
1568
1569 ip->isr(ip->usrData, vecarg);
1570
1571
1572
1573
1574 iobarrier_rw();
1575 }
1576 } while ( (lintstat &= ~msk) );
1577
1578 }
1579 }
1580
1581
1582 static void
1583 my_no_op(const rtems_irq_connect_data * arg)
1584 {}
1585
1586 static int
1587 my_isOn(const rtems_irq_connect_data *arg)
1588 {
1589 return (int)(TSI_RD(THEBASE, TSI_INTEO_REG) & TSI_RD(THEBASE, TSI_INTEN_REG));
1590 }
1591
1592 static void
1593 connectIsr(int shared, rtems_irq_hdl isr, int pic_line, int slot)
1594 {
1595 rtems_irq_connect_data xx;
1596 xx.on = my_no_op;
1597 xx.off = my_no_op;
1598 xx.isOn = my_isOn;
1599 xx.hdl = isr;
1600 xx.handle = (rtems_irq_hdl_param)slot;
1601 xx.name = pic_line;
1602
1603 if ( shared ) {
1604 #if BSP_SHARED_HANDLER_SUPPORT > 0
1605 if (!BSP_install_rtems_shared_irq_handler(&xx))
1606 rtems_panic("unable to install vmeTsi148 shared irq handler");
1607 #else
1608 uprintf(stderr,"vmeTsi148: WARNING: your BSP doesn't support sharing interrupts\n");
1609 if (!BSP_install_rtems_irq_handler(&xx))
1610 rtems_panic("unable to install vmeTsi148 irq handler");
1611 #endif
1612 } else {
1613 if (!BSP_install_rtems_irq_handler(&xx))
1614 rtems_panic("unable to install vmeTsi148 irq handler");
1615 }
1616 }
1617
1618 int
1619 vmeTsi148InstallIrqMgrAlt(int shared, int tsi_pin0, int pic_pin0, ...)
1620 {
1621 int rval;
1622 va_list ap;
1623 va_start(ap, pic_pin0);
1624 rval = vmeTsi148InstallIrqMgrVa(shared, tsi_pin0, pic_pin0, ap);
1625 va_end(ap);
1626 return rval;
1627 }
1628
1629 #ifndef BSP_EARLY_PROBE_VME
1630 #define BSP_EARLY_PROBE_VME(addr) \
1631 ( \
1632 vmeTsi148ClearVMEBusErrorsXX( THEBASE, 0 ), \
1633 ( ((PCI_DEVICE_TSI148 << 16) | PCI_VENDOR_TUNDRA ) == TSI_LE_RD32( ((BERegister*)(addr)), 0 ) \
1634 && 0 == vmeTsi148ClearVMEBusErrorsXX( THEBASE, 0 ) ) \
1635 )
1636 #endif
1637
1638
1639
1640
1641
1642
1643 static int
1644 mappedAndProbed(unsigned long vme_addr, unsigned as, unsigned long *pcpu_addr)
1645 {
1646 int j;
1647 char *regtype = (as & VME_AM_MASK) == VME_AM_CSR ? "CSR" : "CRG";
1648
1649
1650 if ( 0 > (j = xlateFindPort(
1651 THEBASE,
1652 1, 0,
1653 as | VME_MODE_AS_MATCH,
1654 vme_addr,
1655 pcpu_addr ) ) ) {
1656 uprintf(stderr,"vmeTsi148 - Unable to find mapping for %s VME base (0x%08x)\n", regtype, vme_addr);
1657 uprintf(stderr," in outbound windows.\n");
1658 }
1659 else {
1660
1661 *pcpu_addr = BSP_PCI2LOCAL_ADDR( *pcpu_addr );
1662 if ( BSP_EARLY_PROBE_VME(*pcpu_addr) ) {
1663 uprintf(stderr,"vmeTsi148 - IRQ manager using VME %s to flush FIFO\n", regtype);
1664 return j;
1665 } else {
1666 uprintf(stderr,"vmeTsi148 - Found slot info but detection of tsi148 in VME %s space failed\n", regtype);
1667 }
1668 }
1669 return -1;
1670 }
1671
1672 int
1673 vmeTsi148InstallIrqMgrVa(int shared, int tsi_pin0, int pic_pin0, va_list ap)
1674 {
1675 int i,j, specialPin, tsi_pin[TSI_NUM_WIRES+1], pic_pin[TSI_NUM_WIRES];
1676 unsigned long cpu_base, vme_reg_base;
1677
1678 if (vmeTsi148IrqMgrInstalled) return -4;
1679
1680
1681
1682 if ( tsi_pin0 < 0 || tsi_pin0 > 3 ) return -1;
1683
1684 tsi_pin[0] = tsi_pin0;
1685 pic_pin[0] = pic_pin0 < 0 ? devs[0].irqLine : pic_pin0;
1686 i = 1;
1687 while ( (tsi_pin[i] = va_arg(ap, int)) >= 0 ) {
1688
1689 if ( i >= TSI_NUM_WIRES ) {
1690 return -5;
1691 }
1692
1693 pic_pin[i] = va_arg(ap,int);
1694
1695 if ( tsi_pin[i] > 3 ) return -2;
1696 if ( pic_pin[i] < 0 ) return -3;
1697 i++;
1698 }
1699
1700
1701 for ( i=0; tsi_pin[i] >= 0; i++ ) {
1702 for ( j=i+1; tsi_pin[j] >= 0; j++ ) {
1703 if ( tsi_pin[j] == tsi_pin[i] ) return -6;
1704 if ( pic_pin[j] == pic_pin[i] ) return -7;
1705 }
1706 }
1707
1708 i = -1;
1709
1710
1711
1712 uprintf(stderr,"vmeTsi148 IRQ manager: looking for registers on VME...\n");
1713
1714 if ( ( i = ((TSI_RD( THEBASE, TSI_CBAR_REG ) & 0xff) >> 3) ) > 0 ) {
1715 uprintf(stderr,"Trying to find CSR on VME...\n");
1716 vme_reg_base = i*0x80000 + TSI_CSR_OFFSET;
1717 i = mappedAndProbed( vme_reg_base, VME_AM_CSR , &cpu_base);
1718 if ( i >= 0 )
1719 vmeTsi148RegCSR = 1;
1720 } else {
1721 i = -1;
1722 }
1723
1724 if ( -1 == i ) {
1725
1726 uprintf(stderr,"Trying to find CRG on VME...\n");
1727
1728
1729
1730 if ( (TSI_CRGAT_EN & (j = TSI_RD( THEBASE, TSI_CRGAT_REG ))) ) {
1731 switch ( j & TSI_CRGAT_AS_MSK ) {
1732 case TSI_CRGAT_A16 : i = VME_AM_SUP_SHORT_IO; break;
1733 case TSI_CRGAT_A24 : i = VME_AM_STD_SUP_DATA; break;
1734 case TSI_CRGAT_A32 : i = VME_AM_EXT_SUP_DATA; break;
1735 default:
1736 break;
1737 }
1738 vme_reg_base = TSI_RD( THEBASE, TSI_CBAL_REG ) & ~ (TSI_CRG_SIZE - 1);
1739 }
1740
1741 if ( -1 == i ) {
1742 } else {
1743 i = mappedAndProbed( vme_reg_base, (i & VME_AM_MASK), &cpu_base );
1744 }
1745 }
1746
1747 if ( i < 0 ) {
1748 uprintf(stderr,"vmeTsi148 IRQ manager - BSP configuration error: registers not found on VME\n");
1749 uprintf(stderr,"(should open outbound window to CSR space or map CRG [vmeTsi148MapCRG()])\n");
1750 uprintf(stderr,"Falling back to PCI but you might experience spurious VME interrupts; read a register\n");
1751 uprintf(stderr,"back from user ISR to flush posted-write FIFO as a work-around\n");
1752 cpu_base = (unsigned long)THEBASE;
1753 i = -1;
1754 }
1755
1756 vmeTsi148RegBase = (BERegister*)cpu_base;
1757 vmeTsi148RegPort = i;
1758
1759
1760 if ( pic_pin[0] >= 0 && devs[0].irqLine != pic_pin[0] ) {
1761 uprintf(stderr,"Overriding main IRQ line PCI info with %d\n",
1762 pic_pin[0]);
1763 devs[0].irqLine = pic_pin[0];
1764 }
1765
1766 for ( i = 0; tsi_pin[i] >= 0; i++ ) {
1767
1768 tsi_wire[i] = tsi_pin[i] + 1;
1769 connectIsr(shared, tsiVMEISR, pic_pin[i], i);
1770 }
1771
1772 specialPin = tsi_pin[1] >= 0 ? 1 : 0;
1773
1774
1775
1776
1777 vmeTsi148IrqMgrInstalled=1;
1778
1779
1780 for ( i=1; i<8; i++ )
1781 vmeTsi148IntRoute( i, 0 );
1782 for ( i=TSI_DMA_INT_VEC; i<TSI_NUM_INT_VECS; i++ )
1783 vmeTsi148IntRoute( i, specialPin );
1784
1785 for ( i = 0; i<TSI_NUM_WIRES; i++ ) {
1786
1787 devs[0].pic_pin[i] = ( ( tsi_pin[i] >=0 ) ? pic_pin[i] : -1 );
1788 }
1789
1790 return 0;
1791 }
1792
1793 int
1794 vmeTsi148InstallISR(unsigned long vector, VmeTsi148ISR hdl, void *arg)
1795 {
1796 IRQEntry ip;
1797 int v;
1798 volatile IRQEntry *p;
1799 rtems_interrupt_lock_context lock_context;
1800
1801 if ( !vmeTsi148IrqMgrInstalled || (v = uni2tsivec(vector)) < 0 )
1802 return -1;
1803
1804 p = irqHdlTbl + v;
1805
1806 if (*p || !(ip=(IRQEntry)malloc(sizeof(IRQEntryRec))))
1807 return -1;
1808
1809 ip->isr=hdl;
1810 ip->usrData=arg;
1811
1812 rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
1813 if (*p) {
1814 rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
1815 free(ip);
1816 return -1;
1817 }
1818 *p = ip;
1819 rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
1820 return 0;
1821 }
1822
1823 int
1824 vmeTsi148RemoveISR(unsigned long vector, VmeTsi148ISR hdl, void *arg)
1825 {
1826 int v;
1827 IRQEntry ip;
1828 volatile IRQEntry *p;
1829 rtems_interrupt_lock_context lock_context;
1830
1831 if ( !vmeTsi148IrqMgrInstalled || (v = uni2tsivec(vector)) < 0 )
1832 return -1;
1833
1834 p = irqHdlTbl + v;
1835
1836 rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
1837 ip = *p;
1838 if ( !ip || ip->isr!=hdl || ip->usrData!=arg ) {
1839 rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
1840 return -1;
1841 }
1842 *p = 0;
1843 rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
1844
1845 free(ip);
1846 return 0;
1847 }
1848
1849 static int
1850 intDoEnDis(unsigned int level, int dis)
1851 {
1852 BERegister *b = THEBASE;
1853 unsigned long v;
1854 int shift;
1855 rtems_interrupt_lock_context lock_context;
1856
1857 if ( ! vmeTsi148IrqMgrInstalled || (shift = lvl2bitno(level)) < 0 )
1858 return -1;
1859
1860 v = 1<<shift;
1861
1862 if ( !dis )
1863 return (int)(v & TSI_RD(b, TSI_INTEO_REG) & TSI_RD(b, TSI_INTEN_REG)) ? 1 : 0;
1864
1865 rtems_interrupt_lock_acquire( &vmeTsi148_lock, &lock_context );
1866 if ( dis<0 ) {
1867 TSI_WR(b, TSI_INTEN_REG, TSI_RD(b, TSI_INTEN_REG) & ~v);
1868 TSI_WR(b, TSI_INTEO_REG, TSI_RD(b, TSI_INTEO_REG) & ~v);
1869 } else {
1870 TSI_WR(b, TSI_INTEN_REG, TSI_RD(b, TSI_INTEN_REG) | v);
1871 TSI_WR(b, TSI_INTEO_REG, TSI_RD(b, TSI_INTEO_REG) | v);
1872 }
1873 rtems_interrupt_lock_release( &vmeTsi148_lock, &lock_context );
1874 return 0;
1875 }
1876
1877 int
1878 vmeTsi148IntEnable(unsigned int level)
1879 {
1880 return intDoEnDis(level, 1);
1881 }
1882
1883 int
1884 vmeTsi148IntDisable(unsigned int level)
1885 {
1886 return intDoEnDis(level, -1);
1887 }
1888
1889 int
1890 vmeTsi148IntIsEnabled(unsigned int level)
1891 {
1892 return intDoEnDis(level, 0);
1893 }
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903 int
1904 vmeTsi148SetIackWidth(int level, int width)
1905 {
1906 int rval;
1907 if ( level < 1 || level > 7 || !vmeTsi148IrqMgrInstalled )
1908 return -1;
1909
1910 switch ( width ) {
1911 default: return -1;
1912 case 0:
1913 case 1:
1914 case 2:
1915 case 4:
1916 break;
1917 }
1918
1919 rval = tsi_iack_width[level-1];
1920 if ( width )
1921 tsi_iack_width[level-1] = width;
1922 return rval;
1923 }
1924
1925 int
1926 vmeTsi148IntRaiseXX(BERegister *base, int level, unsigned vector)
1927 {
1928 unsigned long v;
1929
1930 CHECK_BASE(base,0,-1);
1931
1932 if ( level < 1 || level > 7 || vector > 255 )
1933 return -1;
1934
1935
1936 if ( (v = TSI_RD(base, TSI_VICR_REG)) & TSI_VICR_IRQS ) {
1937 return -2;
1938 }
1939
1940 v &= ~255;
1941
1942 v |= TSI_VICR_IRQL(level) | TSI_VICR_STID(vector);
1943
1944
1945 TSI_WR(base, TSI_VICR_REG, v);
1946
1947 return 0;
1948
1949 }
1950
1951 int
1952 vmeTsi148IntRaise(int level, unsigned vector)
1953 {
1954 return vmeTsi148IntRaiseXX(THEBASE, level, vector);
1955 }
1956
1957
1958
1959 typedef struct {
1960 rtems_id q;
1961 int l;
1962 } LoopbackTstArgs;
1963
1964 static void
1965 loopbackTstIsr(void *arg, unsigned long vector)
1966 {
1967 LoopbackTstArgs *pa = arg;
1968 if ( RTEMS_SUCCESSFUL != rtems_message_queue_send(pa->q, (void*)&vector, sizeof(vector)) ) {
1969
1970 printk("vmeTsi148IntLoopbackTst: (ISR) message queue full / overrun ? disabling IRQ level %i\n", pa->l);
1971 vmeTsi148IntDisable(pa->l);
1972 }
1973 }
1974
1975 int
1976 vmeTsi148IntLoopbackTst(int level, unsigned vector)
1977 {
1978 BERegister *b = THEBASE;
1979 rtems_status_code sc;
1980 rtems_id q = 0;
1981 int installed = 0;
1982 int i, err = 0;
1983 int doDisable = 0;
1984 size_t size;
1985 unsigned long msg;
1986 char * irqfmt = "VME IRQ @vector %3i %s";
1987 char * iackfmt = "VME IACK %s";
1988 LoopbackTstArgs a;
1989
1990 CHECK_BASE(b,0,-1);
1991
1992
1993 if ( level < 1 || level > 7 || vector > 255 )
1994 return -1;
1995
1996
1997 if ( RTEMS_SUCCESSFUL != (sc=rtems_message_queue_create(
1998 rtems_build_name('t' ,'U','I','I'),
1999 4,
2000 sizeof(unsigned long),
2001 0,
2002 &q)) ) {
2003 rtems_error(sc, "vmeTsi148IntLoopbackTst: Unable to create message queue");
2004 goto bail;
2005 }
2006
2007 a.q = q;
2008 a.l = level;
2009
2010
2011 if ( vmeTsi148InstallISR(vector, loopbackTstIsr, (void*)&a) ) {
2012 uprintf(stderr,"Unable to install VME ISR to vector %i\n",vector);
2013 goto bail;
2014 }
2015 installed++;
2016 if ( vmeTsi148InstallISR(TSI_VME_SW_IACK_INT_VEC, loopbackTstIsr, (void*)&a) ) {
2017 uprintf(stderr,"Unable to install VME ISR to IACK special vector %i\n",TSI_VME_SW_IACK_INT_VEC);
2018 goto bail;
2019 }
2020 installed++;
2021
2022 if ( !vmeTsi148IntIsEnabled(level) && 0==vmeTsi148IntEnable(level) )
2023 doDisable = 1;
2024
2025
2026 TSI_WR(b, TSI_INTC_REG, TSI_INTC_IACKC);
2027
2028 if ( vmeTsi148IntEnable( TSI_VME_SW_IACK_INT_VEC ) ) {
2029 uprintf(stderr,"Unable to enable IACK interrupt\n");
2030 goto bail;
2031 }
2032
2033 printf("vmeTsi148 VME interrupt loopback test; STARTING...\n");
2034 printf(" --> asserting VME IRQ level %i\n", level);
2035 vmeTsi148IntRaise(level, vector);
2036
2037 for ( i = 0; i< 3; i++ ) {
2038 sc = rtems_message_queue_receive(
2039 q,
2040 &msg,
2041 &size,
2042 RTEMS_WAIT,
2043 20);
2044 if ( sc ) {
2045 if ( RTEMS_TIMEOUT == sc && i>1 ) {
2046
2047 sc = 0;
2048 } else {
2049 rtems_error(sc,"Error waiting for interrupts");
2050 }
2051 break;
2052 }
2053 if ( msg == vector ) {
2054 if ( !irqfmt ) {
2055 printf("Excess VME IRQ received ?? -- BAD\n");
2056 err = 1;
2057 } else {
2058 printf(irqfmt, vector, "received -- PASSED\n");
2059 irqfmt = 0;
2060 }
2061 } else if ( msg == TSI_VME_SW_IACK_INT_VEC ) {
2062 if ( !iackfmt ) {
2063 printf("Excess VME IACK received ?? -- BAD\n");
2064 err = 1;
2065 } else {
2066 printf(iackfmt, "received -- PASSED\n");
2067 iackfmt = 0;
2068 }
2069 } else {
2070 printf("Unknown IRQ (vector %lu) received -- BAD\n", msg);
2071 err = 1;
2072 }
2073 }
2074
2075
2076
2077 if ( irqfmt ) {
2078 printf(irqfmt,vector, "MISSED -- BAD\n");
2079 err = 1;
2080 }
2081 if ( iackfmt ) {
2082 printf(iackfmt, "MISSED -- BAD\n");
2083 err = 1;
2084 }
2085
2086 printf("FINISHED.\n");
2087
2088 bail:
2089 if ( doDisable )
2090 vmeTsi148IntDisable(level);
2091 vmeTsi148IntDisable( TSI_VME_SW_IACK_INT_VEC );
2092 if ( installed > 0 )
2093 vmeTsi148RemoveISR(vector, loopbackTstIsr, (void*)&a);
2094 if ( installed > 1 )
2095 vmeTsi148RemoveISR(TSI_VME_SW_IACK_INT_VEC, loopbackTstIsr, (void*)&a);
2096 if ( q )
2097 rtems_message_queue_delete(q);
2098
2099 return sc ? sc : err;
2100 }
2101
2102 unsigned long
2103 vmeTsi148ClearVMEBusErrorsXX(BERegister *base, uint32_t *paddr)
2104 {
2105 unsigned long rval;
2106
2107 CHECK_BASE(base,1,-1);
2108
2109 rval = TSI_RD(base, TSI_VEAT_REG);
2110 if ( rval & TSI_VEAT_VES ) {
2111 if ( paddr ) {
2112 #if 0
2113 *paddr = ((unsigned long long)TSI_RD(base, TSI_VEAU_REG))<<32;
2114 *paddr |= TSI_RD(base, TSI_VEAL_REG);
2115 #else
2116 *paddr = TSI_RD(base, TSI_VEAL_REG);
2117 #endif
2118 }
2119
2120 TSI_WR(base, TSI_VEAT_REG, TSI_VEAT_VESCL);
2121 } else {
2122 rval = 0;
2123 }
2124 return rval;
2125 }
2126
2127 unsigned long
2128 vmeTsi148ClearVMEBusErrors(uint32_t *paddr)
2129 {
2130 return vmeTsi148ClearVMEBusErrorsXX(THEBASE, paddr);
2131 }
2132
2133
2134
2135
2136 typedef struct VmeTsi148DmaListDescriptorRec_ {
2137 BEValue dsau, dsal;
2138 BEValue ddau, ddal;
2139 BEValue dsat, ddat;
2140 BEValue dnlau, dnlal;
2141 BEValue dcnt, ddbs;
2142 } VmeTsi148DmaListDescriptorRec;
2143
2144 static void tsi_desc_init (DmaDescriptor);
2145 static int tsi_desc_setup (DmaDescriptor, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
2146 static void tsi_desc_setnxt(DmaDescriptor, DmaDescriptor);
2147 static void tsi_desc_dump (DmaDescriptor);
2148 static int tsi_desc_start (volatile void *controller_addr, int channel, DmaDescriptor p);
2149
2150 VMEDmaListClassRec vmeTsi148DmaListClass = {
2151 desc_size: sizeof(VmeTsi148DmaListDescriptorRec),
2152 desc_align: 8,
2153 freeList: 0,
2154 desc_alloc: 0,
2155 desc_free: 0,
2156 desc_init: tsi_desc_init,
2157 desc_setnxt:tsi_desc_setnxt,
2158 desc_setup: tsi_desc_setup,
2159 desc_start: tsi_desc_start,
2160 desc_refr: 0,
2161 desc_dump: tsi_desc_dump,
2162 };
2163
2164
2165 #define TSI_DMA_REG(off,i) ((off)+(((i)&1)<<7))
2166
2167 #define TSI_DCTL_REG(i) TSI_DMA_REG(0x500,i)
2168 #define TSI_DCTL0_REG 0x500
2169 #define TSI_DCTL1_REG 0x580
2170 # define TSI_DCTL_ABT (1<<27)
2171 # define TSI_DCTL_PAU (1<<26)
2172 # define TSI_DCTL_DGO (1<<25)
2173 # define TSI_DCTL_MOD (1<<23)
2174 # define TSI_DCTL_VFAR (1<<17)
2175 # define TSI_DCTL_PFAR (1<<16)
2176
2177 # define TSI_DCTL_VBKS(i) (((i)&7)<<12)
2178 # define TSI_DCTL_VBKS_32 TSI_DCTL_VBKS(0)
2179 # define TSI_DCTL_VBKS_64 TSI_DCTL_VBKS(1)
2180 # define TSI_DCTL_VBKS_128 TSI_DCTL_VBKS(2)
2181 # define TSI_DCTL_VBKS_256 TSI_DCTL_VBKS(3)
2182 # define TSI_DCTL_VBKS_512 TSI_DCTL_VBKS(4)
2183 # define TSI_DCTL_VBKS_1024 TSI_DCTL_VBKS(5)
2184 # define TSI_DCTL_VBKS_2048 TSI_DCTL_VBKS(6)
2185 # define TSI_DCTL_VBKS_4096 TSI_DCTL_VBKS(7)
2186
2187 # define TSI_DCTL_VBOT(i) (((i)&7)<< 8)
2188 # define TSI_DCTL_VBOT_0us TSI_DCTL_VBOT(0)
2189 # define TSI_DCTL_VBOT_1us TSI_DCTL_VBOT(1)
2190 # define TSI_DCTL_VBOT_2us TSI_DCTL_VBOT(2)
2191 # define TSI_DCTL_VBOT_4us TSI_DCTL_VBOT(3)
2192 # define TSI_DCTL_VBOT_8us TSI_DCTL_VBOT(4)
2193 # define TSI_DCTL_VBOT_16us TSI_DCTL_VBOT(5)
2194 # define TSI_DCTL_VBOT_32us TSI_DCTL_VBOT(6)
2195 # define TSI_DCTL_VBOT_64us TSI_DCTL_VBOT(7)
2196
2197 # define TSI_DCTL_PBKS(i) (((i)&7)<< 4)
2198 # define TSI_DCTL_PBKS_32 TSI_DCTL_PBKS(0)
2199 # define TSI_DCTL_PBKS_64 TSI_DCTL_PBKS(1)
2200 # define TSI_DCTL_PBKS_128 TSI_DCTL_PBKS(2)
2201 # define TSI_DCTL_PBKS_256 TSI_DCTL_PBKS(3)
2202 # define TSI_DCTL_PBKS_512 TSI_DCTL_PBKS(4)
2203 # define TSI_DCTL_PBKS_1024 TSI_DCTL_PBKS(5)
2204 # define TSI_DCTL_PBKS_2048 TSI_DCTL_PBKS(6)
2205 # define TSI_DCTL_PBKS_4096 TSI_DCTL_PBKS(7)
2206
2207 # define TSI_DCTL_PBOT(i) (((i)&7)<< 0)
2208 # define TSI_DCTL_PBOT_0us TSI_DCTL_PBOT(0)
2209 # define TSI_DCTL_PBOT_1us TSI_DCTL_PBOT(1)
2210 # define TSI_DCTL_PBOT_2us TSI_DCTL_PBOT(2)
2211 # define TSI_DCTL_PBOT_4us TSI_DCTL_PBOT(3)
2212 # define TSI_DCTL_PBOT_8us TSI_DCTL_PBOT(4)
2213 # define TSI_DCTL_PBOT_16us TSI_DCTL_PBOT(5)
2214 # define TSI_DCTL_PBOT_32us TSI_DCTL_PBOT(6)
2215 # define TSI_DCTL_PBOT_64us TSI_DCTL_PBOT(7)
2216
2217
2218 #define TSI_DSTA_REG(i) TSI_DMA_REG(0x504,i)
2219 #define TSI_DSTA0_REG 0x504
2220 #define TSI_DSTA1_REG 0x584
2221 # define TSI_DSTA_ERR (1<<28)
2222 # define TSI_DSTA_ABT (1<<27)
2223 # define TSI_DSTA_PAU (1<<26)
2224 # define TSI_DSTA_DON (1<<25)
2225 # define TSI_DSTA_BSY (1<<24)
2226 # define TSI_DSTA_ERRS (1<<20)
2227 # define TSI_DSTA_ERT_MSK (3<<16)
2228 # define TSI_DSTA_ERT_BERR_E (0<<16)
2229 # define TSI_DSTA_ERT_BERR_O (1<<16)
2230 # define TSI_DSTA_ERT_SLVE_E (2<<16)
2231 # define TSI_DSTA_ERT_SLVE_O (3<<16)
2232
2233
2234 #define TSI_DCSAU_REG(i) TSI_DMA_REG(0x508,i)
2235 #define TSI_DCSAU0_REG 0x508
2236 #define TSI_DCSAU1_REG 0x588
2237
2238
2239 #define TSI_DCSAL_REG(i) TSI_DMA_REG(0x50c,i)
2240 #define TSI_DCSAL0_REG 0x50c
2241 #define TSI_DCSAL1_REG 0x58c
2242
2243
2244 #define TSI_DCDAU_REG(i) TSI_DMA_REG(0x510,i)
2245 #define TSI_DCDAU0_REG 0x510
2246 #define TSI_DCDAU1_REG 0x590
2247
2248
2249 #define TSI_DCDAL_REG(i) TSI_DMA_REG(0x514,i)
2250 #define TSI_DCDAL0_REG 0x514
2251 #define TSI_DCDAL1_REG 0x594
2252
2253
2254 #define TSI_DCLAU_REG(i) TSI_DMA_REG(0x518,i)
2255 #define TSI_DCLAU0_REG 0x518
2256 #define TSI_DCLAU1_REG 0x598
2257
2258
2259 #define TSI_DCLAL_REG(i) TSI_DMA_REG(0x51c,i)
2260 #define TSI_DCLAL0_REG 0x51c
2261 #define TSI_DCLAL1_REG 0x59c
2262
2263
2264 #define TSI_DSAU_REG(i) TSI_DMA_REG(0x520,i)
2265 #define TSI_DSAU0_REG 0x520
2266 #define TSI_DSAU1_REG 0x5a0
2267
2268
2269 #define TSI_DSAL_REG(i) TSI_DMA_REG(0x524,i)
2270 #define TSI_DSAL0_REG 0x524
2271 #define TSI_DSAL1_REG 0x5a4
2272
2273
2274 #define TSI_DDAU_REG(i) TSI_DMA_REG(0x528,i)
2275 #define TSI_DDAU0_REG 0x528
2276 #define TSI_DDAU1_REG 0x5a8
2277
2278
2279 #define TSI_DDAL_REG(i) TSI_DMA_REG(0x52c,i)
2280 #define TSI_DDAL0_REG 0x52c
2281 #define TSI_DDAL1_REG 0x5ac
2282
2283
2284 #define TSI_DSAT_REG(i) TSI_DMA_REG(0x530,i)
2285 #define TSI_DSAT0_REG 0x530
2286 #define TSI_DSAT1_REG 0x5b0
2287
2288
2289 #define TSI_DDAT_REG(i) TSI_DMA_REG(0x534,i)
2290 #define TSI_DDAT0_REG 0x534
2291 #define TSI_DDAT1_REG 0x5b4
2292
2293 # define TSI_DXAT_TYP(i) (((i)&3)<<28)
2294 # define TSI_DXAT_TYP_PCI TSI_DXAT_TYP(0)
2295 # define TSI_DXAT_TYP_VME TSI_DXAT_TYP(1)
2296 # define TSI_DSAT_TYP_PAT TSI_DXAT_TYP(2)
2297
2298 # define TSI_DSAT_PSZ (1<<25)
2299 # define TSI_DSAT_NIN (1<<24)
2300
2301 # define TSI_DXAT_OTAT_MSK ((1<<13)-1)
2302
2303 # define TSI_DXAT_SSTM(i) (((i)&3)<<11)
2304 # define TSI_DXAT_SSTM_116 TSI_DXAT_SSTM(0)
2305 # define TSI_DXAT_SSTM_267 TSI_DXAT_SSTM(1)
2306 # define TSI_DXAT_SSTM_320 TSI_DXAT_SSTM(2)
2307
2308 # define TSI_DXAT_TM(i) (((i)&7)<< 8)
2309 # define TSI_DXAT_TM_SCT TSI_DXAT_TM(0)
2310 # define TSI_DXAT_TM_BLT TSI_DXAT_TM(1)
2311 # define TSI_DXAT_TM_MBLT TSI_DXAT_TM(2)
2312 # define TSI_DXAT_TM_2eVME TSI_DXAT_TM(3)
2313 # define TSI_DXAT_TM_2eSST TSI_DXAT_TM(4)
2314 # define TSI_DSAT_TM_2eSST_B TSI_DXAT_TM(5)
2315
2316 # define TSI_DXAT_DBW(i) (((i)&3)<< 6)
2317 # define TSI_DXAT_DBW_16 TSI_DXAT_DBW(0)
2318 # define TSI_DXAT_DBW_32 TSI_DXAT_DBW(1)
2319
2320 # define TSI_DXAT_SUP (1<<5)
2321 # define TSI_DXAT_PGM (1<<4)
2322
2323 # define TSI_DXAT_AM(i) (((i)&15)<<0)
2324 # define TSI_DXAT_AM_A16 TSI_DXAT_AM(0)
2325 # define TSI_DXAT_AM_A24 TSI_DXAT_AM(1)
2326 # define TSI_DXAT_AM_A32 TSI_DXAT_AM(2)
2327 # define TSI_DXAT_AM_A64 TSI_DXAT_AM(4)
2328 # define TSI_DXAT_AM_CSR TSI_DXAT_AM(5)
2329
2330
2331 #define TSI_DNLAU_REG(i) TSI_DMA_REG(0x538,i)
2332 #define TSI_DNLAU0_REG 0x538
2333 #define TSI_DNLAU1_REG 0x5b8
2334
2335
2336 #define TSI_DNLAL_REG(i) TSI_DMA_REG(0x53c,i)
2337 #define TSI_DNLAL0_REG 0x53c
2338 #define TSI_DNLAL1_REG 0x5bc
2339
2340 # define TSI_DNLAL_LLA 1
2341
2342
2343 #define TSI_DCNT_REG(i) TSI_DMA_REG(0x540,i)
2344 #define TSI_DCNT0_REG 0x540
2345 #define TSI_DCNT1_REG 0x54c
2346
2347
2348 #define TSI_DDBS_REG(i) TSI_DMA_REG(0x544,i)
2349 #define TSI_DDBS0_REG 0x544
2350 #define TSI_DDBS1_REG 0x5c4
2351
2352
2353 static uint32_t
2354 vme_attr(uint32_t xfer_mode)
2355 {
2356 uint32_t vme_mode;
2357 unsigned long ul;
2358 if ( am2omode(xfer_mode, &ul) )
2359 return BSP_VMEDMA_STATUS_UNSUP;
2360 vme_mode = (uint32_t) ul;
2361
2362
2363 vme_mode &= TSI_DXAT_OTAT_MSK;
2364 vme_mode |= TSI_DXAT_TYP_VME;
2365
2366 if ( BSP_VMEDMA_MODE_NOINC_VME & xfer_mode ) {
2367
2368 if ( (BSP_VMEDMA_MODE_PCI2VME & xfer_mode) )
2369 return BSP_VMEDMA_STATUS_UNSUP;
2370 vme_mode |= TSI_DSAT_NIN;
2371 }
2372
2373 return vme_mode;
2374 }
2375
2376 static uint32_t
2377 pci_attr(uint32_t xfer_mode)
2378 {
2379 uint32_t pci_mode = 0;
2380 if ( BSP_VMEDMA_MODE_NOINC_PCI & xfer_mode ) {
2381
2382 if ( ! (BSP_VMEDMA_MODE_PCI2VME & xfer_mode) )
2383 return BSP_VMEDMA_STATUS_UNSUP;
2384 pci_mode |= TSI_DSAT_NIN;
2385 }
2386 return pci_mode;
2387 }
2388
2389 static void tsi_desc_init(DmaDescriptor p)
2390 {
2391 VmeTsi148DmaListDescriptor d = p;
2392 st_be32( &d->dnlau, 0 );
2393 st_be32( &d->dnlal, TSI_DNLAL_LLA );
2394 st_be32( &d->ddbs, (1<<22)-1 );
2395 }
2396
2397 static void
2398 tsi_desc_setnxt(DmaDescriptor p, DmaDescriptor n)
2399 {
2400 VmeTsi148DmaListDescriptor d = p;
2401 if ( 0 == n ) {
2402 st_be32( &d->dnlal, TSI_DNLAL_LLA );
2403 } else {
2404 st_be32( &d->dnlal, BSP_LOCAL2PCI_ADDR((uint32_t)n) );
2405 }
2406 }
2407
2408 static void
2409 tsi_desc_dump(DmaDescriptor p)
2410 {
2411 VmeTsi148DmaListDescriptor d = p;
2412 printf(" DSA: 0x%08" PRIx32 "%08" PRIx32 "\n", ld_be32(&d->dsau), ld_be32(&d->dsal));
2413 printf(" DDA: 0x%08" PRIx32 "%08" PRIx32 "\n", ld_be32(&d->ddau), ld_be32(&d->ddal));
2414 printf(" NLA: 0x%08" PRIx32 "%08" PRIx32 "\n", ld_be32(&d->dnlau), ld_be32(&d->dnlal));
2415 printf(" SAT: 0x%08" PRIx32 " DAT: 0x%08" PRIx32 "\n", ld_be32(&d->dsat), ld_be32(&d->ddat));
2416 printf(" CNT: 0x%08" PRIx32 "\n", ld_be32(&d->dcnt));
2417 }
2418
2419
2420 int
2421 vmeTsi148DmaSetupXX(BERegister *base, int channel, uint32_t mode, uint32_t xfer_mode, void *custom)
2422 {
2423 uint32_t ctl = 0;
2424 uint32_t vmeatt, pciatt, sat, dat;
2425
2426 if ( channel < 0 || channel > 1 )
2427 return BSP_VMEDMA_STATUS_UNSUP;
2428
2429
2430 if ( (uint32_t)BSP_VMEDMA_STATUS_UNSUP == (vmeatt = vme_attr(xfer_mode)) )
2431 return -2;
2432
2433
2434 if ( (uint32_t)BSP_VMEDMA_STATUS_UNSUP == (pciatt = pci_attr(xfer_mode)) )
2435 return -3;
2436
2437
2438 ctl |= TSI_DCTL_PBKS_32;
2439 ctl |= (BSP_VMEDMA_OPT_THROUGHPUT == mode ? TSI_DCTL_PBOT_0us : TSI_DCTL_PBOT_1us);
2440
2441 switch ( mode ) {
2442 case BSP_VMEDMA_OPT_THROUGHPUT:
2443 ctl |= TSI_DCTL_VBKS_1024;
2444 ctl |= TSI_DCTL_VBOT_0us;
2445 break;
2446
2447 case BSP_VMEDMA_OPT_LOWLATENCY:
2448 ctl |= TSI_DCTL_VBKS_32;
2449 ctl |= TSI_DCTL_VBOT_0us;
2450 break;
2451
2452 case BSP_VMEDMA_OPT_SHAREDBUS:
2453 ctl |= TSI_DCTL_VBKS_128;
2454 ctl |= TSI_DCTL_VBOT_64us;
2455 break;
2456
2457 case BSP_VMEDMA_OPT_CUSTOM:
2458 ctl = *(uint32_t*)custom;
2459 break;
2460
2461 default:
2462 case BSP_VMEDMA_OPT_DEFAULT:
2463 ctl = 0;
2464 break;
2465 }
2466 TSI_WR(base, TSI_DCTL_REG(channel), ctl);
2467 if ( BSP_VMEDMA_MODE_PCI2VME & xfer_mode ) {
2468 dat = vmeatt; sat = pciatt;
2469 } else {
2470 sat = vmeatt; dat = pciatt;
2471 }
2472 TSI_WR(base, TSI_DSAT_REG(channel), sat);
2473 TSI_WR(base, TSI_DDAT_REG(channel), dat);
2474 return 0;
2475 }
2476
2477 int
2478 vmeTsi148DmaSetup(int channel, uint32_t mode, uint32_t xfer_mode, void *custom)
2479 {
2480 BERegister *base = THEBASE;
2481 return vmeTsi148DmaSetupXX(base, channel, mode, xfer_mode, custom);
2482 }
2483
2484
2485 int
2486 vmeTsi148DmaListStartXX(BERegister *base, int channel, VmeTsi148DmaListDescriptor d)
2487 {
2488 uint32_t ctl;
2489
2490 if ( d ) {
2491
2492 if ( channel < 0 || channel > 1 )
2493 return BSP_VMEDMA_STATUS_UNSUP;
2494
2495 if ( TSI_DSTA_BSY & TSI_RD(base, TSI_DSTA_REG(channel)) )
2496 return BSP_VMEDMA_STATUS_BUSY;
2497
2498 TSI_WR(base, TSI_DNLAL_REG(channel), (uint32_t)BSP_LOCAL2PCI_ADDR(d));
2499
2500 asm volatile("":::"memory");
2501
2502
2503 ctl = TSI_RD(base, TSI_DCTL_REG(channel)) | TSI_DCTL_DGO;
2504 ctl &= ~TSI_DCTL_MOD;
2505 TSI_WR(base, TSI_DCTL_REG(channel), ctl);
2506 }
2507
2508 return 0;
2509 }
2510
2511 int
2512 vmeTsi148DmaListStart(int channel, VmeTsi148DmaListDescriptor d)
2513 {
2514 BERegister *base = THEBASE;
2515 return vmeTsi148DmaListStartXX(base, channel, d);
2516 }
2517
2518 int
2519 vmeTsi148DmaStartXX(BERegister *base, int channel, uint32_t pci_addr, uint32_t vme_addr, uint32_t n_bytes)
2520 {
2521 uint32_t src, dst, ctl;
2522
2523 if ( channel < 0 || channel > 1 )
2524 return BSP_VMEDMA_STATUS_UNSUP;
2525
2526 if ( TSI_DSTA_BSY & TSI_RD(base, TSI_DSTA_REG(channel)) )
2527 return BSP_VMEDMA_STATUS_BUSY;
2528
2529
2530 if ( TSI_DXAT_TYP_VME & TSI_RD(base, TSI_DDAT_REG(channel)) ) {
2531 dst = vme_addr;
2532 src = pci_addr;
2533 } else {
2534 src = vme_addr;
2535 dst = pci_addr;
2536 }
2537
2538
2539
2540 TSI_WR(base, TSI_DSAL_REG(channel), src);
2541 TSI_WR(base, TSI_DDAL_REG(channel), dst);
2542 TSI_WR(base, TSI_DCNT_REG(channel), n_bytes);
2543
2544 asm volatile("":::"memory");
2545
2546
2547 ctl = TSI_RD(base, TSI_DCTL_REG(channel)) | TSI_DCTL_DGO | TSI_DCTL_MOD;
2548 TSI_WR(base, TSI_DCTL_REG(channel), ctl);
2549
2550 return 0;
2551 }
2552
2553 int
2554 vmeTsi148DmaStart(int channel, uint32_t pci_addr, uint32_t vme_addr, uint32_t n_bytes)
2555 {
2556 BERegister *base = THEBASE;
2557 return vmeTsi148DmaStartXX(base, channel, pci_addr, vme_addr, n_bytes);
2558 }
2559
2560 uint32_t
2561 vmeTsi148DmaStatusXX(BERegister *base, int channel)
2562 {
2563 uint32_t st = TSI_RD(base, TSI_DSTA_REG(channel));
2564
2565 if ( channel < 0 || channel > 1 )
2566 return BSP_VMEDMA_STATUS_UNSUP;
2567
2568 st = TSI_RD(base, TSI_DSTA_REG(channel));
2569
2570
2571 if ( (TSI_DSTA_DON & st) || 0 == st )
2572 return BSP_VMEDMA_STATUS_OK;
2573
2574 if ( TSI_DSTA_BSY & st )
2575 return BSP_VMEDMA_STATUS_BUSY;
2576
2577 if ( TSI_DSTA_ERR & st ) {
2578 if ( TSI_DSTA_ERRS & st )
2579 return BSP_VMEDMA_STATUS_BERR_PCI;
2580 if ( ! (TSI_DSTA_ERT_SLVE_E & st) )
2581 return BSP_VMEDMA_STATUS_BERR_VME;
2582 }
2583
2584 return BSP_VMEDMA_STATUS_OERR;
2585 }
2586
2587 uint32_t
2588 vmeTsi148DmaStatus(int channel)
2589 {
2590 BERegister *base = THEBASE;
2591 return vmeTsi148DmaStatusXX(base, channel);
2592 }
2593
2594 #define ALL_BITS_NEEDED (BSP_VMEDMA_MSK_ATTR | BSP_VMEDMA_MSK_PCIA | BSP_VMEDMA_MSK_VMEA)
2595
2596 static int
2597 tsi_desc_setup (
2598 DmaDescriptor p,
2599 uint32_t attr_mask,
2600 uint32_t xfer_mode,
2601 uint32_t pci_addr,
2602 uint32_t vme_addr,
2603 uint32_t n_bytes)
2604 {
2605 VmeTsi148DmaListDescriptor d = p;
2606 uint32_t vmeatt = 0, pciatt = 0, tmp, src, dst, dat, sat;
2607
2608
2609
2610
2611
2612
2613
2614
2615 tmp = attr_mask & ALL_BITS_NEEDED;
2616 if ( tmp != 0 && tmp != ALL_BITS_NEEDED )
2617 return -1;
2618
2619 if ( BSP_VMEDMA_MSK_ATTR & attr_mask ) {
2620
2621 vmeatt = vme_attr(xfer_mode);
2622 if ( (uint32_t)BSP_VMEDMA_STATUS_UNSUP == vmeatt )
2623 return -1;
2624
2625
2626 pciatt = pci_attr(xfer_mode);
2627 if ( (uint32_t)BSP_VMEDMA_STATUS_UNSUP == pciatt )
2628 return -1;
2629 }
2630
2631 if ( BSP_VMEDMA_MSK_ATTR & attr_mask ) {
2632 if ( BSP_VMEDMA_MODE_PCI2VME & xfer_mode ) {
2633 dat = vmeatt; sat = pciatt;
2634 dst = vme_addr; src = pci_addr;
2635 } else {
2636 sat = vmeatt; dat = pciatt;
2637 src = vme_addr; dst = pci_addr;
2638 }
2639 st_be32( &d->dsau, 0 ); st_be32( &d->dsal, src );
2640 st_be32( &d->ddau, 0 ); st_be32( &d->ddal, dst );
2641 st_be32( &d->dsat, sat ); st_be32( &d->ddat, dat );
2642 }
2643
2644 if ( BSP_VMEDMA_MSK_BCNT & attr_mask )
2645 st_be32( &d->dcnt, n_bytes);
2646
2647 return 0;
2648 }
2649
2650 static int
2651 tsi_desc_start (volatile void *controller_addr, int channel, DmaDescriptor p)
2652 {
2653 VmeTsi148DmaListDescriptor d = p;
2654 if ( !controller_addr )
2655 controller_addr = THEBASE;
2656 return vmeTsi148DmaListStartXX((BERegister*)controller_addr, channel, d);
2657 }
2658
2659 #ifdef DEBUG_MODULAR
2660 void
2661 _cexpModuleInitialize(void* unused)
2662 {
2663 vmeTsi148Init();
2664 vmeTsi148Reset();
2665 }
2666
2667 int
2668 _cexpModuleFinalize(void *unused)
2669 {
2670 int i;
2671 int rval = 1;
2672 void (*isrs[TSI_NUM_WIRES])() = {
2673 isr_pin0,
2674 isr_pin1,
2675 isr_pin2,
2676 isr_pin3,
2677 };
2678
2679 rtems_irq_connect_data xx;
2680 xx.on = my_no_op;
2681 xx.off = my_no_op;
2682 xx.isOn = my_isOn;
2683
2684 TSI_WR(THEBASE, TSI_INTEO_REG, 0);
2685
2686 for ( i=0; i<TSI_NUM_INT_VECS; i++) {
2687
2688 }
2689 if ( vmeTsi148IrqMgrInstalled ) {
2690 for ( i=0; i<TSI_NUM_WIRES; i++ ) {
2691 if ( (int)(xx.name = devs[0].pic_pin[i]) >=0 ) {
2692 xx.hdl = isrs[i];
2693 rval = rval && BSP_remove_rtems_irq_handler(&xx);
2694 }
2695 }
2696 }
2697 return !rval;
2698 }
2699 #endif