1 /*
2  * Diva Server 4BRI specific part of initialisation
3  *
4  * Copyright (C) Eicon Technology Corporation, 2000.
5  *
6  * Eicon File Revision :    1.7
7  *
8  * This software may be used and distributed according to the terms
9  * of the GNU General Public License, incorporated herein by reference.
10  *
11  */
12 
13 #include "sys.h"
14 #include "idi.h"
15 #include "divas.h"
16 #include "pc.h"
17 #include "pr_pc.h"
18 #include "dsp_defs.h"
19 #include "constant.h"
20 #include "adapter.h"
21 #include "uxio.h"
22 
23 #define TEST_INT_DIVAS_Q	0x13
24 
25 #define	DIVAS_MAINT_OFFSET	0xff00	/* value for 4BRI card */
26 #define MQ_BOARD_DSP_OFFSET 0x00a00000
27 #define MQ_DSP1_ADDR_OFFSET 0x00000008
28 #define MQ_DSP_JUNK_OFFSET  0x00000400
29 #define MQ_DSP1_DATA_OFFSET 0x00000000
30 #define MQ_BOARD_ISAC_DSP_RESET  0x00800028
31 #define MQ_BREG_RISC  0x1200      /* RISC Reset */
32 #define MQ_ISAC_DSP_RESET 0x0028 /* ISAC and DSP reset address offset */
33 #define MQ_RISC_COLD_RESET_MASK         0x0001      /* RISC Cold reset                        */
34 #define MQ_RISC_WARM_RESET_MASK         0x0002      /* RISC Warm reset                        */
35 #define MQ_IRQ_REQ_ON                   0x1
36 #define MQ_IRQ_REQ_OFF                  0x0
37 #define MQ_BREG_IRQ_TEST                0x0608
38 #define PLX9054_INTCSR      0x69
39 #define PLX9054_INT_ENA     0x09
40 
41 #define DIVAS_IOBASE	0x01
42 #define M_PCI_RESET	0x10
43 
44 byte mem_in(ADAPTER *a, void *adr);
45 word mem_inw(ADAPTER *a, void *adr);
46 void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);
47 void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
48 void mem_out(ADAPTER *a, void *adr, byte data);
49 void mem_outw(ADAPTER *a, void *adr, word data);
50 void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);
51 void mem_inc(ADAPTER *a, void *adr);
52 
53 int Divas4BRIInitPCI(card_t *card, dia_card_t *cfg);
54 static int fourbri_ISR (card_t* card);
55 
56 int FPGA_Download(word, dword, byte *, byte *, int);
57 extern byte FPGA_Bytes[];
58 extern void *get_card(int);
59 
60 byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);
61 void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);
62 word GetProtFeatureValue(char *sw_id);
63 
64 void memcp(byte *dst, byte *src, dword dwLen);
65 int memcm(byte *dst, byte *src, dword dwLen);
66 
diva_server_4bri_reset(card_t * card)67 static int diva_server_4bri_reset(card_t *card)
68 {
69 	byte *ctl;
70 
71 	DPRINTF(("divas: reset Diva Server 4BRI"));
72 
73 	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
74 
75 	/* stop RISC, DSP's and ISAC  */
76    UxCardMemOut(card->hw, &ctl[MQ_BREG_RISC], 0);
77    UxCardMemOut(card->hw, &ctl[MQ_ISAC_DSP_RESET], 0);
78 
79 	UxCardMemDetach(card->hw, ctl);
80 
81 	return 0;
82 }
83 
diva_server_4bri_config(card_t * card,dia_config_t * config)84 static int diva_server_4bri_config(card_t *card, dia_config_t *config)
85 {
86 	byte *shared;
87 	int i, j;
88 
89 	DPRINTF(("divas: configure Diva Server 4BRI"));
90 
91 	shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
92 
93 	for (i=0; i<256; i++)
94 	{
95 		UxCardMemOut(card->hw, &shared[i], 0);
96 	}
97 
98 	UxCardMemOut(card->hw, &shared[ 8], config->tei);
99 	UxCardMemOut(card->hw, &shared[ 9], config->nt2);
100 	UxCardMemOut(card->hw, &shared[10], config->sig_flags);
101 	UxCardMemOut(card->hw, &shared[11], config->watchdog);
102 	UxCardMemOut(card->hw, &shared[12], config->permanent);
103 	UxCardMemOut(card->hw, &shared[13], config->x_interface);
104 	UxCardMemOut(card->hw, &shared[14], config->stable_l2);
105 	UxCardMemOut(card->hw, &shared[15], config->no_order_check);
106 	UxCardMemOut(card->hw, &shared[16], config->handset_type);
107 	UxCardMemOut(card->hw, &shared[17], 0);
108 	UxCardMemOut(card->hw, &shared[18], config->low_channel);
109 	UxCardMemOut(card->hw, &shared[19], config->prot_version);
110 	UxCardMemOut(card->hw, &shared[20], config->crc4);
111 
112 	if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
113 	{
114 		DPRINTF(("divas: Signifying V.90"));
115 		UxCardMemOut(card->hw, &shared[22], 4);
116 	}
117 	else
118 	{
119 		UxCardMemOut(card->hw, &shared[22], 0);
120 	}
121 
122 	for (i=0; i<2; i++)
123 	{
124 		for (j=0; j<32; j++)
125 		{
126 			UxCardMemOut(card->hw, &shared[32+(i*96)+j],config->terminal[i].oad[j]);
127 		}
128 
129 		for (j=0; j<32; j++)
130 		{
131 			UxCardMemOut(card->hw, &shared[64+(i*96)+j],config->terminal[i].osa[j]);
132 		}
133 
134 		for (j=0; j<32; j++)
135 		{
136 			UxCardMemOut(card->hw, &shared[96+(i*96)+j],config->terminal[i].spid[j]);
137 		}
138 	}
139 
140 	UxCardMemDetach(card->hw, shared);
141 
142 	return 0;
143 }
144 
145 static
diva_server_4bri_reset_int(card_t * card)146 void diva_server_4bri_reset_int(card_t *card)
147 {
148 	byte *ctl;
149 
150 	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
151 
152 	UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);
153 
154 	UxCardMemDetach(card->hw, ctl);
155 
156 	return;
157 }
158 
159 
diva_server_4bri_test_int(card_t * card)160 static int diva_server_4bri_test_int(card_t *card)
161 {
162 	byte *ctl, i;
163 	byte *reg;
164 
165 	DPRINTF(("divas: test interrupt for Diva Server 4BRI"));
166 
167 	/* We get the last (dummy) adapter in so we need to go back to the first */
168 
169 	card = get_card(card->cfg.card_id - 3);
170 
171 	/* Enable interrupts on PLX chip */
172 
173 	reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);
174 
175 	UxCardPortIoOut(card->hw, reg, PLX9054_INTCSR, PLX9054_INT_ENA);
176 
177 	UxCardMemDetach(card->hw, reg);
178 
179 	/* Set the test interrupt flag */
180 	card->test_int_pend = TEST_INT_DIVAS_Q;
181 
182 	/* Now to trigger the interrupt */
183 
184 	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
185 
186 	UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_ON);
187 
188 	UxCardMemDetach(card->hw, ctl);
189 
190 	for (i = 0; i < 50; i++)
191 	{
192 		if (!card->test_int_pend)
193 		{
194 			break;
195 		}
196 		UxPause(10);
197 	}
198 
199 	if (card->test_int_pend)
200 	{
201 		DPRINTF(("active: timeout waiting for card to interrupt"));
202 		return (-1);
203 	}
204 
205 	return 0;
206 }
207 
208 
print_hdr(unsigned char * code,int offset)209 static void print_hdr(unsigned char *code, int offset)
210 {
211 	unsigned char hdr[80];
212 	int i;
213 
214 	i = 0;
215 
216 	while ((i < (DIM(hdr) -1)) &&
217 		(code[offset + i] != '\0') &&
218 		(code[offset + i] != '\r') &&
219 		(code[offset + i] != '\n'))
220 	{
221 		hdr[i] = code[offset + i];
222 		i++;
223 	}
224 
225 	hdr[i] = '\0';
226 
227 	DPRINTF(("divas: loading %s", hdr));
228 }
229 
diva_server_4bri_load(card_t * card,dia_load_t * load)230 static int diva_server_4bri_load(card_t *card, dia_load_t *load)
231 {
232 	byte *pRAM=NULL;
233 	int download_offset=0;
234 	card_t *FirstCard;
235 	byte sw_id[80];
236 
237 	DPRINTF(("divas: loading Diva Server 4BRI[%d]", load->card_id));
238 
239 	switch(load->code_type)
240 	{
241 		case DIA_CPU_CODE:
242 			DPRINTF(("divas: RISC code"));
243 			print_hdr(load->code, 0x80);
244 			card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]);
245 			download_offset = 0; // Protocol code written to offset 0
246 			pRAM = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
247 			break;
248 
249 		case DIA_DSP_CODE:
250 			DPRINTF(("divas: DSP code"));
251 			print_hdr(load->code, 0x0);
252 			FirstCard = get_card(load->card_id - 3);
253 			if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
254 			{
255 				download_offset = MQ_V90D_DSP_CODE_BASE;
256 			}
257 			else
258 			{
259 				download_offset = MQ_ORG_DSP_CODE_BASE;
260 			}
261 			pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
262 			download_offset += (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC);
263 
264 			break;
265 
266 		case DIA_TABLE_CODE:
267 			DPRINTF(("divas: TABLE code"));
268 			FirstCard = get_card(load->card_id - 3);
269 			if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
270 			{
271 				download_offset = MQ_V90D_DSP_CODE_BASE + sizeof(dword);
272 			}
273 			else
274 			{
275 				download_offset = MQ_ORG_DSP_CODE_BASE + sizeof(dword);
276 			}
277 			pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
278 			break;
279 
280 		case DIA_CONT_CODE:
281 			DPRINTF(("divas: continuation code"));
282 			break;
283 
284         case DIA_DLOAD_CNT:
285 			DPRINTF(("divas: COUNT code"));
286 			FirstCard = get_card(load->card_id - 3);
287 			if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
288 			{
289 				download_offset = MQ_V90D_DSP_CODE_BASE;
290 			}
291 			else
292 			{
293 				download_offset = MQ_ORG_DSP_CODE_BASE;
294 			}
295 			pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
296 			break;
297 
298 		case DIA_FPGA_CODE:
299 			DPRINTF(("divas: 4BRI FPGA download - %d bytes", load->length));
300 			if (FPGA_Download(IDI_ADAPTER_MAESTRAQ,
301  			card->hw->io_base,
302 			 sw_id,
303 			 load->code,
304 			 load->length
305 			) == -1)
306 			{
307 				DPRINTF(("divas: FPGA download failed"));
308 				return -1;
309 			}
310 
311 			/* NOW reset the 4BRI */
312 			diva_server_4bri_reset(card);
313 			return 0; // No need for anything further loading
314 
315 		default:
316 			DPRINTF(("divas: unknown code type"));
317 			return -1;
318 	}
319 
320    memcp(pRAM + (download_offset & 0x3FFFFF), load->code, load->length);
321 
322 	{
323 		int mism_off;
324 	if ((mism_off = memcm(pRAM + (download_offset & 0x3FFFFF), load->code, load->length)))
325 	{
326 		DPRINTF(("divas: memory mismatch at offset %d", mism_off));
327 		UxCardMemDetach(card->hw, pRAM);
328 		return -1;
329 	}
330 	}
331 
332 	UxCardMemDetach(card->hw, pRAM);
333 
334 	return 0;
335 }
336 
diva_server_4bri_start(card_t * card,byte * channels)337 static int diva_server_4bri_start(card_t *card, byte *channels)
338 {
339 	byte *ctl;
340 	byte *shared;
341 	int i;
342 	int adapter_num;
343 
344 	DPRINTF(("divas: start Diva Server 4BRI"));
345 	*channels = 0;
346 	card->is_live = FALSE;
347 
348 	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
349 
350 	UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_COLD_RESET_MASK);
351 
352 	UxPause(2);
353 
354 	UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK);
355 
356 	UxPause(10);
357 
358 	UxCardMemDetach(card->hw, ctl);
359 
360 	shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
361 
362 	for ( i = 0 ; i < 300 ; ++i )
363 	{
364 		UxPause (10) ;
365 
366 		if ( UxCardMemInW(card->hw, &shared[0x1E]) == 0x4447 )
367 		{
368 			DPRINTF(("divas: Protocol startup time %d.%02d seconds",
369 			         (i / 100), (i % 100) ));
370 
371 			break;
372 		}
373 	}
374 
375 	if (i==300)
376 	{
377 		DPRINTF(("divas: Timeout starting card"));
378 		DPRINTF(("divas: Signature == 0x%04X", UxCardMemInW(card->hw, &shared[0x1E])));
379 
380 		UxCardMemDetach(card->hw, shared);
381 		return -1;
382 	}
383 
384 	UxCardMemDetach(card->hw, shared);
385 
386 	for (adapter_num=3; adapter_num >= 0; adapter_num--)
387 	{
388 		card_t *qbri_card;
389 
390 		qbri_card = get_card(card->cfg.card_id - adapter_num);
391 
392 		if (qbri_card)
393 		{
394 			qbri_card->is_live = TRUE;
395 			shared = UxCardMemAttach(qbri_card->hw, DIVAS_SHARED_MEMORY);
396 			*channels += UxCardMemIn(qbri_card->hw, &shared[0x3F6]);
397 			UxCardMemDetach(qbri_card->hw, shared);
398 		}
399 		else
400 		{
401 			DPRINTF(("divas: Couldn't get card info %d", card->cfg.card_id));
402 		}
403 	}
404 
405 	diva_server_4bri_test_int(card);
406 
407 	return 0;
408 }
409 
410 static
diva_server_4bri_mem_get(card_t * card,mem_block_t * mem_block)411 int 	diva_server_4bri_mem_get(card_t *card, mem_block_t *mem_block)
412 
413 {
414 	byte	*a;
415 	byte	*card_addr;
416 	word	length = 0;
417 	int		i;
418 
419 	a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
420 
421 	card_addr = a;
422 	card_addr += mem_block->addr;
423 
424 	for (i=0; i < sizeof(mem_block->data); i++)
425 	{
426 		mem_block->data[i] = UxCardMemIn(card->hw, card_addr);
427 		card_addr++;
428 		length++;
429 	}
430 
431 	UxCardMemDetach(card->hw, a);
432 
433 	return length;
434 }
435 
436 /*
437  * Initialise 4BRI specific entry points
438  */
439 
Divas4BriInit(card_t * card,dia_card_t * cfg)440 int Divas4BriInit(card_t *card, dia_card_t *cfg)
441 {
442 //	byte sw_id[80];
443 //	extern int FPGA_Done;
444 
445 	DPRINTF(("divas: initialise Diva Server 4BRI"));
446 
447 	if (Divas4BRIInitPCI(card, cfg) == -1)
448 	{
449 		return -1;
450 	}
451 
452 	/* Need to download the FPGA */
453 /*	if (!FPGA_Done)
454 	{
455 		int retVal;
456 
457 		retVal=FPGA_Download(IDI_ADAPTER_MAESTRAQ,
458  			cfg->io_base,
459 			 sw_id,
460 			 FPGA_Bytes
461 			);
462 		if(retVal==-1)
463 		{
464 
465 			DPRINTF(("divas: FPGA Download Failed"));
466 			return -1;
467 
468 		}
469 		FPGA_Done = 1;
470 	} */
471 
472 	card->card_reset = diva_server_4bri_reset;
473 	card->card_load = diva_server_4bri_load;
474 	card->card_config = diva_server_4bri_config;
475 	card->card_start = diva_server_4bri_start;
476 	card->reset_int = diva_server_4bri_reset_int;
477 	card->card_mem_get = diva_server_4bri_mem_get;
478 
479 	card->xlog_offset = DIVAS_MAINT_OFFSET;
480 
481 	card->out = DivasOut;
482 	card->test_int = DivasTestInt;
483 	card->dpc = DivasDpc;
484 	card->clear_int = DivasClearInt;
485 	card->card_isr = fourbri_ISR;
486 
487 	card->a.ram_out = mem_out;
488 	card->a.ram_outw = mem_outw;
489 	card->a.ram_out_buffer = mem_out_buffer;
490 	card->a.ram_inc = mem_inc;
491 
492 	card->a.ram_in = mem_in;
493 	card->a.ram_inw = mem_inw;
494 	card->a.ram_in_buffer = mem_in_buffer;
495 	card->a.ram_look_ahead = mem_look_ahead;
496 
497 	return 0;
498 }
499 
memcp(byte * dst,byte * src,dword dwLen)500 void memcp(byte *dst, byte *src, dword dwLen)
501 {
502 	while (dwLen)
503 	{
504 		*dst = *src;
505 		dst++; src++;
506 		dwLen--;
507 	}
508 }
509 
memcm(byte * dst,byte * src,dword dwLen)510 int memcm(byte *dst, byte *src, dword dwLen)
511 {
512 	int offset = 0;
513 
514 	while (offset < dwLen)
515 	{
516 		if(*dst != *src)
517 			return (offset+1);
518 
519 		offset++;
520 		src++;
521 		dst++;
522 	}
523 
524 	return 0;
525 }
526 
527 
528 
529 /*int fourbri_ISR (card_t* card)
530 {
531 	int served = 0;
532 	byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
533 
534 
535 	if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01)
536 	{
537 		served = 1;
538 		card->int_pend  += 1;
539 		DivasDpcSchedule();
540 		UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);
541 	}
542 
543 	UxCardMemDetach(card->hw, DivasIOBase);
544 
545 	return (served != 0);
546 }*/
547 
548 
fourbri_ISR(card_t * card)549 static int fourbri_ISR (card_t* card)
550 {
551 	byte *ctl;
552 
553 	card->int_pend  += 1;
554 	DivasDpcSchedule(); /* ISR DPC */
555 
556 	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
557 	UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);
558 	UxCardMemDetach(card->hw, ctl);
559 
560 	return (1);
561 }
562