2 |
- |
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
|
|
|
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
|
|
|
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
|
|
|
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 |
|