aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/asihpi/hpi6000.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/asihpi/hpi6000.c')
-rw-r--r--sound/pci/asihpi/hpi6000.c332
1 files changed, 150 insertions, 182 deletions
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index f7e374ec4414..df4aed5295dd 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -43,16 +43,17 @@
43#define HPI_HIF_ERROR_MASK 0x4000 43#define HPI_HIF_ERROR_MASK 0x4000
44 44
45/* HPI6000 specific error codes */ 45/* HPI6000 specific error codes */
46#define HPI6000_ERROR_BASE 900 /* not actually used anywhere */
46 47
47#define HPI6000_ERROR_BASE 900 48/* operational/messaging errors */
48#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 49#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
49#define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902 50
50#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 51#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
51#define HPI6000_ERROR_MSG_GET_ADR 904 52#define HPI6000_ERROR_MSG_GET_ADR 904
52#define HPI6000_ERROR_RESP_GET_ADR 905 53#define HPI6000_ERROR_RESP_GET_ADR 905
53#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 54#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
54#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 55#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
55#define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908 56
56#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909 57#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
57 58
58#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 59#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
@@ -62,7 +63,6 @@
62#define HPI6000_ERROR_SEND_DATA_CMD 915 63#define HPI6000_ERROR_SEND_DATA_CMD 915
63#define HPI6000_ERROR_SEND_DATA_WRITE 916 64#define HPI6000_ERROR_SEND_DATA_WRITE 916
64#define HPI6000_ERROR_SEND_DATA_IDLECMD 917 65#define HPI6000_ERROR_SEND_DATA_IDLECMD 917
65#define HPI6000_ERROR_SEND_DATA_VERIFY 918
66 66
67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921 67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
68#define HPI6000_ERROR_GET_DATA_ACK 922 68#define HPI6000_ERROR_GET_DATA_ACK 922
@@ -76,9 +76,8 @@
76 76
77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962 78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962
79#define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963
80 79
81/* adapter init errors */ 80/* Initialisation/bootload errors */
82#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930 81#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
83 82
84/* can't access PCI2040 */ 83/* can't access PCI2040 */
@@ -201,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
201static void subsys_create_adapter(struct hpi_message *phm, 200static void subsys_create_adapter(struct hpi_message *phm,
202 struct hpi_response *phr); 201 struct hpi_response *phr);
203 202
204static void subsys_delete_adapter(struct hpi_message *phm, 203static void adapter_delete(struct hpi_adapter_obj *pao,
205 struct hpi_response *phr); 204 struct hpi_message *phm, struct hpi_response *phr);
206 205
207static void adapter_get_asserts(struct hpi_adapter_obj *pao, 206static void adapter_get_asserts(struct hpi_adapter_obj *pao,
208 struct hpi_message *phm, struct hpi_response *phr); 207 struct hpi_message *phm, struct hpi_response *phr);
@@ -210,6 +209,8 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
210static short create_adapter_obj(struct hpi_adapter_obj *pao, 209static short create_adapter_obj(struct hpi_adapter_obj *pao,
211 u32 *pos_error_code); 210 u32 *pos_error_code);
212 211
212static void delete_adapter_obj(struct hpi_adapter_obj *pao);
213
213/* local globals */ 214/* local globals */
214 215
215static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ 216static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
@@ -217,23 +218,10 @@ static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
217 218
218static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 219static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
219{ 220{
220
221 switch (phm->function) { 221 switch (phm->function) {
222 case HPI_SUBSYS_OPEN:
223 case HPI_SUBSYS_CLOSE:
224 case HPI_SUBSYS_GET_INFO:
225 case HPI_SUBSYS_DRIVER_UNLOAD:
226 case HPI_SUBSYS_DRIVER_LOAD:
227 case HPI_SUBSYS_FIND_ADAPTERS:
228 /* messages that should not get here */
229 phr->error = HPI_ERROR_UNIMPLEMENTED;
230 break;
231 case HPI_SUBSYS_CREATE_ADAPTER: 222 case HPI_SUBSYS_CREATE_ADAPTER:
232 subsys_create_adapter(phm, phr); 223 subsys_create_adapter(phm, phr);
233 break; 224 break;
234 case HPI_SUBSYS_DELETE_ADAPTER:
235 subsys_delete_adapter(phm, phr);
236 break;
237 default: 225 default:
238 phr->error = HPI_ERROR_INVALID_FUNC; 226 phr->error = HPI_ERROR_INVALID_FUNC;
239 break; 227 break;
@@ -243,7 +231,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
243static void control_message(struct hpi_adapter_obj *pao, 231static void control_message(struct hpi_adapter_obj *pao,
244 struct hpi_message *phm, struct hpi_response *phr) 232 struct hpi_message *phm, struct hpi_response *phr)
245{ 233{
246
247 switch (phm->function) { 234 switch (phm->function) {
248 case HPI_CONTROL_GET_STATE: 235 case HPI_CONTROL_GET_STATE:
249 if (pao->has_control_cache) { 236 if (pao->has_control_cache) {
@@ -251,7 +238,13 @@ static void control_message(struct hpi_adapter_obj *pao,
251 err = hpi6000_update_control_cache(pao, phm); 238 err = hpi6000_update_control_cache(pao, phm);
252 239
253 if (err) { 240 if (err) {
254 phr->error = err; 241 if (err >= HPI_ERROR_BACKEND_BASE) {
242 phr->error =
243 HPI_ERROR_CONTROL_CACHING;
244 phr->specific_error = err;
245 } else {
246 phr->error = err;
247 }
255 break; 248 break;
256 } 249 }
257 250
@@ -262,16 +255,15 @@ static void control_message(struct hpi_adapter_obj *pao,
262 } 255 }
263 hw_message(pao, phm, phr); 256 hw_message(pao, phm, phr);
264 break; 257 break;
265 case HPI_CONTROL_GET_INFO:
266 hw_message(pao, phm, phr);
267 break;
268 case HPI_CONTROL_SET_STATE: 258 case HPI_CONTROL_SET_STATE:
269 hw_message(pao, phm, phr); 259 hw_message(pao, phm, phr);
270 hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)-> 260 hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao->
271 p_cache, phm, phr); 261 priv)->p_cache, phm, phr);
272 break; 262 break;
263
264 case HPI_CONTROL_GET_INFO:
273 default: 265 default:
274 phr->error = HPI_ERROR_INVALID_FUNC; 266 hw_message(pao, phm, phr);
275 break; 267 break;
276 } 268 }
277} 269}
@@ -280,26 +272,16 @@ static void adapter_message(struct hpi_adapter_obj *pao,
280 struct hpi_message *phm, struct hpi_response *phr) 272 struct hpi_message *phm, struct hpi_response *phr)
281{ 273{
282 switch (phm->function) { 274 switch (phm->function) {
283 case HPI_ADAPTER_GET_INFO:
284 hw_message(pao, phm, phr);
285 break;
286 case HPI_ADAPTER_GET_ASSERT: 275 case HPI_ADAPTER_GET_ASSERT:
287 adapter_get_asserts(pao, phm, phr); 276 adapter_get_asserts(pao, phm, phr);
288 break; 277 break;
289 case HPI_ADAPTER_OPEN: 278
290 case HPI_ADAPTER_CLOSE: 279 case HPI_ADAPTER_DELETE:
291 case HPI_ADAPTER_TEST_ASSERT: 280 adapter_delete(pao, phm, phr);
292 case HPI_ADAPTER_SELFTEST:
293 case HPI_ADAPTER_GET_MODE:
294 case HPI_ADAPTER_SET_MODE:
295 case HPI_ADAPTER_FIND_OBJECT:
296 case HPI_ADAPTER_GET_PROPERTY:
297 case HPI_ADAPTER_SET_PROPERTY:
298 case HPI_ADAPTER_ENUM_PROPERTY:
299 hw_message(pao, phm, phr);
300 break; 281 break;
282
301 default: 283 default:
302 phr->error = HPI_ERROR_INVALID_FUNC; 284 hw_message(pao, phm, phr);
303 break; 285 break;
304 } 286 }
305} 287}
@@ -311,7 +293,7 @@ static void outstream_message(struct hpi_adapter_obj *pao,
311 case HPI_OSTREAM_HOSTBUFFER_ALLOC: 293 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
312 case HPI_OSTREAM_HOSTBUFFER_FREE: 294 case HPI_OSTREAM_HOSTBUFFER_FREE:
313 /* Don't let these messages go to the HW function because 295 /* Don't let these messages go to the HW function because
314 * they're called without allocating the spinlock. 296 * they're called without locking the spinlock.
315 * For the HPI6000 adapters the HW would return 297 * For the HPI6000 adapters the HW would return
316 * HPI_ERROR_INVALID_FUNC anyway. 298 * HPI_ERROR_INVALID_FUNC anyway.
317 */ 299 */
@@ -331,7 +313,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
331 case HPI_ISTREAM_HOSTBUFFER_ALLOC: 313 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
332 case HPI_ISTREAM_HOSTBUFFER_FREE: 314 case HPI_ISTREAM_HOSTBUFFER_FREE:
333 /* Don't let these messages go to the HW function because 315 /* Don't let these messages go to the HW function because
334 * they're called without allocating the spinlock. 316 * they're called without locking the spinlock.
335 * For the HPI6000 adapters the HW would return 317 * For the HPI6000 adapters the HW would return
336 * HPI_ERROR_INVALID_FUNC anyway. 318 * HPI_ERROR_INVALID_FUNC anyway.
337 */ 319 */
@@ -352,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
352{ 334{
353 struct hpi_adapter_obj *pao = NULL; 335 struct hpi_adapter_obj *pao = NULL;
354 336
355 /* subsytem messages get executed by every HPI. */
356 /* All other messages are ignored unless the adapter index matches */
357 /* an adapter in the HPI */
358 HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function);
359
360 /* if Dsp has crashed then do not communicate with it any more */
361 if (phm->object != HPI_OBJ_SUBSYSTEM) { 337 if (phm->object != HPI_OBJ_SUBSYSTEM) {
362 pao = hpi_find_adapter(phm->adapter_index); 338 pao = hpi_find_adapter(phm->adapter_index);
363 if (!pao) { 339 if (!pao) {
364 HPI_DEBUG_LOG(DEBUG, 340 hpi_init_response(phr, phm->object, phm->function,
365 " %d,%d refused, for another HPI?\n", 341 HPI_ERROR_BAD_ADAPTER_NUMBER);
366 phm->object, phm->function); 342 HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
343 phm->adapter_index);
367 return; 344 return;
368 } 345 }
369 346
347 /* Don't even try to communicate with crashed DSP */
370 if (pao->dsp_crashed >= 10) { 348 if (pao->dsp_crashed >= 10) {
371 hpi_init_response(phr, phm->object, phm->function, 349 hpi_init_response(phr, phm->object, phm->function,
372 HPI_ERROR_DSP_HARDWARE); 350 HPI_ERROR_DSP_HARDWARE);
373 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", 351 HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
374 phm->object, phm->function); 352 phm->adapter_index);
375 return; 353 return;
376 } 354 }
377 } 355 }
@@ -433,39 +411,34 @@ static void subsys_create_adapter(struct hpi_message *phm,
433 struct hpi_adapter_obj ao; 411 struct hpi_adapter_obj ao;
434 struct hpi_adapter_obj *pao; 412 struct hpi_adapter_obj *pao;
435 u32 os_error_code; 413 u32 os_error_code;
436 short error = 0; 414 u16 err = 0;
437 u32 dsp_index = 0; 415 u32 dsp_index = 0;
438 416
439 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n"); 417 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n");
440 418
441 memset(&ao, 0, sizeof(ao)); 419 memset(&ao, 0, sizeof(ao));
442 420
443 /* this HPI only creates adapters for TI/PCI2040 based devices */
444 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
445 return;
446 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
447 return;
448 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_PCI2040)
449 return;
450
451 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); 421 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
452 if (!ao.priv) { 422 if (!ao.priv) {
453 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); 423 HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n");
454 phr->error = HPI_ERROR_MEMORY_ALLOC; 424 phr->error = HPI_ERROR_MEMORY_ALLOC;
455 return; 425 return;
456 } 426 }
457 427
458 /* create the adapter object based on the resource information */ 428 /* create the adapter object based on the resource information */
459 /*? memcpy(&ao.Pci,&phm->u.s.Resource.r.Pci,sizeof(ao.Pci)); */
460 ao.pci = *phm->u.s.resource.r.pci; 429 ao.pci = *phm->u.s.resource.r.pci;
461 430
462 error = create_adapter_obj(&ao, &os_error_code); 431 err = create_adapter_obj(&ao, &os_error_code);
463 if (!error) 432 if (err) {
464 error = hpi_add_adapter(&ao); 433 delete_adapter_obj(&ao);
465 if (error) { 434 if (err >= HPI_ERROR_BACKEND_BASE) {
435 phr->error = HPI_ERROR_DSP_BOOTLOAD;
436 phr->specific_error = err;
437 } else {
438 phr->error = err;
439 }
440
466 phr->u.s.data = os_error_code; 441 phr->u.s.data = os_error_code;
467 kfree(ao.priv);
468 phr->error = error;
469 return; 442 return;
470 } 443 }
471 /* need to update paParentAdapter */ 444 /* need to update paParentAdapter */
@@ -473,7 +446,7 @@ static void subsys_create_adapter(struct hpi_message *phm,
473 if (!pao) { 446 if (!pao) {
474 /* We just added this adapter, why can't we find it!? */ 447 /* We just added this adapter, why can't we find it!? */
475 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n"); 448 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n");
476 phr->error = 950; 449 phr->error = HPI_ERROR_BAD_ADAPTER;
477 return; 450 return;
478 } 451 }
479 452
@@ -482,30 +455,16 @@ static void subsys_create_adapter(struct hpi_message *phm,
482 phw->ado[dsp_index].pa_parent_adapter = pao; 455 phw->ado[dsp_index].pa_parent_adapter = pao;
483 } 456 }
484 457
485 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; 458 phr->u.s.adapter_type = ao.adapter_type;
486 phr->u.s.adapter_index = ao.index; 459 phr->u.s.adapter_index = ao.index;
487 phr->u.s.num_adapters++;
488 phr->error = 0; 460 phr->error = 0;
489} 461}
490 462
491static void subsys_delete_adapter(struct hpi_message *phm, 463static void adapter_delete(struct hpi_adapter_obj *pao,
492 struct hpi_response *phr) 464 struct hpi_message *phm, struct hpi_response *phr)
493{ 465{
494 struct hpi_adapter_obj *pao = NULL; 466 delete_adapter_obj(pao);
495 struct hpi_hw_obj *phw;
496
497 pao = hpi_find_adapter(phm->adapter_index);
498 if (!pao)
499 return;
500
501 phw = (struct hpi_hw_obj *)pao->priv;
502
503 if (pao->has_control_cache)
504 hpi_free_control_cache(phw->p_cache);
505
506 hpi_delete_adapter(pao); 467 hpi_delete_adapter(pao);
507 kfree(phw);
508
509 phr->error = 0; 468 phr->error = 0;
510} 469}
511 470
@@ -519,9 +478,6 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
519 u32 control_cache_count = 0; 478 u32 control_cache_count = 0;
520 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 479 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
521 480
522 /* init error reporting */
523 pao->dsp_crashed = 0;
524
525 /* The PCI2040 has the following address map */ 481 /* The PCI2040 has the following address map */
526 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ 482 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
527 /* BAR1 - 32K = HPI registers on DSP */ 483 /* BAR1 - 32K = HPI registers on DSP */
@@ -575,36 +531,36 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
575 /* get info about the adapter by asking the adapter */ 531 /* get info about the adapter by asking the adapter */
576 /* send a HPI_ADAPTER_GET_INFO message */ 532 /* send a HPI_ADAPTER_GET_INFO message */
577 { 533 {
578 struct hpi_message hM; 534 struct hpi_message hm;
579 struct hpi_response hR0; /* response from DSP 0 */ 535 struct hpi_response hr0; /* response from DSP 0 */
580 struct hpi_response hR1; /* response from DSP 1 */ 536 struct hpi_response hr1; /* response from DSP 1 */
581 u16 error = 0; 537 u16 error = 0;
582 538
583 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); 539 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
584 memset(&hM, 0, sizeof(hM)); 540 memset(&hm, 0, sizeof(hm));
585 hM.type = HPI_TYPE_MESSAGE; 541 hm.type = HPI_TYPE_MESSAGE;
586 hM.size = sizeof(struct hpi_message); 542 hm.size = sizeof(struct hpi_message);
587 hM.object = HPI_OBJ_ADAPTER; 543 hm.object = HPI_OBJ_ADAPTER;
588 hM.function = HPI_ADAPTER_GET_INFO; 544 hm.function = HPI_ADAPTER_GET_INFO;
589 hM.adapter_index = 0; 545 hm.adapter_index = 0;
590 memset(&hR0, 0, sizeof(hR0)); 546 memset(&hr0, 0, sizeof(hr0));
591 memset(&hR1, 0, sizeof(hR1)); 547 memset(&hr1, 0, sizeof(hr1));
592 hR0.size = sizeof(hR0); 548 hr0.size = sizeof(hr0);
593 hR1.size = sizeof(hR1); 549 hr1.size = sizeof(hr1);
594 550
595 error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0); 551 error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0);
596 if (hR0.error) { 552 if (hr0.error) {
597 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error); 553 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error);
598 return hR0.error; 554 return hr0.error;
599 } 555 }
600 if (phw->num_dsp == 2) { 556 if (phw->num_dsp == 2) {
601 error = hpi6000_message_response_sequence(pao, 1, &hM, 557 error = hpi6000_message_response_sequence(pao, 1, &hm,
602 &hR1); 558 &hr1);
603 if (error) 559 if (error)
604 return error; 560 return error;
605 } 561 }
606 pao->adapter_type = hR0.u.a.adapter_type; 562 pao->adapter_type = hr0.u.ax.info.adapter_type;
607 pao->index = hR0.u.a.adapter_index; 563 pao->index = hr0.u.ax.info.adapter_index;
608 } 564 }
609 565
610 memset(&phw->control_cache[0], 0, 566 memset(&phw->control_cache[0], 0,
@@ -618,20 +574,37 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
618 control_cache_count = 574 control_cache_count =
619 hpi_read_word(&phw->ado[0], 575 hpi_read_word(&phw->ado[0],
620 HPI_HIF_ADDR(control_cache_count)); 576 HPI_HIF_ADDR(control_cache_count));
621 pao->has_control_cache = 1;
622 577
623 phw->p_cache = 578 phw->p_cache =
624 hpi_alloc_control_cache(control_cache_count, 579 hpi_alloc_control_cache(control_cache_count,
625 control_cache_size, (struct hpi_control_cache_info *) 580 control_cache_size, (unsigned char *)
626 &phw->control_cache[0] 581 &phw->control_cache[0]
627 ); 582 );
628 } else 583 if (phw->p_cache)
629 pao->has_control_cache = 0; 584 pao->has_control_cache = 1;
585 }
630 586
631 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", 587 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
632 pao->adapter_type, pao->index); 588 pao->adapter_type, pao->index);
633 pao->open = 0; /* upon creation the adapter is closed */ 589 pao->open = 0; /* upon creation the adapter is closed */
634 return 0; 590
591 if (phw->p_cache)
592 phw->p_cache->adap_idx = pao->index;
593
594 return hpi_add_adapter(pao);
595}
596
597static void delete_adapter_obj(struct hpi_adapter_obj *pao)
598{
599 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
600
601 if (pao->has_control_cache)
602 hpi_free_control_cache(phw->p_cache);
603
604 /* reset DSPs on adapter */
605 iowrite32(0x0003000F, phw->dw2040_HPICSR + HPI_RESET);
606
607 kfree(phw);
635} 608}
636 609
637/************************************************************************/ 610/************************************************************************/
@@ -643,11 +616,13 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
643#ifndef HIDE_PCI_ASSERTS 616#ifndef HIDE_PCI_ASSERTS
644 /* if we have PCI2040 asserts then collect them */ 617 /* if we have PCI2040 asserts then collect them */
645 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { 618 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
646 phr->u.a.serial_number = 619 phr->u.ax.assert.p1 =
647 gw_pci_read_asserts * 100 + gw_pci_write_asserts; 620 gw_pci_read_asserts * 100 + gw_pci_write_asserts;
648 phr->u.a.adapter_index = 1; /* assert count */ 621 phr->u.ax.assert.p2 = 0;
649 phr->u.a.adapter_type = -1; /* "dsp index" */ 622 phr->u.ax.assert.count = 1; /* assert count */
650 strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error"); 623 phr->u.ax.assert.dsp_index = -1; /* "dsp index" */
624 strcpy(phr->u.ax.assert.sz_message, "PCI2040 error");
625 phr->u.ax.assert.dsp_msg_addr = 0;
651 gw_pci_read_asserts = 0; 626 gw_pci_read_asserts = 0;
652 gw_pci_write_asserts = 0; 627 gw_pci_write_asserts = 0;
653 phr->error = 0; 628 phr->error = 0;
@@ -684,10 +659,10 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
684 659
685 /* NOTE don't use wAdapterType in this routine. It is not setup yet */ 660 /* NOTE don't use wAdapterType in this routine. It is not setup yet */
686 661
687 switch (pao->pci.subsys_device_id) { 662 switch (pao->pci.pci_dev->subsystem_device) {
688 case 0x5100: 663 case 0x5100:
689 case 0x5110: /* ASI5100 revB or higher with C6711D */ 664 case 0x5110: /* ASI5100 revB or higher with C6711D */
690 case 0x5200: /* ASI5200 PC_ie version of ASI5100 */ 665 case 0x5200: /* ASI5200 PCIe version of ASI5100 */
691 case 0x6100: 666 case 0x6100:
692 case 0x6200: 667 case 0x6200:
693 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); 668 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
@@ -707,8 +682,9 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
707 * note that bits 4..15 are read-only and so should always return zero, 682 * note that bits 4..15 are read-only and so should always return zero,
708 * even though we wrote 1 to them 683 * even though we wrote 1 to them
709 */ 684 */
710 for (i = 0; i < 1000; i++) 685 hpios_delay_micro_seconds(1000);
711 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); 686 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
687
712 if (delay != dw2040_reset) { 688 if (delay != dw2040_reset) {
713 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, 689 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
714 delay); 690 delay);
@@ -741,8 +717,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
741 dw2040_reset = dw2040_reset & (~0x00000008); 717 dw2040_reset = dw2040_reset & (~0x00000008);
742 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); 718 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
743 /*delay to allow DSP to get going */ 719 /*delay to allow DSP to get going */
744 for (i = 0; i < 100; i++) 720 hpios_delay_micro_seconds(100);
745 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
746 721
747 /* loop through all DSPs, downloading DSP code */ 722 /* loop through all DSPs, downloading DSP code */
748 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { 723 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
@@ -781,27 +756,27 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
781 */ 756 */
782 /* bypass PLL */ 757 /* bypass PLL */
783 hpi_write_word(pdo, 0x01B7C100, 0x0000); 758 hpi_write_word(pdo, 0x01B7C100, 0x0000);
784 for (i = 0; i < 100; i++) 759 hpios_delay_micro_seconds(100);
785 delay = ioread32(phw->dw2040_HPICSR +
786 HPI_RESET);
787 760
788 /* ** use default of PLL x7 ** */ 761 /* ** use default of PLL x7 ** */
789 /* EMIF = 225/3=75MHz */ 762 /* EMIF = 225/3=75MHz */
790 hpi_write_word(pdo, 0x01B7C120, 0x8002); 763 hpi_write_word(pdo, 0x01B7C120, 0x8002);
764 hpios_delay_micro_seconds(100);
765
791 /* peri = 225/2 */ 766 /* peri = 225/2 */
792 hpi_write_word(pdo, 0x01B7C11C, 0x8001); 767 hpi_write_word(pdo, 0x01B7C11C, 0x8001);
768 hpios_delay_micro_seconds(100);
769
793 /* cpu = 225/1 */ 770 /* cpu = 225/1 */
794 hpi_write_word(pdo, 0x01B7C118, 0x8000); 771 hpi_write_word(pdo, 0x01B7C118, 0x8000);
795 /* ~200us delay */ 772
796 for (i = 0; i < 2000; i++) 773 /* ~2ms delay */
797 delay = ioread32(phw->dw2040_HPICSR + 774 hpios_delay_micro_seconds(2000);
798 HPI_RESET); 775
799 /* PLL not bypassed */ 776 /* PLL not bypassed */
800 hpi_write_word(pdo, 0x01B7C100, 0x0001); 777 hpi_write_word(pdo, 0x01B7C100, 0x0001);
801 /* ~200us delay */ 778 /* ~2ms delay */
802 for (i = 0; i < 2000; i++) 779 hpios_delay_micro_seconds(2000);
803 delay = ioread32(phw->dw2040_HPICSR +
804 HPI_RESET);
805 } 780 }
806 781
807 /* test r/w to internal DSP memory 782 /* test r/w to internal DSP memory
@@ -925,9 +900,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
925 } 900 }
926 901
927 /* delay a little to allow SDRAM and DSP to "get going" */ 902 /* delay a little to allow SDRAM and DSP to "get going" */
928 903 hpios_delay_micro_seconds(1000);
929 for (i = 0; i < 1000; i++)
930 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
931 904
932 /* test access to SDRAM */ 905 /* test access to SDRAM */
933 { 906 {
@@ -974,7 +947,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
974 947
975 /* write the DSP code down into the DSPs memory */ 948 /* write the DSP code down into the DSPs memory */
976 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ 949 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
977 dsp_code.ps_dev = pao->pci.p_os_data; 950 dsp_code.ps_dev = pao->pci.pci_dev;
978 951
979 error = hpi_dsp_code_open(boot_load_family, &dsp_code, 952 error = hpi_dsp_code_open(boot_load_family, &dsp_code,
980 pos_error_code); 953 pos_error_code);
@@ -1071,8 +1044,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1071 1044
1072 /* step 3. Start code by sending interrupt */ 1045 /* step 3. Start code by sending interrupt */
1073 iowrite32(0x00030003, pdo->prHPI_control); 1046 iowrite32(0x00030003, pdo->prHPI_control);
1074 for (i = 0; i < 10000; i++) 1047 hpios_delay_micro_seconds(10000);
1075 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
1076 1048
1077 /* wait for a non-zero value in hostcmd - 1049 /* wait for a non-zero value in hostcmd -
1078 * indicating initialization is complete 1050 * indicating initialization is complete
@@ -1099,7 +1071,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1099 * locks up with a bluescreen (NOT GPF or pagefault). 1071 * locks up with a bluescreen (NOT GPF or pagefault).
1100 */ 1072 */
1101 else 1073 else
1102 hpios_delay_micro_seconds(1000); 1074 hpios_delay_micro_seconds(10000);
1103 } 1075 }
1104 if (timeout == 0) 1076 if (timeout == 0)
1105 return HPI6000_ERROR_INIT_NOACK; 1077 return HPI6000_ERROR_INIT_NOACK;
@@ -1130,14 +1102,14 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1130 mask = 0xFFFFFF00L; 1102 mask = 0xFFFFFF00L;
1131 /* ASI5100 uses AX6 code, */ 1103 /* ASI5100 uses AX6 code, */
1132 /* but has no PLD r/w register to test */ 1104 /* but has no PLD r/w register to test */
1133 if (HPI_ADAPTER_FAMILY_ASI(pao->pci. 1105 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
1134 subsys_device_id) == 1106 subsystem_device) ==
1135 HPI_ADAPTER_FAMILY_ASI(0x5100)) 1107 HPI_ADAPTER_FAMILY_ASI(0x5100))
1136 mask = 0x00000000L; 1108 mask = 0x00000000L;
1137 /* ASI5200 uses AX6 code, */ 1109 /* ASI5200 uses AX6 code, */
1138 /* but has no PLD r/w register to test */ 1110 /* but has no PLD r/w register to test */
1139 if (HPI_ADAPTER_FAMILY_ASI(pao->pci. 1111 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
1140 subsys_device_id) == 1112 subsystem_device) ==
1141 HPI_ADAPTER_FAMILY_ASI(0x5200)) 1113 HPI_ADAPTER_FAMILY_ASI(0x5200))
1142 mask = 0x00000000L; 1114 mask = 0x00000000L;
1143 break; 1115 break;
@@ -1202,7 +1174,7 @@ static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
1202 u32 data = 0; 1174 u32 data = 0;
1203 1175
1204 if (hpi_set_address(pdo, address)) 1176 if (hpi_set_address(pdo, address))
1205 return 0; /*? no way to return error */ 1177 return 0; /*? No way to return error */
1206 1178
1207 /* take care of errata in revB DSP (2.0.1) */ 1179 /* take care of errata in revB DSP (2.0.1) */
1208 data = ioread32(pdo->prHPI_data); 1180 data = ioread32(pdo->prHPI_data);
@@ -1338,10 +1310,6 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1338 u32 *p_data; 1310 u32 *p_data;
1339 u16 error = 0; 1311 u16 error = 0;
1340 1312
1341 /* does the DSP we are referencing exist? */
1342 if (dsp_index >= phw->num_dsp)
1343 return HPI6000_ERROR_MSG_INVALID_DSP_INDEX;
1344
1345 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); 1313 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1346 if (ack & HPI_HIF_ERROR_MASK) { 1314 if (ack & HPI_HIF_ERROR_MASK) {
1347 pao->dsp_crashed++; 1315 pao->dsp_crashed++;
@@ -1349,9 +1317,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1349 } 1317 }
1350 pao->dsp_crashed = 0; 1318 pao->dsp_crashed = 0;
1351 1319
1352 /* send the message */ 1320 /* get the message address and size */
1353
1354 /* get the address and size */
1355 if (phw->message_buffer_address_on_dsp == 0) { 1321 if (phw->message_buffer_address_on_dsp == 0) {
1356 timeout = TIMEOUT; 1322 timeout = TIMEOUT;
1357 do { 1323 do {
@@ -1366,10 +1332,9 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1366 } else 1332 } else
1367 address = phw->message_buffer_address_on_dsp; 1333 address = phw->message_buffer_address_on_dsp;
1368 1334
1369 /* dwLength = sizeof(struct hpi_message); */
1370 length = phm->size; 1335 length = phm->size;
1371 1336
1372 /* send it */ 1337 /* send the message */
1373 p_data = (u32 *)phm; 1338 p_data = (u32 *)phm;
1374 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, 1339 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
1375 (u16)length / 4)) 1340 (u16)length / 4))
@@ -1383,7 +1348,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1383 if (ack & HPI_HIF_ERROR_MASK) 1348 if (ack & HPI_HIF_ERROR_MASK)
1384 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; 1349 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
1385 1350
1386 /* get the address and size */ 1351 /* get the response address */
1387 if (phw->response_buffer_address_on_dsp == 0) { 1352 if (phw->response_buffer_address_on_dsp == 0) {
1388 timeout = TIMEOUT; 1353 timeout = TIMEOUT;
1389 do { 1354 do {
@@ -1407,7 +1372,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1407 if (!timeout) 1372 if (!timeout)
1408 length = sizeof(struct hpi_response); 1373 length = sizeof(struct hpi_response);
1409 1374
1410 /* get it */ 1375 /* get the response */
1411 p_data = (u32 *)phr; 1376 p_data = (u32 *)phr;
1412 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, 1377 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
1413 (u16)length / 4)) 1378 (u16)length / 4))
@@ -1803,17 +1768,11 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1803 hpios_dsplock_lock(pao); 1768 hpios_dsplock_lock(pao);
1804 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); 1769 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
1805 1770
1806 /* maybe an error response */ 1771 if (error) /* something failed in the HPI/DSP interface */
1807 if (error) {
1808 /* something failed in the HPI/DSP interface */
1809 phr->error = error;
1810 /* just the header of the response is valid */
1811 phr->size = sizeof(struct hpi_response_header);
1812 goto err; 1772 goto err;
1813 }
1814 1773
1815 if (phr->error != 0) /* something failed in the DSP */ 1774 if (phr->error) /* something failed in the DSP */
1816 goto err; 1775 goto out;
1817 1776
1818 switch (phm->function) { 1777 switch (phm->function) {
1819 case HPI_OSTREAM_WRITE: 1778 case HPI_OSTREAM_WRITE:
@@ -1825,21 +1784,30 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1825 error = hpi6000_get_data(pao, dsp_index, phm, phr); 1784 error = hpi6000_get_data(pao, dsp_index, phm, phr);
1826 break; 1785 break;
1827 case HPI_ADAPTER_GET_ASSERT: 1786 case HPI_ADAPTER_GET_ASSERT:
1828 phr->u.a.adapter_index = 0; /* dsp 0 default */ 1787 phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */
1829 if (num_dsp == 2) { 1788 if (num_dsp == 2) {
1830 if (!phr->u.a.adapter_type) { 1789 if (!phr->u.ax.assert.count) {
1831 /* no assert from dsp 0, check dsp 1 */ 1790 /* no assert from dsp 0, check dsp 1 */
1832 error = hpi6000_message_response_sequence(pao, 1791 error = hpi6000_message_response_sequence(pao,
1833 1, phm, phr); 1792 1, phm, phr);
1834 phr->u.a.adapter_index = 1; 1793 phr->u.ax.assert.dsp_index = 1;
1835 } 1794 }
1836 } 1795 }
1837 } 1796 }
1838 1797
1839 if (error)
1840 phr->error = error;
1841
1842err: 1798err:
1799 if (error) {
1800 if (error >= HPI_ERROR_BACKEND_BASE) {
1801 phr->error = HPI_ERROR_DSP_COMMUNICATION;
1802 phr->specific_error = error;
1803 } else {
1804 phr->error = error;
1805 }
1806
1807 /* just the header of the response is valid */
1808 phr->size = sizeof(struct hpi_response_header);
1809 }
1810out:
1843 hpios_dsplock_unlock(pao); 1811 hpios_dsplock_unlock(pao);
1844 return; 1812 return;
1845} 1813}