diff options
Diffstat (limited to 'sound/pci/asihpi/hpi6205.c')
-rw-r--r-- | sound/pci/asihpi/hpi6205.c | 603 |
1 files changed, 250 insertions, 353 deletions
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 2672f6591ceb..620525bdac59 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -38,27 +38,26 @@ | |||
38 | 38 | ||
39 | /*****************************************************************************/ | 39 | /*****************************************************************************/ |
40 | /* HPI6205 specific error codes */ | 40 | /* HPI6205 specific error codes */ |
41 | #define HPI6205_ERROR_BASE 1000 | 41 | #define HPI6205_ERROR_BASE 1000 /* not actually used anywhere */ |
42 | /*#define HPI6205_ERROR_MEM_ALLOC 1001 */ | 42 | |
43 | /* operational/messaging errors */ | ||
44 | #define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015 | ||
45 | #define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016 | ||
46 | |||
47 | /* initialization/bootload errors */ | ||
43 | #define HPI6205_ERROR_6205_NO_IRQ 1002 | 48 | #define HPI6205_ERROR_6205_NO_IRQ 1002 |
44 | #define HPI6205_ERROR_6205_INIT_FAILED 1003 | 49 | #define HPI6205_ERROR_6205_INIT_FAILED 1003 |
45 | /*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */ | ||
46 | #define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005 | ||
47 | #define HPI6205_ERROR_6205_REG 1006 | 50 | #define HPI6205_ERROR_6205_REG 1006 |
48 | #define HPI6205_ERROR_6205_DSPPAGE 1007 | 51 | #define HPI6205_ERROR_6205_DSPPAGE 1007 |
49 | #define HPI6205_ERROR_BAD_DSPINDEX 1008 | ||
50 | #define HPI6205_ERROR_C6713_HPIC 1009 | 52 | #define HPI6205_ERROR_C6713_HPIC 1009 |
51 | #define HPI6205_ERROR_C6713_HPIA 1010 | 53 | #define HPI6205_ERROR_C6713_HPIA 1010 |
52 | #define HPI6205_ERROR_C6713_PLL 1011 | 54 | #define HPI6205_ERROR_C6713_PLL 1011 |
53 | #define HPI6205_ERROR_DSP_INTMEM 1012 | 55 | #define HPI6205_ERROR_DSP_INTMEM 1012 |
54 | #define HPI6205_ERROR_DSP_EXTMEM 1013 | 56 | #define HPI6205_ERROR_DSP_EXTMEM 1013 |
55 | #define HPI6205_ERROR_DSP_PLD 1014 | 57 | #define HPI6205_ERROR_DSP_PLD 1014 |
56 | #define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015 | ||
57 | #define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016 | ||
58 | #define HPI6205_ERROR_6205_EEPROM 1017 | 58 | #define HPI6205_ERROR_6205_EEPROM 1017 |
59 | #define HPI6205_ERROR_DSP_EMIF 1018 | 59 | #define HPI6205_ERROR_DSP_EMIF 1018 |
60 | 60 | ||
61 | #define hpi6205_error(dsp_index, err) (err) | ||
62 | /*****************************************************************************/ | 61 | /*****************************************************************************/ |
63 | /* for C6205 PCI i/f */ | 62 | /* for C6205 PCI i/f */ |
64 | /* Host Status Register (HSR) bitfields */ | 63 | /* Host Status Register (HSR) bitfields */ |
@@ -128,9 +127,6 @@ struct hpi_hw_obj { | |||
128 | u32 outstream_host_buffer_size[HPI_MAX_STREAMS]; | 127 | u32 outstream_host_buffer_size[HPI_MAX_STREAMS]; |
129 | 128 | ||
130 | struct consistent_dma_area h_control_cache; | 129 | struct consistent_dma_area h_control_cache; |
131 | struct consistent_dma_area h_async_event_buffer; | ||
132 | /* struct hpi_control_cache_single *pControlCache; */ | ||
133 | struct hpi_async_event *p_async_event_buffer; | ||
134 | struct hpi_control_cache *p_cache; | 130 | struct hpi_control_cache *p_cache; |
135 | }; | 131 | }; |
136 | 132 | ||
@@ -208,8 +204,8 @@ static void instream_start(struct hpi_adapter_obj *pao, | |||
208 | static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index, | 204 | static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index, |
209 | u32 address); | 205 | u32 address); |
210 | 206 | ||
211 | static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, | 207 | static void boot_loader_write_mem32(struct hpi_adapter_obj *pao, |
212 | u32 address, u32 data); | 208 | int dsp_index, u32 address, u32 data); |
213 | 209 | ||
214 | static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, | 210 | static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, |
215 | int dsp_index); | 211 | int dsp_index); |
@@ -229,17 +225,7 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index); | |||
229 | 225 | ||
230 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | 226 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) |
231 | { | 227 | { |
232 | |||
233 | switch (phm->function) { | 228 | switch (phm->function) { |
234 | case HPI_SUBSYS_OPEN: | ||
235 | case HPI_SUBSYS_CLOSE: | ||
236 | case HPI_SUBSYS_GET_INFO: | ||
237 | case HPI_SUBSYS_DRIVER_UNLOAD: | ||
238 | case HPI_SUBSYS_DRIVER_LOAD: | ||
239 | case HPI_SUBSYS_FIND_ADAPTERS: | ||
240 | /* messages that should not get here */ | ||
241 | phr->error = HPI_ERROR_UNIMPLEMENTED; | ||
242 | break; | ||
243 | case HPI_SUBSYS_CREATE_ADAPTER: | 229 | case HPI_SUBSYS_CREATE_ADAPTER: |
244 | subsys_create_adapter(phm, phr); | 230 | subsys_create_adapter(phm, phr); |
245 | break; | 231 | break; |
@@ -257,15 +243,22 @@ static void control_message(struct hpi_adapter_obj *pao, | |||
257 | { | 243 | { |
258 | 244 | ||
259 | struct hpi_hw_obj *phw = pao->priv; | 245 | struct hpi_hw_obj *phw = pao->priv; |
246 | u16 pending_cache_error = 0; | ||
260 | 247 | ||
261 | switch (phm->function) { | 248 | switch (phm->function) { |
262 | case HPI_CONTROL_GET_STATE: | 249 | case HPI_CONTROL_GET_STATE: |
263 | if (pao->has_control_cache) { | 250 | if (pao->has_control_cache) { |
264 | rmb(); /* make sure we see updates DM_aed from DSP */ | 251 | rmb(); /* make sure we see updates DMAed from DSP */ |
265 | if (hpi_check_control_cache(phw->p_cache, phm, phr)) | 252 | if (hpi_check_control_cache(phw->p_cache, phm, phr)) { |
266 | break; | 253 | break; |
254 | } else if (phm->u.c.attribute == HPI_METER_PEAK) { | ||
255 | pending_cache_error = | ||
256 | HPI_ERROR_CONTROL_CACHING; | ||
257 | } | ||
267 | } | 258 | } |
268 | hw_message(pao, phm, phr); | 259 | hw_message(pao, phm, phr); |
260 | if (pending_cache_error && !phr->error) | ||
261 | phr->error = pending_cache_error; | ||
269 | break; | 262 | break; |
270 | case HPI_CONTROL_GET_INFO: | 263 | case HPI_CONTROL_GET_INFO: |
271 | hw_message(pao, phm, phr); | 264 | hw_message(pao, phm, phr); |
@@ -273,7 +266,8 @@ static void control_message(struct hpi_adapter_obj *pao, | |||
273 | case HPI_CONTROL_SET_STATE: | 266 | case HPI_CONTROL_SET_STATE: |
274 | hw_message(pao, phm, phr); | 267 | hw_message(pao, phm, phr); |
275 | if (pao->has_control_cache) | 268 | if (pao->has_control_cache) |
276 | hpi_sync_control_cache(phw->p_cache, phm, phr); | 269 | hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm, |
270 | phr); | ||
277 | break; | 271 | break; |
278 | default: | 272 | default: |
279 | phr->error = HPI_ERROR_INVALID_FUNC; | 273 | phr->error = HPI_ERROR_INVALID_FUNC; |
@@ -296,9 +290,9 @@ static void outstream_message(struct hpi_adapter_obj *pao, | |||
296 | { | 290 | { |
297 | 291 | ||
298 | if (phm->obj_index >= HPI_MAX_STREAMS) { | 292 | if (phm->obj_index >= HPI_MAX_STREAMS) { |
299 | phr->error = HPI_ERROR_INVALID_STREAM; | 293 | phr->error = HPI_ERROR_INVALID_OBJ_INDEX; |
300 | HPI_DEBUG_LOG(WARNING, | 294 | HPI_DEBUG_LOG(WARNING, |
301 | "message referencing invalid stream %d " | 295 | "Message referencing invalid stream %d " |
302 | "on adapter index %d\n", phm->obj_index, | 296 | "on adapter index %d\n", phm->obj_index, |
303 | phm->adapter_index); | 297 | phm->adapter_index); |
304 | return; | 298 | return; |
@@ -340,9 +334,9 @@ static void instream_message(struct hpi_adapter_obj *pao, | |||
340 | { | 334 | { |
341 | 335 | ||
342 | if (phm->obj_index >= HPI_MAX_STREAMS) { | 336 | if (phm->obj_index >= HPI_MAX_STREAMS) { |
343 | phr->error = HPI_ERROR_INVALID_STREAM; | 337 | phr->error = HPI_ERROR_INVALID_OBJ_INDEX; |
344 | HPI_DEBUG_LOG(WARNING, | 338 | HPI_DEBUG_LOG(WARNING, |
345 | "message referencing invalid stream %d " | 339 | "Message referencing invalid stream %d " |
346 | "on adapter index %d\n", phm->obj_index, | 340 | "on adapter index %d\n", phm->obj_index, |
347 | phm->adapter_index); | 341 | phm->adapter_index); |
348 | return; | 342 | return; |
@@ -385,8 +379,8 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) | |||
385 | * All other messages are ignored unless the adapter index matches | 379 | * All other messages are ignored unless the adapter index matches |
386 | * an adapter in the HPI | 380 | * an adapter in the HPI |
387 | */ | 381 | */ |
388 | HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object, | 382 | /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject, |
389 | phm->function); | 383 | phm->wFunction); */ |
390 | 384 | ||
391 | /* if Dsp has crashed then do not communicate with it any more */ | 385 | /* if Dsp has crashed then do not communicate with it any more */ |
392 | if (phm->object != HPI_OBJ_SUBSYSTEM) { | 386 | if (phm->object != HPI_OBJ_SUBSYSTEM) { |
@@ -411,8 +405,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) | |||
411 | 405 | ||
412 | /* Init default response */ | 406 | /* Init default response */ |
413 | if (phm->function != HPI_SUBSYS_CREATE_ADAPTER) | 407 | if (phm->function != HPI_SUBSYS_CREATE_ADAPTER) |
414 | hpi_init_response(phr, phm->object, phm->function, | 408 | phr->error = HPI_ERROR_PROCESSING_MESSAGE; |
415 | HPI_ERROR_PROCESSING_MESSAGE); | ||
416 | 409 | ||
417 | HPI_DEBUG_LOG(VERBOSE, "start of switch\n"); | 410 | HPI_DEBUG_LOG(VERBOSE, "start of switch\n"); |
418 | switch (phm->type) { | 411 | switch (phm->type) { |
@@ -423,9 +416,6 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) | |||
423 | break; | 416 | break; |
424 | 417 | ||
425 | case HPI_OBJ_ADAPTER: | 418 | case HPI_OBJ_ADAPTER: |
426 | phr->size = | ||
427 | sizeof(struct hpi_response_header) + | ||
428 | sizeof(struct hpi_adapter_res); | ||
429 | adapter_message(pao, phm, phr); | 419 | adapter_message(pao, phm, phr); |
430 | break; | 420 | break; |
431 | 421 | ||
@@ -474,14 +464,6 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
474 | 464 | ||
475 | memset(&ao, 0, sizeof(ao)); | 465 | memset(&ao, 0, sizeof(ao)); |
476 | 466 | ||
477 | /* this HPI only creates adapters for TI/PCI devices */ | ||
478 | if (phm->u.s.resource.bus_type != HPI_BUS_PCI) | ||
479 | return; | ||
480 | if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI) | ||
481 | return; | ||
482 | if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205) | ||
483 | return; | ||
484 | |||
485 | ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); | 467 | ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); |
486 | if (!ao.priv) { | 468 | if (!ao.priv) { |
487 | HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); | 469 | HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); |
@@ -491,18 +473,20 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
491 | 473 | ||
492 | ao.pci = *phm->u.s.resource.r.pci; | 474 | ao.pci = *phm->u.s.resource.r.pci; |
493 | err = create_adapter_obj(&ao, &os_error_code); | 475 | err = create_adapter_obj(&ao, &os_error_code); |
494 | if (!err) | ||
495 | err = hpi_add_adapter(&ao); | ||
496 | if (err) { | 476 | if (err) { |
497 | phr->u.s.data = os_error_code; | ||
498 | delete_adapter_obj(&ao); | 477 | delete_adapter_obj(&ao); |
499 | phr->error = err; | 478 | if (err >= HPI_ERROR_BACKEND_BASE) { |
479 | phr->error = HPI_ERROR_DSP_BOOTLOAD; | ||
480 | phr->specific_error = err; | ||
481 | } else { | ||
482 | phr->error = err; | ||
483 | } | ||
484 | phr->u.s.data = os_error_code; | ||
500 | return; | 485 | return; |
501 | } | 486 | } |
502 | 487 | ||
503 | phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; | 488 | phr->u.s.adapter_type = ao.adapter_type; |
504 | phr->u.s.adapter_index = ao.index; | 489 | phr->u.s.adapter_index = ao.index; |
505 | phr->u.s.num_adapters++; | ||
506 | phr->error = 0; | 490 | phr->error = 0; |
507 | } | 491 | } |
508 | 492 | ||
@@ -513,7 +497,7 @@ static void subsys_delete_adapter(struct hpi_message *phm, | |||
513 | struct hpi_adapter_obj *pao; | 497 | struct hpi_adapter_obj *pao; |
514 | struct hpi_hw_obj *phw; | 498 | struct hpi_hw_obj *phw; |
515 | 499 | ||
516 | pao = hpi_find_adapter(phm->adapter_index); | 500 | pao = hpi_find_adapter(phm->obj_index); |
517 | if (!pao) { | 501 | if (!pao) { |
518 | phr->error = HPI_ERROR_INVALID_OBJ_INDEX; | 502 | phr->error = HPI_ERROR_INVALID_OBJ_INDEX; |
519 | return; | 503 | return; |
@@ -526,6 +510,7 @@ static void subsys_delete_adapter(struct hpi_message *phm, | |||
526 | iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR); | 510 | iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR); |
527 | 511 | ||
528 | delete_adapter_obj(pao); | 512 | delete_adapter_obj(pao); |
513 | hpi_delete_adapter(pao); | ||
529 | phr->error = 0; | 514 | phr->error = 0; |
530 | } | 515 | } |
531 | 516 | ||
@@ -538,10 +523,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
538 | struct hpi_hw_obj *phw = pao->priv; | 523 | struct hpi_hw_obj *phw = pao->priv; |
539 | struct bus_master_interface *interface; | 524 | struct bus_master_interface *interface; |
540 | u32 phys_addr; | 525 | u32 phys_addr; |
541 | #ifndef HPI6205_NO_HSR_POLL | ||
542 | u32 time_out = HPI6205_TIMEOUT; | ||
543 | u32 temp1; | ||
544 | #endif | ||
545 | int i; | 526 | int i; |
546 | u16 err; | 527 | u16 err; |
547 | 528 | ||
@@ -566,7 +547,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
566 | 547 | ||
567 | if (hpios_locked_mem_alloc(&phw->h_locked_mem, | 548 | if (hpios_locked_mem_alloc(&phw->h_locked_mem, |
568 | sizeof(struct bus_master_interface), | 549 | sizeof(struct bus_master_interface), |
569 | pao->pci.p_os_data)) | 550 | pao->pci.pci_dev)) |
570 | phw->p_interface_buffer = NULL; | 551 | phw->p_interface_buffer = NULL; |
571 | else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem, | 552 | else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem, |
572 | (void *)&phw->p_interface_buffer)) | 553 | (void *)&phw->p_interface_buffer)) |
@@ -591,49 +572,29 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
591 | 572 | ||
592 | /* allow boot load even if mem alloc wont work */ | 573 | /* allow boot load even if mem alloc wont work */ |
593 | if (!phw->p_interface_buffer) | 574 | if (!phw->p_interface_buffer) |
594 | return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC); | 575 | return HPI_ERROR_MEMORY_ALLOC; |
595 | 576 | ||
596 | interface = phw->p_interface_buffer; | 577 | interface = phw->p_interface_buffer; |
597 | 578 | ||
598 | #ifndef HPI6205_NO_HSR_POLL | ||
599 | /* wait for first interrupt indicating the DSP init is done */ | ||
600 | time_out = HPI6205_TIMEOUT * 10; | ||
601 | temp1 = 0; | ||
602 | while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out) | ||
603 | temp1 = ioread32(phw->prHSR); | ||
604 | |||
605 | if (temp1 & C6205_HSR_INTSRC) | ||
606 | HPI_DEBUG_LOG(INFO, | ||
607 | "interrupt confirming DSP code running OK\n"); | ||
608 | else { | ||
609 | HPI_DEBUG_LOG(ERROR, | ||
610 | "timed out waiting for interrupt " | ||
611 | "confirming DSP code running\n"); | ||
612 | return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ); | ||
613 | } | ||
614 | |||
615 | /* reset the interrupt */ | ||
616 | iowrite32(C6205_HSR_INTSRC, phw->prHSR); | ||
617 | #endif | ||
618 | |||
619 | /* make sure the DSP has started ok */ | 579 | /* make sure the DSP has started ok */ |
620 | if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) { | 580 | if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) { |
621 | HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n"); | 581 | HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n"); |
622 | return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED); | 582 | return HPI6205_ERROR_6205_INIT_FAILED; |
623 | } | 583 | } |
624 | /* Note that *pao, *phw are zeroed after allocation, | 584 | /* Note that *pao, *phw are zeroed after allocation, |
625 | * so pointers and flags are NULL by default. | 585 | * so pointers and flags are NULL by default. |
626 | * Allocate bus mastering control cache buffer and tell the DSP about it | 586 | * Allocate bus mastering control cache buffer and tell the DSP about it |
627 | */ | 587 | */ |
628 | if (interface->control_cache.number_of_controls) { | 588 | if (interface->control_cache.number_of_controls) { |
629 | void *p_control_cache_virtual; | 589 | u8 *p_control_cache_virtual; |
630 | 590 | ||
631 | err = hpios_locked_mem_alloc(&phw->h_control_cache, | 591 | err = hpios_locked_mem_alloc(&phw->h_control_cache, |
632 | interface->control_cache.size_in_bytes, | 592 | interface->control_cache.size_in_bytes, |
633 | pao->pci.p_os_data); | 593 | pao->pci.pci_dev); |
634 | if (!err) | 594 | if (!err) |
635 | err = hpios_locked_mem_get_virt_addr(&phw-> | 595 | err = hpios_locked_mem_get_virt_addr(&phw-> |
636 | h_control_cache, &p_control_cache_virtual); | 596 | h_control_cache, |
597 | (void *)&p_control_cache_virtual); | ||
637 | if (!err) { | 598 | if (!err) { |
638 | memset(p_control_cache_virtual, 0, | 599 | memset(p_control_cache_virtual, 0, |
639 | interface->control_cache.size_in_bytes); | 600 | interface->control_cache.size_in_bytes); |
@@ -642,7 +603,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
642 | hpi_alloc_control_cache(interface-> | 603 | hpi_alloc_control_cache(interface-> |
643 | control_cache.number_of_controls, | 604 | control_cache.number_of_controls, |
644 | interface->control_cache.size_in_bytes, | 605 | interface->control_cache.size_in_bytes, |
645 | (struct hpi_control_cache_info *) | ||
646 | p_control_cache_virtual); | 606 | p_control_cache_virtual); |
647 | if (!phw->p_cache) | 607 | if (!phw->p_cache) |
648 | err = HPI_ERROR_MEMORY_ALLOC; | 608 | err = HPI_ERROR_MEMORY_ALLOC; |
@@ -662,78 +622,56 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
662 | pao->has_control_cache = 0; | 622 | pao->has_control_cache = 0; |
663 | } | 623 | } |
664 | } | 624 | } |
665 | /* allocate bus mastering async buffer and tell the DSP about it */ | ||
666 | if (interface->async_buffer.b.size) { | ||
667 | err = hpios_locked_mem_alloc(&phw->h_async_event_buffer, | ||
668 | interface->async_buffer.b.size * | ||
669 | sizeof(struct hpi_async_event), pao->pci.p_os_data); | ||
670 | if (!err) | ||
671 | err = hpios_locked_mem_get_virt_addr | ||
672 | (&phw->h_async_event_buffer, (void *) | ||
673 | &phw->p_async_event_buffer); | ||
674 | if (!err) | ||
675 | memset((void *)phw->p_async_event_buffer, 0, | ||
676 | interface->async_buffer.b.size * | ||
677 | sizeof(struct hpi_async_event)); | ||
678 | if (!err) { | ||
679 | err = hpios_locked_mem_get_phys_addr | ||
680 | (&phw->h_async_event_buffer, &phys_addr); | ||
681 | interface->async_buffer.physical_address32 = | ||
682 | phys_addr; | ||
683 | } | ||
684 | if (err) { | ||
685 | if (hpios_locked_mem_valid(&phw-> | ||
686 | h_async_event_buffer)) { | ||
687 | hpios_locked_mem_free | ||
688 | (&phw->h_async_event_buffer); | ||
689 | phw->p_async_event_buffer = NULL; | ||
690 | } | ||
691 | } | ||
692 | } | ||
693 | send_dsp_command(phw, H620_HIF_IDLE); | 625 | send_dsp_command(phw, H620_HIF_IDLE); |
694 | 626 | ||
695 | { | 627 | { |
696 | struct hpi_message hM; | 628 | struct hpi_message hm; |
697 | struct hpi_response hR; | 629 | struct hpi_response hr; |
698 | u32 max_streams; | 630 | u32 max_streams; |
699 | 631 | ||
700 | HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); | 632 | HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); |
701 | memset(&hM, 0, sizeof(hM)); | 633 | memset(&hm, 0, sizeof(hm)); |
702 | hM.type = HPI_TYPE_MESSAGE; | 634 | hm.type = HPI_TYPE_MESSAGE; |
703 | hM.size = sizeof(hM); | 635 | hm.size = sizeof(hm); |
704 | hM.object = HPI_OBJ_ADAPTER; | 636 | hm.object = HPI_OBJ_ADAPTER; |
705 | hM.function = HPI_ADAPTER_GET_INFO; | 637 | hm.function = HPI_ADAPTER_GET_INFO; |
706 | hM.adapter_index = 0; | 638 | hm.adapter_index = 0; |
707 | memset(&hR, 0, sizeof(hR)); | 639 | memset(&hr, 0, sizeof(hr)); |
708 | hR.size = sizeof(hR); | 640 | hr.size = sizeof(hr); |
709 | 641 | ||
710 | err = message_response_sequence(pao, &hM, &hR); | 642 | err = message_response_sequence(pao, &hm, &hr); |
711 | if (err) { | 643 | if (err) { |
712 | HPI_DEBUG_LOG(ERROR, "message transport error %d\n", | 644 | HPI_DEBUG_LOG(ERROR, "message transport error %d\n", |
713 | err); | 645 | err); |
714 | return err; | 646 | return err; |
715 | } | 647 | } |
716 | if (hR.error) | 648 | if (hr.error) |
717 | return hR.error; | 649 | return hr.error; |
718 | 650 | ||
719 | pao->adapter_type = hR.u.a.adapter_type; | 651 | pao->adapter_type = hr.u.ax.info.adapter_type; |
720 | pao->index = hR.u.a.adapter_index; | 652 | pao->index = hr.u.ax.info.adapter_index; |
721 | 653 | ||
722 | max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams; | 654 | max_streams = |
655 | hr.u.ax.info.num_outstreams + | ||
656 | hr.u.ax.info.num_instreams; | ||
723 | 657 | ||
724 | hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams, | 658 | hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams, |
725 | 65536, pao->pci.p_os_data); | 659 | 65536, pao->pci.pci_dev); |
726 | 660 | ||
727 | HPI_DEBUG_LOG(VERBOSE, | 661 | HPI_DEBUG_LOG(VERBOSE, |
728 | "got adapter info type %x index %d serial %d\n", | 662 | "got adapter info type %x index %d serial %d\n", |
729 | hR.u.a.adapter_type, hR.u.a.adapter_index, | 663 | hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index, |
730 | hR.u.a.serial_number); | 664 | hr.u.ax.info.serial_number); |
731 | } | 665 | } |
732 | 666 | ||
733 | pao->open = 0; /* upon creation the adapter is closed */ | 667 | pao->open = 0; /* upon creation the adapter is closed */ |
734 | 668 | ||
669 | if (phw->p_cache) | ||
670 | phw->p_cache->adap_idx = pao->index; | ||
671 | |||
735 | HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); | 672 | HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); |
736 | return 0; | 673 | |
674 | return hpi_add_adapter(pao); | ||
737 | } | 675 | } |
738 | 676 | ||
739 | /** Free memory areas allocated by adapter | 677 | /** Free memory areas allocated by adapter |
@@ -747,11 +685,6 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao) | |||
747 | 685 | ||
748 | phw = pao->priv; | 686 | phw = pao->priv; |
749 | 687 | ||
750 | if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) { | ||
751 | hpios_locked_mem_free(&phw->h_async_event_buffer); | ||
752 | phw->p_async_event_buffer = NULL; | ||
753 | } | ||
754 | |||
755 | if (hpios_locked_mem_valid(&phw->h_control_cache)) { | 688 | if (hpios_locked_mem_valid(&phw->h_control_cache)) { |
756 | hpios_locked_mem_free(&phw->h_control_cache); | 689 | hpios_locked_mem_free(&phw->h_control_cache); |
757 | hpi_free_control_cache(phw->p_cache); | 690 | hpi_free_control_cache(phw->p_cache); |
@@ -776,13 +709,15 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao) | |||
776 | phw->outstream_host_buffer_size[i] = 0; | 709 | phw->outstream_host_buffer_size[i] = 0; |
777 | } | 710 | } |
778 | 711 | ||
779 | hpios_locked_mem_unprepare(pao->pci.p_os_data); | 712 | hpios_locked_mem_unprepare(pao->pci.pci_dev); |
780 | 713 | ||
781 | hpi_delete_adapter(pao); | ||
782 | kfree(phw); | 714 | kfree(phw); |
783 | } | 715 | } |
784 | 716 | ||
785 | /*****************************************************************************/ | 717 | /*****************************************************************************/ |
718 | /* Adapter functions */ | ||
719 | |||
720 | /*****************************************************************************/ | ||
786 | /* OutStream Host buffer functions */ | 721 | /* OutStream Host buffer functions */ |
787 | 722 | ||
788 | /** Allocate or attach buffer for busmastering | 723 | /** Allocate or attach buffer for busmastering |
@@ -824,7 +759,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, | |||
824 | 759 | ||
825 | err = hpios_locked_mem_alloc(&phw->outstream_host_buffers | 760 | err = hpios_locked_mem_alloc(&phw->outstream_host_buffers |
826 | [phm->obj_index], phm->u.d.u.buffer.buffer_size, | 761 | [phm->obj_index], phm->u.d.u.buffer.buffer_size, |
827 | pao->pci.p_os_data); | 762 | pao->pci.pci_dev); |
828 | 763 | ||
829 | if (err) { | 764 | if (err) { |
830 | phr->error = HPI_ERROR_INVALID_DATASIZE; | 765 | phr->error = HPI_ERROR_INVALID_DATASIZE; |
@@ -861,7 +796,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, | |||
861 | if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. | 796 | if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. |
862 | buffer_size - 1)) { | 797 | buffer_size - 1)) { |
863 | HPI_DEBUG_LOG(ERROR, | 798 | HPI_DEBUG_LOG(ERROR, |
864 | "buffer size must be 2^N not %d\n", | 799 | "Buffer size must be 2^N not %d\n", |
865 | phm->u.d.u.buffer.buffer_size); | 800 | phm->u.d.u.buffer.buffer_size); |
866 | phr->error = HPI_ERROR_INVALID_DATASIZE; | 801 | phr->error = HPI_ERROR_INVALID_DATASIZE; |
867 | return; | 802 | return; |
@@ -875,6 +810,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, | |||
875 | status->dSP_index = 0; | 810 | status->dSP_index = 0; |
876 | status->host_index = status->dSP_index; | 811 | status->host_index = status->dSP_index; |
877 | status->size_in_bytes = phm->u.d.u.buffer.buffer_size; | 812 | status->size_in_bytes = phm->u.d.u.buffer.buffer_size; |
813 | status->auxiliary_data_available = 0; | ||
878 | 814 | ||
879 | hw_message(pao, phm, phr); | 815 | hw_message(pao, phm, phr); |
880 | 816 | ||
@@ -966,51 +902,6 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
966 | hpi_init_response(phr, phm->object, phm->function, 0); | 902 | hpi_init_response(phr, phm->object, phm->function, 0); |
967 | status = &interface->outstream_host_buffer_status[phm->obj_index]; | 903 | status = &interface->outstream_host_buffer_status[phm->obj_index]; |
968 | 904 | ||
969 | if (phw->flag_outstream_just_reset[phm->obj_index]) { | ||
970 | /* First OutStremWrite() call following reset will write data to the | ||
971 | adapter's buffers, reducing delay before stream can start. The DSP | ||
972 | takes care of setting the stream data format using format information | ||
973 | embedded in phm. | ||
974 | */ | ||
975 | int partial_write = 0; | ||
976 | unsigned int original_size = 0; | ||
977 | |||
978 | phw->flag_outstream_just_reset[phm->obj_index] = 0; | ||
979 | |||
980 | /* Send the first buffer to the DSP the old way. */ | ||
981 | /* Limit size of first transfer - */ | ||
982 | /* expect that this will not usually be triggered. */ | ||
983 | if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) { | ||
984 | partial_write = 1; | ||
985 | original_size = phm->u.d.u.data.data_size; | ||
986 | phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA; | ||
987 | } | ||
988 | /* write it */ | ||
989 | phm->function = HPI_OSTREAM_WRITE; | ||
990 | hw_message(pao, phm, phr); | ||
991 | |||
992 | if (phr->error) | ||
993 | return; | ||
994 | |||
995 | /* update status information that the DSP would typically | ||
996 | * update (and will update next time the DSP | ||
997 | * buffer update task reads data from the host BBM buffer) | ||
998 | */ | ||
999 | status->auxiliary_data_available = phm->u.d.u.data.data_size; | ||
1000 | status->host_index += phm->u.d.u.data.data_size; | ||
1001 | status->dSP_index += phm->u.d.u.data.data_size; | ||
1002 | |||
1003 | /* if we did a full write, we can return from here. */ | ||
1004 | if (!partial_write) | ||
1005 | return; | ||
1006 | |||
1007 | /* tweak buffer parameters and let the rest of the */ | ||
1008 | /* buffer land in internal BBM buffer */ | ||
1009 | phm->u.d.u.data.data_size = | ||
1010 | original_size - HPI6205_SIZEOF_DATA; | ||
1011 | phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA; | ||
1012 | } | ||
1013 | |||
1014 | space_available = outstream_get_space_available(status); | 905 | space_available = outstream_get_space_available(status); |
1015 | if (space_available < phm->u.d.u.data.data_size) { | 906 | if (space_available < phm->u.d.u.data.data_size) { |
1016 | phr->error = HPI_ERROR_INVALID_DATASIZE; | 907 | phr->error = HPI_ERROR_INVALID_DATASIZE; |
@@ -1047,6 +938,24 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
1047 | memcpy(p_bbm_data, p_app_data + l_first_write, | 938 | memcpy(p_bbm_data, p_app_data + l_first_write, |
1048 | phm->u.d.u.data.data_size - l_first_write); | 939 | phm->u.d.u.data.data_size - l_first_write); |
1049 | } | 940 | } |
941 | |||
942 | /* | ||
943 | * This version relies on the DSP code triggering an OStream buffer | ||
944 | * update immediately following a SET_FORMAT call. The host has | ||
945 | * already written data into the BBM buffer, but the DSP won't know | ||
946 | * about it until dwHostIndex is adjusted. | ||
947 | */ | ||
948 | if (phw->flag_outstream_just_reset[phm->obj_index]) { | ||
949 | /* Format can only change after reset. Must tell DSP. */ | ||
950 | u16 function = phm->function; | ||
951 | phw->flag_outstream_just_reset[phm->obj_index] = 0; | ||
952 | phm->function = HPI_OSTREAM_SET_FORMAT; | ||
953 | hw_message(pao, phm, phr); /* send the format to the DSP */ | ||
954 | phm->function = function; | ||
955 | if (phr->error) | ||
956 | return; | ||
957 | } | ||
958 | |||
1050 | status->host_index += phm->u.d.u.data.data_size; | 959 | status->host_index += phm->u.d.u.data.data_size; |
1051 | } | 960 | } |
1052 | 961 | ||
@@ -1132,7 +1041,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao, | |||
1132 | 1041 | ||
1133 | err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm-> | 1042 | err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm-> |
1134 | obj_index], phm->u.d.u.buffer.buffer_size, | 1043 | obj_index], phm->u.d.u.buffer.buffer_size, |
1135 | pao->pci.p_os_data); | 1044 | pao->pci.pci_dev); |
1136 | 1045 | ||
1137 | if (err) { | 1046 | if (err) { |
1138 | phr->error = HPI_ERROR_INVALID_DATASIZE; | 1047 | phr->error = HPI_ERROR_INVALID_DATASIZE; |
@@ -1163,7 +1072,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao, | |||
1163 | if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. | 1072 | if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. |
1164 | buffer_size - 1)) { | 1073 | buffer_size - 1)) { |
1165 | HPI_DEBUG_LOG(ERROR, | 1074 | HPI_DEBUG_LOG(ERROR, |
1166 | "buffer size must be 2^N not %d\n", | 1075 | "Buffer size must be 2^N not %d\n", |
1167 | phm->u.d.u.buffer.buffer_size); | 1076 | phm->u.d.u.buffer.buffer_size); |
1168 | phr->error = HPI_ERROR_INVALID_DATASIZE; | 1077 | phr->error = HPI_ERROR_INVALID_DATASIZE; |
1169 | return; | 1078 | return; |
@@ -1178,8 +1087,10 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao, | |||
1178 | status->dSP_index = 0; | 1087 | status->dSP_index = 0; |
1179 | status->host_index = status->dSP_index; | 1088 | status->host_index = status->dSP_index; |
1180 | status->size_in_bytes = phm->u.d.u.buffer.buffer_size; | 1089 | status->size_in_bytes = phm->u.d.u.buffer.buffer_size; |
1090 | status->auxiliary_data_available = 0; | ||
1181 | 1091 | ||
1182 | hw_message(pao, phm, phr); | 1092 | hw_message(pao, phm, phr); |
1093 | |||
1183 | if (phr->error | 1094 | if (phr->error |
1184 | && hpios_locked_mem_valid(&phw-> | 1095 | && hpios_locked_mem_valid(&phw-> |
1185 | instream_host_buffers[phm->obj_index])) { | 1096 | instream_host_buffers[phm->obj_index])) { |
@@ -1344,33 +1255,36 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1344 | struct hpi_hw_obj *phw = pao->priv; | 1255 | struct hpi_hw_obj *phw = pao->priv; |
1345 | struct dsp_code dsp_code; | 1256 | struct dsp_code dsp_code; |
1346 | u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD]; | 1257 | u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD]; |
1347 | u16 firmware_id = pao->pci.subsys_device_id; | ||
1348 | u32 temp; | 1258 | u32 temp; |
1349 | int dsp = 0, i = 0; | 1259 | int dsp = 0, i = 0; |
1350 | u16 err = 0; | 1260 | u16 err = 0; |
1351 | 1261 | ||
1352 | boot_code_id[0] = HPI_ADAPTER_ASI(0x6205); | 1262 | boot_code_id[0] = HPI_ADAPTER_ASI(0x6205); |
1353 | 1263 | ||
1354 | /* special cases where firmware_id != subsys ID */ | 1264 | boot_code_id[1] = pao->pci.pci_dev->subsystem_device; |
1355 | switch (firmware_id) { | 1265 | boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(boot_code_id[1]); |
1266 | |||
1267 | /* fix up cases where bootcode id[1] != subsys id */ | ||
1268 | switch (boot_code_id[1]) { | ||
1356 | case HPI_ADAPTER_FAMILY_ASI(0x5000): | 1269 | case HPI_ADAPTER_FAMILY_ASI(0x5000): |
1357 | boot_code_id[0] = firmware_id; | 1270 | boot_code_id[0] = boot_code_id[1]; |
1358 | firmware_id = 0; | 1271 | boot_code_id[1] = 0; |
1359 | break; | 1272 | break; |
1360 | case HPI_ADAPTER_FAMILY_ASI(0x5300): | 1273 | case HPI_ADAPTER_FAMILY_ASI(0x5300): |
1361 | case HPI_ADAPTER_FAMILY_ASI(0x5400): | 1274 | case HPI_ADAPTER_FAMILY_ASI(0x5400): |
1362 | case HPI_ADAPTER_FAMILY_ASI(0x6300): | 1275 | case HPI_ADAPTER_FAMILY_ASI(0x6300): |
1363 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400); | 1276 | boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); |
1364 | break; | 1277 | break; |
1365 | case HPI_ADAPTER_FAMILY_ASI(0x5600): | 1278 | case HPI_ADAPTER_FAMILY_ASI(0x5600): |
1366 | case HPI_ADAPTER_FAMILY_ASI(0x6500): | 1279 | case HPI_ADAPTER_FAMILY_ASI(0x6500): |
1367 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600); | 1280 | boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); |
1368 | break; | 1281 | break; |
1369 | case HPI_ADAPTER_FAMILY_ASI(0x8800): | 1282 | case HPI_ADAPTER_FAMILY_ASI(0x8800): |
1370 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900); | 1283 | boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x8900); |
1284 | break; | ||
1285 | default: | ||
1371 | break; | 1286 | break; |
1372 | } | 1287 | } |
1373 | boot_code_id[1] = firmware_id; | ||
1374 | 1288 | ||
1375 | /* reset DSP by writing a 1 to the WARMRESET bit */ | 1289 | /* reset DSP by writing a 1 to the WARMRESET bit */ |
1376 | temp = C6205_HDCR_WARMRESET; | 1290 | temp = C6205_HDCR_WARMRESET; |
@@ -1381,7 +1295,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1381 | temp = ioread32(phw->prHSR); | 1295 | temp = ioread32(phw->prHSR); |
1382 | if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) != | 1296 | if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) != |
1383 | C6205_HSR_EEREAD) | 1297 | C6205_HSR_EEREAD) |
1384 | return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM); | 1298 | return HPI6205_ERROR_6205_EEPROM; |
1385 | temp |= 0x04; | 1299 | temp |= 0x04; |
1386 | /* disable PINTA interrupt */ | 1300 | /* disable PINTA interrupt */ |
1387 | iowrite32(temp, phw->prHSR); | 1301 | iowrite32(temp, phw->prHSR); |
@@ -1389,27 +1303,27 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1389 | /* check control register reports PCI boot mode */ | 1303 | /* check control register reports PCI boot mode */ |
1390 | temp = ioread32(phw->prHDCR); | 1304 | temp = ioread32(phw->prHDCR); |
1391 | if (!(temp & C6205_HDCR_PCIBOOT)) | 1305 | if (!(temp & C6205_HDCR_PCIBOOT)) |
1392 | return hpi6205_error(0, HPI6205_ERROR_6205_REG); | 1306 | return HPI6205_ERROR_6205_REG; |
1393 | 1307 | ||
1394 | /* try writing a couple of numbers to the DSP page register */ | 1308 | /* try writing a few numbers to the DSP page register */ |
1395 | /* and reading them back. */ | 1309 | /* and reading them back. */ |
1396 | temp = 1; | 1310 | temp = 3; |
1397 | iowrite32(temp, phw->prDSPP); | 1311 | iowrite32(temp, phw->prDSPP); |
1398 | if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) | 1312 | if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) |
1399 | return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); | 1313 | return HPI6205_ERROR_6205_DSPPAGE; |
1400 | temp = 2; | 1314 | temp = 2; |
1401 | iowrite32(temp, phw->prDSPP); | 1315 | iowrite32(temp, phw->prDSPP); |
1402 | if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) | 1316 | if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) |
1403 | return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); | 1317 | return HPI6205_ERROR_6205_DSPPAGE; |
1404 | temp = 3; | 1318 | temp = 1; |
1405 | iowrite32(temp, phw->prDSPP); | 1319 | iowrite32(temp, phw->prDSPP); |
1406 | if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) | 1320 | if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) |
1407 | return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); | 1321 | return HPI6205_ERROR_6205_DSPPAGE; |
1408 | /* reset DSP page to the correct number */ | 1322 | /* reset DSP page to the correct number */ |
1409 | temp = 0; | 1323 | temp = 0; |
1410 | iowrite32(temp, phw->prDSPP); | 1324 | iowrite32(temp, phw->prDSPP); |
1411 | if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) | 1325 | if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) |
1412 | return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); | 1326 | return HPI6205_ERROR_6205_DSPPAGE; |
1413 | phw->dsp_page = 0; | 1327 | phw->dsp_page = 0; |
1414 | 1328 | ||
1415 | /* release 6713 from reset before 6205 is bootloaded. | 1329 | /* release 6713 from reset before 6205 is bootloaded. |
@@ -1455,7 +1369,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1455 | return err; | 1369 | return err; |
1456 | 1370 | ||
1457 | /* write the DSP code down into the DSPs memory */ | 1371 | /* write the DSP code down into the DSPs memory */ |
1458 | dsp_code.ps_dev = pao->pci.p_os_data; | 1372 | dsp_code.ps_dev = pao->pci.pci_dev; |
1459 | err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code, | 1373 | err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code, |
1460 | pos_error_code); | 1374 | pos_error_code); |
1461 | if (err) | 1375 | if (err) |
@@ -1484,10 +1398,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1484 | if (err) | 1398 | if (err) |
1485 | break; | 1399 | break; |
1486 | for (i = 0; i < (int)length; i++) { | 1400 | for (i = 0; i < (int)length; i++) { |
1487 | err = boot_loader_write_mem32(pao, dsp, | 1401 | boot_loader_write_mem32(pao, dsp, address, |
1488 | address, *pcode); | 1402 | *pcode); |
1489 | if (err) | ||
1490 | break; | ||
1491 | /* dummy read every 4 words */ | 1403 | /* dummy read every 4 words */ |
1492 | /* for 6205 advisory 1.4.4 */ | 1404 | /* for 6205 advisory 1.4.4 */ |
1493 | if (i % 4 == 0) | 1405 | if (i % 4 == 0) |
@@ -1561,7 +1473,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1561 | host_mailbox_address_on_dsp = 0x80000000; | 1473 | host_mailbox_address_on_dsp = 0x80000000; |
1562 | while ((physicalPC_iaddress != physicalPC_iaddress_verify) | 1474 | while ((physicalPC_iaddress != physicalPC_iaddress_verify) |
1563 | && time_out--) { | 1475 | && time_out--) { |
1564 | err = boot_loader_write_mem32(pao, 0, | 1476 | boot_loader_write_mem32(pao, 0, |
1565 | host_mailbox_address_on_dsp, | 1477 | host_mailbox_address_on_dsp, |
1566 | physicalPC_iaddress); | 1478 | physicalPC_iaddress); |
1567 | physicalPC_iaddress_verify = | 1479 | physicalPC_iaddress_verify = |
@@ -1631,11 +1543,10 @@ static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index, | |||
1631 | return data; | 1543 | return data; |
1632 | } | 1544 | } |
1633 | 1545 | ||
1634 | static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, | 1546 | static void boot_loader_write_mem32(struct hpi_adapter_obj *pao, |
1635 | u32 address, u32 data) | 1547 | int dsp_index, u32 address, u32 data) |
1636 | { | 1548 | { |
1637 | struct hpi_hw_obj *phw = pao->priv; | 1549 | struct hpi_hw_obj *phw = pao->priv; |
1638 | u16 err = 0; | ||
1639 | __iomem u32 *p_data; | 1550 | __iomem u32 *p_data; |
1640 | /* u32 dwVerifyData=0; */ | 1551 | /* u32 dwVerifyData=0; */ |
1641 | 1552 | ||
@@ -1675,15 +1586,11 @@ static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, | |||
1675 | 1586 | ||
1676 | /* dummy read every 4 words for 6205 advisory 1.4.4 */ | 1587 | /* dummy read every 4 words for 6205 advisory 1.4.4 */ |
1677 | boot_loader_read_mem32(pao, 0, 0); | 1588 | boot_loader_read_mem32(pao, 0, 0); |
1678 | } else | 1589 | } |
1679 | err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX); | ||
1680 | return err; | ||
1681 | } | 1590 | } |
1682 | 1591 | ||
1683 | static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) | 1592 | static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) |
1684 | { | 1593 | { |
1685 | u16 err = 0; | ||
1686 | |||
1687 | if (dsp_index == 0) { | 1594 | if (dsp_index == 0) { |
1688 | u32 setting; | 1595 | u32 setting; |
1689 | 1596 | ||
@@ -1711,8 +1618,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) | |||
1711 | boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting); | 1618 | boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting); |
1712 | if (setting != boot_loader_read_mem32(pao, dsp_index, | 1619 | if (setting != boot_loader_read_mem32(pao, dsp_index, |
1713 | 0x01800008)) | 1620 | 0x01800008)) |
1714 | return hpi6205_error(dsp_index, | 1621 | return HPI6205_ERROR_DSP_EMIF; |
1715 | HPI6205_ERROR_DSP_EMIF); | ||
1716 | 1622 | ||
1717 | /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */ | 1623 | /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */ |
1718 | /* which occupies D15..0. 6713 starts at 27MHz, so need */ | 1624 | /* which occupies D15..0. 6713 starts at 27MHz, so need */ |
@@ -1725,8 +1631,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) | |||
1725 | boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting); | 1631 | boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting); |
1726 | if (setting != boot_loader_read_mem32(pao, dsp_index, | 1632 | if (setting != boot_loader_read_mem32(pao, dsp_index, |
1727 | 0x01800004)) | 1633 | 0x01800004)) |
1728 | return hpi6205_error(dsp_index, | 1634 | return HPI6205_ERROR_DSP_EMIF; |
1729 | HPI6205_ERROR_DSP_EMIF); | ||
1730 | 1635 | ||
1731 | /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */ | 1636 | /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */ |
1732 | /* which occupies D15..0. 6713 starts at 27MHz, so need */ | 1637 | /* which occupies D15..0. 6713 starts at 27MHz, so need */ |
@@ -1738,8 +1643,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) | |||
1738 | boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting); | 1643 | boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting); |
1739 | if (setting != boot_loader_read_mem32(pao, dsp_index, | 1644 | if (setting != boot_loader_read_mem32(pao, dsp_index, |
1740 | 0x01800010)) | 1645 | 0x01800010)) |
1741 | return hpi6205_error(dsp_index, | 1646 | return HPI6205_ERROR_DSP_EMIF; |
1742 | HPI6205_ERROR_DSP_EMIF); | ||
1743 | 1647 | ||
1744 | /* EMIF CE3 setup - 32 bit async. */ | 1648 | /* EMIF CE3 setup - 32 bit async. */ |
1745 | /* This is the PLD on the ASI5000 cards only */ | 1649 | /* This is the PLD on the ASI5000 cards only */ |
@@ -1750,8 +1654,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) | |||
1750 | boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting); | 1654 | boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting); |
1751 | if (setting != boot_loader_read_mem32(pao, dsp_index, | 1655 | if (setting != boot_loader_read_mem32(pao, dsp_index, |
1752 | 0x01800014)) | 1656 | 0x01800014)) |
1753 | return hpi6205_error(dsp_index, | 1657 | return HPI6205_ERROR_DSP_EMIF; |
1754 | HPI6205_ERROR_DSP_EMIF); | ||
1755 | 1658 | ||
1756 | /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */ | 1659 | /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */ |
1757 | /* need to use this else DSP code crashes? */ | 1660 | /* need to use this else DSP code crashes? */ |
@@ -1775,12 +1678,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) | |||
1775 | read_data = | 1678 | read_data = |
1776 | 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR); | 1679 | 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR); |
1777 | if (write_data != read_data) { | 1680 | if (write_data != read_data) { |
1778 | err = hpi6205_error(dsp_index, | ||
1779 | HPI6205_ERROR_C6713_HPIC); | ||
1780 | HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data, | 1681 | HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data, |
1781 | read_data); | 1682 | read_data); |
1782 | 1683 | return HPI6205_ERROR_C6713_HPIC; | |
1783 | return err; | ||
1784 | } | 1684 | } |
1785 | /* HPIA - walking ones test */ | 1685 | /* HPIA - walking ones test */ |
1786 | write_data = 1; | 1686 | write_data = 1; |
@@ -1798,11 +1698,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) | |||
1798 | HPIAH_ADDR)) | 1698 | HPIAH_ADDR)) |
1799 | << 16); | 1699 | << 16); |
1800 | if (read_data != write_data) { | 1700 | if (read_data != write_data) { |
1801 | err = hpi6205_error(dsp_index, | ||
1802 | HPI6205_ERROR_C6713_HPIA); | ||
1803 | HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n", | 1701 | HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n", |
1804 | write_data, read_data); | 1702 | write_data, read_data); |
1805 | return err; | 1703 | return HPI6205_ERROR_C6713_HPIA; |
1806 | } | 1704 | } |
1807 | write_data = write_data << 1; | 1705 | write_data = write_data << 1; |
1808 | } | 1706 | } |
@@ -1847,30 +1745,81 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) | |||
1847 | /* PLL should not be bypassed! */ | 1745 | /* PLL should not be bypassed! */ |
1848 | if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF) | 1746 | if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF) |
1849 | != 0x0001) { | 1747 | != 0x0001) { |
1850 | err = hpi6205_error(dsp_index, | 1748 | return HPI6205_ERROR_C6713_PLL; |
1851 | HPI6205_ERROR_C6713_PLL); | ||
1852 | return err; | ||
1853 | } | 1749 | } |
1854 | /* setup C67x EMIF (note this is the only use of | 1750 | /* setup C67x EMIF (note this is the only use of |
1855 | BAR1 via BootLoader_WriteMem32) */ | 1751 | BAR1 via BootLoader_WriteMem32) */ |
1856 | boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL, | 1752 | boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL, |
1857 | 0x000034A8); | 1753 | 0x000034A8); |
1754 | |||
1755 | /* EMIF CE0 setup - 2Mx32 Sync DRAM | ||
1756 | 31..28 Wr setup | ||
1757 | 27..22 Wr strobe | ||
1758 | 21..20 Wr hold | ||
1759 | 19..16 Rd setup | ||
1760 | 15..14 - | ||
1761 | 13..8 Rd strobe | ||
1762 | 7..4 MTYPE 0011 Sync DRAM 32bits | ||
1763 | 3 Wr hold MSB | ||
1764 | 2..0 Rd hold | ||
1765 | */ | ||
1858 | boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0, | 1766 | boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0, |
1859 | 0x00000030); | 1767 | 0x00000030); |
1768 | |||
1769 | /* EMIF SDRAM Extension | ||
1770 | 0x00 | ||
1771 | 31-21 0000b 0000b 000b | ||
1772 | 20 WR2RD = 2cycles-1 = 1b | ||
1773 | |||
1774 | 19-18 WR2DEAC = 3cycle-1 = 10b | ||
1775 | 17 WR2WR = 2cycle-1 = 1b | ||
1776 | 16-15 R2WDQM = 4cycle-1 = 11b | ||
1777 | 14-12 RD2WR = 6cycles-1 = 101b | ||
1778 | |||
1779 | 11-10 RD2DEAC = 4cycle-1 = 11b | ||
1780 | 9 RD2RD = 2cycle-1 = 1b | ||
1781 | 8-7 THZP = 3cycle-1 = 10b | ||
1782 | 6-5 TWR = 2cycle-1 = 01b (tWR = 17ns) | ||
1783 | 4 TRRD = 2cycle = 0b (tRRD = 14ns) | ||
1784 | 3-1 TRAS = 5cycle-1 = 100b (Tras=42ns) | ||
1785 | 1 CAS latency = 3cyc = 1b | ||
1786 | (for Micron 2M32-7 operating at 100MHz) | ||
1787 | */ | ||
1860 | boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT, | 1788 | boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT, |
1861 | 0x001BDF29); | 1789 | 0x001BDF29); |
1790 | |||
1791 | /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank) | ||
1792 | 31 - 0b - | ||
1793 | 30 SDBSZ 1b 4 bank | ||
1794 | 29..28 SDRSZ 00b 11 row address pins | ||
1795 | |||
1796 | 27..26 SDCSZ 01b 8 column address pins | ||
1797 | 25 RFEN 1b refersh enabled | ||
1798 | 24 INIT 1b init SDRAM! | ||
1799 | |||
1800 | 23..20 TRCD 0001b (Trcd/Tcyc)-1 = (20/10)-1 = 1 | ||
1801 | |||
1802 | 19..16 TRP 0001b (Trp/Tcyc)-1 = (20/10)-1 = 1 | ||
1803 | |||
1804 | 15..12 TRC 0110b (Trc/Tcyc)-1 = (70/10)-1 = 6 | ||
1805 | |||
1806 | 11..0 - 0000b 0000b 0000b | ||
1807 | */ | ||
1862 | boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL, | 1808 | boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL, |
1863 | 0x47117000); | 1809 | 0x47116000); |
1810 | |||
1811 | /* SDRAM refresh timing | ||
1812 | Need 4,096 refresh cycles every 64ms = 15.625us = 1562cycles of 100MHz = 0x61A | ||
1813 | */ | ||
1864 | boot_loader_write_mem32(pao, dsp_index, | 1814 | boot_loader_write_mem32(pao, dsp_index, |
1865 | C6713_EMIF_SDRAMTIMING, 0x00000410); | 1815 | C6713_EMIF_SDRAMTIMING, 0x00000410); |
1866 | 1816 | ||
1867 | hpios_delay_micro_seconds(1000); | 1817 | hpios_delay_micro_seconds(1000); |
1868 | } else if (dsp_index == 2) { | 1818 | } else if (dsp_index == 2) { |
1869 | /* DSP 2 is a C6713 */ | 1819 | /* DSP 2 is a C6713 */ |
1820 | } | ||
1870 | 1821 | ||
1871 | } else | 1822 | return 0; |
1872 | err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX); | ||
1873 | return err; | ||
1874 | } | 1823 | } |
1875 | 1824 | ||
1876 | static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, | 1825 | static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, |
@@ -1896,7 +1845,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, | |||
1896 | test_addr); | 1845 | test_addr); |
1897 | if (data != test_data) { | 1846 | if (data != test_data) { |
1898 | HPI_DEBUG_LOG(VERBOSE, | 1847 | HPI_DEBUG_LOG(VERBOSE, |
1899 | "memtest error details " | 1848 | "Memtest error details " |
1900 | "%08x %08x %08x %i\n", test_addr, | 1849 | "%08x %08x %08x %i\n", test_addr, |
1901 | test_data, data, dsp_index); | 1850 | test_data, data, dsp_index); |
1902 | return 1; /* error */ | 1851 | return 1; /* error */ |
@@ -1916,7 +1865,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, | |||
1916 | data = boot_loader_read_mem32(pao, dsp_index, test_addr); | 1865 | data = boot_loader_read_mem32(pao, dsp_index, test_addr); |
1917 | if (data != test_data) { | 1866 | if (data != test_data) { |
1918 | HPI_DEBUG_LOG(VERBOSE, | 1867 | HPI_DEBUG_LOG(VERBOSE, |
1919 | "memtest error details " | 1868 | "Memtest error details " |
1920 | "%08x %08x %08x %i\n", test_addr, test_data, | 1869 | "%08x %08x %08x %i\n", test_addr, test_data, |
1921 | data, dsp_index); | 1870 | data, dsp_index); |
1922 | return 1; /* error */ | 1871 | return 1; /* error */ |
@@ -1946,8 +1895,8 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao, | |||
1946 | /* 64K data mem */ | 1895 | /* 64K data mem */ |
1947 | err = boot_loader_test_memory(pao, dsp_index, | 1896 | err = boot_loader_test_memory(pao, dsp_index, |
1948 | 0x80000000, 0x10000); | 1897 | 0x80000000, 0x10000); |
1949 | } else if ((dsp_index == 1) || (dsp_index == 2)) { | 1898 | } else if (dsp_index == 1) { |
1950 | /* DSP 1&2 are a C6713 */ | 1899 | /* DSP 1 is a C6713 */ |
1951 | /* 192K internal mem */ | 1900 | /* 192K internal mem */ |
1952 | err = boot_loader_test_memory(pao, dsp_index, 0x00000000, | 1901 | err = boot_loader_test_memory(pao, dsp_index, 0x00000000, |
1953 | 0x30000); | 1902 | 0x30000); |
@@ -1955,11 +1904,10 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao, | |||
1955 | /* 64K internal mem / L2 cache */ | 1904 | /* 64K internal mem / L2 cache */ |
1956 | err = boot_loader_test_memory(pao, dsp_index, | 1905 | err = boot_loader_test_memory(pao, dsp_index, |
1957 | 0x00030000, 0x10000); | 1906 | 0x00030000, 0x10000); |
1958 | } else | 1907 | } |
1959 | return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX); | ||
1960 | 1908 | ||
1961 | if (err) | 1909 | if (err) |
1962 | return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM); | 1910 | return HPI6205_ERROR_DSP_INTMEM; |
1963 | else | 1911 | else |
1964 | return 0; | 1912 | return 0; |
1965 | } | 1913 | } |
@@ -1972,24 +1920,23 @@ static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao, | |||
1972 | 1920 | ||
1973 | if (dsp_index == 0) { | 1921 | if (dsp_index == 0) { |
1974 | /* only test for SDRAM if an ASI5000 card */ | 1922 | /* only test for SDRAM if an ASI5000 card */ |
1975 | if (pao->pci.subsys_device_id == 0x5000) { | 1923 | if (pao->pci.pci_dev->subsystem_device == 0x5000) { |
1976 | /* DSP 0 is always C6205 */ | 1924 | /* DSP 0 is always C6205 */ |
1977 | dRAM_start_address = 0x00400000; | 1925 | dRAM_start_address = 0x00400000; |
1978 | dRAM_size = 0x200000; | 1926 | dRAM_size = 0x200000; |
1979 | /*dwDRAMinc=1024; */ | 1927 | /*dwDRAMinc=1024; */ |
1980 | } else | 1928 | } else |
1981 | return 0; | 1929 | return 0; |
1982 | } else if ((dsp_index == 1) || (dsp_index == 2)) { | 1930 | } else if (dsp_index == 1) { |
1983 | /* DSP 1 is a C6713 */ | 1931 | /* DSP 1 is a C6713 */ |
1984 | dRAM_start_address = 0x80000000; | 1932 | dRAM_start_address = 0x80000000; |
1985 | dRAM_size = 0x200000; | 1933 | dRAM_size = 0x200000; |
1986 | /*dwDRAMinc=1024; */ | 1934 | /*dwDRAMinc=1024; */ |
1987 | } else | 1935 | } |
1988 | return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX); | ||
1989 | 1936 | ||
1990 | if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address, | 1937 | if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address, |
1991 | dRAM_size)) | 1938 | dRAM_size)) |
1992 | return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM); | 1939 | return HPI6205_ERROR_DSP_EXTMEM; |
1993 | return 0; | 1940 | return 0; |
1994 | } | 1941 | } |
1995 | 1942 | ||
@@ -1998,28 +1945,25 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index) | |||
1998 | u32 data = 0; | 1945 | u32 data = 0; |
1999 | if (dsp_index == 0) { | 1946 | if (dsp_index == 0) { |
2000 | /* only test for DSP0 PLD on ASI5000 card */ | 1947 | /* only test for DSP0 PLD on ASI5000 card */ |
2001 | if (pao->pci.subsys_device_id == 0x5000) { | 1948 | if (pao->pci.pci_dev->subsystem_device == 0x5000) { |
2002 | /* PLD is located at CE3=0x03000000 */ | 1949 | /* PLD is located at CE3=0x03000000 */ |
2003 | data = boot_loader_read_mem32(pao, dsp_index, | 1950 | data = boot_loader_read_mem32(pao, dsp_index, |
2004 | 0x03000008); | 1951 | 0x03000008); |
2005 | if ((data & 0xF) != 0x5) | 1952 | if ((data & 0xF) != 0x5) |
2006 | return hpi6205_error(dsp_index, | 1953 | return HPI6205_ERROR_DSP_PLD; |
2007 | HPI6205_ERROR_DSP_PLD); | ||
2008 | data = boot_loader_read_mem32(pao, dsp_index, | 1954 | data = boot_loader_read_mem32(pao, dsp_index, |
2009 | 0x0300000C); | 1955 | 0x0300000C); |
2010 | if ((data & 0xF) != 0xA) | 1956 | if ((data & 0xF) != 0xA) |
2011 | return hpi6205_error(dsp_index, | 1957 | return HPI6205_ERROR_DSP_PLD; |
2012 | HPI6205_ERROR_DSP_PLD); | ||
2013 | } | 1958 | } |
2014 | } else if (dsp_index == 1) { | 1959 | } else if (dsp_index == 1) { |
2015 | /* DSP 1 is a C6713 */ | 1960 | /* DSP 1 is a C6713 */ |
2016 | if (pao->pci.subsys_device_id == 0x8700) { | 1961 | if (pao->pci.pci_dev->subsystem_device == 0x8700) { |
2017 | /* PLD is located at CE1=0x90000000 */ | 1962 | /* PLD is located at CE1=0x90000000 */ |
2018 | data = boot_loader_read_mem32(pao, dsp_index, | 1963 | data = boot_loader_read_mem32(pao, dsp_index, |
2019 | 0x90000010); | 1964 | 0x90000010); |
2020 | if ((data & 0xFF) != 0xAA) | 1965 | if ((data & 0xFF) != 0xAA) |
2021 | return hpi6205_error(dsp_index, | 1966 | return HPI6205_ERROR_DSP_PLD; |
2022 | HPI6205_ERROR_DSP_PLD); | ||
2023 | /* 8713 - LED on */ | 1967 | /* 8713 - LED on */ |
2024 | boot_loader_write_mem32(pao, dsp_index, 0x90000000, | 1968 | boot_loader_write_mem32(pao, dsp_index, 0x90000000, |
2025 | 0x02); | 1969 | 0x02); |
@@ -2037,14 +1981,11 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data, | |||
2037 | struct hpi_hw_obj *phw = pao->priv; | 1981 | struct hpi_hw_obj *phw = pao->priv; |
2038 | u32 data_transferred = 0; | 1982 | u32 data_transferred = 0; |
2039 | u16 err = 0; | 1983 | u16 err = 0; |
2040 | #ifndef HPI6205_NO_HSR_POLL | ||
2041 | u32 time_out; | ||
2042 | #endif | ||
2043 | u32 temp2; | 1984 | u32 temp2; |
2044 | struct bus_master_interface *interface = phw->p_interface_buffer; | 1985 | struct bus_master_interface *interface = phw->p_interface_buffer; |
2045 | 1986 | ||
2046 | if (!p_data) | 1987 | if (!p_data) |
2047 | return HPI_ERROR_INVALID_DATA_TRANSFER; | 1988 | return HPI_ERROR_INVALID_DATA_POINTER; |
2048 | 1989 | ||
2049 | data_size &= ~3L; /* round data_size down to nearest 4 bytes */ | 1990 | data_size &= ~3L; /* round data_size down to nearest 4 bytes */ |
2050 | 1991 | ||
@@ -2064,14 +2005,10 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data, | |||
2064 | 2005 | ||
2065 | interface->transfer_size_in_bytes = this_copy; | 2006 | interface->transfer_size_in_bytes = this_copy; |
2066 | 2007 | ||
2067 | #ifdef HPI6205_NO_HSR_POLL | ||
2068 | /* DSP must change this back to nOperation */ | 2008 | /* DSP must change this back to nOperation */ |
2069 | interface->dsp_ack = H620_HIF_IDLE; | 2009 | interface->dsp_ack = H620_HIF_IDLE; |
2070 | #endif | ||
2071 | |||
2072 | send_dsp_command(phw, operation); | 2010 | send_dsp_command(phw, operation); |
2073 | 2011 | ||
2074 | #ifdef HPI6205_NO_HSR_POLL | ||
2075 | temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT); | 2012 | temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT); |
2076 | HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n", | 2013 | HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n", |
2077 | HPI6205_TIMEOUT - temp2, this_copy); | 2014 | HPI6205_TIMEOUT - temp2, this_copy); |
@@ -2079,45 +2016,11 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data, | |||
2079 | if (!temp2) { | 2016 | if (!temp2) { |
2080 | /* timed out */ | 2017 | /* timed out */ |
2081 | HPI_DEBUG_LOG(ERROR, | 2018 | HPI_DEBUG_LOG(ERROR, |
2082 | "timed out waiting for " "state %d got %d\n", | 2019 | "Timed out waiting for " "state %d got %d\n", |
2083 | operation, interface->dsp_ack); | 2020 | operation, interface->dsp_ack); |
2084 | 2021 | ||
2085 | break; | 2022 | break; |
2086 | } | 2023 | } |
2087 | #else | ||
2088 | /* spin waiting on the result */ | ||
2089 | time_out = HPI6205_TIMEOUT; | ||
2090 | temp2 = 0; | ||
2091 | while ((temp2 == 0) && time_out--) { | ||
2092 | /* give 16k bus mastering transfer time to happen */ | ||
2093 | /*(16k / 132Mbytes/s = 122usec) */ | ||
2094 | hpios_delay_micro_seconds(20); | ||
2095 | temp2 = ioread32(phw->prHSR); | ||
2096 | temp2 &= C6205_HSR_INTSRC; | ||
2097 | } | ||
2098 | HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n", | ||
2099 | HPI6205_TIMEOUT - time_out, this_copy); | ||
2100 | if (temp2 == C6205_HSR_INTSRC) { | ||
2101 | HPI_DEBUG_LOG(VERBOSE, | ||
2102 | "interrupt from HIF <data> OK\n"); | ||
2103 | /* | ||
2104 | if(interface->dwDspAck != nOperation) { | ||
2105 | HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d, | ||
2106 | expected %d \n", | ||
2107 | interface->dwDspAck,nOperation); | ||
2108 | } | ||
2109 | */ | ||
2110 | } | ||
2111 | /* need to handle this differently... */ | ||
2112 | else { | ||
2113 | HPI_DEBUG_LOG(ERROR, | ||
2114 | "interrupt from HIF <data> BAD\n"); | ||
2115 | err = HPI_ERROR_DSP_HARDWARE; | ||
2116 | } | ||
2117 | |||
2118 | /* reset the interrupt from the DSP */ | ||
2119 | iowrite32(C6205_HSR_INTSRC, phw->prHSR); | ||
2120 | #endif | ||
2121 | if (operation == H620_HIF_GET_DATA) | 2024 | if (operation == H620_HIF_GET_DATA) |
2122 | memcpy(&p_data[data_transferred], | 2025 | memcpy(&p_data[data_transferred], |
2123 | (void *)&interface->u.b_data[0], this_copy); | 2026 | (void *)&interface->u.b_data[0], this_copy); |
@@ -2174,31 +2077,39 @@ static unsigned int message_count; | |||
2174 | static u16 message_response_sequence(struct hpi_adapter_obj *pao, | 2077 | static u16 message_response_sequence(struct hpi_adapter_obj *pao, |
2175 | struct hpi_message *phm, struct hpi_response *phr) | 2078 | struct hpi_message *phm, struct hpi_response *phr) |
2176 | { | 2079 | { |
2177 | #ifndef HPI6205_NO_HSR_POLL | ||
2178 | u32 temp2; | ||
2179 | #endif | ||
2180 | u32 time_out, time_out2; | 2080 | u32 time_out, time_out2; |
2181 | struct hpi_hw_obj *phw = pao->priv; | 2081 | struct hpi_hw_obj *phw = pao->priv; |
2182 | struct bus_master_interface *interface = phw->p_interface_buffer; | 2082 | struct bus_master_interface *interface = phw->p_interface_buffer; |
2183 | u16 err = 0; | 2083 | u16 err = 0; |
2184 | 2084 | ||
2185 | message_count++; | 2085 | message_count++; |
2086 | if (phm->size > sizeof(interface->u)) { | ||
2087 | phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL; | ||
2088 | phr->specific_error = sizeof(interface->u); | ||
2089 | phr->size = sizeof(struct hpi_response_header); | ||
2090 | HPI_DEBUG_LOG(ERROR, | ||
2091 | "message len %d too big for buffer %zd \n", phm->size, | ||
2092 | sizeof(interface->u)); | ||
2093 | return 0; | ||
2094 | } | ||
2095 | |||
2186 | /* Assume buffer of type struct bus_master_interface | 2096 | /* Assume buffer of type struct bus_master_interface |
2187 | is allocated "noncacheable" */ | 2097 | is allocated "noncacheable" */ |
2188 | 2098 | ||
2189 | if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { | 2099 | if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { |
2190 | HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n"); | 2100 | HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n"); |
2191 | return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT); | 2101 | return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT; |
2192 | } | 2102 | } |
2193 | interface->u.message_buffer = *phm; | 2103 | |
2104 | memcpy(&interface->u.message_buffer, phm, phm->size); | ||
2194 | /* signal we want a response */ | 2105 | /* signal we want a response */ |
2195 | send_dsp_command(phw, H620_HIF_GET_RESP); | 2106 | send_dsp_command(phw, H620_HIF_GET_RESP); |
2196 | 2107 | ||
2197 | time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT); | 2108 | time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT); |
2198 | 2109 | ||
2199 | if (time_out2 == 0) { | 2110 | if (!time_out2) { |
2200 | HPI_DEBUG_LOG(ERROR, | 2111 | HPI_DEBUG_LOG(ERROR, |
2201 | "(%u) timed out waiting for " "GET_RESP state [%x]\n", | 2112 | "(%u) Timed out waiting for " "GET_RESP state [%x]\n", |
2202 | message_count, interface->dsp_ack); | 2113 | message_count, interface->dsp_ack); |
2203 | } else { | 2114 | } else { |
2204 | HPI_DEBUG_LOG(VERBOSE, | 2115 | HPI_DEBUG_LOG(VERBOSE, |
@@ -2208,58 +2119,38 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao, | |||
2208 | /* spin waiting on HIF interrupt flag (end of msg process) */ | 2119 | /* spin waiting on HIF interrupt flag (end of msg process) */ |
2209 | time_out = HPI6205_TIMEOUT; | 2120 | time_out = HPI6205_TIMEOUT; |
2210 | 2121 | ||
2211 | #ifndef HPI6205_NO_HSR_POLL | 2122 | /* read the result */ |
2212 | temp2 = 0; | 2123 | if (time_out) { |
2213 | while ((temp2 == 0) && --time_out) { | 2124 | if (interface->u.response_buffer.size <= phr->size) |
2214 | temp2 = ioread32(phw->prHSR); | 2125 | memcpy(phr, &interface->u.response_buffer, |
2215 | temp2 &= C6205_HSR_INTSRC; | 2126 | interface->u.response_buffer.size); |
2216 | hpios_delay_micro_seconds(1); | 2127 | else { |
2217 | } | 2128 | HPI_DEBUG_LOG(ERROR, |
2218 | if (temp2 == C6205_HSR_INTSRC) { | 2129 | "response len %d too big for buffer %d\n", |
2219 | rmb(); /* ensure we see latest value for dsp_ack */ | 2130 | interface->u.response_buffer.size, phr->size); |
2220 | if ((interface->dsp_ack != H620_HIF_GET_RESP)) { | 2131 | memcpy(phr, &interface->u.response_buffer, |
2221 | HPI_DEBUG_LOG(DEBUG, | 2132 | sizeof(struct hpi_response_header)); |
2222 | "(%u)interface->dsp_ack(0x%x) != " | 2133 | phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL; |
2223 | "H620_HIF_GET_RESP, t=%u\n", message_count, | 2134 | phr->specific_error = |
2224 | interface->dsp_ack, | 2135 | interface->u.response_buffer.size; |
2225 | HPI6205_TIMEOUT - time_out); | 2136 | phr->size = sizeof(struct hpi_response_header); |
2226 | } else { | ||
2227 | HPI_DEBUG_LOG(VERBOSE, | ||
2228 | "(%u)int with GET_RESP after %u\n", | ||
2229 | message_count, HPI6205_TIMEOUT - time_out); | ||
2230 | } | 2137 | } |
2231 | |||
2232 | } else { | ||
2233 | /* can we do anything else in response to the error ? */ | ||
2234 | HPI_DEBUG_LOG(ERROR, | ||
2235 | "interrupt from HIF module BAD (function %x)\n", | ||
2236 | phm->function); | ||
2237 | } | 2138 | } |
2238 | |||
2239 | /* reset the interrupt from the DSP */ | ||
2240 | iowrite32(C6205_HSR_INTSRC, phw->prHSR); | ||
2241 | #endif | ||
2242 | |||
2243 | /* read the result */ | ||
2244 | if (time_out != 0) | ||
2245 | *phr = interface->u.response_buffer; | ||
2246 | |||
2247 | /* set interface back to idle */ | 2139 | /* set interface back to idle */ |
2248 | send_dsp_command(phw, H620_HIF_IDLE); | 2140 | send_dsp_command(phw, H620_HIF_IDLE); |
2249 | 2141 | ||
2250 | if ((time_out == 0) || (time_out2 == 0)) { | 2142 | if (!time_out || !time_out2) { |
2251 | HPI_DEBUG_LOG(DEBUG, "something timed out!\n"); | 2143 | HPI_DEBUG_LOG(DEBUG, "something timed out!\n"); |
2252 | return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT); | 2144 | return HPI6205_ERROR_MSG_RESP_TIMEOUT; |
2253 | } | 2145 | } |
2254 | /* special case for adapter close - */ | 2146 | /* special case for adapter close - */ |
2255 | /* wait for the DSP to indicate it is idle */ | 2147 | /* wait for the DSP to indicate it is idle */ |
2256 | if (phm->function == HPI_ADAPTER_CLOSE) { | 2148 | if (phm->function == HPI_ADAPTER_CLOSE) { |
2257 | if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { | 2149 | if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { |
2258 | HPI_DEBUG_LOG(DEBUG, | 2150 | HPI_DEBUG_LOG(DEBUG, |
2259 | "timeout waiting for idle " | 2151 | "Timeout waiting for idle " |
2260 | "(on adapter_close)\n"); | 2152 | "(on adapter_close)\n"); |
2261 | return hpi6205_error(0, | 2153 | return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT; |
2262 | HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT); | ||
2263 | } | 2154 | } |
2264 | } | 2155 | } |
2265 | err = hpi_validate_response(phm, phr); | 2156 | err = hpi_validate_response(phm, phr); |
@@ -2279,7 +2170,13 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
2279 | /* maybe an error response */ | 2170 | /* maybe an error response */ |
2280 | if (err) { | 2171 | if (err) { |
2281 | /* something failed in the HPI/DSP interface */ | 2172 | /* something failed in the HPI/DSP interface */ |
2282 | phr->error = err; | 2173 | if (err >= HPI_ERROR_BACKEND_BASE) { |
2174 | phr->error = HPI_ERROR_DSP_COMMUNICATION; | ||
2175 | phr->specific_error = err; | ||
2176 | } else { | ||
2177 | phr->error = err; | ||
2178 | } | ||
2179 | |||
2283 | pao->dsp_crashed++; | 2180 | pao->dsp_crashed++; |
2284 | 2181 | ||
2285 | /* just the header of the response is valid */ | 2182 | /* just the header of the response is valid */ |