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