xref: /plan9/sys/src/9/ppc/mcc.c (revision 458db83292ea45506704800dedf36a95598fc2ec)
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8 
9 /*
10  *
11  * mcc.c
12  *
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
17  * external interface.
18  *
19  * Neville Chandler
20  * Lucent Technologies - Bell Labs
21  * March 2001
22  *
23  */
24 
25 #define	PKT_LEN			40
26 #define MPC82XX_INIT_DELAY      0x10000
27 
28 #define HPIC		0xFC000000
29 #define HPIA		0xFC000010
30 #define HPID_A		0xFC000020
31 #define HPID		0xFC000030
32 
33 
34 #include "mcc2.h"
35 
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 * );
42 
43 void MPC82xxCpmInit( void );
44 void PortInit( void );
45 void PortSelectPin( unsigned short );
46 
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 *);
53 
54 void InitLinkedList( void );
55 boolean DwCreateList( ListDB * );
56 void *DwMalloc( U32 );
57 void DwFree( U32, void * );
58 
59 void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
60 
61 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
62 
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;
71 
72 //static void disp_led( unsigned char );
73 
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 );
82 
83 static	int	mcc2_major = MCC_MAJOR;
84 
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 ** );
90 void	AppInit( void );
91 
92 #define physaddr(ADDR)	(0x60020000 | ((ADDR) << 23) | (2 << 18))
93 
94 mcc_iorw_t mcc_iorw;
95 
96 #if 0
97 typedef struct mcc_io {
98 	unsigned int	cmd;
99         unsigned int    address;
100         unsigned int    *buf;
101 	int		ind;
102         int             nbytes;
103 	siramctl_t	SiRam;
104 	cpmux_t		CpMux;
105 	mcc_t		Mcc_T;
106 	iop8260_t	Io_Ports;
107 } mcc_iorw_t;
108 #endif
109 
110 static void
ioctl_parm(unsigned int loop_mode)111 ioctl_parm( unsigned int loop_mode )
112 {
113 
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 */
125 }
126 
127 #if 0
128 static void
disp_led(unsigned char byte)129 disp_led( unsigned char byte )
130 {
131      //int i;
132 
133      *leds = byte;
134      //for(i=0; i<1000; i++);
135 
136 }
137 #endif
138 
139 
140 
141 static ssize_t
mcc2_ioctl(struct inode * inode,struct file * file,unsigned int ioctl_cmd,unsigned long param)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
146 {
147 	static unsigned char mode;
148 	char cp, *cptr;
149 	void *vptr;
150 	unsigned long *lptr;
151 	int i, j;
152 	unsigned int ld;
153 	unsigned long lng;
154 	volatile immap_t *Mmap;
155 
156 	cptr = (char *)param;
157 	mode = (unsigned char)*cptr;
158 	Mmap = ((volatile immap_t *)IMAP_ADDR);
159 	switch(ioctl_cmd)
160 	{
161 		case IOCTL_SET_MODE:
162 			    //mode = (unsigned char)*param;
163 			    mode = ((mcc_iorw_t *)param)->cmd;
164 			    switch( mode )
165 			    {
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  */
170 					break;
171 
172 				case AUTOMATIC_ECHO:
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  */
176 					break;
177 
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  */
182 					break;
183 
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  */
188 					break;
189 
190 
191 				default:
192 					printk("mcc2_ioctl: Error, unrecognized ioctl parameter, device operation unchanged.\n");
193 					break;
194 
195 			    }
196 			break;
197 
198 		case IOCTL_RWX_MODE:
199 			mode = ((mcc_iorw_t *)param)->cmd;
200 			switch(mode)
201 			{
202 				case HPI_RD:
203 					lng = (long)(((mcc_iorw_t *)param)->address);
204 					lptr =  ((unsigned long *)lng);
205 					vptr = (void *)lptr;
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");
208 						return -EFAULT;
209 					}
210 					break;
211 
212 
213 				case HPI_WR:
214 					lng = (long)(((mcc_iorw_t *)param)->address);
215 					lptr =  ((unsigned long *)lng);
216 					vptr = (void *)lptr;
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");
219 						return -EFAULT;
220 					}
221 					break;
222 
223 
224 
225                                 case FPGA_RD:
226                                         lng = (long)(((mcc_iorw_t *)param)->address);
227                                         lptr =  ((unsigned long *)lng);
228                                         vptr = (void *)lptr;
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");
231                                                 return -EFAULT;
232                                         }
233                                         break;
234 
235 
236                                 case FPGA_WR:
237                                         lng = (long)(((mcc_iorw_t *)param)->address);
238                                         lptr =  ((unsigned long *)lng);
239                                         vptr = (void *)lptr;
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");
242                                                 return -EFAULT;
243                                         }
244                                         break;
245 
246 
247 
248 
249 
250 				case MEM_MODR:
251 					cptr = (char *)Mmap;
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");
255 						return -EFAULT;
256 					}
257 					break;
258 
259 				case MEM_MODW:
260 					cptr = (char *)Mmap;
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");
264 						return -EFAULT;
265 					}
266 					break;
267 
268 				case IO_PORTS:
269 					break;
270 				case SI_RAM_CTL1:
271 					break;
272 				case SI_RAM_CTL2:
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");
275 						return -EFAULT;
276 					}
277 					break;
278 
279 
280 
281 				default:
282 					break;
283 			}
284 			break;
285 
286 				default:
287 					//if (copy_to_user((void *)param, &mode, sizeof(mode)))
288 					printk("We are at the end ...\n");
289 					return -EFAULT;
290 					break;
291 			}
292 			break;
293 
294 		default:
295 			break;
296 	}
297 
298 	return 0;
299 }
300 
301 
302 ////////////////////////////////////////////////////////////////////////////////
303 //
304 ////////////////////////////////////////////////////////////////////////////////
305 
306 static ssize_t
307 mcc2_open( struct inode *inode, struct file *file )
308 {
309 	MOD_INC_USE_COUNT;
310 	return 0;
311 }
312 
313 
314 
315 ////////////////////////////////////////////////////////////////////////////////
316 //
317 ////////////////////////////////////////////////////////////////////////////////
318 
319 static int
320 mcc2_release( struct inode *inode, struct file *file )
321 {
322 	MOD_DEC_USE_COUNT;
323 	return 0;
324 }
325 
326 
327 
328 
329 
330 
331 #ifndef MODULE
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 //
335 ////////////////////////////////////////////////////////////////////////////////
336 
337 long
338 mcc2_init( long mem_start, long mem_end )
339 {
340 
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);
343 	else {
344 		//MPC82xxSiuInit();
345 		MPC82xxCpmInit();
346 	}
347 	return mem_start;
348 }
349 
350 #else
351 
352