diff options
author | Eliot Blennerhassett <eblennerhassett@audioscience.com> | 2011-02-09 23:25:58 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-02-10 12:22:40 -0500 |
commit | 3285ea10e9b09d68da18d2f805980246ec53523a (patch) | |
tree | f6c7ccc09d07fd808357b50ddad25e5f5b4fa3c9 /sound/pci/asihpi/hpi6000.c | |
parent | ad210ad10ec96e32d32459545f54e4d3d9c6a088 (diff) |
ALSA: asihpi - Interrelated HPI tidy up.
Remove many unused functions.
Update some message and cache structs.
Use pci info directly from pci_dev.
Allow control cache elements with variable size, and handle
large message/response from dsp.
hpi6000 and hpi6205: fix error path when adapter bootload fails.
hpimsgx.c get rid of code duplicated in hpicmn.c
Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/asihpi/hpi6000.c')
-rw-r--r-- | sound/pci/asihpi/hpi6000.c | 252 |
1 files changed, 103 insertions, 149 deletions
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 1b9bf9395cfe..c85db49e5ec5 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -43,16 +43,16 @@ | |||
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 | 46 | #define HPI6000_ERROR_BASE 900 /* not actually used anywhere */ | |
47 | #define HPI6000_ERROR_BASE 900 | 47 | /* operational/messaging errors */ |
48 | #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 | 48 | #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 |
49 | #define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902 | 49 | |
50 | #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 | 50 | #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 |
51 | #define HPI6000_ERROR_MSG_GET_ADR 904 | 51 | #define HPI6000_ERROR_MSG_GET_ADR 904 |
52 | #define HPI6000_ERROR_RESP_GET_ADR 905 | 52 | #define HPI6000_ERROR_RESP_GET_ADR 905 |
53 | #define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 | 53 | #define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 |
54 | #define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 | 54 | #define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 |
55 | #define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908 | 55 | |
56 | #define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909 | 56 | #define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909 |
57 | 57 | ||
58 | #define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 | 58 | #define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 |
@@ -62,7 +62,6 @@ | |||
62 | #define HPI6000_ERROR_SEND_DATA_CMD 915 | 62 | #define HPI6000_ERROR_SEND_DATA_CMD 915 |
63 | #define HPI6000_ERROR_SEND_DATA_WRITE 916 | 63 | #define HPI6000_ERROR_SEND_DATA_WRITE 916 |
64 | #define HPI6000_ERROR_SEND_DATA_IDLECMD 917 | 64 | #define HPI6000_ERROR_SEND_DATA_IDLECMD 917 |
65 | #define HPI6000_ERROR_SEND_DATA_VERIFY 918 | ||
66 | 65 | ||
67 | #define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921 | 66 | #define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921 |
68 | #define HPI6000_ERROR_GET_DATA_ACK 922 | 67 | #define HPI6000_ERROR_GET_DATA_ACK 922 |
@@ -76,9 +75,8 @@ | |||
76 | 75 | ||
77 | #define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 | 76 | #define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 |
78 | #define HPI6000_ERROR_MSG_RESP_IDLECMD 962 | 77 | #define HPI6000_ERROR_MSG_RESP_IDLECMD 962 |
79 | #define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963 | ||
80 | 78 | ||
81 | /* adapter init errors */ | 79 | /* Initialisation/bootload errors */ |
82 | #define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930 | 80 | #define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930 |
83 | 81 | ||
84 | /* can't access PCI2040 */ | 82 | /* can't access PCI2040 */ |
@@ -210,6 +208,8 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao, | |||
210 | static short create_adapter_obj(struct hpi_adapter_obj *pao, | 208 | static short create_adapter_obj(struct hpi_adapter_obj *pao, |
211 | u32 *pos_error_code); | 209 | u32 *pos_error_code); |
212 | 210 | ||
211 | static void delete_adapter_obj(struct hpi_adapter_obj *pao); | ||
212 | |||
213 | /* local globals */ | 213 | /* local globals */ |
214 | 214 | ||
215 | static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ | 215 | static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ |
@@ -217,17 +217,7 @@ static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */ | |||
217 | 217 | ||
218 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | 218 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) |
219 | { | 219 | { |
220 | |||
221 | switch (phm->function) { | 220 | 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: | 221 | case HPI_SUBSYS_CREATE_ADAPTER: |
232 | subsys_create_adapter(phm, phr); | 222 | subsys_create_adapter(phm, phr); |
233 | break; | 223 | break; |
@@ -243,17 +233,13 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | |||
243 | static void control_message(struct hpi_adapter_obj *pao, | 233 | static void control_message(struct hpi_adapter_obj *pao, |
244 | struct hpi_message *phm, struct hpi_response *phr) | 234 | struct hpi_message *phm, struct hpi_response *phr) |
245 | { | 235 | { |
246 | |||
247 | switch (phm->function) { | 236 | switch (phm->function) { |
248 | case HPI_CONTROL_GET_STATE: | 237 | case HPI_CONTROL_GET_STATE: |
249 | if (pao->has_control_cache) { | 238 | if (pao->has_control_cache) { |
250 | u16 err; | 239 | phr->error = hpi6000_update_control_cache(pao, phm); |
251 | err = hpi6000_update_control_cache(pao, phm); | ||
252 | 240 | ||
253 | if (err) { | 241 | if (phr->error) |
254 | phr->error = err; | ||
255 | break; | 242 | break; |
256 | } | ||
257 | 243 | ||
258 | if (hpi_check_control_cache(((struct hpi_hw_obj *) | 244 | if (hpi_check_control_cache(((struct hpi_hw_obj *) |
259 | pao->priv)->p_cache, phm, | 245 | pao->priv)->p_cache, phm, |
@@ -262,16 +248,15 @@ static void control_message(struct hpi_adapter_obj *pao, | |||
262 | } | 248 | } |
263 | hw_message(pao, phm, phr); | 249 | hw_message(pao, phm, phr); |
264 | break; | 250 | break; |
265 | case HPI_CONTROL_GET_INFO: | ||
266 | hw_message(pao, phm, phr); | ||
267 | break; | ||
268 | case HPI_CONTROL_SET_STATE: | 251 | case HPI_CONTROL_SET_STATE: |
269 | hw_message(pao, phm, phr); | 252 | hw_message(pao, phm, phr); |
270 | hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)-> | 253 | hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao-> |
271 | p_cache, phm, phr); | 254 | priv)->p_cache, phm, phr); |
272 | break; | 255 | break; |
256 | |||
257 | case HPI_CONTROL_GET_INFO: | ||
273 | default: | 258 | default: |
274 | phr->error = HPI_ERROR_INVALID_FUNC; | 259 | hw_message(pao, phm, phr); |
275 | break; | 260 | break; |
276 | } | 261 | } |
277 | } | 262 | } |
@@ -280,26 +265,12 @@ static void adapter_message(struct hpi_adapter_obj *pao, | |||
280 | struct hpi_message *phm, struct hpi_response *phr) | 265 | struct hpi_message *phm, struct hpi_response *phr) |
281 | { | 266 | { |
282 | switch (phm->function) { | 267 | switch (phm->function) { |
283 | case HPI_ADAPTER_GET_INFO: | ||
284 | hw_message(pao, phm, phr); | ||
285 | break; | ||
286 | case HPI_ADAPTER_GET_ASSERT: | 268 | case HPI_ADAPTER_GET_ASSERT: |
287 | adapter_get_asserts(pao, phm, phr); | 269 | adapter_get_asserts(pao, phm, phr); |
288 | break; | 270 | break; |
289 | case HPI_ADAPTER_OPEN: | 271 | |
290 | case HPI_ADAPTER_CLOSE: | ||
291 | case HPI_ADAPTER_TEST_ASSERT: | ||
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; | ||
301 | default: | 272 | default: |
302 | phr->error = HPI_ERROR_INVALID_FUNC; | 273 | hw_message(pao, phm, phr); |
303 | break; | 274 | break; |
304 | } | 275 | } |
305 | } | 276 | } |
@@ -311,7 +282,7 @@ static void outstream_message(struct hpi_adapter_obj *pao, | |||
311 | case HPI_OSTREAM_HOSTBUFFER_ALLOC: | 282 | case HPI_OSTREAM_HOSTBUFFER_ALLOC: |
312 | case HPI_OSTREAM_HOSTBUFFER_FREE: | 283 | case HPI_OSTREAM_HOSTBUFFER_FREE: |
313 | /* Don't let these messages go to the HW function because | 284 | /* Don't let these messages go to the HW function because |
314 | * they're called without allocating the spinlock. | 285 | * they're called without locking the spinlock. |
315 | * For the HPI6000 adapters the HW would return | 286 | * For the HPI6000 adapters the HW would return |
316 | * HPI_ERROR_INVALID_FUNC anyway. | 287 | * HPI_ERROR_INVALID_FUNC anyway. |
317 | */ | 288 | */ |
@@ -331,7 +302,7 @@ static void instream_message(struct hpi_adapter_obj *pao, | |||
331 | case HPI_ISTREAM_HOSTBUFFER_ALLOC: | 302 | case HPI_ISTREAM_HOSTBUFFER_ALLOC: |
332 | case HPI_ISTREAM_HOSTBUFFER_FREE: | 303 | case HPI_ISTREAM_HOSTBUFFER_FREE: |
333 | /* Don't let these messages go to the HW function because | 304 | /* Don't let these messages go to the HW function because |
334 | * they're called without allocating the spinlock. | 305 | * they're called without locking the spinlock. |
335 | * For the HPI6000 adapters the HW would return | 306 | * For the HPI6000 adapters the HW would return |
336 | * HPI_ERROR_INVALID_FUNC anyway. | 307 | * HPI_ERROR_INVALID_FUNC anyway. |
337 | */ | 308 | */ |
@@ -355,7 +326,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) | |||
355 | /* subsytem messages get executed by every HPI. */ | 326 | /* subsytem messages get executed by every HPI. */ |
356 | /* All other messages are ignored unless the adapter index matches */ | 327 | /* All other messages are ignored unless the adapter index matches */ |
357 | /* an adapter in the HPI */ | 328 | /* an adapter in the HPI */ |
358 | HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function); | 329 | /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */ |
359 | 330 | ||
360 | /* if Dsp has crashed then do not communicate with it any more */ | 331 | /* if Dsp has crashed then do not communicate with it any more */ |
361 | if (phm->object != HPI_OBJ_SUBSYSTEM) { | 332 | if (phm->object != HPI_OBJ_SUBSYSTEM) { |
@@ -440,14 +411,6 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
440 | 411 | ||
441 | memset(&ao, 0, sizeof(ao)); | 412 | memset(&ao, 0, sizeof(ao)); |
442 | 413 | ||
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); | 414 | ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); |
452 | if (!ao.priv) { | 415 | if (!ao.priv) { |
453 | HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); | 416 | HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); |
@@ -456,16 +419,13 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
456 | } | 419 | } |
457 | 420 | ||
458 | /* create the adapter object based on the resource information */ | 421 | /* 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; | 422 | ao.pci = *phm->u.s.resource.r.pci; |
461 | 423 | ||
462 | error = create_adapter_obj(&ao, &os_error_code); | 424 | error = create_adapter_obj(&ao, &os_error_code); |
463 | if (!error) | ||
464 | error = hpi_add_adapter(&ao); | ||
465 | if (error) { | 425 | if (error) { |
466 | phr->u.s.data = os_error_code; | 426 | delete_adapter_obj(&ao); |
467 | kfree(ao.priv); | ||
468 | phr->error = error; | 427 | phr->error = error; |
428 | phr->u.s.data = os_error_code; | ||
469 | return; | 429 | return; |
470 | } | 430 | } |
471 | /* need to update paParentAdapter */ | 431 | /* need to update paParentAdapter */ |
@@ -492,20 +452,13 @@ static void subsys_delete_adapter(struct hpi_message *phm, | |||
492 | struct hpi_response *phr) | 452 | struct hpi_response *phr) |
493 | { | 453 | { |
494 | struct hpi_adapter_obj *pao = NULL; | 454 | struct hpi_adapter_obj *pao = NULL; |
495 | struct hpi_hw_obj *phw; | ||
496 | 455 | ||
497 | pao = hpi_find_adapter(phm->adapter_index); | 456 | pao = hpi_find_adapter(phm->obj_index); |
498 | if (!pao) | 457 | if (!pao) |
499 | return; | 458 | return; |
500 | 459 | ||
501 | phw = (struct hpi_hw_obj *)pao->priv; | 460 | delete_adapter_obj(pao); |
502 | |||
503 | if (pao->has_control_cache) | ||
504 | hpi_free_control_cache(phw->p_cache); | ||
505 | |||
506 | hpi_delete_adapter(pao); | 461 | hpi_delete_adapter(pao); |
507 | kfree(phw); | ||
508 | |||
509 | phr->error = 0; | 462 | phr->error = 0; |
510 | } | 463 | } |
511 | 464 | ||
@@ -519,9 +472,6 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, | |||
519 | u32 control_cache_count = 0; | 472 | u32 control_cache_count = 0; |
520 | struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; | 473 | struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; |
521 | 474 | ||
522 | /* init error reporting */ | ||
523 | pao->dsp_crashed = 0; | ||
524 | |||
525 | /* The PCI2040 has the following address map */ | 475 | /* The PCI2040 has the following address map */ |
526 | /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ | 476 | /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ |
527 | /* BAR1 - 32K = HPI registers on DSP */ | 477 | /* BAR1 - 32K = HPI registers on DSP */ |
@@ -575,36 +525,36 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, | |||
575 | /* get info about the adapter by asking the adapter */ | 525 | /* get info about the adapter by asking the adapter */ |
576 | /* send a HPI_ADAPTER_GET_INFO message */ | 526 | /* send a HPI_ADAPTER_GET_INFO message */ |
577 | { | 527 | { |
578 | struct hpi_message hM; | 528 | struct hpi_message hm; |
579 | struct hpi_response hR0; /* response from DSP 0 */ | 529 | struct hpi_response hr0; /* response from DSP 0 */ |
580 | struct hpi_response hR1; /* response from DSP 1 */ | 530 | struct hpi_response hr1; /* response from DSP 1 */ |
581 | u16 error = 0; | 531 | u16 error = 0; |
582 | 532 | ||
583 | HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); | 533 | HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); |
584 | memset(&hM, 0, sizeof(hM)); | 534 | memset(&hm, 0, sizeof(hm)); |
585 | hM.type = HPI_TYPE_MESSAGE; | 535 | hm.type = HPI_TYPE_MESSAGE; |
586 | hM.size = sizeof(struct hpi_message); | 536 | hm.size = sizeof(struct hpi_message); |
587 | hM.object = HPI_OBJ_ADAPTER; | 537 | hm.object = HPI_OBJ_ADAPTER; |
588 | hM.function = HPI_ADAPTER_GET_INFO; | 538 | hm.function = HPI_ADAPTER_GET_INFO; |
589 | hM.adapter_index = 0; | 539 | hm.adapter_index = 0; |
590 | memset(&hR0, 0, sizeof(hR0)); | 540 | memset(&hr0, 0, sizeof(hr0)); |
591 | memset(&hR1, 0, sizeof(hR1)); | 541 | memset(&hr1, 0, sizeof(hr1)); |
592 | hR0.size = sizeof(hR0); | 542 | hr0.size = sizeof(hr0); |
593 | hR1.size = sizeof(hR1); | 543 | hr1.size = sizeof(hr1); |
594 | 544 | ||
595 | error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0); | 545 | error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0); |
596 | if (hR0.error) { | 546 | if (hr0.error) { |
597 | HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error); | 547 | HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error); |
598 | return hR0.error; | 548 | return hr0.error; |
599 | } | 549 | } |
600 | if (phw->num_dsp == 2) { | 550 | if (phw->num_dsp == 2) { |
601 | error = hpi6000_message_response_sequence(pao, 1, &hM, | 551 | error = hpi6000_message_response_sequence(pao, 1, &hm, |
602 | &hR1); | 552 | &hr1); |
603 | if (error) | 553 | if (error) |
604 | return error; | 554 | return error; |
605 | } | 555 | } |
606 | pao->adapter_type = hR0.u.a.adapter_type; | 556 | pao->adapter_type = hr0.u.ax.info.adapter_type; |
607 | pao->index = hR0.u.a.adapter_index; | 557 | pao->index = hr0.u.ax.info.adapter_index; |
608 | } | 558 | } |
609 | 559 | ||
610 | memset(&phw->control_cache[0], 0, | 560 | memset(&phw->control_cache[0], 0, |
@@ -618,22 +568,34 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, | |||
618 | control_cache_count = | 568 | control_cache_count = |
619 | hpi_read_word(&phw->ado[0], | 569 | hpi_read_word(&phw->ado[0], |
620 | HPI_HIF_ADDR(control_cache_count)); | 570 | HPI_HIF_ADDR(control_cache_count)); |
621 | pao->has_control_cache = 1; | ||
622 | 571 | ||
623 | phw->p_cache = | 572 | phw->p_cache = |
624 | hpi_alloc_control_cache(control_cache_count, | 573 | hpi_alloc_control_cache(control_cache_count, |
625 | control_cache_size, (struct hpi_control_cache_info *) | 574 | control_cache_size, (unsigned char *) |
626 | &phw->control_cache[0] | 575 | &phw->control_cache[0] |
627 | ); | 576 | ); |
628 | if (!phw->p_cache) | 577 | if (phw->p_cache) |
629 | pao->has_control_cache = 0; | 578 | pao->has_control_cache = 1; |
630 | } else | 579 | } |
631 | pao->has_control_cache = 0; | ||
632 | 580 | ||
633 | HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", | 581 | HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", |
634 | pao->adapter_type, pao->index); | 582 | pao->adapter_type, pao->index); |
635 | pao->open = 0; /* upon creation the adapter is closed */ | 583 | pao->open = 0; /* upon creation the adapter is closed */ |
636 | return 0; | 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); | ||
637 | } | 599 | } |
638 | 600 | ||
639 | /************************************************************************/ | 601 | /************************************************************************/ |
@@ -645,11 +607,13 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao, | |||
645 | #ifndef HIDE_PCI_ASSERTS | 607 | #ifndef HIDE_PCI_ASSERTS |
646 | /* if we have PCI2040 asserts then collect them */ | 608 | /* if we have PCI2040 asserts then collect them */ |
647 | if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { | 609 | if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { |
648 | phr->u.a.serial_number = | 610 | phr->u.ax.assert.p1 = |
649 | gw_pci_read_asserts * 100 + gw_pci_write_asserts; | 611 | gw_pci_read_asserts * 100 + gw_pci_write_asserts; |
650 | phr->u.a.adapter_index = 1; /* assert count */ | 612 | phr->u.ax.assert.p2 = 0; |
651 | phr->u.a.adapter_type = -1; /* "dsp index" */ | 613 | phr->u.ax.assert.count = 1; /* assert count */ |
652 | strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error"); | 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; | ||
653 | gw_pci_read_asserts = 0; | 617 | gw_pci_read_asserts = 0; |
654 | gw_pci_write_asserts = 0; | 618 | gw_pci_write_asserts = 0; |
655 | phr->error = 0; | 619 | phr->error = 0; |
@@ -686,10 +650,10 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
686 | 650 | ||
687 | /* NOTE don't use wAdapterType in this routine. It is not setup yet */ | 651 | /* NOTE don't use wAdapterType in this routine. It is not setup yet */ |
688 | 652 | ||
689 | switch (pao->pci.subsys_device_id) { | 653 | switch (pao->pci.pci_dev->subsystem_device) { |
690 | case 0x5100: | 654 | case 0x5100: |
691 | case 0x5110: /* ASI5100 revB or higher with C6711D */ | 655 | case 0x5110: /* ASI5100 revB or higher with C6711D */ |
692 | case 0x5200: /* ASI5200 PC_ie version of ASI5100 */ | 656 | case 0x5200: /* ASI5200 PCIe version of ASI5100 */ |
693 | case 0x6100: | 657 | case 0x6100: |
694 | case 0x6200: | 658 | case 0x6200: |
695 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); | 659 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); |
@@ -709,8 +673,9 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
709 | * note that bits 4..15 are read-only and so should always return zero, | 673 | * note that bits 4..15 are read-only and so should always return zero, |
710 | * even though we wrote 1 to them | 674 | * even though we wrote 1 to them |
711 | */ | 675 | */ |
712 | for (i = 0; i < 1000; i++) | 676 | hpios_delay_micro_seconds(1000); |
713 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); | 677 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); |
678 | |||
714 | if (delay != dw2040_reset) { | 679 | if (delay != dw2040_reset) { |
715 | HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, | 680 | HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, |
716 | delay); | 681 | delay); |
@@ -743,8 +708,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
743 | dw2040_reset = dw2040_reset & (~0x00000008); | 708 | dw2040_reset = dw2040_reset & (~0x00000008); |
744 | iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); | 709 | iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); |
745 | /*delay to allow DSP to get going */ | 710 | /*delay to allow DSP to get going */ |
746 | for (i = 0; i < 100; i++) | 711 | hpios_delay_micro_seconds(100); |
747 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); | ||
748 | 712 | ||
749 | /* loop through all DSPs, downloading DSP code */ | 713 | /* loop through all DSPs, downloading DSP code */ |
750 | for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { | 714 | for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { |
@@ -783,27 +747,27 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
783 | */ | 747 | */ |
784 | /* bypass PLL */ | 748 | /* bypass PLL */ |
785 | hpi_write_word(pdo, 0x01B7C100, 0x0000); | 749 | hpi_write_word(pdo, 0x01B7C100, 0x0000); |
786 | for (i = 0; i < 100; i++) | 750 | hpios_delay_micro_seconds(100); |
787 | delay = ioread32(phw->dw2040_HPICSR + | ||
788 | HPI_RESET); | ||
789 | 751 | ||
790 | /* ** use default of PLL x7 ** */ | 752 | /* ** use default of PLL x7 ** */ |
791 | /* EMIF = 225/3=75MHz */ | 753 | /* EMIF = 225/3=75MHz */ |
792 | hpi_write_word(pdo, 0x01B7C120, 0x8002); | 754 | hpi_write_word(pdo, 0x01B7C120, 0x8002); |
755 | hpios_delay_micro_seconds(100); | ||
756 | |||
793 | /* peri = 225/2 */ | 757 | /* peri = 225/2 */ |
794 | hpi_write_word(pdo, 0x01B7C11C, 0x8001); | 758 | hpi_write_word(pdo, 0x01B7C11C, 0x8001); |
759 | hpios_delay_micro_seconds(100); | ||
760 | |||
795 | /* cpu = 225/1 */ | 761 | /* cpu = 225/1 */ |
796 | hpi_write_word(pdo, 0x01B7C118, 0x8000); | 762 | hpi_write_word(pdo, 0x01B7C118, 0x8000); |
797 | /* ~200us delay */ | 763 | |
798 | for (i = 0; i < 2000; i++) | 764 | /* ~2ms delay */ |
799 | delay = ioread32(phw->dw2040_HPICSR + | 765 | hpios_delay_micro_seconds(2000); |
800 | HPI_RESET); | 766 | |
801 | /* PLL not bypassed */ | 767 | /* PLL not bypassed */ |
802 | hpi_write_word(pdo, 0x01B7C100, 0x0001); | 768 | hpi_write_word(pdo, 0x01B7C100, 0x0001); |
803 | /* ~200us delay */ | 769 | /* ~2ms delay */ |
804 | for (i = 0; i < 2000; i++) | 770 | hpios_delay_micro_seconds(2000); |
805 | delay = ioread32(phw->dw2040_HPICSR + | ||
806 | HPI_RESET); | ||
807 | } | 771 | } |
808 | 772 | ||
809 | /* test r/w to internal DSP memory | 773 | /* test r/w to internal DSP memory |
@@ -927,9 +891,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
927 | } | 891 | } |
928 | 892 | ||
929 | /* delay a little to allow SDRAM and DSP to "get going" */ | 893 | /* delay a little to allow SDRAM and DSP to "get going" */ |
930 | 894 | hpios_delay_micro_seconds(1000); | |
931 | for (i = 0; i < 1000; i++) | ||
932 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); | ||
933 | 895 | ||
934 | /* test access to SDRAM */ | 896 | /* test access to SDRAM */ |
935 | { | 897 | { |
@@ -976,7 +938,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
976 | 938 | ||
977 | /* write the DSP code down into the DSPs memory */ | 939 | /* write the DSP code down into the DSPs memory */ |
978 | /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ | 940 | /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ |
979 | dsp_code.ps_dev = pao->pci.p_os_data; | 941 | dsp_code.ps_dev = pao->pci.pci_dev; |
980 | 942 | ||
981 | error = hpi_dsp_code_open(boot_load_family, &dsp_code, | 943 | error = hpi_dsp_code_open(boot_load_family, &dsp_code, |
982 | pos_error_code); | 944 | pos_error_code); |
@@ -1073,8 +1035,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1073 | 1035 | ||
1074 | /* step 3. Start code by sending interrupt */ | 1036 | /* step 3. Start code by sending interrupt */ |
1075 | iowrite32(0x00030003, pdo->prHPI_control); | 1037 | iowrite32(0x00030003, pdo->prHPI_control); |
1076 | for (i = 0; i < 10000; i++) | 1038 | hpios_delay_micro_seconds(10000); |
1077 | delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); | ||
1078 | 1039 | ||
1079 | /* wait for a non-zero value in hostcmd - | 1040 | /* wait for a non-zero value in hostcmd - |
1080 | * indicating initialization is complete | 1041 | * indicating initialization is complete |
@@ -1101,7 +1062,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1101 | * locks up with a bluescreen (NOT GPF or pagefault). | 1062 | * locks up with a bluescreen (NOT GPF or pagefault). |
1102 | */ | 1063 | */ |
1103 | else | 1064 | else |
1104 | hpios_delay_micro_seconds(1000); | 1065 | hpios_delay_micro_seconds(10000); |
1105 | } | 1066 | } |
1106 | if (timeout == 0) | 1067 | if (timeout == 0) |
1107 | return HPI6000_ERROR_INIT_NOACK; | 1068 | return HPI6000_ERROR_INIT_NOACK; |
@@ -1132,14 +1093,14 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1132 | mask = 0xFFFFFF00L; | 1093 | mask = 0xFFFFFF00L; |
1133 | /* ASI5100 uses AX6 code, */ | 1094 | /* ASI5100 uses AX6 code, */ |
1134 | /* but has no PLD r/w register to test */ | 1095 | /* but has no PLD r/w register to test */ |
1135 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci. | 1096 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev-> |
1136 | subsys_device_id) == | 1097 | subsystem_device) == |
1137 | HPI_ADAPTER_FAMILY_ASI(0x5100)) | 1098 | HPI_ADAPTER_FAMILY_ASI(0x5100)) |
1138 | mask = 0x00000000L; | 1099 | mask = 0x00000000L; |
1139 | /* ASI5200 uses AX6 code, */ | 1100 | /* ASI5200 uses AX6 code, */ |
1140 | /* but has no PLD r/w register to test */ | 1101 | /* but has no PLD r/w register to test */ |
1141 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci. | 1102 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev-> |
1142 | subsys_device_id) == | 1103 | subsystem_device) == |
1143 | HPI_ADAPTER_FAMILY_ASI(0x5200)) | 1104 | HPI_ADAPTER_FAMILY_ASI(0x5200)) |
1144 | mask = 0x00000000L; | 1105 | mask = 0x00000000L; |
1145 | break; | 1106 | break; |
@@ -1204,7 +1165,7 @@ static u32 hpi_read_word(struct dsp_obj *pdo, u32 address) | |||
1204 | u32 data = 0; | 1165 | u32 data = 0; |
1205 | 1166 | ||
1206 | if (hpi_set_address(pdo, address)) | 1167 | if (hpi_set_address(pdo, address)) |
1207 | return 0; /*? no way to return error */ | 1168 | return 0; /*? No way to return error */ |
1208 | 1169 | ||
1209 | /* take care of errata in revB DSP (2.0.1) */ | 1170 | /* take care of errata in revB DSP (2.0.1) */ |
1210 | data = ioread32(pdo->prHPI_data); | 1171 | data = ioread32(pdo->prHPI_data); |
@@ -1340,10 +1301,6 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1340 | u32 *p_data; | 1301 | u32 *p_data; |
1341 | u16 error = 0; | 1302 | u16 error = 0; |
1342 | 1303 | ||
1343 | /* does the DSP we are referencing exist? */ | ||
1344 | if (dsp_index >= phw->num_dsp) | ||
1345 | return HPI6000_ERROR_MSG_INVALID_DSP_INDEX; | ||
1346 | |||
1347 | ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); | 1304 | ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); |
1348 | if (ack & HPI_HIF_ERROR_MASK) { | 1305 | if (ack & HPI_HIF_ERROR_MASK) { |
1349 | pao->dsp_crashed++; | 1306 | pao->dsp_crashed++; |
@@ -1351,9 +1308,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1351 | } | 1308 | } |
1352 | pao->dsp_crashed = 0; | 1309 | pao->dsp_crashed = 0; |
1353 | 1310 | ||
1354 | /* send the message */ | 1311 | /* get the message address and size */ |
1355 | |||
1356 | /* get the address and size */ | ||
1357 | if (phw->message_buffer_address_on_dsp == 0) { | 1312 | if (phw->message_buffer_address_on_dsp == 0) { |
1358 | timeout = TIMEOUT; | 1313 | timeout = TIMEOUT; |
1359 | do { | 1314 | do { |
@@ -1368,10 +1323,9 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1368 | } else | 1323 | } else |
1369 | address = phw->message_buffer_address_on_dsp; | 1324 | address = phw->message_buffer_address_on_dsp; |
1370 | 1325 | ||
1371 | /* dwLength = sizeof(struct hpi_message); */ | ||
1372 | length = phm->size; | 1326 | length = phm->size; |
1373 | 1327 | ||
1374 | /* send it */ | 1328 | /* send the message */ |
1375 | p_data = (u32 *)phm; | 1329 | p_data = (u32 *)phm; |
1376 | if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, | 1330 | if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, |
1377 | (u16)length / 4)) | 1331 | (u16)length / 4)) |
@@ -1385,7 +1339,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1385 | if (ack & HPI_HIF_ERROR_MASK) | 1339 | if (ack & HPI_HIF_ERROR_MASK) |
1386 | return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; | 1340 | return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; |
1387 | 1341 | ||
1388 | /* get the address and size */ | 1342 | /* get the response address */ |
1389 | if (phw->response_buffer_address_on_dsp == 0) { | 1343 | if (phw->response_buffer_address_on_dsp == 0) { |
1390 | timeout = TIMEOUT; | 1344 | timeout = TIMEOUT; |
1391 | do { | 1345 | do { |
@@ -1409,7 +1363,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, | |||
1409 | if (!timeout) | 1363 | if (!timeout) |
1410 | length = sizeof(struct hpi_response); | 1364 | length = sizeof(struct hpi_response); |
1411 | 1365 | ||
1412 | /* get it */ | 1366 | /* get the response */ |
1413 | p_data = (u32 *)phr; | 1367 | p_data = (u32 *)phr; |
1414 | if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, | 1368 | if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, |
1415 | (u16)length / 4)) | 1369 | (u16)length / 4)) |
@@ -1827,13 +1781,13 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
1827 | error = hpi6000_get_data(pao, dsp_index, phm, phr); | 1781 | error = hpi6000_get_data(pao, dsp_index, phm, phr); |
1828 | break; | 1782 | break; |
1829 | case HPI_ADAPTER_GET_ASSERT: | 1783 | case HPI_ADAPTER_GET_ASSERT: |
1830 | phr->u.a.adapter_index = 0; /* dsp 0 default */ | 1784 | phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */ |
1831 | if (num_dsp == 2) { | 1785 | if (num_dsp == 2) { |
1832 | if (!phr->u.a.adapter_type) { | 1786 | if (!phr->u.ax.assert.count) { |
1833 | /* no assert from dsp 0, check dsp 1 */ | 1787 | /* no assert from dsp 0, check dsp 1 */ |
1834 | error = hpi6000_message_response_sequence(pao, | 1788 | error = hpi6000_message_response_sequence(pao, |
1835 | 1, phm, phr); | 1789 | 1, phm, phr); |
1836 | phr->u.a.adapter_index = 1; | 1790 | phr->u.ax.assert.dsp_index = 1; |
1837 | } | 1791 | } |
1838 | } | 1792 | } |
1839 | } | 1793 | } |