1 /****************************************************************************** 2 3 AudioScience HPI driver 4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of version 2 of the GNU General Public License as 8 published by the Free Software Foundation; 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 Hardware Programming Interface (HPI) for AudioScience ASI6200 series adapters. 20 These PCI bus adapters are based on the TI C6711 DSP. 21 22 Exported functions: 23 void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) 24 25 #defines 26 HIDE_PCI_ASSERTS to show the PCI asserts 27 PROFILE_DSP2 get profile data from DSP2 if present (instead of DSP 1) 28 29 (C) Copyright AudioScience Inc. 1998-2003 30 *******************************************************************************/ 31 #define SOURCEFILE_NAME "hpi6000.c" 32 33 #include "hpi_internal.h" 34 #include "hpimsginit.h" 35 #include "hpidebug.h" 36 #include "hpi6000.h" 37 #include "hpidspcd.h" 38 #include "hpicmn.h" 39 40 #define HPI_HIF_BASE (0x00000200) /* start of C67xx internal RAM */ 41 #define HPI_HIF_ADDR(member) \ 42 (HPI_HIF_BASE + offsetof(struct hpi_hif_6000, member)) 43 #define HPI_HIF_ERROR_MASK 0x4000 44 45 /* HPI6000 specific error codes */ 46 #define HPI6000_ERROR_BASE 900 /* not actually used anywhere */ 47 /* operational/messaging errors */ 48 #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 49 50 #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 51 #define HPI6000_ERROR_MSG_GET_ADR 904 52 #define HPI6000_ERROR_RESP_GET_ADR 905 53 #define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 54 #define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 55 56 #define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909 57 58 #define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 59 #define HPI6000_ERROR_SEND_DATA_ACK 912 60 #define HPI6000_ERROR_SEND_DATA_ADR 913 61 #define HPI6000_ERROR_SEND_DATA_TIMEOUT 914 62 #define HPI6000_ERROR_SEND_DATA_CMD 915 63 #define HPI6000_ERROR_SEND_DATA_WRITE 916 64 #define HPI6000_ERROR_SEND_DATA_IDLECMD 917 65 66 #define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921 67 #define HPI6000_ERROR_GET_DATA_ACK 922 68 #define HPI6000_ERROR_GET_DATA_CMD 923 69 #define HPI6000_ERROR_GET_DATA_READ 924 70 #define HPI6000_ERROR_GET_DATA_IDLECMD 925 71 72 #define HPI6000_ERROR_CONTROL_CACHE_ADDRLEN 951 73 #define HPI6000_ERROR_CONTROL_CACHE_READ 952 74 #define HPI6000_ERROR_CONTROL_CACHE_FLUSH 953 75 76 #define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 77 #define HPI6000_ERROR_MSG_RESP_IDLECMD 962 78 79 /* Initialisation/bootload errors */ 80 #define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930 81 82 /* can't access PCI2040 */ 83 #define HPI6000_ERROR_INIT_PCI2040 931 84 /* can't access DSP HPI i/f */ 85 #define HPI6000_ERROR_INIT_DSPHPI 932 86 /* can't access internal DSP memory */ 87 #define HPI6000_ERROR_INIT_DSPINTMEM 933 88 /* can't access SDRAM - test#1 */ 89 #define HPI6000_ERROR_INIT_SDRAM1 934 90 /* can't access SDRAM - test#2 */ 91 #define HPI6000_ERROR_INIT_SDRAM2 935 92 93 #define HPI6000_ERROR_INIT_VERIFY 938 94 95 #define HPI6000_ERROR_INIT_NOACK 939 96 97 #define HPI6000_ERROR_INIT_PLDTEST1 941 98 #define HPI6000_ERROR_INIT_PLDTEST2 942 99 100 /* local defines */ 101 102 #define HIDE_PCI_ASSERTS 103 #define PROFILE_DSP2 104 105 /* for PCI2040 i/f chip */ 106 /* HPI CSR registers */ 107 /* word offsets from CSR base */ 108 /* use when io addresses defined as u32 * */ 109 110 #define INTERRUPT_EVENT_SET 0 111 #define INTERRUPT_EVENT_CLEAR 1 112 #define INTERRUPT_MASK_SET 2 113 #define INTERRUPT_MASK_CLEAR 3 114 #define HPI_ERROR_REPORT 4 115 #define HPI_RESET 5 116 #define HPI_DATA_WIDTH 6 117 118 #define MAX_DSPS 2 119 /* HPI registers, spaced 8K bytes = 2K words apart */ 120 #define DSP_SPACING 0x800 121 122 #define CONTROL 0x0000 123 #define ADDRESS 0x0200 124 #define DATA_AUTOINC 0x0400 125 #define DATA 0x0600 126 127 #define TIMEOUT 500000 128 129 struct dsp_obj { 130 __iomem u32 *prHPI_control; 131 __iomem u32 *prHPI_address; 132 __iomem u32 *prHPI_data; 133 __iomem u32 *prHPI_data_auto_inc; 134 char c_dsp_rev; /*A, B */ 135 u32 control_cache_address_on_dsp; 136 u32 control_cache_length_on_dsp; 137 struct hpi_adapter_obj *pa_parent_adapter; 138 }; 139 140 struct hpi_hw_obj { 141 __iomem u32 *dw2040_HPICSR; 142 __iomem u32 *dw2040_HPIDSP; 143 144 u16 num_dsp; 145 struct dsp_obj ado[MAX_DSPS]; 146 147 u32 message_buffer_address_on_dsp; 148 u32 response_buffer_address_on_dsp; 149 u32 pCI2040HPI_error_count; 150 151 struct hpi_control_cache_single control_cache[HPI_NMIXER_CONTROLS]; 152 struct hpi_control_cache *p_cache; 153 }; 154 155 static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao, 156 u16 dsp_index, u32 hpi_address, u32 *source, u32 count); 157 static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao, 158 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count); 159 160 static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, 161 u32 *pos_error_code); 162 static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao, 163 u16 read_or_write); 164 #define H6READ 1 165 #define H6WRITE 0 166 167 static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao, 168 struct hpi_message *phm); 169 static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, 170 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr); 171 172 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, 173 struct hpi_response *phr); 174 175 static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index, 176 u32 ack_value); 177 178 static short hpi6000_send_host_command(struct hpi_adapter_obj *pao, 179 u16 dsp_index, u32 host_cmd); 180 181 static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo); 182 183 static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index, 184 struct hpi_message *phm, struct hpi_response *phr); 185 186 static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index, 187 struct hpi_message *phm, struct hpi_response *phr); 188 189 static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data); 190 191 static u32 hpi_read_word(struct dsp_obj *pdo, u32 address); 192 193 static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata, 194 u32 length); 195 196 static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata, 197 u32 length); 198 199 static void subsys_create_adapter(struct hpi_message *phm, 200 struct hpi_response *phr); 201 202 static void subsys_delete_adapter(struct hpi_message *phm, 203 struct hpi_response *phr); 204 205 static void adapter_get_asserts(struct hpi_adapter_obj *pao, 206 struct hpi_message *phm, struct hpi_response *phr); 207 208 static short create_adapter_obj(struct hpi_adapter_obj *pao, 209 u32 *pos_error_code); 210 211 static void delete_adapter_obj(struct hpi_adapter_obj *pao); 212 213 /* local globals */ 214 215 static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ 216 static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */ 217 218 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 219 { 220 switch (phm->function) { 221 case HPI_SUBSYS_CREATE_ADAPTER: 222 subsys_create_adapter(phm, phr); 223 break; 224 case HPI_SUBSYS_DELETE_ADAPTER: 225 subsys_delete_adapter(phm, phr); 226 break; 227 default: 228 phr->error = HPI_ERROR_INVALID_FUNC; 229 break; 230 } 231 } 232 233 static void control_message(struct hpi_adapter_obj *pao, 234 struct hpi_message *phm, struct hpi_response *phr) 235 { 236 switch (phm->function) { 237 case HPI_CONTROL_GET_STATE: 238 if (pao->has_control_cache) { 239 phr->error = hpi6000_update_control_cache(pao, phm); 240 241 if (phr->error) 242 break; 243 244 if (hpi_check_control_cache(((struct hpi_hw_obj *) 245 pao->priv)->p_cache, phm, 246 phr)) 247 break; 248 } 249 hw_message(pao, phm, phr); 250 break; 251 case HPI_CONTROL_SET_STATE: 252 hw_message(pao, phm, phr); 253 hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao-> 254 priv)->p_cache, phm, phr); 255 break; 256 257 case HPI_CONTROL_GET_INFO: 258 default: 259 hw_message(pao, phm, phr); 260 break; 261 } 262 } 263 264 static void adapter_message(struct hpi_adapter_obj *pao, 265 struct hpi_message *phm, struct hpi_response *phr) 266 { 267 switch (phm->function) { 268 case HPI_ADAPTER_GET_ASSERT: 269 adapter_get_asserts(pao, phm, phr); 270 break; 271 272 default: 273 hw_message(pao, phm, phr); 274 break; 275 } 276 } 277 278 static void outstream_message(struct hpi_adapter_obj *pao, 279 struct hpi_message *phm, struct hpi_response *phr) 280 { 281 switch (phm->function) { 282 case HPI_OSTREAM_HOSTBUFFER_ALLOC: 283 case HPI_OSTREAM_HOSTBUFFER_FREE: 284 /* Don't let these messages go to the HW function because 285 * they're called without locking the spinlock. 286 * For the HPI6000 adapters the HW would return 287 * HPI_ERROR_INVALID_FUNC anyway. 288 */ 289 phr->error = HPI_ERROR_INVALID_FUNC; 290 break; 291 default: 292 hw_message(pao, phm, phr); 293 return; 294 } 295 } 296 297 static void instream_message(struct hpi_adapter_obj *pao, 298 struct hpi_message *phm, struct hpi_response *phr) 299 { 300 301 switch (phm->function) { 302 case HPI_ISTREAM_HOSTBUFFER_ALLOC: 303 case HPI_ISTREAM_HOSTBUFFER_FREE: 304 /* Don't let these messages go to the HW function because 305 * they're called without locking the spinlock. 306 * For the HPI6000 adapters the HW would return 307 * HPI_ERROR_INVALID_FUNC anyway. 308 */ 309 phr->error = HPI_ERROR_INVALID_FUNC; 310 break; 311 default: 312 hw_message(pao, phm, phr); 313 return; 314 } 315 } 316 317 /************************************************************************/ 318 /** HPI_6000() 319 * Entry point from HPIMAN 320 * All calls to the HPI start here 321 */ 322 void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) 323 { 324 struct hpi_adapter_obj *pao = NULL; 325 326 /* subsytem messages get executed by every HPI. */ 327 /* All other messages are ignored unless the adapter index matches */ 328 /* an adapter in the HPI */ 329 /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */ 330 331 /* if Dsp has crashed then do not communicate with it any more */ 332 if (phm->object != HPI_OBJ_SUBSYSTEM) { 333 pao = hpi_find_adapter(phm->adapter_index); 334 if (!pao) { 335 HPI_DEBUG_LOG(DEBUG, 336 " %d,%d refused, for another HPI?\n", 337 phm->object, phm->function); 338 return; 339 } 340 341 if (pao->dsp_crashed >= 10) { 342 hpi_init_response(phr, phm->object, phm->function, 343 HPI_ERROR_DSP_HARDWARE); 344 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", 345 phm->object, phm->function); 346 return; 347 } 348 } 349 /* Init default response including the size field */ 350 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER) 351 hpi_init_response(phr, phm->object, phm->function, 352 HPI_ERROR_PROCESSING_MESSAGE); 353 354 switch (phm->type) { 355 case HPI_TYPE_MESSAGE: 356 switch (phm->object) { 357 case HPI_OBJ_SUBSYSTEM: 358 subsys_message(phm, phr); 359 break; 360 361 case HPI_OBJ_ADAPTER: 362 phr->size = 363 sizeof(struct hpi_response_header) + 364 sizeof(struct hpi_adapter_res); 365 adapter_message(pao, phm, phr); 366 break; 367 368 case HPI_OBJ_CONTROL: 369 control_message(pao, phm, phr); 370 break; 371 372 case HPI_OBJ_OSTREAM: 373 outstream_message(pao, phm, phr); 374 break; 375 376 case HPI_OBJ_ISTREAM: 377 instream_message(pao, phm, phr); 378 break; 379 380 default: 381 hw_message(pao, phm, phr); 382 break; 383 } 384 break; 385 386 default: 387 phr->error = HPI_ERROR_INVALID_TYPE; 388 break; 389 } 390 } 391 392 /************************************************************************/ 393 /* SUBSYSTEM */ 394 395 /* create an adapter object and initialise it based on resource information 396 * passed in in the message 397 * NOTE - you cannot use this function AND the FindAdapters function at the 398 * same time, the application must use only one of them to get the adapters 399 */ 400 static void subsys_create_adapter(struct hpi_message *phm, 401 struct hpi_response *phr) 402 { 403 /* create temp adapter obj, because we don't know what index yet */ 404 struct hpi_adapter_obj ao; 405 struct hpi_adapter_obj *pao; 406 u32 os_error_code; 407 short error = 0; 408 u32 dsp_index = 0; 409 410 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n"); 411 412 memset(&ao, 0, sizeof(ao)); 413 414 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); 415 if (!ao.priv) { 416 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); 417 phr->error = HPI_ERROR_MEMORY_ALLOC; 418 return; 419 } 420 421 /* create the adapter object based on the resource information */ 422 ao.pci = *phm->u.s.resource.r.pci; 423 424 error = create_adapter_obj(&ao, &os_error_code); 425 if (error) { 426 delete_adapter_obj(&ao); 427 phr->error = error; 428 phr->u.s.data = os_error_code; 429 return; 430 } 431 /* need to update paParentAdapter */ 432 pao = hpi_find_adapter(ao.index); 433 if (!pao) { 434 /* We just added this adapter, why can't we find it!? */ 435 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n"); 436 phr->error = 950; 437 return; 438 } 439 440 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) { 441 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 442 phw->ado[dsp_index].pa_parent_adapter = pao; 443 } 444 445 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; 446 phr->u.s.adapter_index = ao.index; 447 phr->u.s.num_adapters++; 448 phr->error = 0; 449 } 450 451 static void subsys_delete_adapter(struct hpi_message *phm, 452 struct hpi_response *phr) 453 { 454 struct hpi_adapter_obj *pao = NULL; 455 456 pao = hpi_find_adapter(phm->obj_index); 457 if (!pao) 458 return; 459 460 delete_adapter_obj(pao); 461 hpi_delete_adapter(pao); 462 phr->error = 0; 463 } 464 465 /* this routine is called from SubSysFindAdapter and SubSysCreateAdapter */ 466 static short create_adapter_obj(struct hpi_adapter_obj *pao, 467 u32 *pos_error_code) 468 { 469 short boot_error = 0; 470 u32 dsp_index = 0; 471 u32 control_cache_size = 0; 472 u32 control_cache_count = 0; 473 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 474 475 /* The PCI2040 has the following address map */ 476 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ 477 /* BAR1 - 32K = HPI registers on DSP */ 478 phw->dw2040_HPICSR = pao->pci.ap_mem_base[0]; 479 phw->dw2040_HPIDSP = pao->pci.ap_mem_base[1]; 480 HPI_DEBUG_LOG(VERBOSE, "csr %p, dsp %p\n", phw->dw2040_HPICSR, 481 phw->dw2040_HPIDSP); 482 483 /* set addresses for the possible DSP HPI interfaces */ 484 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) { 485 phw->ado[dsp_index].prHPI_control = 486 phw->dw2040_HPIDSP + (CONTROL + 487 DSP_SPACING * dsp_index); 488 489 phw->ado[dsp_index].prHPI_address = 490 phw->dw2040_HPIDSP + (ADDRESS + 491 DSP_SPACING * dsp_index); 492 phw->ado[dsp_index].prHPI_data = 493 phw->dw2040_HPIDSP + (DATA + DSP_SPACING * dsp_index); 494 495 phw->ado[dsp_index].prHPI_data_auto_inc = 496 phw->dw2040_HPIDSP + (DATA_AUTOINC + 497 DSP_SPACING * dsp_index); 498 499 HPI_DEBUG_LOG(VERBOSE, "ctl %p, adr %p, dat %p, dat++ %p\n", 500 phw->ado[dsp_index].prHPI_control, 501 phw->ado[dsp_index].prHPI_address, 502 phw->ado[dsp_index].prHPI_data, 503 phw->ado[dsp_index].prHPI_data_auto_inc); 504 505 phw->ado[dsp_index].pa_parent_adapter = pao; 506 } 507 508 phw->pCI2040HPI_error_count = 0; 509 pao->has_control_cache = 0; 510 511 /* Set the default number of DSPs on this card */ 512 /* This is (conditionally) adjusted after bootloading */ 513 /* of the first DSP in the bootload section. */ 514 phw->num_dsp = 1; 515 516 boot_error = hpi6000_adapter_boot_load_dsp(pao, pos_error_code); 517 if (boot_error) 518 return boot_error; 519 520 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); 521 522 phw->message_buffer_address_on_dsp = 0L; 523 phw->response_buffer_address_on_dsp = 0L; 524 525 /* get info about the adapter by asking the adapter */ 526 /* send a HPI_ADAPTER_GET_INFO message */ 527 { 528 struct hpi_message hm; 529 struct hpi_response hr0; /* response from DSP 0 */ 530 struct hpi_response hr1; /* response from DSP 1 */ 531 u16 error = 0; 532 533 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); 534 memset(&hm, 0, sizeof(hm)); 535 hm.type = HPI_TYPE_MESSAGE; 536 hm.size = sizeof(struct hpi_message); 537 hm.object = HPI_OBJ_ADAPTER; 538 hm.function = HPI_ADAPTER_GET_INFO; 539 hm.adapter_index = 0; 540 memset(&hr0, 0, sizeof(hr0)); 541 memset(&hr1, 0, sizeof(hr1)); 542 hr0.size = sizeof(hr0); 543 hr1.size = sizeof(hr1); 544 545 error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0); 546 if (hr0.error) { 547 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error); 548 return hr0.error; 549 } 550 if (phw->num_dsp == 2) { 551 error = hpi6000_message_response_sequence(pao, 1, &hm, 552 &hr1); 553 if (error) 554 return error; 555 } 556 pao->adapter_type = hr0.u.ax.info.adapter_type; 557 pao->index = hr0.u.ax.info.adapter_index; 558 } 559 560 memset(&phw->control_cache[0], 0, 561 sizeof(struct hpi_control_cache_single) * 562 HPI_NMIXER_CONTROLS); 563 /* Read the control cache length to figure out if it is turned on */ 564 control_cache_size = 565 hpi_read_word(&phw->ado[0], 566 HPI_HIF_ADDR(control_cache_size_in_bytes)); 567 if (control_cache_size) { 568 control_cache_count = 569 hpi_read_word(&phw->ado[0], 570 HPI_HIF_ADDR(control_cache_count)); 571 572 phw->p_cache = 573 hpi_alloc_control_cache(control_cache_count, 574 control_cache_size, (unsigned char *) 575 &phw->control_cache[0] 576 ); 577 if (phw->p_cache) 578 pao->has_control_cache = 1; 579 } 580 581 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", 582 pao->adapter_type, pao->index); 583 pao->open = 0; /* upon creation the adapter is closed */ 584 585 return hpi_add_adapter(pao); 586 } 587 588 static void delete_adapter_obj(struct hpi_adapter_obj *pao) 589 { 590 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 591 592 if (pao->has_control_cache) 593 hpi_free_control_cache(phw->p_cache); 594 595 /* reset DSPs on adapter */ 596 iowrite32(0x0003000F, phw->dw2040_HPICSR + HPI_RESET); 597 598 kfree(phw); 599 } 600 601 /************************************************************************/ 602 /* ADAPTER */ 603 604 static void adapter_get_asserts(struct hpi_adapter_obj *pao, 605 struct hpi_message *phm, struct hpi_response *phr) 606 { 607 #ifndef HIDE_PCI_ASSERTS 608 /* if we have PCI2040 asserts then collect them */ 609 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { 610 phr->u.ax.assert.p1 = 611 gw_pci_read_asserts * 100 + gw_pci_write_asserts; 612 phr->u.ax.assert.p2 = 0; 613 phr->u.ax.assert.count = 1; /* assert count */ 614 phr->u.ax.assert.dsp_index = -1; /* "dsp index" */ 615 strcpy(phr->u.ax.assert.sz_message, "PCI2040 error"); 616 phr->u.ax.assert.dsp_msg_addr = 0; 617 gw_pci_read_asserts = 0; 618 gw_pci_write_asserts = 0; 619 phr->error = 0; 620 } else 621 #endif 622 hw_message(pao, phm, phr); /*get DSP asserts */ 623 624 return; 625 } 626 627 /************************************************************************/ 628 /* LOW-LEVEL */ 629 630 static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, 631 u32 *pos_error_code) 632 { 633 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 634 short error; 635 u32 timeout; 636 u32 read = 0; 637 u32 i = 0; 638 u32 data = 0; 639 u32 j = 0; 640 u32 test_addr = 0x80000000; 641 u32 test_data = 0x00000001; 642 u32 dw2040_reset = 0; 643 u32 dsp_index = 0; 644 u32 endian = 0; 645 u32 adapter_info = 0; 646 u32 delay = 0; 647 648 struct dsp_code dsp_code; 649 u16 boot_load_family = 0; 650 651 /* NOTE don't use wAdapterType in this routine. It is not setup yet */ 652 653 switch (pao->pci.pci_dev->subsystem_device) { 654 case 0x5100: 655 case 0x5110: /* ASI5100 revB or higher with C6711D */ 656 case 0x5200: /* ASI5200 PCIe version of ASI5100 */ 657 case 0x6100: 658 case 0x6200: 659 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); 660 break; 661 default: 662 return HPI6000_ERROR_UNHANDLED_SUBSYS_ID; 663 } 664 665 /* reset all DSPs, indicate two DSPs are present 666 * set RST3-=1 to disconnect HAD8 to set DSP in little endian mode 667 */ 668 endian = 0; 669 dw2040_reset = 0x0003000F; 670 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); 671 672 /* read back register to make sure PCI2040 chip is functioning 673 * note that bits 4..15 are read-only and so should always return zero, 674 * even though we wrote 1 to them 675 */ 676 hpios_delay_micro_seconds(1000); 677 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); 678 679 if (delay != dw2040_reset) { 680 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, 681 delay); 682 return HPI6000_ERROR_INIT_PCI2040; 683 } 684 685 /* Indicate that DSP#0,1 is a C6X */ 686 iowrite32(0x00000003, phw->dw2040_HPICSR + HPI_DATA_WIDTH); 687 /* set Bit30 and 29 - which will prevent Target aborts from being 688 * issued upon HPI or GP error 689 */ 690 iowrite32(0x60000000, phw->dw2040_HPICSR + INTERRUPT_MASK_SET); 691 692 /* isolate DSP HAD8 line from PCI2040 so that 693 * Little endian can be set by pullup 694 */ 695 dw2040_reset = dw2040_reset & (~(endian << 3)); 696 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); 697 698 phw->ado[0].c_dsp_rev = 'B'; /* revB */ 699 phw->ado[1].c_dsp_rev = 'B'; /* revB */ 700 701 /*Take both DSPs out of reset, setting HAD8 to the correct Endian */ 702 dw2040_reset = dw2040_reset & (~0x00000001); /* start DSP 0 */ 703 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); 704 dw2040_reset = dw2040_reset & (~0x00000002); /* start DSP 1 */ 705 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); 706 707 /* set HAD8 back to PCI2040, now that DSP set to little endian mode */ 708 dw2040_reset = dw2040_reset & (~0x00000008); 709 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); 710 /*delay to allow DSP to get going */ 711 hpios_delay_micro_seconds(100); 712 713 /* loop through all DSPs, downloading DSP code */ 714 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { 715 struct dsp_obj *pdo = &phw->ado[dsp_index]; 716 717 /* configure DSP so that we download code into the SRAM */ 718 /* set control reg for little endian, HWOB=1 */ 719 iowrite32(0x00010001, pdo->prHPI_control); 720 721 /* test access to the HPI address register (HPIA) */ 722 test_data = 0x00000001; 723 for (j = 0; j < 32; j++) { 724 iowrite32(test_data, pdo->prHPI_address); 725 data = ioread32(pdo->prHPI_address); 726 if (data != test_data) { 727 HPI_DEBUG_LOG(ERROR, "INIT_DSPHPI %x %x %x\n", 728 test_data, data, dsp_index); 729 return HPI6000_ERROR_INIT_DSPHPI; 730 } 731 test_data = test_data << 1; 732 } 733 734 /* if C6713 the setup PLL to generate 225MHz from 25MHz. 735 * Since the PLLDIV1 read is sometimes wrong, even on a C6713, 736 * we're going to do this unconditionally 737 */ 738 /* PLLDIV1 should have a value of 8000 after reset */ 739 /* 740 if (HpiReadWord(pdo,0x01B7C118) == 0x8000) 741 */ 742 { 743 /* C6713 datasheet says we cannot program PLL from HPI, 744 * and indeed if we try to set the PLL multiply from the 745 * HPI, the PLL does not seem to lock, 746 * so we enable the PLL and use the default of x 7 747 */ 748 /* bypass PLL */ 749 hpi_write_word(pdo, 0x01B7C100, 0x0000); 750 hpios_delay_micro_seconds(100); 751 752 /* ** use default of PLL x7 ** */ 753 /* EMIF = 225/3=75MHz */ 754 hpi_write_word(pdo, 0x01B7C120, 0x8002); 755 hpios_delay_micro_seconds(100); 756 757 /* peri = 225/2 */ 758 hpi_write_word(pdo, 0x01B7C11C, 0x8001); 759 hpios_delay_micro_seconds(100); 760 761 /* cpu = 225/1 */ 762 hpi_write_word(pdo, 0x01B7C118, 0x8000); 763 764 /* ~2ms delay */ 765 hpios_delay_micro_seconds(2000); 766 767 /* PLL not bypassed */ 768 hpi_write_word(pdo, 0x01B7C100, 0x0001); 769 /* ~2ms delay */ 770 hpios_delay_micro_seconds(2000); 771 } 772 773 /* test r/w to internal DSP memory 774 * C6711 has L2 cache mapped to 0x0 when reset 775 * 776 * revB - because of bug 3.0.1 last HPI read 777 * (before HPI address issued) must be non-autoinc 778 */ 779 /* test each bit in the 32bit word */ 780 for (i = 0; i < 100; i++) { 781 test_addr = 0x00000000; 782 test_data = 0x00000001; 783 for (j = 0; j < 32; j++) { 784 hpi_write_word(pdo, test_addr + i, test_data); 785 data = hpi_read_word(pdo, test_addr + i); 786 if (data != test_data) { 787 HPI_DEBUG_LOG(ERROR, 788 "DSP mem %x %x %x %x\n", 789 test_addr + i, test_data, 790 data, dsp_index); 791 792 return HPI6000_ERROR_INIT_DSPINTMEM; 793 } 794 test_data = test_data << 1; 795 } 796 } 797 798 /* memory map of ASI6200 799 00000000-0000FFFF 16Kx32 internal program 800 01800000-019FFFFF Internal peripheral 801 80000000-807FFFFF CE0 2Mx32 SDRAM running @ 100MHz 802 90000000-9000FFFF CE1 Async peripherals: 803 804 EMIF config 805 ------------ 806 Global EMIF control 807 0 - 808 1 - 809 2 - 810 3 CLK2EN = 1 CLKOUT2 enabled 811 4 CLK1EN = 0 CLKOUT1 disabled 812 5 EKEN = 1 <--!! C6713 specific, enables ECLKOUT 813 6 - 814 7 NOHOLD = 1 external HOLD disabled 815 8 HOLDA = 0 HOLDA output is low 816 9 HOLD = 0 HOLD input is low 817 10 ARDY = 1 ARDY input is high 818 11 BUSREQ = 0 BUSREQ output is low 819 12,13 Reserved = 1 820 */ 821 hpi_write_word(pdo, 0x01800000, 0x34A8); 822 823 /* EMIF CE0 setup - 2Mx32 Sync DRAM 824 31..28 Wr setup 825 27..22 Wr strobe 826 21..20 Wr hold 827 19..16 Rd setup 828 15..14 - 829 13..8 Rd strobe 830 7..4 MTYPE 0011 Sync DRAM 32bits 831 3 Wr hold MSB 832 2..0 Rd hold 833 */ 834 hpi_write_word(pdo, 0x01800008, 0x00000030); 835 836 /* EMIF SDRAM Extension 837 31-21 0 838 20 WR2RD = 0 839 19-18 WR2DEAC = 1 840 17 WR2WR = 0 841 16-15 R2WDQM = 2 842 14-12 RD2WR = 4 843 11-10 RD2DEAC = 1 844 9 RD2RD = 1 845 8-7 THZP = 10b 846 6-5 TWR = 2-1 = 01b (tWR = 10ns) 847 4 TRRD = 0b = 2 ECLK (tRRD = 14ns) 848 3-1 TRAS = 5-1 = 100b (Tras=42ns = 5 ECLK) 849 1 CAS latency = 3 ECLK 850 (for Micron 2M32-7 operating at 100Mhz) 851 */ 852 853 /* need to use this else DSP code crashes */ 854 hpi_write_word(pdo, 0x01800020, 0x001BDF29); 855 856 /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank) 857 31 - - 858 30 SDBSZ 1 4 bank 859 29..28 SDRSZ 00 11 row address pins 860 27..26 SDCSZ 01 8 column address pins 861 25 RFEN 1 refersh enabled 862 24 INIT 1 init SDRAM 863 23..20 TRCD 0001 864 19..16 TRP 0001 865 15..12 TRC 0110 866 11..0 - - 867 */ 868 /* need to use this else DSP code crashes */ 869 hpi_write_word(pdo, 0x01800018, 0x47117000); 870 871 /* EMIF SDRAM Refresh Timing */ 872 hpi_write_word(pdo, 0x0180001C, 0x00000410); 873 874 /*MIF CE1 setup - Async peripherals 875 @100MHz bus speed, each cycle is 10ns, 876 31..28 Wr setup = 1 877 27..22 Wr strobe = 3 30ns 878 21..20 Wr hold = 1 879 19..16 Rd setup =1 880 15..14 Ta = 2 881 13..8 Rd strobe = 3 30ns 882 7..4 MTYPE 0010 Async 32bits 883 3 Wr hold MSB =0 884 2..0 Rd hold = 1 885 */ 886 { 887 u32 cE1 = 888 (1L << 28) | (3L << 22) | (1L << 20) | (1L << 889 16) | (2L << 14) | (3L << 8) | (2L << 4) | 1L; 890 hpi_write_word(pdo, 0x01800004, cE1); 891 } 892 893 /* delay a little to allow SDRAM and DSP to "get going" */ 894 hpios_delay_micro_seconds(1000); 895 896 /* test access to SDRAM */ 897 { 898 test_addr = 0x80000000; 899 test_data = 0x00000001; 900 /* test each bit in the 32bit word */ 901 for (j = 0; j < 32; j++) { 902 hpi_write_word(pdo, test_addr, test_data); 903 data = hpi_read_word(pdo, test_addr); 904 if (data != test_data) { 905 HPI_DEBUG_LOG(ERROR, 906 "DSP dram %x %x %x %x\n", 907 test_addr, test_data, data, 908 dsp_index); 909 910 return HPI6000_ERROR_INIT_SDRAM1; 911 } 912 test_data = test_data << 1; 913 } 914 /* test every Nth address in the DRAM */ 915 #define DRAM_SIZE_WORDS 0x200000 /*2_mx32 */ 916 #define DRAM_INC 1024 917 test_addr = 0x80000000; 918 test_data = 0x0; 919 for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) { 920 hpi_write_word(pdo, test_addr + i, test_data); 921 test_data++; 922 } 923 test_addr = 0x80000000; 924 test_data = 0x0; 925 for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) { 926 data = hpi_read_word(pdo, test_addr + i); 927 if (data != test_data) { 928 HPI_DEBUG_LOG(ERROR, 929 "DSP dram %x %x %x %x\n", 930 test_addr + i, test_data, 931 data, dsp_index); 932 return HPI6000_ERROR_INIT_SDRAM2; 933 } 934 test_data++; 935 } 936 937 } 938 939 /* write the DSP code down into the DSPs memory */ 940 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ 941 dsp_code.ps_dev = pao->pci.pci_dev; 942 943 error = hpi_dsp_code_open(boot_load_family, &dsp_code, 944 pos_error_code); 945 946 if (error) 947 return error; 948 949 while (1) { 950 u32 length; 951 u32 address; 952 u32 type; 953 u32 *pcode; 954 955 error = hpi_dsp_code_read_word(&dsp_code, &length); 956 if (error) 957 break; 958 if (length == 0xFFFFFFFF) 959 break; /* end of code */ 960 961 error = hpi_dsp_code_read_word(&dsp_code, &address); 962 if (error) 963 break; 964 error = hpi_dsp_code_read_word(&dsp_code, &type); 965 if (error) 966 break; 967 error = hpi_dsp_code_read_block(length, &dsp_code, 968 &pcode); 969 if (error) 970 break; 971 error = hpi6000_dsp_block_write32(pao, (u16)dsp_index, 972 address, pcode, length); 973 if (error) 974 break; 975 } 976 977 if (error) { 978 hpi_dsp_code_close(&dsp_code); 979 return error; 980 } 981 /* verify that code was written correctly */ 982 /* this time through, assume no errors in DSP code file/array */ 983 hpi_dsp_code_rewind(&dsp_code); 984 while (1) { 985 u32 length; 986 u32 address; 987 u32 type; 988 u32 *pcode; 989 990 hpi_dsp_code_read_word(&dsp_code, &length); 991 if (length == 0xFFFFFFFF) 992 break; /* end of code */ 993 994 hpi_dsp_code_read_word(&dsp_code, &address); 995 hpi_dsp_code_read_word(&dsp_code, &type); 996 hpi_dsp_code_read_block(length, &dsp_code, &pcode); 997 998 for (i = 0; i < length; i++) { 999 data = hpi_read_word(pdo, address); 1000 if (data != *pcode) { 1001 error = HPI6000_ERROR_INIT_VERIFY; 1002 HPI_DEBUG_LOG(ERROR, 1003 "DSP verify %x %x %x %x\n", 1004 address, *pcode, data, 1005 dsp_index); 1006 break; 1007 } 1008 pcode++; 1009 address += 4; 1010 } 1011 if (error) 1012 break; 1013 } 1014 hpi_dsp_code_close(&dsp_code); 1015 if (error) 1016 return error; 1017 1018 /* zero out the hostmailbox */ 1019 { 1020 u32 address = HPI_HIF_ADDR(host_cmd); 1021 for (i = 0; i < 4; i++) { 1022 hpi_write_word(pdo, address, 0); 1023 address += 4; 1024 } 1025 } 1026 /* write the DSP number into the hostmailbox */ 1027 /* structure before starting the DSP */ 1028 hpi_write_word(pdo, HPI_HIF_ADDR(dsp_number), dsp_index); 1029 1030 /* write the DSP adapter Info into the */ 1031 /* hostmailbox before starting the DSP */ 1032 if (dsp_index > 0) 1033 hpi_write_word(pdo, HPI_HIF_ADDR(adapter_info), 1034 adapter_info); 1035 1036 /* step 3. Start code by sending interrupt */ 1037 iowrite32(0x00030003, pdo->prHPI_control); 1038 hpios_delay_micro_seconds(10000); 1039 1040 /* wait for a non-zero value in hostcmd - 1041 * indicating initialization is complete 1042 * 1043 * Init could take a while if DSP checks SDRAM memory 1044 * Was 200000. Increased to 2000000 for ASI8801 so we 1045 * don't get 938 errors. 1046 */ 1047 timeout = 2000000; 1048 while (timeout) { 1049 do { 1050 read = hpi_read_word(pdo, 1051 HPI_HIF_ADDR(host_cmd)); 1052 } while (--timeout 1053 && hpi6000_check_PCI2040_error_flag(pao, 1054 H6READ)); 1055 1056 if (read) 1057 break; 1058 /* The following is a workaround for bug #94: 1059 * Bluescreen on install and subsequent boots on a 1060 * DELL PowerEdge 600SC PC with 1.8GHz P4 and 1061 * ServerWorks chipset. Without this delay the system 1062 * locks up with a bluescreen (NOT GPF or pagefault). 1063 */ 1064 else 1065 hpios_delay_micro_seconds(10000); 1066 } 1067 if (timeout == 0) 1068 return HPI6000_ERROR_INIT_NOACK; 1069 1070 /* read the DSP adapter Info from the */ 1071 /* hostmailbox structure after starting the DSP */ 1072 if (dsp_index == 0) { 1073 /*u32 dwTestData=0; */ 1074 u32 mask = 0; 1075 1076 adapter_info = 1077 hpi_read_word(pdo, 1078 HPI_HIF_ADDR(adapter_info)); 1079 if (HPI_ADAPTER_FAMILY_ASI 1080 (HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER 1081 (adapter_info)) == 1082 HPI_ADAPTER_FAMILY_ASI(0x6200)) 1083 /* all 6200 cards have this many DSPs */ 1084 phw->num_dsp = 2; 1085 1086 /* test that the PLD is programmed */ 1087 /* and we can read/write 24bits */ 1088 #define PLD_BASE_ADDRESS 0x90000000L /*for ASI6100/6200/8800 */ 1089 1090 switch (boot_load_family) { 1091 case HPI_ADAPTER_FAMILY_ASI(0x6200): 1092 /* ASI6100/6200 has 24bit path to FPGA */ 1093 mask = 0xFFFFFF00L; 1094 /* ASI5100 uses AX6 code, */ 1095 /* but has no PLD r/w register to test */ 1096 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev-> 1097 subsystem_device) == 1098 HPI_ADAPTER_FAMILY_ASI(0x5100)) 1099 mask = 0x00000000L; 1100 /* ASI5200 uses AX6 code, */ 1101 /* but has no PLD r/w register to test */ 1102 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev-> 1103 subsystem_device) == 1104 HPI_ADAPTER_FAMILY_ASI(0x5200)) 1105 mask = 0x00000000L; 1106 break; 1107 case HPI_ADAPTER_FAMILY_ASI(0x8800): 1108 /* ASI8800 has 16bit path to FPGA */ 1109 mask = 0xFFFF0000L; 1110 break; 1111 } 1112 test_data = 0xAAAAAA00L & mask; 1113 /* write to 24 bit Debug register (D31-D8) */ 1114 hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data); 1115 read = hpi_read_word(pdo, 1116 PLD_BASE_ADDRESS + 4L) & mask; 1117 if (read != test_data) { 1118 HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data, 1119 read); 1120 return HPI6000_ERROR_INIT_PLDTEST1; 1121 } 1122 test_data = 0x55555500L & mask; 1123 hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data); 1124 read = hpi_read_word(pdo, 1125 PLD_BASE_ADDRESS + 4L) & mask; 1126 if (read != test_data) { 1127 HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data, 1128 read); 1129 return HPI6000_ERROR_INIT_PLDTEST2; 1130 } 1131 } 1132 } /* for numDSP */ 1133 return 0; 1134 } 1135 1136 #define PCI_TIMEOUT 100 1137 1138 static int hpi_set_address(struct dsp_obj *pdo, u32 address) 1139 { 1140 u32 timeout = PCI_TIMEOUT; 1141 1142 do { 1143 iowrite32(address, pdo->prHPI_address); 1144 } while (hpi6000_check_PCI2040_error_flag(pdo->pa_parent_adapter, 1145 H6WRITE) 1146 && --timeout); 1147 1148 if (timeout) 1149 return 0; 1150 1151 return 1; 1152 } 1153 1154 /* write one word to the HPI port */ 1155 static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data) 1156 { 1157 if (hpi_set_address(pdo, address)) 1158 return; 1159 iowrite32(data, pdo->prHPI_data); 1160 } 1161 1162 /* read one word from the HPI port */ 1163 static u32 hpi_read_word(struct dsp_obj *pdo, u32 address) 1164 { 1165 u32 data = 0; 1166 1167 if (hpi_set_address(pdo, address)) 1168 return 0; /*? No way to return error */ 1169 1170 /* take care of errata in revB DSP (2.0.1) */ 1171 data = ioread32(pdo->prHPI_data); 1172 return data; 1173 } 1174 1175 /* write a block of 32bit words to the DSP HPI port using auto-inc mode */ 1176 static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata, 1177 u32 length) 1178 { 1179 u16 length16 = length - 1; 1180 1181 if (length == 0) 1182 return; 1183 1184 if (hpi_set_address(pdo, address)) 1185 return; 1186 1187 iowrite32_rep(pdo->prHPI_data_auto_inc, pdata, length16); 1188 1189 /* take care of errata in revB DSP (2.0.1) */ 1190 /* must end with non auto-inc */ 1191 iowrite32(*(pdata + length - 1), pdo->prHPI_data); 1192 } 1193 1194 /** read a block of 32bit words from the DSP HPI port using auto-inc mode 1195 */ 1196 static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata, 1197 u32 length) 1198 { 1199 u16 length16 = length - 1; 1200 1201 if (length == 0) 1202 return; 1203 1204 if (hpi_set_address(pdo, address)) 1205 return; 1206 1207 ioread32_rep(pdo->prHPI_data_auto_inc, pdata, length16); 1208 1209 /* take care of errata in revB DSP (2.0.1) */ 1210 /* must end with non auto-inc */ 1211 *(pdata + length - 1) = ioread32(pdo->prHPI_data); 1212 } 1213 1214 static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao, 1215 u16 dsp_index, u32 hpi_address, u32 *source, u32 count) 1216 { 1217 struct dsp_obj *pdo = 1218 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1219 u32 time_out = PCI_TIMEOUT; 1220 int c6711_burst_size = 128; 1221 u32 local_hpi_address = hpi_address; 1222 int local_count = count; 1223 int xfer_size; 1224 u32 *pdata = source; 1225 1226 while (local_count) { 1227 if (local_count > c6711_burst_size) 1228 xfer_size = c6711_burst_size; 1229 else 1230 xfer_size = local_count; 1231 1232 time_out = PCI_TIMEOUT; 1233 do { 1234 hpi_write_block(pdo, local_hpi_address, pdata, 1235 xfer_size); 1236 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) 1237 && --time_out); 1238 1239 if (!time_out) 1240 break; 1241 pdata += xfer_size; 1242 local_hpi_address += sizeof(u32) * xfer_size; 1243 local_count -= xfer_size; 1244 } 1245 1246 if (time_out) 1247 return 0; 1248 else 1249 return 1; 1250 } 1251 1252 static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao, 1253 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count) 1254 { 1255 struct dsp_obj *pdo = 1256 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1257 u32 time_out = PCI_TIMEOUT; 1258 int c6711_burst_size = 16; 1259 u32 local_hpi_address = hpi_address; 1260 int local_count = count; 1261 int xfer_size; 1262 u32 *pdata = dest; 1263 u32 loop_count = 0; 1264 1265 while (local_count) { 1266 if (local_count > c6711_burst_size) 1267 xfer_size = c6711_burst_size; 1268 else 1269 xfer_size = local_count; 1270 1271 time_out = PCI_TIMEOUT; 1272 do { 1273 hpi_read_block(pdo, local_hpi_address, pdata, 1274 xfer_size); 1275 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) 1276 && --time_out); 1277 if (!time_out) 1278 break; 1279 1280 pdata += xfer_size; 1281 local_hpi_address += sizeof(u32) * xfer_size; 1282 local_count -= xfer_size; 1283 loop_count++; 1284 } 1285 1286 if (time_out) 1287 return 0; 1288 else 1289 return 1; 1290 } 1291 1292 static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, 1293 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr) 1294 { 1295 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 1296 struct dsp_obj *pdo = &phw->ado[dsp_index]; 1297 u32 timeout; 1298 u16 ack; 1299 u32 address; 1300 u32 length; 1301 u32 *p_data; 1302 u16 error = 0; 1303 1304 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); 1305 if (ack & HPI_HIF_ERROR_MASK) { 1306 pao->dsp_crashed++; 1307 return HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT; 1308 } 1309 pao->dsp_crashed = 0; 1310 1311 /* get the message address and size */ 1312 if (phw->message_buffer_address_on_dsp == 0) { 1313 timeout = TIMEOUT; 1314 do { 1315 address = 1316 hpi_read_word(pdo, 1317 HPI_HIF_ADDR(message_buffer_address)); 1318 phw->message_buffer_address_on_dsp = address; 1319 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) 1320 && --timeout); 1321 if (!timeout) 1322 return HPI6000_ERROR_MSG_GET_ADR; 1323 } else 1324 address = phw->message_buffer_address_on_dsp; 1325 1326 length = phm->size; 1327 1328 /* send the message */ 1329 p_data = (u32 *)phm; 1330 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, 1331 (u16)length / 4)) 1332 return HPI6000_ERROR_MSG_RESP_BLOCKWRITE32; 1333 1334 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_GET_RESP)) 1335 return HPI6000_ERROR_MSG_RESP_GETRESPCMD; 1336 hpi6000_send_dsp_interrupt(pdo); 1337 1338 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_RESP); 1339 if (ack & HPI_HIF_ERROR_MASK) 1340 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; 1341 1342 /* get the response address */ 1343 if (phw->response_buffer_address_on_dsp == 0) { 1344 timeout = TIMEOUT; 1345 do { 1346 address = 1347 hpi_read_word(pdo, 1348 HPI_HIF_ADDR(response_buffer_address)); 1349 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) 1350 && --timeout); 1351 phw->response_buffer_address_on_dsp = address; 1352 1353 if (!timeout) 1354 return HPI6000_ERROR_RESP_GET_ADR; 1355 } else 1356 address = phw->response_buffer_address_on_dsp; 1357 1358 /* read the length of the response back from the DSP */ 1359 timeout = TIMEOUT; 1360 do { 1361 length = hpi_read_word(pdo, HPI_HIF_ADDR(length)); 1362 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout); 1363 if (!timeout) 1364 length = sizeof(struct hpi_response); 1365 1366 /* get the response */ 1367 p_data = (u32 *)phr; 1368 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, 1369 (u16)length / 4)) 1370 return HPI6000_ERROR_MSG_RESP_BLOCKREAD32; 1371 1372 /* set i/f back to idle */ 1373 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE)) 1374 return HPI6000_ERROR_MSG_RESP_IDLECMD; 1375 hpi6000_send_dsp_interrupt(pdo); 1376 1377 error = hpi_validate_response(phm, phr); 1378 return error; 1379 } 1380 1381 /* have to set up the below defines to match stuff in the MAP file */ 1382 1383 #define MSG_ADDRESS (HPI_HIF_BASE+0x18) 1384 #define MSG_LENGTH 11 1385 #define RESP_ADDRESS (HPI_HIF_BASE+0x44) 1386 #define RESP_LENGTH 16 1387 #define QUEUE_START (HPI_HIF_BASE+0x88) 1388 #define QUEUE_SIZE 0x8000 1389 1390 static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords) 1391 { 1392 /*#define CHECKING // comment this line in to enable checking */ 1393 #ifdef CHECKING 1394 if (address < (u32)MSG_ADDRESS) 1395 return 0; 1396 if (address > (u32)(QUEUE_START + QUEUE_SIZE)) 1397 return 0; 1398 if ((address + (length_in_dwords << 2)) > 1399 (u32)(QUEUE_START + QUEUE_SIZE)) 1400 return 0; 1401 #else 1402 (void)address; 1403 (void)length_in_dwords; 1404 return 1; 1405 #endif 1406 } 1407 1408 static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index, 1409 struct hpi_message *phm, struct hpi_response *phr) 1410 { 1411 struct dsp_obj *pdo = 1412 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1413 u32 data_sent = 0; 1414 u16 ack; 1415 u32 length, address; 1416 u32 *p_data = (u32 *)phm->u.d.u.data.pb_data; 1417 u16 time_out = 8; 1418 1419 (void)phr; 1420 1421 /* round dwDataSize down to nearest 4 bytes */ 1422 while ((data_sent < (phm->u.d.u.data.data_size & ~3L)) 1423 && --time_out) { 1424 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); 1425 if (ack & HPI_HIF_ERROR_MASK) 1426 return HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT; 1427 1428 if (hpi6000_send_host_command(pao, dsp_index, 1429 HPI_HIF_SEND_DATA)) 1430 return HPI6000_ERROR_SEND_DATA_CMD; 1431 1432 hpi6000_send_dsp_interrupt(pdo); 1433 1434 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_SEND_DATA); 1435 1436 if (ack & HPI_HIF_ERROR_MASK) 1437 return HPI6000_ERROR_SEND_DATA_ACK; 1438 1439 do { 1440 /* get the address and size */ 1441 address = hpi_read_word(pdo, HPI_HIF_ADDR(address)); 1442 /* DSP returns number of DWORDS */ 1443 length = hpi_read_word(pdo, HPI_HIF_ADDR(length)); 1444 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)); 1445 1446 if (!hpi6000_send_data_check_adr(address, length)) 1447 return HPI6000_ERROR_SEND_DATA_ADR; 1448 1449 /* send the data. break data into 512 DWORD blocks (2K bytes) 1450 * and send using block write. 2Kbytes is the max as this is the 1451 * memory window given to the HPI data register by the PCI2040 1452 */ 1453 1454 { 1455 u32 len = length; 1456 u32 blk_len = 512; 1457 while (len) { 1458 if (len < blk_len) 1459 blk_len = len; 1460 if (hpi6000_dsp_block_write32(pao, dsp_index, 1461 address, p_data, blk_len)) 1462 return HPI6000_ERROR_SEND_DATA_WRITE; 1463 address += blk_len * 4; 1464 p_data += blk_len; 1465 len -= blk_len; 1466 } 1467 } 1468 1469 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE)) 1470 return HPI6000_ERROR_SEND_DATA_IDLECMD; 1471 1472 hpi6000_send_dsp_interrupt(pdo); 1473 1474 data_sent += length * 4; 1475 } 1476 if (!time_out) 1477 return HPI6000_ERROR_SEND_DATA_TIMEOUT; 1478 return 0; 1479 } 1480 1481 static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index, 1482 struct hpi_message *phm, struct hpi_response *phr) 1483 { 1484 struct dsp_obj *pdo = 1485 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1486 u32 data_got = 0; 1487 u16 ack; 1488 u32 length, address; 1489 u32 *p_data = (u32 *)phm->u.d.u.data.pb_data; 1490 1491 (void)phr; /* this parameter not used! */ 1492 1493 /* round dwDataSize down to nearest 4 bytes */ 1494 while (data_got < (phm->u.d.u.data.data_size & ~3L)) { 1495 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); 1496 if (ack & HPI_HIF_ERROR_MASK) 1497 return HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT; 1498 1499 if (hpi6000_send_host_command(pao, dsp_index, 1500 HPI_HIF_GET_DATA)) 1501 return HPI6000_ERROR_GET_DATA_CMD; 1502 hpi6000_send_dsp_interrupt(pdo); 1503 1504 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_DATA); 1505 1506 if (ack & HPI_HIF_ERROR_MASK) 1507 return HPI6000_ERROR_GET_DATA_ACK; 1508 1509 /* get the address and size */ 1510 do { 1511 address = hpi_read_word(pdo, HPI_HIF_ADDR(address)); 1512 length = hpi_read_word(pdo, HPI_HIF_ADDR(length)); 1513 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)); 1514 1515 /* read the data */ 1516 { 1517 u32 len = length; 1518 u32 blk_len = 512; 1519 while (len) { 1520 if (len < blk_len) 1521 blk_len = len; 1522 if (hpi6000_dsp_block_read32(pao, dsp_index, 1523 address, p_data, blk_len)) 1524 return HPI6000_ERROR_GET_DATA_READ; 1525 address += blk_len * 4; 1526 p_data += blk_len; 1527 len -= blk_len; 1528 } 1529 } 1530 1531 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE)) 1532 return HPI6000_ERROR_GET_DATA_IDLECMD; 1533 hpi6000_send_dsp_interrupt(pdo); 1534 1535 data_got += length * 4; 1536 } 1537 return 0; 1538 } 1539 1540 static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo) 1541 { 1542 iowrite32(0x00030003, pdo->prHPI_control); /* DSPINT */ 1543 } 1544 1545 static short hpi6000_send_host_command(struct hpi_adapter_obj *pao, 1546 u16 dsp_index, u32 host_cmd) 1547 { 1548 struct dsp_obj *pdo = 1549 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1550 u32 timeout = TIMEOUT; 1551 1552 /* set command */ 1553 do { 1554 hpi_write_word(pdo, HPI_HIF_ADDR(host_cmd), host_cmd); 1555 /* flush the FIFO */ 1556 hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd)); 1557 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) && --timeout); 1558 1559 /* reset the interrupt bit */ 1560 iowrite32(0x00040004, pdo->prHPI_control); 1561 1562 if (timeout) 1563 return 0; 1564 else 1565 return 1; 1566 } 1567 1568 /* if the PCI2040 has recorded an HPI timeout, reset the error and return 1 */ 1569 static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao, 1570 u16 read_or_write) 1571 { 1572 u32 hPI_error; 1573 1574 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 1575 1576 /* read the error bits from the PCI2040 */ 1577 hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT); 1578 if (hPI_error) { 1579 /* reset the error flag */ 1580 iowrite32(0L, phw->dw2040_HPICSR + HPI_ERROR_REPORT); 1581 phw->pCI2040HPI_error_count++; 1582 if (read_or_write == 1) 1583 gw_pci_read_asserts++; /************* inc global */ 1584 else 1585 gw_pci_write_asserts++; 1586 return 1; 1587 } else 1588 return 0; 1589 } 1590 1591 static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index, 1592 u32 ack_value) 1593 { 1594 struct dsp_obj *pdo = 1595 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; 1596 u32 ack = 0L; 1597 u32 timeout; 1598 u32 hPIC = 0L; 1599 1600 /* wait for host interrupt to signal ack is ready */ 1601 timeout = TIMEOUT; 1602 while (--timeout) { 1603 hPIC = ioread32(pdo->prHPI_control); 1604 if (hPIC & 0x04) /* 0x04 = HINT from DSP */ 1605 break; 1606 } 1607 if (timeout == 0) 1608 return HPI_HIF_ERROR_MASK; 1609 1610 /* wait for dwAckValue */ 1611 timeout = TIMEOUT; 1612 while (--timeout) { 1613 /* read the ack mailbox */ 1614 ack = hpi_read_word(pdo, HPI_HIF_ADDR(dsp_ack)); 1615 if (ack == ack_value) 1616 break; 1617 if ((ack & HPI_HIF_ERROR_MASK) 1618 && !hpi6000_check_PCI2040_error_flag(pao, H6READ)) 1619 break; 1620 /*for (i=0;i<1000;i++) */ 1621 /* dwPause=i+1; */ 1622 } 1623 if (ack & HPI_HIF_ERROR_MASK) 1624 /* indicates bad read from DSP - 1625 typically 0xffffff is read for some reason */ 1626 ack = HPI_HIF_ERROR_MASK; 1627 1628 if (timeout == 0) 1629 ack = HPI_HIF_ERROR_MASK; 1630 return (short)ack; 1631 } 1632 1633 static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao, 1634 struct hpi_message *phm) 1635 { 1636 const u16 dsp_index = 0; 1637 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 1638 struct dsp_obj *pdo = &phw->ado[dsp_index]; 1639 u32 timeout; 1640 u32 cache_dirty_flag; 1641 u16 err; 1642 1643 hpios_dsplock_lock(pao); 1644 1645 timeout = TIMEOUT; 1646 do { 1647 cache_dirty_flag = 1648 hpi_read_word((struct dsp_obj *)pdo, 1649 HPI_HIF_ADDR(control_cache_is_dirty)); 1650 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout); 1651 if (!timeout) { 1652 err = HPI6000_ERROR_CONTROL_CACHE_PARAMS; 1653 goto unlock; 1654 } 1655 1656 if (cache_dirty_flag) { 1657 /* read the cached controls */ 1658 u32 address; 1659 u32 length; 1660 1661 timeout = TIMEOUT; 1662 if (pdo->control_cache_address_on_dsp == 0) { 1663 do { 1664 address = 1665 hpi_read_word((struct dsp_obj *)pdo, 1666 HPI_HIF_ADDR(control_cache_address)); 1667 1668 length = hpi_read_word((struct dsp_obj *)pdo, 1669 HPI_HIF_ADDR 1670 (control_cache_size_in_bytes)); 1671 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) 1672 && --timeout); 1673 if (!timeout) { 1674 err = HPI6000_ERROR_CONTROL_CACHE_ADDRLEN; 1675 goto unlock; 1676 } 1677 pdo->control_cache_address_on_dsp = address; 1678 pdo->control_cache_length_on_dsp = length; 1679 } else { 1680 address = pdo->control_cache_address_on_dsp; 1681 length = pdo->control_cache_length_on_dsp; 1682 } 1683 1684 if (hpi6000_dsp_block_read32(pao, dsp_index, address, 1685 (u32 *)&phw->control_cache[0], 1686 length / sizeof(u32))) { 1687 err = HPI6000_ERROR_CONTROL_CACHE_READ; 1688 goto unlock; 1689 } 1690 do { 1691 hpi_write_word((struct dsp_obj *)pdo, 1692 HPI_HIF_ADDR(control_cache_is_dirty), 0); 1693 /* flush the FIFO */ 1694 hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd)); 1695 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) 1696 && --timeout); 1697 if (!timeout) { 1698 err = HPI6000_ERROR_CONTROL_CACHE_FLUSH; 1699 goto unlock; 1700 } 1701 1702 } 1703 err = 0; 1704 1705 unlock: 1706 hpios_dsplock_unlock(pao); 1707 return err; 1708 } 1709 1710 /** Get dsp index for multi DSP adapters only */ 1711 static u16 get_dsp_index(struct hpi_adapter_obj *pao, struct hpi_message *phm) 1712 { 1713 u16 ret = 0; 1714 switch (phm->object) { 1715 case HPI_OBJ_ISTREAM: 1716 if (phm->obj_index < 2) 1717 ret = 1; 1718 break; 1719 case HPI_OBJ_PROFILE: 1720 ret = phm->obj_index; 1721 break; 1722 default: 1723 break; 1724 } 1725 return ret; 1726 } 1727 1728 /** Complete transaction with DSP 1729 1730 Send message, get response, send or get stream data if any. 1731 */ 1732 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, 1733 struct hpi_response *phr) 1734 { 1735 u16 error = 0; 1736 u16 dsp_index = 0; 1737 u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp; 1738 1739 if (num_dsp < 2) 1740 dsp_index = 0; 1741 else { 1742 dsp_index = get_dsp_index(pao, phm); 1743 1744 /* is this checked on the DSP anyway? */ 1745 if ((phm->function == HPI_ISTREAM_GROUP_ADD) 1746 || (phm->function == HPI_OSTREAM_GROUP_ADD)) { 1747 struct hpi_message hm; 1748 u16 add_index; 1749 hm.obj_index = phm->u.d.u.stream.stream_index; 1750 hm.object = phm->u.d.u.stream.object_type; 1751 add_index = get_dsp_index(pao, &hm); 1752 if (add_index != dsp_index) { 1753 phr->error = HPI_ERROR_NO_INTERDSP_GROUPS; 1754 return; 1755 } 1756 } 1757 } 1758 1759 hpios_dsplock_lock(pao); 1760 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); 1761 1762 /* maybe an error response */ 1763 if (error) { 1764 /* something failed in the HPI/DSP interface */ 1765 phr->error = error; 1766 /* just the header of the response is valid */ 1767 phr->size = sizeof(struct hpi_response_header); 1768 goto err; 1769 } 1770 1771 if (phr->error != 0) /* something failed in the DSP */ 1772 goto err; 1773 1774 switch (phm->function) { 1775 case HPI_OSTREAM_WRITE: 1776 case HPI_ISTREAM_ANC_WRITE: 1777 error = hpi6000_send_data(pao, dsp_index, phm, phr); 1778 break; 1779 case HPI_ISTREAM_READ: 1780 case HPI_OSTREAM_ANC_READ: 1781 error = hpi6000_get_data(pao, dsp_index, phm, phr); 1782 break; 1783 case HPI_ADAPTER_GET_ASSERT: 1784 phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */ 1785 if (num_dsp == 2) { 1786 if (!phr->u.ax.assert.count) { 1787 /* no assert from dsp 0, check dsp 1 */ 1788 error = hpi6000_message_response_sequence(pao, 1789 1, phm, phr); 1790 phr->u.ax.assert.dsp_index = 1; 1791 } 1792 } 1793 } 1794 1795 if (error) 1796 phr->error = error; 1797 1798 err: 1799 hpios_dsplock_unlock(pao); 1800 return; 1801 } 1802