diff options
Diffstat (limited to 'sound/pci/asihpi/hpi6205.c')
| -rw-r--r-- | sound/pci/asihpi/hpi6205.c | 761 |
1 files changed, 319 insertions, 442 deletions
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 2672f6591ce..4f2873880b1 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -38,27 +38,29 @@ /*****************************************************************************/ /* HPI6205 specific error codes */ -#define HPI6205_ERROR_BASE 1000 -/*#define HPI6205_ERROR_MEM_ALLOC 1001 */ -#define HPI6205_ERROR_6205_NO_IRQ 1002 -#define HPI6205_ERROR_6205_INIT_FAILED 1003 -/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */ -#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005 -#define HPI6205_ERROR_6205_REG 1006 -#define HPI6205_ERROR_6205_DSPPAGE 1007 -#define HPI6205_ERROR_BAD_DSPINDEX 1008 -#define HPI6205_ERROR_C6713_HPIC 1009 -#define HPI6205_ERROR_C6713_HPIA 1010 -#define HPI6205_ERROR_C6713_PLL 1011 -#define HPI6205_ERROR_DSP_INTMEM 1012 -#define HPI6205_ERROR_DSP_EXTMEM 1013 -#define HPI6205_ERROR_DSP_PLD 1014 +#define HPI6205_ERROR_BASE 1000 /* not actually used anywhere */ + +/* operational/messaging errors */ #define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015 #define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016 -#define HPI6205_ERROR_6205_EEPROM 1017 -#define HPI6205_ERROR_DSP_EMIF 1018 -#define hpi6205_error(dsp_index, err) (err) +/* initialization/bootload errors */ +#define HPI6205_ERROR_6205_NO_IRQ 1002 +#define HPI6205_ERROR_6205_INIT_FAILED 1003 +#define HPI6205_ERROR_6205_REG 1006 +#define HPI6205_ERROR_6205_DSPPAGE 1007 +#define HPI6205_ERROR_C6713_HPIC 1009 +#define HPI6205_ERROR_C6713_HPIA 1010 +#define HPI6205_ERROR_C6713_PLL 1011 +#define HPI6205_ERROR_DSP_INTMEM 1012 +#define HPI6205_ERROR_DSP_EXTMEM 1013 +#define HPI6205_ERROR_DSP_PLD 1014 +#define HPI6205_ERROR_6205_EEPROM 1017 +#define HPI6205_ERROR_DSP_EMIF1 1018 +#define HPI6205_ERROR_DSP_EMIF2 1019 +#define HPI6205_ERROR_DSP_EMIF3 1020 +#define HPI6205_ERROR_DSP_EMIF4 1021 + /*****************************************************************************/ /* for C6205 PCI i/f */ /* Host Status Register (HSR) bitfields */ @@ -128,9 +130,6 @@ struct hpi_hw_obj { u32 outstream_host_buffer_size[HPI_MAX_STREAMS]; struct consistent_dma_area h_control_cache; - struct consistent_dma_area h_async_event_buffer; -/* struct hpi_control_cache_single *pControlCache; */ - struct hpi_async_event *p_async_event_buffer; struct hpi_control_cache *p_cache; }; @@ -156,8 +155,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, static void subsys_create_adapter(struct hpi_message *phm, struct hpi_response *phr); -static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr); +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr); static u16 create_adapter_obj(struct hpi_adapter_obj *pao, u32 *pos_error_code); @@ -208,8 +207,8 @@ static void instream_start(struct hpi_adapter_obj *pao, static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index, u32 address); -static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, - u32 address, u32 data); +static void boot_loader_write_mem32(struct hpi_adapter_obj *pao, + int dsp_index, u32 address, u32 data); static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index); @@ -227,25 +226,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index); /*****************************************************************************/ -static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) +static void subsys_message(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr) { - switch (phm->function) { - case HPI_SUBSYS_OPEN: - case HPI_SUBSYS_CLOSE: - case HPI_SUBSYS_GET_INFO: - case HPI_SUBSYS_DRIVER_UNLOAD: - case HPI_SUBSYS_DRIVER_LOAD: - case HPI_SUBSYS_FIND_ADAPTERS: - /* messages that should not get here */ - phr->error = HPI_ERROR_UNIMPLEMENTED; - break; case HPI_SUBSYS_CREATE_ADAPTER: subsys_create_adapter(phm, phr); break; - case HPI_SUBSYS_DELETE_ADAPTER: - subsys_delete_adapter(phm, phr); - break; default: phr->error = HPI_ERROR_INVALID_FUNC; break; @@ -257,15 +244,22 @@ static void control_message(struct hpi_adapter_obj *pao, { struct hpi_hw_obj *phw = pao->priv; + u16 pending_cache_error = 0; switch (phm->function) { case HPI_CONTROL_GET_STATE: if (pao->has_control_cache) { - rmb(); /* make sure we see updates DM_aed from DSP */ - if (hpi_check_control_cache(phw->p_cache, phm, phr)) + rmb(); /* make sure we see updates DMAed from DSP */ + if (hpi_check_control_cache(phw->p_cache, phm, phr)) { break; + } else if (phm->u.c.attribute == HPI_METER_PEAK) { + pending_cache_error = + HPI_ERROR_CONTROL_CACHING; + } } hw_message(pao, phm, phr); + if (pending_cache_error && !phr->error) + phr->error = pending_cache_error; break; case HPI_CONTROL_GET_INFO: hw_message(pao, phm, phr); @@ -273,7 +267,8 @@ static void control_message(struct hpi_adapter_obj *pao, case HPI_CONTROL_SET_STATE: hw_message(pao, phm, phr); if (pao->has_control_cache) - hpi_sync_control_cache(phw->p_cache, phm, phr); + hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm, + phr); break; default: phr->error = HPI_ERROR_INVALID_FUNC; @@ -285,6 +280,10 @@ static void adapter_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr) { switch (phm->function) { + case HPI_ADAPTER_DELETE: + adapter_delete(pao, phm, phr); + break; + default: hw_message(pao, phm, phr); break; @@ -296,9 +295,9 @@ static void outstream_message(struct hpi_adapter_obj *pao, { if (phm->obj_index >= HPI_MAX_STREAMS) { - phr->error = HPI_ERROR_INVALID_STREAM; + phr->error = HPI_ERROR_INVALID_OBJ_INDEX; HPI_DEBUG_LOG(WARNING, - "message referencing invalid stream %d " + "Message referencing invalid stream %d " "on adapter index %d\n", phm->obj_index, phm->adapter_index); return; @@ -340,9 +339,9 @@ static void instream_message(struct hpi_adapter_obj *pao, { if (phm->obj_index >= HPI_MAX_STREAMS) { - phr->error = HPI_ERROR_INVALID_STREAM; + phr->error = HPI_ERROR_INVALID_OBJ_INDEX; HPI_DEBUG_LOG(WARNING, - "message referencing invalid stream %d " + "Message referencing invalid stream %d " "on adapter index %d\n", phm->obj_index, phm->adapter_index); return; @@ -377,59 +376,36 @@ static void instream_message(struct hpi_adapter_obj *pao, /** Entry point to this HPI backend * All calls to the HPI start here */ -void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) +static +void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm, + struct hpi_response *phr) { - struct hpi_adapter_obj *pao = NULL; - - /* subsytem messages are processed by every HPI. - * All other messages are ignored unless the adapter index matches - * an adapter in the HPI - */ - HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object, - phm->function); - - /* if Dsp has crashed then do not communicate with it any more */ - if (phm->object != HPI_OBJ_SUBSYSTEM) { - pao = hpi_find_adapter(phm->adapter_index); - if (!pao) { - HPI_DEBUG_LOG(DEBUG, - " %d,%d refused, for another HPI?\n", - phm->object, phm->function); - return; - } - - if ((pao->dsp_crashed >= 10) - && (phm->function != HPI_ADAPTER_DEBUG_READ)) { - /* allow last resort debug read even after crash */ - hpi_init_response(phr, phm->object, phm->function, - HPI_ERROR_DSP_HARDWARE); - HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", - phm->object, phm->function); - return; - } + if (pao && (pao->dsp_crashed >= 10) + && (phm->function != HPI_ADAPTER_DEBUG_READ)) { + /* allow last resort debug read even after crash */ + hpi_init_response(phr, phm->object, phm->function, + HPI_ERROR_DSP_HARDWARE); + HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object, + phm->function); + return; } /* Init default response */ if (phm->function != HPI_SUBSYS_CREATE_ADAPTER) - hpi_init_response(phr, phm->object, phm->function, - HPI_ERROR_PROCESSING_MESSAGE); + phr->error = HPI_ERROR_PROCESSING_MESSAGE; HPI_DEBUG_LOG(VERBOSE, "start of switch\n"); switch (phm->type) { - case HPI_TYPE_MESSAGE: + case HPI_TYPE_REQUEST: switch (phm->object) { case HPI_OBJ_SUBSYSTEM: - subsys_message(phm, phr); + subsys_message(pao, phm, phr); break; case HPI_OBJ_ADAPTER: - phr->size = - sizeof(struct hpi_response_header) + - sizeof(struct hpi_adapter_res); adapter_message(pao, phm, phr); break; - case HPI_OBJ_CONTROLEX: case HPI_OBJ_CONTROL: control_message(pao, phm, phr); break; @@ -454,6 +430,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) } } +void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) +{ + struct hpi_adapter_obj *pao = NULL; + + if (phm->object != HPI_OBJ_SUBSYSTEM) { + /* normal messages must have valid adapter index */ + pao = hpi_find_adapter(phm->adapter_index); + } else { + /* subsys messages don't address an adapter */ + _HPI_6205(NULL, phm, phr); + return; + } + + if (pao) + _HPI_6205(pao, phm, phr); + else + hpi_init_response(phr, phm->object, phm->function, + HPI_ERROR_BAD_ADAPTER_NUMBER); +} + /*****************************************************************************/ /* SUBSYSTEM */ @@ -474,51 +470,43 @@ static void subsys_create_adapter(struct hpi_message *phm, memset(&ao, 0, sizeof(ao)); - /* this HPI only creates adapters for TI/PCI devices */ - if (phm->u.s.resource.bus_type != HPI_BUS_PCI) - return; - if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI) - return; - if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205) - return; - ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); if (!ao.priv) { - HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); + HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n"); phr->error = HPI_ERROR_MEMORY_ALLOC; return; } ao.pci = *phm->u.s.resource.r.pci; err = create_adapter_obj(&ao, &os_error_code); - if (!err) - err = hpi_add_adapter(&ao); if (err) { - phr->u.s.data = os_error_code; delete_adapter_obj(&ao); - phr->error = err; + if (err >= HPI_ERROR_BACKEND_BASE) { + phr->error = HPI_ERROR_DSP_BOOTLOAD; + phr->specific_error = err; + } else { + phr->error = err; + } + phr->u.s.data = os_error_code; return; } - phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; + phr->u.s.adapter_type = ao.type; phr->u.s.adapter_index = ao.index; - phr->u.s.num_adapters++; phr->error = 0; } /** delete an adapter - required by WDM driver */ -static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr) +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr) { - struct hpi_adapter_obj *pao; struct hpi_hw_obj *phw; - pao = hpi_find_adapter(phm->adapter_index); if (!pao) { phr->error = HPI_ERROR_INVALID_OBJ_INDEX; return; } - phw = (struct hpi_hw_obj *)pao->priv; + phw = pao->priv; /* reset adapter h/w */ /* Reset C6713 #1 */ boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0); @@ -526,6 +514,7 @@ static void subsys_delete_adapter(struct hpi_message *phm, iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR); delete_adapter_obj(pao); + hpi_delete_adapter(pao); phr->error = 0; } @@ -538,10 +527,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, struct hpi_hw_obj *phw = pao->priv; struct bus_master_interface *interface; u32 phys_addr; -#ifndef HPI6205_NO_HSR_POLL - u32 time_out = HPI6205_TIMEOUT; - u32 temp1; -#endif int i; u16 err; @@ -566,7 +551,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, if (hpios_locked_mem_alloc(&phw->h_locked_mem, sizeof(struct bus_master_interface), - pao->pci.p_os_data)) + pao->pci.pci_dev)) phw->p_interface_buffer = NULL; else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem, (void *)&phw->p_interface_buffer)) @@ -582,58 +567,39 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, } err = adapter_boot_load_dsp(pao, pos_error_code); - if (err) + if (err) { + HPI_DEBUG_LOG(ERROR, "DSP code load failed\n"); /* no need to clean up as SubSysCreateAdapter */ /* calls DeleteAdapter on error. */ return err; - + } HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); /* allow boot load even if mem alloc wont work */ if (!phw->p_interface_buffer) - return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC); + return HPI_ERROR_MEMORY_ALLOC; interface = phw->p_interface_buffer; -#ifndef HPI6205_NO_HSR_POLL - /* wait for first interrupt indicating the DSP init is done */ - time_out = HPI6205_TIMEOUT * 10; - temp1 = 0; - while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out) - temp1 = ioread32(phw->prHSR); - - if (temp1 & C6205_HSR_INTSRC) - HPI_DEBUG_LOG(INFO, - "interrupt confirming DSP code running OK\n"); - else { - HPI_DEBUG_LOG(ERROR, - "timed out waiting for interrupt " - "confirming DSP code running\n"); - return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ); - } - - /* reset the interrupt */ - iowrite32(C6205_HSR_INTSRC, phw->prHSR); -#endif - /* make sure the DSP has started ok */ if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) { HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n"); - return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED); + return HPI6205_ERROR_6205_INIT_FAILED; } /* Note that *pao, *phw are zeroed after allocation, * so pointers and flags are NULL by default. * Allocate bus mastering control cache buffer and tell the DSP about it */ if (interface->control_cache.number_of_controls) { - void *p_control_cache_virtual; + u8 *p_control_cache_virtual; err = hpios_locked_mem_alloc(&phw->h_control_cache, interface->control_cache.size_in_bytes, - pao->pci.p_os_data); + pao->pci.pci_dev); if (!err) err = hpios_locked_mem_get_virt_addr(&phw-> - h_control_cache, &p_control_cache_virtual); + h_control_cache, + (void *)&p_control_cache_virtual); if (!err) { memset(p_control_cache_virtual, 0, interface->control_cache.size_in_bytes); @@ -642,8 +608,8 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, hpi_alloc_control_cache(interface-> control_cache.number_of_controls, interface->control_cache.size_in_bytes, - (struct hpi_control_cache_info *) p_control_cache_virtual); + if (!phw->p_cache) err = HPI_ERROR_MEMORY_ALLOC; } @@ -662,96 +628,63 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, pao->has_control_cache = 0; } } - /* allocate bus mastering async buffer and tell the DSP about it */ - if (interface->async_buffer.b.size) { - err = hpios_locked_mem_alloc(&phw->h_async_event_buffer, - interface->async_buffer.b.size * - sizeof(struct hpi_async_event), pao->pci.p_os_data); - if (!err) - err = hpios_locked_mem_get_virt_addr - (&phw->h_async_event_buffer, (void *) - &phw->p_async_event_buffer); - if (!err) - memset((void *)phw->p_async_event_buffer, 0, - interface->async_buffer.b.size * - sizeof(struct hpi_async_event)); - if (!err) { - err = hpios_locked_mem_get_phys_addr - (&phw->h_async_event_buffer, &phys_addr); - interface->async_buffer.physical_address32 = - phys_addr; - } - if (err) { - if (hpios_locked_mem_valid(&phw-> - h_async_event_buffer)) { - hpios_locked_mem_free - (&phw->h_async_event_buffer); - phw->p_async_event_buffer = NULL; - } - } - } send_dsp_command(phw, H620_HIF_IDLE); { - struct hpi_message hM; - struct hpi_response hR; + struct hpi_message hm; + struct hpi_response hr; u32 max_streams; HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); - memset(&hM, 0, sizeof(hM)); - hM.type = HPI_TYPE_MESSAGE; - hM.size = sizeof(hM); - hM.object = HPI_OBJ_ADAPTER; - hM.function = HPI_ADAPTER_GET_INFO; - hM.adapter_index = 0; - memset(&hR, 0, sizeof(hR)); - hR.size = sizeof(hR); - - err = message_response_sequence(pao, &hM, &hR); + memset(&hm, 0, sizeof(hm)); + /* wAdapterIndex == version == 0 */ + hm.type = HPI_TYPE_REQUEST; + hm.size = sizeof(hm); + hm.object = HPI_OBJ_ADAPTER; + hm.function = HPI_ADAPTER_GET_INFO; + + memset(&hr, 0, sizeof(hr)); + hr.size = sizeof(hr); + + err = message_response_sequence(pao, &hm, &hr); if (err) { HPI_DEBUG_LOG(ERROR, "message transport error %d\n", err); return err; } - if (hR.error) - return hR.error; - - pao->adapter_type = hR.u.a.adapter_type; - pao->index = hR.u.a.adapter_index; + if (hr.error) + return hr.error; - max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams; + pao->type = hr.u.ax.info.adapter_type; + pao->index = hr.u.ax.info.adapter_index; - hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams, - 65536, pao->pci.p_os_data); + max_streams = + hr.u.ax.info.num_outstreams + + hr.u.ax.info.num_instreams; HPI_DEBUG_LOG(VERBOSE, "got adapter info type %x index %d serial %d\n", - hR.u.a.adapter_type, hR.u.a.adapter_index, - hR.u.a.serial_number); + hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index, + hr.u.ax.info.serial_number); } - pao->open = 0; /* upon creation the adapter is closed */ + if (phw->p_cache) + phw->p_cache->adap_idx = pao->index; HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); - return 0; + + return hpi_add_adapter(pao); } /** Free memory areas allocated by adapter - * this routine is called from SubSysDeleteAdapter, + * this routine is called from AdapterDelete, * and SubSysCreateAdapter if duplicate index */ static void delete_adapter_obj(struct hpi_adapter_obj *pao) { - struct hpi_hw_obj *phw; + struct hpi_hw_obj *phw = pao->priv; int i; - phw = pao->priv; - - if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) { - hpios_locked_mem_free(&phw->h_async_event_buffer); - phw->p_async_event_buffer = NULL; - } - if (hpios_locked_mem_valid(&phw->h_control_cache)) { hpios_locked_mem_free(&phw->h_control_cache); hpi_free_control_cache(phw->p_cache); @@ -775,14 +708,13 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao) [i]); phw->outstream_host_buffer_size[i] = 0; } - - hpios_locked_mem_unprepare(pao->pci.p_os_data); - - hpi_delete_adapter(pao); kfree(phw); } /*****************************************************************************/ +/* Adapter functions */ + +/*****************************************************************************/ /* OutStream Host buffer functions */ /** Allocate or attach buffer for busmastering @@ -824,7 +756,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, err = hpios_locked_mem_alloc(&phw->outstream_host_buffers [phm->obj_index], phm->u.d.u.buffer.buffer_size, - pao->pci.p_os_data); + pao->pci.pci_dev); if (err) { phr->error = HPI_ERROR_INVALID_DATASIZE; @@ -861,7 +793,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. buffer_size - 1)) { HPI_DEBUG_LOG(ERROR, - "buffer size must be 2^N not %d\n", + "Buffer size must be 2^N not %d\n", phm->u.d.u.buffer.buffer_size); phr->error = HPI_ERROR_INVALID_DATASIZE; return; @@ -872,9 +804,10 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, obj_index]; status->samples_processed = 0; status->stream_state = HPI_STATE_STOPPED; - status->dSP_index = 0; - status->host_index = status->dSP_index; + status->dsp_index = 0; + status->host_index = status->dsp_index; status->size_in_bytes = phm->u.d.u.buffer.buffer_size; + status->auxiliary_data_available = 0; hw_message(pao, phm, phr); @@ -946,7 +879,7 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao, static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status) { return status->size_in_bytes - (status->host_index - - status->dSP_index); + status->dsp_index); } static void outstream_write(struct hpi_adapter_obj *pao, @@ -966,51 +899,6 @@ static void outstream_write(struct hpi_adapter_obj *pao, hpi_init_response(phr, phm->object, phm->function, 0); status = &interface->outstream_host_buffer_status[phm->obj_index]; - if (phw->flag_outstream_just_reset[phm->obj_index]) { - /* First OutStremWrite() call following reset will write data to the - adapter's buffers, reducing delay before stream can start. The DSP - takes care of setting the stream data format using format information - embedded in phm. - */ - int partial_write = 0; - unsigned int original_size = 0; - - phw->flag_outstream_just_reset[phm->obj_index] = 0; - - /* Send the first buffer to the DSP the old way. */ - /* Limit size of first transfer - */ - /* expect that this will not usually be triggered. */ - if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) { - partial_write = 1; - original_size = phm->u.d.u.data.data_size; - phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA; - } - /* write it */ - phm->function = HPI_OSTREAM_WRITE; - hw_message(pao, phm, phr); - - if (phr->error) - return; - - /* update status information that the DSP would typically - * update (and will update next time the DSP - * buffer update task reads data from the host BBM buffer) - */ - status->auxiliary_data_available = phm->u.d.u.data.data_size; - status->host_index += phm->u.d.u.data.data_size; - status->dSP_index += phm->u.d.u.data.data_size; - - /* if we did a full write, we can return from here. */ - if (!partial_write) - return; - - /* tweak buffer parameters and let the rest of the */ - /* buffer land in internal BBM buffer */ - phm->u.d.u.data.data_size = - original_size - HPI6205_SIZEOF_DATA; - phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA; - } - space_available = outstream_get_space_available(status); if (space_available < phm->u.d.u.data.data_size) { phr->error = HPI_ERROR_INVALID_DATASIZE; @@ -1047,6 +935,24 @@ static void outstream_write(struct hpi_adapter_obj *pao, memcpy(p_bbm_data, p_app_data + l_first_write, phm->u.d.u.data.data_size - l_first_write); } + + /* + * This version relies on the DSP code triggering an OStream buffer + * update immediately following a SET_FORMAT call. The host has + * already written data into the BBM buffer, but the DSP won't know + * about it until dwHostIndex is adjusted. + */ + if (phw->flag_outstream_just_reset[phm->obj_index]) { + /* Format can only change after reset. Must tell DSP. */ + u16 function = phm->function; + phw->flag_outstream_just_reset[phm->obj_index] = 0; + phm->function = HPI_OSTREAM_SET_FORMAT; + hw_message(pao, phm, phr); /* send the format to the DSP */ + phm->function = function; + if (phr->error) + return; + } + status->host_index += phm->u.d.u.data.data_size; } @@ -1132,7 +1038,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao, err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm-> obj_index], phm->u.d.u.buffer.buffer_size, - pao->pci.p_os_data); + pao->pci.pci_dev); if (err) { phr->error = HPI_ERROR_INVALID_DATASIZE; @@ -1163,7 +1069,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao, if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. buffer_size - 1)) { HPI_DEBUG_LOG(ERROR, - "buffer size must be 2^N not %d\n", + "Buffer size must be 2^N not %d\n", phm->u.d.u.buffer.buffer_size); phr->error = HPI_ERROR_INVALID_DATASIZE; return; @@ -1175,11 +1081,13 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao, obj_index]; status->samples_processed = 0; status->stream_state = HPI_STATE_STOPPED; - status->dSP_index = 0; - status->host_index = status->dSP_index; + status->dsp_index = 0; + status->host_index = status->dsp_index; status->size_in_bytes = phm->u.d.u.buffer.buffer_size; + status->auxiliary_data_available = 0; hw_message(pao, phm, phr); + if (phr->error && hpios_locked_mem_valid(&phw-> instream_host_buffers[phm->obj_index])) { @@ -1255,7 +1163,7 @@ static void instream_start(struct hpi_adapter_obj *pao, static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status) { - return status->dSP_index - status->host_index; + return status->dsp_index - status->host_index; } static void instream_read(struct hpi_adapter_obj *pao, @@ -1344,33 +1252,37 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, struct hpi_hw_obj *phw = pao->priv; struct dsp_code dsp_code; u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD]; - u16 firmware_id = pao->pci.subsys_device_id; u32 temp; int dsp = 0, i = 0; u16 err = 0; boot_code_id[0] = HPI_ADAPTER_ASI(0x6205); - /* special cases where firmware_id != subsys ID */ - switch (firmware_id) { + boot_code_id[1] = pao->pci.pci_dev->subsystem_device; + boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(boot_code_id[1]); + + /* fix up cases where bootcode id[1] != subsys id */ + switch (boot_code_id[1]) { case HPI_ADAPTER_FAMILY_ASI(0x5000): - boot_code_id[0] = firmware_id; - firmware_id = 0; + boot_code_id[0] = boot_code_id[1]; + boot_code_id[1] = 0; break; case HPI_ADAPTER_FAMILY_ASI(0x5300): case HPI_ADAPTER_FAMILY_ASI(0x5400): case HPI_ADAPTER_FAMILY_ASI(0x6300): - firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400); + boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); break; + case HPI_ADAPTER_FAMILY_ASI(0x5500): case HPI_ADAPTER_FAMILY_ASI(0x5600): case HPI_ADAPTER_FAMILY_ASI(0x6500): - firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600); + boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); break; case HPI_ADAPTER_FAMILY_ASI(0x8800): - firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900); + boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x8900); + break; + default: break; } - boot_code_id[1] = firmware_id; /* reset DSP by writing a 1 to the WARMRESET bit */ temp = C6205_HDCR_WARMRESET; @@ -1381,7 +1293,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, temp = ioread32(phw->prHSR); if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) != C6205_HSR_EEREAD) - return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM); + return HPI6205_ERROR_6205_EEPROM; temp |= 0x04; /* disable PINTA interrupt */ iowrite32(temp, phw->prHSR); @@ -1389,27 +1301,27 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, /* check control register reports PCI boot mode */ temp = ioread32(phw->prHDCR); if (!(temp & C6205_HDCR_PCIBOOT)) - return hpi6205_error(0, HPI6205_ERROR_6205_REG); + return HPI6205_ERROR_6205_REG; - /* try writing a couple of numbers to the DSP page register */ + /* try writing a few numbers to the DSP page register */ /* and reading them back. */ - temp = 1; + temp = 3; iowrite32(temp, phw->prDSPP); if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) - return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); + return HPI6205_ERROR_6205_DSPPAGE; temp = 2; iowrite32(temp, phw->prDSPP); if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) - return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); - temp = 3; + return HPI6205_ERROR_6205_DSPPAGE; + temp = 1; iowrite32(temp, phw->prDSPP); if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) - return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); + return HPI6205_ERROR_6205_DSPPAGE; /* reset DSP page to the correct number */ temp = 0; iowrite32(temp, phw->prDSPP); if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) - return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); + return HPI6205_ERROR_6205_DSPPAGE; phw->dsp_page = 0; /* release 6713 from reset before 6205 is bootloaded. @@ -1455,9 +1367,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, return err; /* write the DSP code down into the DSPs memory */ - dsp_code.ps_dev = pao->pci.p_os_data; - err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code, - pos_error_code); + err = hpi_dsp_code_open(boot_code_id[dsp], pao->pci.pci_dev, + &dsp_code, pos_error_code); if (err) return err; @@ -1484,10 +1395,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, if (err) break; for (i = 0; i < (int)length; i++) { - err = boot_loader_write_mem32(pao, dsp, - address, *pcode); - if (err) - break; + boot_loader_write_mem32(pao, dsp, address, + *pcode); /* dummy read every 4 words */ /* for 6205 advisory 1.4.4 */ if (i % 4 == 0) @@ -1561,7 +1470,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, host_mailbox_address_on_dsp = 0x80000000; while ((physicalPC_iaddress != physicalPC_iaddress_verify) && time_out--) { - err = boot_loader_write_mem32(pao, 0, + boot_loader_write_mem32(pao, 0, host_mailbox_address_on_dsp, physicalPC_iaddress); physicalPC_iaddress_verify = @@ -1631,11 +1540,10 @@ static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index, return data; } -static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, - u32 address, u32 data) +static void boot_loader_write_mem32(struct hpi_adapter_obj *pao, + int dsp_index, u32 address, u32 data) { struct hpi_hw_obj *phw = pao->priv; - u16 err = 0; __iomem u32 *p_data; /* u32 dwVerifyData=0; */ @@ -1675,15 +1583,11 @@ static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, /* dummy read every 4 words for 6205 advisory 1.4.4 */ boot_loader_read_mem32(pao, 0, 0); - } else - err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX); - return err; + } } static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) { - u16 err = 0; - if (dsp_index == 0) { u32 setting; @@ -1711,8 +1615,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting); if (setting != boot_loader_read_mem32(pao, dsp_index, 0x01800008)) - return hpi6205_error(dsp_index, - HPI6205_ERROR_DSP_EMIF); + return HPI6205_ERROR_DSP_EMIF1; /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */ /* which occupies D15..0. 6713 starts at 27MHz, so need */ @@ -1725,8 +1628,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting); if (setting != boot_loader_read_mem32(pao, dsp_index, 0x01800004)) - return hpi6205_error(dsp_index, - HPI6205_ERROR_DSP_EMIF); + return HPI6205_ERROR_DSP_EMIF2; /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */ /* which occupies D15..0. 6713 starts at 27MHz, so need */ @@ -1738,8 +1640,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting); if (setting != boot_loader_read_mem32(pao, dsp_index, 0x01800010)) - return hpi6205_error(dsp_index, - HPI6205_ERROR_DSP_EMIF); + return HPI6205_ERROR_DSP_EMIF3; /* EMIF CE3 setup - 32 bit async. */ /* This is the PLD on the ASI5000 cards only */ @@ -1750,8 +1651,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting); if (setting != boot_loader_read_mem32(pao, dsp_index, 0x01800014)) - return hpi6205_error(dsp_index, - HPI6205_ERROR_DSP_EMIF); + return HPI6205_ERROR_DSP_EMIF4; /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */ /* need to use this else DSP code crashes? */ @@ -1775,12 +1675,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) read_data = 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR); if (write_data != read_data) { - err = hpi6205_error(dsp_index, - HPI6205_ERROR_C6713_HPIC); HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data, read_data); - - return err; + return HPI6205_ERROR_C6713_HPIC; } /* HPIA - walking ones test */ write_data = 1; @@ -1798,11 +1695,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) HPIAH_ADDR)) << 16); if (read_data != write_data) { - err = hpi6205_error(dsp_index, - HPI6205_ERROR_C6713_HPIA); HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n", write_data, read_data); - return err; + return HPI6205_ERROR_C6713_HPIA; } write_data = write_data << 1; } @@ -1847,30 +1742,81 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) /* PLL should not be bypassed! */ if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF) != 0x0001) { - err = hpi6205_error(dsp_index, - HPI6205_ERROR_C6713_PLL); - return err; + return HPI6205_ERROR_C6713_PLL; } /* setup C67x EMIF (note this is the only use of BAR1 via BootLoader_WriteMem32) */ boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL, 0x000034A8); + + /* EMIF CE0 setup - 2Mx32 Sync DRAM + 31..28 Wr setup + 27..22 Wr strobe + 21..20 Wr hold + 19..16 Rd setup + 15..14 - + 13..8 Rd strobe + 7..4 MTYPE 0011 Sync DRAM 32bits + 3 Wr hold MSB + 2..0 Rd hold + */ boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0, 0x00000030); + + /* EMIF SDRAM Extension + 0x00 + 31-21 0000b 0000b 000b + 20 WR2RD = 2cycles-1 = 1b + + 19-18 WR2DEAC = 3cycle-1 = 10b + 17 WR2WR = 2cycle-1 = 1b + 16-15 R2WDQM = 4cycle-1 = 11b + 14-12 RD2WR = 6cycles-1 = 101b + + 11-10 RD2DEAC = 4cycle-1 = 11b + 9 RD2RD = 2cycle-1 = 1b + 8-7 THZP = 3cycle-1 = 10b + 6-5 TWR = 2cycle-1 = 01b (tWR = 17ns) + 4 TRRD = 2cycle = 0b (tRRD = 14ns) + 3-1 TRAS = 5cycle-1 = 100b (Tras=42ns) + 1 CAS latency = 3cyc = 1b + (for Micron 2M32-7 operating at 100MHz) + */ boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT, 0x001BDF29); + + /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank) + 31 - 0b - + 30 SDBSZ 1b 4 bank + 29..28 SDRSZ 00b 11 row address pins + + 27..26 SDCSZ 01b 8 column address pins + 25 RFEN 1b refersh enabled + 24 INIT 1b init SDRAM! + + 23..20 TRCD 0001b (Trcd/Tcyc)-1 = (20/10)-1 = 1 + + 19..16 TRP 0001b (Trp/Tcyc)-1 = (20/10)-1 = 1 + + 15..12 TRC 0110b (Trc/Tcyc)-1 = (70/10)-1 = 6 + + 11..0 - 0000b 0000b 0000b + */ boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL, - 0x47117000); + 0x47116000); + + /* SDRAM refresh timing + Need 4,096 refresh cycles every 64ms = 15.625us = 1562cycles of 100MHz = 0x61A + */ boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMTIMING, 0x00000410); hpios_delay_micro_seconds(1000); } else if (dsp_index == 2) { /* DSP 2 is a C6713 */ + } - } else - err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX); - return err; + return 0; } static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, @@ -1896,7 +1842,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, test_addr); if (data != test_data) { HPI_DEBUG_LOG(VERBOSE, - "memtest error details " + "Memtest error details " "%08x %08x %08x %i\n", test_addr, test_data, data, dsp_index); return 1; /* error */ @@ -1916,7 +1862,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, data = boot_loader_read_mem32(pao, dsp_index, test_addr); if (data != test_data) { HPI_DEBUG_LOG(VERBOSE, - "memtest error details " + "Memtest error details " "%08x %08x %08x %i\n", test_addr, test_data, data, dsp_index); return 1; /* error */ @@ -1946,8 +1892,8 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao, /* 64K data mem */ err = boot_loader_test_memory(pao, dsp_index, 0x80000000, 0x10000); - } else if ((dsp_index == 1) || (dsp_index == 2)) { - /* DSP 1&2 are a C6713 */ + } else if (dsp_index == 1) { + /* DSP 1 is a C6713 */ /* 192K internal mem */ err = boot_loader_test_memory(pao, dsp_index, 0x00000000, 0x30000); @@ -1955,11 +1901,10 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao, /* 64K internal mem / L2 cache */ err = boot_loader_test_memory(pao, dsp_index, 0x00030000, 0x10000); - } else - return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX); + } if (err) - return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM); + return HPI6205_ERROR_DSP_INTMEM; else return 0; } @@ -1972,24 +1917,23 @@ static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao, if (dsp_index == 0) { /* only test for SDRAM if an ASI5000 card */ - if (pao->pci.subsys_device_id == 0x5000) { + if (pao->pci.pci_dev->subsystem_device == 0x5000) { /* DSP 0 is always C6205 */ dRAM_start_address = 0x00400000; dRAM_size = 0x200000; /*dwDRAMinc=1024; */ } else return 0; - } else if ((dsp_index == 1) || (dsp_index == 2)) { + } else if (dsp_index == 1) { /* DSP 1 is a C6713 */ dRAM_start_address = 0x80000000; dRAM_size = 0x200000; /*dwDRAMinc=1024; */ - } else - return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX); + } if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address, dRAM_size)) - return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM); + return HPI6205_ERROR_DSP_EXTMEM; return 0; } @@ -1998,28 +1942,25 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index) u32 data = 0; if (dsp_index == 0) { /* only test for DSP0 PLD on ASI5000 card */ - if (pao->pci.subsys_device_id == 0x5000) { + if (pao->pci.pci_dev->subsystem_device == 0x5000) { /* PLD is located at CE3=0x03000000 */ data = boot_loader_read_mem32(pao, dsp_index, 0x03000008); if ((data & 0xF) != 0x5) - return hpi6205_error(dsp_index, - HPI6205_ERROR_DSP_PLD); + return HPI6205_ERROR_DSP_PLD; data = boot_loader_read_mem32(pao, dsp_index, 0x0300000C); if ((data & 0xF) != 0xA) - return hpi6205_error(dsp_index, - HPI6205_ERROR_DSP_PLD); + return HPI6205_ERROR_DSP_PLD; } } else if (dsp_index == 1) { /* DSP 1 is a C6713 */ - if (pao->pci.subsys_device_id == 0x8700) { + if (pao->pci.pci_dev->subsystem_device == 0x8700) { /* PLD is located at CE1=0x90000000 */ data = boot_loader_read_mem32(pao, dsp_index, 0x90000010); if ((data & 0xFF) != 0xAA) - return hpi6205_error(dsp_index, - HPI6205_ERROR_DSP_PLD); + return HPI6205_ERROR_DSP_PLD; /* 8713 - LED on */ boot_loader_write_mem32(pao, dsp_index, 0x90000000, 0x02); @@ -2037,14 +1978,11 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data, struct hpi_hw_obj *phw = pao->priv; u32 data_transferred = 0; u16 err = 0; -#ifndef HPI6205_NO_HSR_POLL - u32 time_out; -#endif u32 temp2; struct bus_master_interface *interface = phw->p_interface_buffer; if (!p_data) - return HPI_ERROR_INVALID_DATA_TRANSFER; + return HPI_ERROR_INVALID_DATA_POINTER; data_size &= ~3L; /* round data_size down to nearest 4 bytes */ @@ -2064,14 +2002,10 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data, interface->transfer_size_in_bytes = this_copy; -#ifdef HPI6205_NO_HSR_POLL /* DSP must change this back to nOperation */ interface->dsp_ack = H620_HIF_IDLE; -#endif - send_dsp_command(phw, operation); -#ifdef HPI6205_NO_HSR_POLL temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT); HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n", HPI6205_TIMEOUT - temp2, this_copy); @@ -2079,45 +2013,11 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data, if (!temp2) { /* timed out */ HPI_DEBUG_LOG(ERROR, - "timed out waiting for " "state %d got %d\n", + "Timed out waiting for " "state %d got %d\n", operation, interface->dsp_ack); break; } -#else - /* spin waiting on the result */ - time_out = HPI6205_TIMEOUT; - temp2 = 0; - while ((temp2 == 0) && time_out--) { - /* give 16k bus mastering transfer time to happen */ - /*(16k / 132Mbytes/s = 122usec) */ - hpios_delay_micro_seconds(20); - temp2 = ioread32(phw->prHSR); - temp2 &= C6205_HSR_INTSRC; - } - HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n", - HPI6205_TIMEOUT - time_out, this_copy); - if (temp2 == C6205_HSR_INTSRC) { - HPI_DEBUG_LOG(VERBOSE, - "interrupt from HIF <data> OK\n"); - /* - if(interface->dwDspAck != nOperation) { - HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d, - expected %d \n", - interface->dwDspAck,nOperation); - } - */ - } -/* need to handle this differently... */ - else { - HPI_DEBUG_LOG(ERROR, - "interrupt from HIF <data> BAD\n"); - err = HPI_ERROR_DSP_HARDWARE; - } - - /* reset the interrupt from the DSP */ - iowrite32(C6205_HSR_INTSRC, phw->prHSR); -#endif if (operation == H620_HIF_GET_DATA) memcpy(&p_data[data_transferred], (void *)&interface->u.b_data[0], this_copy); @@ -2156,7 +2056,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us) static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) { struct bus_master_interface *interface = phw->p_interface_buffer; - u32 r; interface->host_cmd = cmd; @@ -2174,31 +2073,39 @@ static unsigned int message_count; static u16 message_response_sequence(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr) { -#ifndef HPI6205_NO_HSR_POLL - u32 temp2; -#endif u32 time_out, time_out2; struct hpi_hw_obj *phw = pao->priv; struct bus_master_interface *interface = phw->p_interface_buffer; u16 err = 0; message_count++; + if (phm->size > sizeof(interface->u.message_buffer)) { + phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL; + phr->specific_error = sizeof(interface->u.message_buffer); + phr->size = sizeof(struct hpi_response_header); + HPI_DEBUG_LOG(ERROR, + "message len %d too big for buffer %zd \n", phm->size, + sizeof(interface->u.message_buffer)); + return 0; + } + /* Assume buffer of type struct bus_master_interface is allocated "noncacheable" */ if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n"); - return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT); + return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT; } - interface->u.message_buffer = *phm; + + memcpy(&interface->u.message_buffer, phm, phm->size); /* signal we want a response */ send_dsp_command(phw, H620_HIF_GET_RESP); time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT); - if (time_out2 == 0) { + if (!time_out2) { HPI_DEBUG_LOG(ERROR, - "(%u) timed out waiting for " "GET_RESP state [%x]\n", + "(%u) Timed out waiting for " "GET_RESP state [%x]\n", message_count, interface->dsp_ack); } else { HPI_DEBUG_LOG(VERBOSE, @@ -2208,58 +2115,39 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao, /* spin waiting on HIF interrupt flag (end of msg process) */ time_out = HPI6205_TIMEOUT; -#ifndef HPI6205_NO_HSR_POLL - temp2 = 0; - while ((temp2 == 0) && --time_out) { - temp2 = ioread32(phw->prHSR); - temp2 &= C6205_HSR_INTSRC; - hpios_delay_micro_seconds(1); - } - if (temp2 == C6205_HSR_INTSRC) { - rmb(); /* ensure we see latest value for dsp_ack */ - if ((interface->dsp_ack != H620_HIF_GET_RESP)) { - HPI_DEBUG_LOG(DEBUG, - "(%u)interface->dsp_ack(0x%x) != " - "H620_HIF_GET_RESP, t=%u\n", message_count, - interface->dsp_ack, - HPI6205_TIMEOUT - time_out); - } else { - HPI_DEBUG_LOG(VERBOSE, - "(%u)int with GET_RESP after %u\n", - message_count, HPI6205_TIMEOUT - time_out); + /* read the result */ + if (time_out) { + if (interface->u.response_buffer.response.size <= phr->size) + memcpy(phr, &interface->u.response_buffer, + interface->u.response_buffer.response.size); + else { + HPI_DEBUG_LOG(ERROR, + "response len %d too big for buffer %d\n", + interface->u.response_buffer.response.size, + phr->size); + memcpy(phr, &interface->u.response_buffer, + sizeof(struct hpi_response_header)); + phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL; + phr->specific_error = + interface->u.response_buffer.response.size; + phr->size = sizeof(struct hpi_response_header); } - - } else { - /* can we do anything else in response to the error ? */ - HPI_DEBUG_LOG(ERROR, - "interrupt from HIF module BAD (function %x)\n", - phm->function); } - - /* reset the interrupt from the DSP */ - iowrite32(C6205_HSR_INTSRC, phw->prHSR); -#endif - - /* read the result */ - if (time_out != 0) - *phr = interface->u.response_buffer; - /* set interface back to idle */ send_dsp_command(phw, H620_HIF_IDLE); - if ((time_out == 0) || (time_out2 == 0)) { + if (!time_out || !time_out2) { HPI_DEBUG_LOG(DEBUG, "something timed out!\n"); - return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT); + return HPI6205_ERROR_MSG_RESP_TIMEOUT; } /* special case for adapter close - */ /* wait for the DSP to indicate it is idle */ if (phm->function == HPI_ADAPTER_CLOSE) { if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { HPI_DEBUG_LOG(DEBUG, - "timeout waiting for idle " + "Timeout waiting for idle " "(on adapter_close)\n"); - return hpi6205_error(0, - HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT); + return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT; } } err = hpi_validate_response(phm, phr); @@ -2279,7 +2167,13 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, /* maybe an error response */ if (err) { /* something failed in the HPI/DSP interface */ - phr->error = err; + if (err >= HPI_ERROR_BACKEND_BASE) { + phr->error = HPI_ERROR_DSP_COMMUNICATION; + phr->specific_error = err; + } else { + phr->error = err; + } + pao->dsp_crashed++; /* just the header of the response is valid */ @@ -2304,23 +2198,6 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, phm->u.d.u.data.data_size, H620_HIF_GET_DATA); break; - case HPI_CONTROL_SET_STATE: - if (phm->object == HPI_OBJ_CONTROLEX - && phm->u.cx.attribute == HPI_COBRANET_SET_DATA) - err = hpi6205_transfer_data(pao, - phm->u.cx.u.cobranet_bigdata.pb_data, - phm->u.cx.u.cobranet_bigdata.byte_count, - H620_HIF_SEND_DATA); - break; - - case HPI_CONTROL_GET_STATE: - if (phm->object == HPI_OBJ_CONTROLEX - && phm->u.cx.attribute == HPI_COBRANET_GET_DATA) - err = hpi6205_transfer_data(pao, - phm->u.cx.u.cobranet_bigdata.pb_data, - phr->u.cx.u.cobranet_data.byte_count, - H620_HIF_GET_DATA); - break; } phr->error = err; |
