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 44byte mem_in(ADAPTER *a, void *adr); 45word mem_inw(ADAPTER *a, void *adr); 46void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length); 47void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e); 48void mem_out(ADAPTER *a, void *adr, byte data); 49void mem_outw(ADAPTER *a, void *adr, word data); 50void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length); 51void mem_inc(ADAPTER *a, void *adr); 52 53int Divas4BRIInitPCI(card_t *card, dia_card_t *cfg); 54static int fourbri_ISR (card_t* card); 55 56int FPGA_Download(word, dword, byte *, byte *, int); 57extern byte FPGA_Bytes[]; 58extern void *get_card(int); 59 60byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset); 61void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte); 62word GetProtFeatureValue(char *sw_id); 63 64void memcp(byte *dst, byte *src, dword dwLen); 65int memcm(byte *dst, byte *src, dword dwLen); 66 67static 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 84static 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 145static 146void 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 160static 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 209static 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 230static 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 337static int diva_server_4bri_start(card_t *card, byte *channels) 338{ 339 byte *ctl; 340 byte *shared, i; 341 int adapter_num; 342 343 DPRINTF(("divas: start Diva Server 4BRI")); 344 *channels = 0; 345 card->is_live = FALSE; 346 347 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY); 348 349 UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_COLD_RESET_MASK); 350 351 UxPause(2); 352 353 UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK); 354 355 UxPause(10); 356 357 UxCardMemDetach(card->hw, ctl); 358 359 shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY); 360 361 for ( i = 0 ; i < 300 ; ++i ) 362 { 363 UxPause (10) ; 364 365 if ( UxCardMemInW(card->hw, &shared[0x1E]) == 0x4447 ) 366 { 367 DPRINTF(("divas: Protocol startup time %d.%02d seconds", 368 (i / 100), (i % 100) )); 369 370 break; 371 } 372 } 373 374 if (i==300) 375 { 376 DPRINTF(("divas: Timeout starting card")); 377 DPRINTF(("divas: Signature == 0x%04X", UxCardMemInW(card->hw, &shared[0x1E]))); 378 379 UxCardMemDetach(card->hw, shared); 380 return -1; 381 } 382 383 UxCardMemDetach(card->hw, shared); 384 385 for (adapter_num=3; adapter_num >= 0; adapter_num--) 386 { 387 card_t *qbri_card; 388 389 qbri_card = get_card(card->cfg.card_id - adapter_num); 390 391 if (qbri_card) 392 { 393 qbri_card->is_live = TRUE; 394 shared = UxCardMemAttach(qbri_card->hw, DIVAS_SHARED_MEMORY); 395 *channels += UxCardMemIn(qbri_card->hw, &shared[0x3F6]); 396 UxCardMemDetach(qbri_card->hw, shared); 397 } 398 else 399 { 400 DPRINTF(("divas: Couldn't get card info %d", card->cfg.card_id)); 401 } 402 } 403 404 diva_server_4bri_test_int(card); 405 406 return 0; 407} 408 409static 410int diva_server_4bri_mem_get(card_t *card, mem_block_t *mem_block) 411 412{ 413 byte *a; 414 byte *card_addr; 415 word length = 0; 416 int i; 417 418 a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY); 419 420 card_addr = a; 421 card_addr += mem_block->addr; 422 423 for (i=0; i < sizeof(mem_block->data); i++) 424 { 425 mem_block->data[i] = UxCardMemIn(card->hw, card_addr); 426 card_addr++; 427 length++; 428 } 429 430 UxCardMemDetach(card->hw, a); 431 432 return length; 433} 434 435/* 436 * Initialise 4BRI specific entry points 437 */ 438 439int Divas4BriInit(card_t *card, dia_card_t *cfg) 440{ 441// byte sw_id[80]; 442// extern int FPGA_Done; 443 444 DPRINTF(("divas: initialise Diva Server 4BRI")); 445 446 if (Divas4BRIInitPCI(card, cfg) == -1) 447 { 448 return -1; 449 } 450 451 /* Need to download the FPGA */ 452/* if (!FPGA_Done) 453 { 454 int retVal; 455 456 retVal=FPGA_Download(IDI_ADAPTER_MAESTRAQ, 457 cfg->io_base, 458 sw_id, 459 FPGA_Bytes 460 ); 461 if(retVal==-1) 462 { 463 464 DPRINTF(("divas: FPGA Download Failed")); 465 return -1; 466 467 } 468 FPGA_Done = 1; 469 } */ 470 471 card->card_reset = diva_server_4bri_reset; 472 card->card_load = diva_server_4bri_load; 473 card->card_config = diva_server_4bri_config; 474 card->card_start = diva_server_4bri_start; 475 card->reset_int = diva_server_4bri_reset_int; 476 card->card_mem_get = diva_server_4bri_mem_get; 477 478 card->xlog_offset = DIVAS_MAINT_OFFSET; 479 480 card->out = DivasOut; 481 card->test_int = DivasTestInt; 482 card->dpc = DivasDpc; 483 card->clear_int = DivasClearInt; 484 card->card_isr = fourbri_ISR; 485 486 card->a.ram_out = mem_out; 487 card->a.ram_outw = mem_outw; 488 card->a.ram_out_buffer = mem_out_buffer; 489 card->a.ram_inc = mem_inc; 490 491 card->a.ram_in = mem_in; 492 card->a.ram_inw = mem_inw; 493 card->a.ram_in_buffer = mem_in_buffer; 494 card->a.ram_look_ahead = mem_look_ahead; 495 496 return 0; 497} 498 499void memcp(byte *dst, byte *src, dword dwLen) 500{ 501 while (dwLen) 502 { 503 *dst = *src; 504 dst++; src++; 505 dwLen--; 506 } 507} 508 509int memcm(byte *dst, byte *src, dword dwLen) 510{ 511 int offset = 0; 512 513 while (offset < dwLen) 514 { 515 if(*dst != *src) 516 return (offset+1); 517 518 offset++; 519 src++; 520 dst++; 521 } 522 523 return 0; 524} 525 526 527 528/*int fourbri_ISR (card_t* card) 529{ 530 int served = 0; 531 byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE); 532 533 534 if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01) 535 { 536 served = 1; 537 card->int_pend += 1; 538 DivasDpcSchedule(); 539 UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08); 540 } 541 542 UxCardMemDetach(card->hw, DivasIOBase); 543 544 return (served != 0); 545}*/ 546 547 548static int fourbri_ISR (card_t* card) 549{ 550 byte *ctl; 551 552 card->int_pend += 1; 553 DivasDpcSchedule(); /* ISR DPC */ 554 555 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY); 556 UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF); 557 UxCardMemDetach(card->hw, ctl); 558 559 return (1); 560} 561