2 #include "../port/lib.h"
7 #include "../port/error.h"
13 * This is the driver for the Multi-Channel Communications Controller
14 * of the MPC8260. This version is constructed for the EST SBC8260 to
15 * handle data from an interface to an offboard T1 framer. The driver
16 * supports MCC2 + TDM A:2 (channel 128) which is connected to the
20 * Lucent Technologies - Bell Labs
26 #define MPC82XX_INIT_DELAY 0x10000
28 #define HPIC 0xFC000000
29 #define HPIA 0xFC000010
30 #define HPID_A 0xFC000020
31 #define HPID 0xFC000030
36 static ssize_t mcc2_read( struct file *, char *, size_t, loff_t * );
37 static ssize_t mcc2_write( struct file *, const char *, size_t, loff_t *);
38 static loff_t mcc2_lseek( struct file *, loff_t, int );
39 static int mcc2_release( struct inode *, struct file * );
40 static ssize_t mcc2_ioctl( struct inode *, struct file *, unsigned int, unsigned long );
41 //static ssize_t mcc2_ioctl( struct inode *, struct file *, unsigned int, char * );
43 void MPC82xxCpmInit( void );
44 void PortInit( void );
45 void PortSelectPin( unsigned short );
47 void InitMemAlloc( void );
48 void HeapCreate( U32, U32, U32, U32, char *);
49 void HeapCreate( U32, U32, U32, U32, char *);
50 void *HeapSearchMem( U32, U32);
51 void *HeapAllocMem( U32, U32);
52 void HeapFreeMem( U32, void *);
54 void InitLinkedList( void );
55 boolean DwCreateList( ListDB * );
56 void *DwMalloc( U32 );
57 void DwFree( U32, void * );
59 void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
61 #define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
63 extern int ppc_spurious_interrupts;
64 extern int ppc_second_irq;
65 extern struct irqaction *ppc_irq_action[NR_IRQS];
66 extern unsigned int ppc_local_bh_count[NR_CPUS];
67 extern unsigned int ppc_local_irq_count[NR_CPUS];
68 extern unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
69 extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
70 extern atomic_t ppc_n_lost_interrupts;
72 //static void disp_led( unsigned char );
74 void Mcc2Init( void );
75 void MccDisable( unsigned char );
76 void MccEnable( unsigned char, unsigned char, unsigned char );
77 void MccRiscCmd( unsigned char, dwv_RISC_OPCODE, unsigned char );
78 boolean MccTest( void );
79 int MccTxBuffer( unsigned char, unsigned char, char *, unsigned short, unsigned short );
80 extern U32 PpcDisable( void );
81 extern void PpcMsrRestore( U32 );
83 static int mcc2_major = MCC_MAJOR;
85 static BOOLEAN insertBD_T( BD_PFIFO *, BD_P );
86 static BOOLEAN removBD_T( BD_PFIFO *, BD_P * );
87 BOOLEAN empty(volatile register FIFO *);
88 int insert( FIFO *, char * );
89 int remove( FIFO *, char ** );
92 #define physaddr(ADDR) (0x60020000 | ((ADDR) << 23) | (2 << 18))
97 typedef struct mcc_io {
111 ioctl_parm( unsigned int loop_mode )
114 /* Setup the SIMODE Register */
115 Si2Regs->SiAmr = SIxMR_SAD_BANK0_FIRST_HALF | /* SADx */
116 loop_mode | /* SDMx */
117 SIxMR_NO_BIT_RX_SYNC_DELAY | /* RFSDx */
118 SIxMR_DSC_CH_DATA_CLK_EQU | /* DSCx */
119 SIxMR_CRT_SPEPARATE_PINS | /* CRTx */
120 SIxMR_SLx_NORMAL_OPERATION | /* SLx */
121 SIxMR_CE_TX_RISING_RX_FALLING | /* CEx */
122 SIxMR_FE_FALLING_EDGE | /* FEx */
123 SIxMR_GM_GCI_SCIT_MODE | /* GMx */
124 SIxMR_NO_BIT_TX_SYNC_DELAY; /* TFSDx */
129 disp_led( unsigned char byte )
134 //for(i=0; i<1000; i++);
142 mcc2_ioctl( struct inode *inode, struct file *file,
143 unsigned int ioctl_cmd, // IOCTL number
144 unsigned long param )
145 // char *param ) // IOCTL parameter
147 static unsigned char mode;
154 volatile immap_t *Mmap;
156 cptr = (char *)param;
157 mode = (unsigned char)*cptr;
158 Mmap = ((volatile immap_t *)IMAP_ADDR);
162 //mode = (unsigned char)*param;
163 mode = ((mcc_iorw_t *)param)->cmd;
166 case NORMAL_OPERATION:
167 /* Setup the SIMODE Register */
168 D( printk("mcc2_ioctl: ioctl set NORMAL_OPERATION mode\n"); )
169 ioctl_parm( (unsigned int)SIxMR_SDM_NORMAL_OPERATION ); /* SDMx */
173 /* Setup the SIMODE Register */
174 D( printk("mcc2_ioctl: ioctl set AUTOMATIC_ECHO mode\n"); )
175 ioctl_parm( (unsigned int)SIxMR_SDM_AUTOMATIC_ECHO ); /* SDMx */
178 case INTERNAL_LOOPBACK:
179 /* Setup the SIMODE Register */
180 D( printk("mcc2_ioctl: ioctl set INTERNAL_LOOPBACK mode\n"); )
181 ioctl_parm( (unsigned int)SIxMR_SDM_INTERNAL_LOOPBACK ); /* SDMx */
184 case LOOPBACK_CONTROL:
185 /* Setup the SIMODE Register */
186 D( printk("mcc2_ioctl: ioctl set LOOPBACK_CONTROL mode\n"); )
187 ioctl_parm( (unsigned int)SIxMR_SDM_LOOPBACK_CONTROL ); /* SDMx */
192 printk("mcc2_ioctl: Error, unrecognized ioctl parameter, device operation unchanged.\n");
199 mode = ((mcc_iorw_t *)param)->cmd;
203 lng = (long)(((mcc_iorw_t *)param)->address);
204 lptr = ((unsigned long *)lng);
206 if (copy_to_user( (((mcc_iorw_t *)param)->buf), (void *)vptr, (((mcc_iorw_t *)param)->nbytes))) {
207 printk("mcc2_ioctl: Failed during read from hpi.\n");
214 lng = (long)(((mcc_iorw_t *)param)->address);
215 lptr = ((unsigned long *)lng);
217 if (copy_from_user( (void *)vptr, (((mcc_iorw_t *)param)->buf), (((mcc_iorw_t *)param)->nbytes))) {
218 printk("mcc2_ioctl: Failed during write to hpi\n");
226 lng = (long)(((mcc_iorw_t *)param)->address);
227 lptr = ((unsigned long *)lng);
229 if (copy_to_user( (((mcc_iorw_t *)param)->buf), (void *)vptr, (((mcc_iorw_t *)param)->nbytes))) {
230 printk("mcc2_ioctl: Failed during read from FPGA.\n");
237 lng = (long)(((mcc_iorw_t *)param)->address);
238 lptr = ((unsigned long *)lng);
240 if (copy_from_user( (void *)vptr, (((mcc_iorw_t *)param)->buf), (((mcc_iorw_t *)param)->nbytes))) {
241 printk("mcc2_ioctl: Failed during write to FPGA\n");
252 cptr += ((mcc_iorw_t *)param)->address;
253 if (copy_to_user( (((mcc_iorw_t *)param)->buf), (void *)cptr, (((mcc_iorw_t *)param)->nbytes))) {
254 printk("mcc2_ioctl: Failed during read of read-modify memory\n");
261 cptr += ((mcc_iorw_t *)param)->address;
262 if (copy_from_user( (void *)cptr, (((mcc_iorw_t *)param)->buf), (((mcc_iorw_t *)param)->nbytes))) {
263 printk("mcc2_ioctl: Failed during modify of read-modify memory\n");
273 if (copy_to_user( (void *)param, (siramctl_t *)&(Mmap->im_siramctl2), sizeof(siramctl_t))) {
274 printk("mcc2_ioctl: Failed to copy SI_RAM_CTL2 struct\n");
287 //if (copy_to_user((void *)param, &mode, sizeof(mode)))
288 printk("We are at the end ...\n");
302 ////////////////////////////////////////////////////////////////////////////////
304 ////////////////////////////////////////////////////////////////////////////////
307 mcc2_open( struct inode *inode, struct file *file )
315 ////////////////////////////////////////////////////////////////////////////////
317 ////////////////////////////////////////////////////////////////////////////////
320 mcc2_release( struct inode *inode, struct file *file )
333 ////////////////////////////////////////////////////////////////////////////////
335 ////////////////////////////////////////////////////////////////////////////////
338 mcc2_init( long mem_start, long mem_end )
341 if ((mcc2_major = register_chrdev(MCC_MAJOR, MCC_NAME, &mcc2_fops)))
342 printk("mcc2_init: Unable to get major for mcc2 device %d\n", MCC_MAJOR);