2 * Diva Server 4BRI specific part of initialisation
4 * Copyright (C) Eicon Technology Corporation, 2000.
6 * Eicon File Revision : 1.7
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
23 #define TEST_INT_DIVAS_Q 0x13
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
41 #define DIVAS_IOBASE 0x01
42 #define M_PCI_RESET 0x10
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);
53 int Divas4BRIInitPCI(card_t *card, dia_card_t *cfg);
54 static int fourbri_ISR (card_t* card);
56 int FPGA_Download(word, dword, byte *, byte *, int);
57 extern byte FPGA_Bytes[];
58 extern void *get_card(int);
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);
64 void memcp(byte *dst, byte *src, dword dwLen);
65 int memcm(byte *dst, byte *src, dword dwLen);
67 static int diva_server_4bri_reset(card_t *card)
71 DPRINTF(("divas: reset Diva Server 4BRI"));
73 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
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);
79 UxCardMemDetach(card->hw, ctl);
84 static int diva_server_4bri_config(card_t *card, dia_config_t *config)
89 DPRINTF(("divas: configure Diva Server 4BRI"));
91 shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
95 UxCardMemOut(card->hw, &shared[i], 0);
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);
112 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
114 DPRINTF(("divas: Signifying V.90"));
115 UxCardMemOut(card->hw, &shared[22], 4);
119 UxCardMemOut(card->hw, &shared[22], 0);
126 UxCardMemOut(card->hw, &shared[32+(i*96)+j],config->terminal[i].oad[j]);
131 UxCardMemOut(card->hw, &shared[64+(i*96)+j],config->terminal[i].osa[j]);
136 UxCardMemOut(card->hw, &shared[96+(i*96)+j],config->terminal[i].spid[j]);
140 UxCardMemDetach(card->hw, shared);
146 void diva_server_4bri_reset_int(card_t *card)
150 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
152 UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);
154 UxCardMemDetach(card->hw, ctl);
160 static int diva_server_4bri_test_int(card_t *card)
165 DPRINTF(("divas: test interrupt for Diva Server 4BRI"));
167 /* We get the last (dummy) adapter in so we need to go back to the first */
169 card = get_card(card->cfg.card_id - 3);
171 /* Enable interrupts on PLX chip */
173 reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);
175 UxCardPortIoOut(card->hw, reg, PLX9054_INTCSR, PLX9054_INT_ENA);
177 UxCardMemDetach(card->hw, reg);
179 /* Set the test interrupt flag */
180 card->test_int_pend = TEST_INT_DIVAS_Q;
182 /* Now to trigger the interrupt */
184 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
186 UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_ON);
188 UxCardMemDetach(card->hw, ctl);
190 for (i = 0; i < 50; i++)
192 if (!card->test_int_pend)
199 if (card->test_int_pend)
201 DPRINTF(("active: timeout waiting for card to interrupt"));
209 static void print_hdr(unsigned char *code, int offset)
211 unsigned char hdr[80];
216 while ((i < (DIM(hdr) -1)) &&
217 (code[offset + i] != '\0') &&
218 (code[offset + i] != '\r') &&
219 (code[offset + i] != '\n'))
221 hdr[i] = code[offset + i];
227 DPRINTF(("divas: loading %s", hdr));
230 static int diva_server_4bri_load(card_t *card, dia_load_t *load)
233 int download_offset=0;
237 DPRINTF(("divas: loading Diva Server 4BRI[%d]", load->card_id));
239 switch(load->code_type)
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);
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))
255 download_offset = MQ_V90D_DSP_CODE_BASE;
259 download_offset = MQ_ORG_DSP_CODE_BASE;
261 pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
262 download_offset += (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC);
267 DPRINTF(("divas: TABLE code"));
268 FirstCard = get_card(load->card_id - 3);
269 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
271 download_offset = MQ_V90D_DSP_CODE_BASE + sizeof(dword);
275 download_offset = MQ_ORG_DSP_CODE_BASE + sizeof(dword);
277 pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
281 DPRINTF(("divas: continuation code"));
285 DPRINTF(("divas: COUNT code"));
286 FirstCard = get_card(load->card_id - 3);
287 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
289 download_offset = MQ_V90D_DSP_CODE_BASE;
293 download_offset = MQ_ORG_DSP_CODE_BASE;
295 pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
299 DPRINTF(("divas: 4BRI FPGA download - %d bytes", load->length));
300 if (FPGA_Download(IDI_ADAPTER_MAESTRAQ,
307 DPRINTF(("divas: FPGA download failed"));
311 /* NOW reset the 4BRI */
312 diva_server_4bri_reset(card);
313 return 0; // No need for anything further loading
316 DPRINTF(("divas: unknown code type"));
320 memcp(pRAM + (download_offset & 0x3FFFFF), load->code, load->length);
324 if ((mism_off = memcm(pRAM + (download_offset & 0x3FFFFF), load->code, load->length)))
326 DPRINTF(("divas: memory mismatch at offset %d", mism_off));
327 UxCardMemDetach(card->hw, pRAM);
332 UxCardMemDetach(card->hw, pRAM);
337 static int diva_server_4bri_start(card_t *card, byte *channels)
344 DPRINTF(("divas: start Diva Server 4BRI"));
346 card->is_live = FALSE;
348 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
350 UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_COLD_RESET_MASK);
354 UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK);
358 UxCardMemDetach(card->hw, ctl);
360 shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
362 for ( i = 0 ; i < 300 ; ++i )
366 if ( UxCardMemInW(card->hw, &shared[0x1E]) == 0x4447 )
368 DPRINTF(("divas: Protocol startup time %d.%02d seconds",
369 (i / 100), (i % 100) ));
377 DPRINTF(("divas: Timeout starting card"));
378 DPRINTF(("divas: Signature == 0x%04X", UxCardMemInW(card->hw, &shared[0x1E])));
380 UxCardMemDetach(card->hw, shared);
384 UxCardMemDetach(card->hw, shared);
386 for (adapter_num=3; adapter_num >= 0; adapter_num--)
390 qbri_card = get_card(card->cfg.card_id - adapter_num);
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);
401 DPRINTF(("divas: Couldn't get card info %d", card->cfg.card_id));
405 diva_server_4bri_test_int(card);
411 int diva_server_4bri_mem_get(card_t *card, mem_block_t *mem_block)
419 a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
422 card_addr += mem_block->addr;
424 for (i=0; i < sizeof(mem_block->data); i++)
426 mem_block->data[i] = UxCardMemIn(card->hw, card_addr);
431 UxCardMemDetach(card->hw, a);
437 * Initialise 4BRI specific entry points
440 int Divas4BriInit(card_t *card, dia_card_t *cfg)
443 // extern int FPGA_Done;
445 DPRINTF(("divas: initialise Diva Server 4BRI"));
447 if (Divas4BRIInitPCI(card, cfg) == -1)
452 /* Need to download the FPGA */
457 retVal=FPGA_Download(IDI_ADAPTER_MAESTRAQ,
465 DPRINTF(("divas: FPGA Download Failed"));
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;
479 card->xlog_offset = DIVAS_MAINT_OFFSET;
481 card->out = DivasOut;
482 card->test_int = DivasTestInt;
483 card->dpc = DivasDpc;
484 card->clear_int = DivasClearInt;
485 card->card_isr = fourbri_ISR;
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;
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;
500 void memcp(byte *dst, byte *src, dword dwLen)
510 int memcm(byte *dst, byte *src, dword dwLen)
514 while (offset < dwLen)
529 /*int fourbri_ISR (card_t* card)
532 byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
535 if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01)
540 UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);
543 UxCardMemDetach(card->hw, DivasIOBase);
545 return (served != 0);
549 static int fourbri_ISR (card_t* card)
554 DivasDpcSchedule(); /* ISR DPC */
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);