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