2 * Diva Server PRI specific part of initialisation
4 * Copyright (C) Eicon Technology Corporation, 2000.
6 * Eicon File Revision : 1.5
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 DIVAS_LOAD_CMD 0x02
24 #define DIVAS_START_CMD 0x03
25 #define DIVAS_IRQ_RESET 0xC18
26 #define DIVAS_IRQ_RESET_VAL 0xFE
28 #define TEST_INT_DIVAS 0x11
29 #define TEST_INT_DIVAS_BRI 0x12
31 #define DIVAS_RESET 0x81
32 #define DIVAS_LED1 0x04
33 #define DIVAS_LED2 0x08
34 #define DIVAS_LED3 0x20
35 #define DIVAS_LED4 0x40
37 #define DIVAS_RESET_REG 0x20
39 #define DIVAS_SIGNATURE 0x4447
41 /* offset to start of MAINT area (used by xlog) */
43 #define DIVAS_MAINT_OFFSET 0xef00 /* value for PRI card */
45 #define MP_PROTOCOL_ADDR 0xA0011000
46 #define MP_DSP_CODE_BASE 0xa03a0000
54 dword reserved[(0x1020>>2)-6];
59 byte mem_in(ADAPTER *a, void *adr);
60 word mem_inw(ADAPTER *a, void *adr);
61 void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);
62 void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
63 void mem_out(ADAPTER *a, void *adr, byte data);
64 void mem_outw(ADAPTER *a, void *adr, word data);
65 void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);
66 void mem_inc(ADAPTER *a, void *adr);
68 int DivasPRIInitPCI(card_t *card, dia_card_t *cfg);
69 static int pri_ISR (card_t* card);
71 static int diva_server_reset(card_t *card)
74 diva_server_boot_t *boot = NULL;
79 DPRINTF(("divas: reset Diva Server PRI"));
81 reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);
83 UxCardMemOut(card->hw, ®[DIVAS_RESET_REG], DIVAS_RESET |
84 DIVAS_LED1 | DIVAS_LED2 | DIVAS_LED3 | DIVAS_LED4);
86 for (dwWait = 0x000fffff; dwWait; dwWait--)
89 UxCardMemOut(card->hw, ®[DIVAS_RESET_REG], 0x00);
91 for (dwWait = 0x000fffff; dwWait; dwWait--)
94 UxCardMemDetach(card->hw, reg);
96 boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
98 UxCardMemOutD(card->hw, boot->reserved, 0);
100 live = UxCardMemInD(card->hw, &boot->live);
104 if (live != UxCardMemInD(card->hw, &boot->live))
113 UxCardMemDetach(card->hw, boot);
115 DPRINTF(("divas: card is reset but CPU not running"));
119 UxCardMemDetach(card->hw, boot);
121 DPRINTF(("divas: card reset after %d ms", i * 10));
126 static int diva_server_config(card_t *card, dia_config_t *config)
131 DPRINTF(("divas: configure Diva Server PRI"));
133 shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
136 for (i=0; i<256; i++)
138 UxCardMemOut(card->hw, &shared[i], 0);
141 UxCardMemOut(card->hw, &shared[ 8], config->tei);
142 UxCardMemOut(card->hw, &shared[ 9], config->nt2);
143 UxCardMemOut(card->hw, &shared[10], config->sig_flags);
144 UxCardMemOut(card->hw, &shared[11], config->watchdog);
145 UxCardMemOut(card->hw, &shared[12], config->permanent);
146 UxCardMemOut(card->hw, &shared[13], config->x_interface);
147 UxCardMemOut(card->hw, &shared[14], config->stable_l2);
148 UxCardMemOut(card->hw, &shared[15], config->no_order_check);
149 UxCardMemOut(card->hw, &shared[16], config->handset_type);
150 UxCardMemOut(card->hw, &shared[17], 0);
151 UxCardMemOut(card->hw, &shared[18], config->low_channel);
152 UxCardMemOut(card->hw, &shared[19], config->prot_version);
153 UxCardMemOut(card->hw, &shared[20], config->crc4);
159 UxCardMemOut(card->hw, &shared[32+(i*96)+j],config->terminal[i].oad[j]);
164 UxCardMemOut(card->hw, &shared[64+(i*96)+j],config->terminal[i].osa[j]);
169 UxCardMemOut(card->hw, &shared[96+(i*96)+j],config->terminal[i].spid[j]);
173 UxCardMemDetach(card->hw, shared);
179 void diva_server_reset_int(card_t *card)
183 cfg = UxCardMemAttach(card->hw, DIVAS_CFG_MEMORY);
185 UxCardMemOutW(card->hw, &cfg[DIVAS_IRQ_RESET], DIVAS_IRQ_RESET_VAL);
186 UxCardMemOutW(card->hw, &cfg[DIVAS_IRQ_RESET + 2], 0);
187 UxCardMemDetach(card->hw, cfg);
193 static int diva_server_test_int(card_t *card)
199 DPRINTF(("divas: test interrupt for Diva Server PRI"));
201 shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
203 UxCardMemIn(card->hw, &shared[0x3FE]);
204 UxCardMemOut(card->hw, &shared[0x3FE], 0);
205 UxCardMemIn(card->hw, &shared[0x3FE]);
207 UxCardMemDetach(card->hw, shared);
209 diva_server_reset_int(card);
211 shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
213 card->test_int_pend = TEST_INT_DIVAS;
215 req_int = UxCardMemIn(card->hw, &(((struct pr_ram *)shared)->ReadyInt));
219 UxCardMemOut(card->hw, &(((struct pr_ram *)shared)->ReadyInt), req_int);
221 UxCardMemDetach(card->hw, shared);
224 for (i = 0; i < 50; i++)
226 if (!card->test_int_pend)
234 if (card->test_int_pend)
237 DPRINTF(("active: timeout waiting for card to interrupt"));
246 static void print_hdr(unsigned char *code, int offset)
248 unsigned char hdr[80];
253 while ((i < (DIM(hdr) -1)) &&
254 (code[offset + i] != '\0') &&
255 (code[offset + i] != '\r') &&
256 (code[offset + i] != '\n'))
258 hdr[i] = code[offset + i];
264 DPRINTF(("divas: loading %s", hdr));
267 static int diva_server_load(card_t *card, dia_load_t *load)
269 diva_server_boot_t *boot;
270 int i, offset, length;
273 DPRINTF(("divas: loading Diva Server PRI"));
275 boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
277 switch(load->code_type)
280 DPRINTF(("divas: RISC code"));
281 print_hdr(load->code, 0x80);
283 UxCardMemOutD(card->hw, &boot->addr, MP_PROTOCOL_ADDR);
287 DPRINTF(("divas: DSP code"));
288 print_hdr(load->code, 0x0);
290 UxCardMemOutD(card->hw, &boot->addr,
291 (MP_DSP_CODE_BASE + (((sizeof(dword) +
292 (sizeof(t_dsp_download_desc) * DSP_MAX_DOWNLOAD_COUNT))
293 + ~ALIGNMENT_MASK_MAESTRA) & ALIGNMENT_MASK_MAESTRA)));
297 DPRINTF(("divas: TABLE code"));
298 UxCardMemOutD(card->hw, &boot->addr,
299 (MP_DSP_CODE_BASE + sizeof(dword)));
303 DPRINTF(("divas: continuation code"));
307 DPRINTF(("divas: COUNT code"));
308 UxCardMemOutD(card->hw, &boot->addr, MP_DSP_CODE_BASE);
312 DPRINTF(("divas: unknown code type"));
313 UxCardMemDetach(card->hw, boot);
322 length = (load->length - offset >= 400) ? 400 : load->length - offset;
324 for (i=0; i<length; i++)
326 UxCardMemOut(card->hw, &boot->data[i], load->code[offset+i]);
329 for (i=0; i<length; i++)
331 if (load->code[offset + i] != UxCardMemIn(card->hw, &boot->data[i]))
333 UxCardMemDetach(card->hw, boot);
335 DPRINTF(("divas: card code block verify failed"));
340 UxCardMemOutD(card->hw, &boot->len, (length + 3) / 4);
341 UxCardMemOutD(card->hw, &boot->cmd, DIVAS_LOAD_CMD);
343 for (i=0; i<50000; i++)
345 cmd = UxCardMemInD(card->hw, &boot->cmd);
355 DPRINTF(("divas: timeout waiting for card to ACK load (offset = %d)", offset));
356 UxCardMemDetach(card->hw, boot);
362 } while (offset < load->length);
364 UxCardMemDetach(card->hw, boot);
366 DPRINTF(("divas: DIVA Server card loaded"));
371 static int diva_server_start(card_t *card, byte *channels)
373 diva_server_boot_t *boot;
378 DPRINTF(("divas: start Diva Server PRI"));
380 card->is_live = FALSE;
382 boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
384 UxCardMemOutD(card->hw, &boot->addr, MP_PROTOCOL_ADDR);
385 UxCardMemOutD(card->hw, &boot->cmd, DIVAS_START_CMD);
389 for (i = 0; i < 300; i++)
391 signature = UxCardMemInD(card->hw, &boot->signature);
392 if ((signature >> 16) == DIVAS_SIGNATURE)
394 DPRINTF(("divas: started card after %d ms", i * 10));
400 if ((signature >> 16) != DIVAS_SIGNATURE)
402 UxCardMemDetach(card->hw, boot);
403 DPRINTF(("divas: timeout waiting for card to run protocol code (sig = 0x%x)", signature));
407 card->is_live = TRUE;
410 ram += DIVAS_SHARED_OFFSET;
412 *channels = UxCardMemIn(card->hw, &ram[0x3F6]);
413 card->serial_no = UxCardMemInD(card->hw, &ram[0x3F0]);
415 UxCardMemDetach(card->hw, boot);
417 if (diva_server_test_int(card))
419 DPRINTF(("divas: interrupt test failed"));
423 DPRINTF(("divas: DIVA Server card started"));
429 int diva_server_mem_get(card_t *card, mem_block_t *mem_block)
437 a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
440 card_addr += mem_block->addr;
442 for (i=0; i < sizeof(mem_block->data); i++)
444 mem_block->data[i] = UxCardMemIn(card->hw, card_addr);
449 UxCardMemDetach(card->hw, a);
455 * Initialise PRI specific entry points
458 int DivasPriInit(card_t *card, dia_card_t *cfg)
460 DPRINTF(("divas: initialise Diva Server PRI"));
462 if (DivasPRIInitPCI(card, cfg) == -1)
467 card->card_reset = diva_server_reset;
468 card->card_load = diva_server_load;
469 card->card_config = diva_server_config;
470 card->card_start = diva_server_start;
471 card->reset_int = diva_server_reset_int;
472 card->card_mem_get = diva_server_mem_get;
474 card->xlog_offset = DIVAS_MAINT_OFFSET;
476 card->out = DivasOut;
477 card->test_int = DivasTestInt;
478 card->dpc = DivasDpc;
479 card->clear_int = DivasClearInt;
480 card->card_isr = pri_ISR;
482 card->a.ram_out = mem_out;
483 card->a.ram_outw = mem_outw;
484 card->a.ram_out_buffer = mem_out_buffer;
485 card->a.ram_inc = mem_inc;
487 card->a.ram_in = mem_in;
488 card->a.ram_inw = mem_inw;
489 card->a.ram_in_buffer = mem_in_buffer;
490 card->a.ram_look_ahead = mem_look_ahead;
496 static int pri_ISR (card_t* card)
499 byte* cfg = UxCardMemAttach(card->hw, DIVAS_CFG_MEMORY);
500 volatile unsigned long* isr = (unsigned long*)&cfg[DIVAS_IRQ_RESET];
501 register unsigned long val = *isr;
503 if (val & 0x80000000) /* our card had caused interrupt ??? */
507 DivasDpcSchedule(); /* ISR DPC */
509 *isr = (unsigned long)~0x03E00000; /* Clear interrupt line */
512 UxCardMemDetach(card->hw, cfg);
514 return (served != 0);