RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / sound / pci / asihpi / hpi6205.c
blob22c5fc6255335ac94aca5ac297432f16b0950c4e
1 /******************************************************************************
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 Hardware Programming Interface (HPI) for AudioScience
20 ASI50xx, AS51xx, ASI6xxx, ASI87xx ASI89xx series adapters.
21 These PCI and PCIe bus adapters are based on a
22 TMS320C6205 PCI bus mastering DSP,
23 and (except ASI50xx) TI TMS320C6xxx floating point DSP
25 Exported function:
26 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
28 (C) Copyright AudioScience Inc. 1998-2010
29 *******************************************************************************/
30 #define SOURCEFILE_NAME "hpi6205.c"
32 #include "hpi_internal.h"
33 #include "hpimsginit.h"
34 #include "hpidebug.h"
35 #include "hpi6205.h"
36 #include "hpidspcd.h"
37 #include "hpicmn.h"
39 /*****************************************************************************/
40 /* HPI6205 specific error codes */
41 #define HPI6205_ERROR_BASE 1000
42 /*#define HPI6205_ERROR_MEM_ALLOC 1001 */
43 #define HPI6205_ERROR_6205_NO_IRQ 1002
44 #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
48 #define HPI6205_ERROR_6205_DSPPAGE 1007
49 #define HPI6205_ERROR_BAD_DSPINDEX 1008
50 #define HPI6205_ERROR_C6713_HPIC 1009
51 #define HPI6205_ERROR_C6713_HPIA 1010
52 #define HPI6205_ERROR_C6713_PLL 1011
53 #define HPI6205_ERROR_DSP_INTMEM 1012
54 #define HPI6205_ERROR_DSP_EXTMEM 1013
55 #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
59 #define HPI6205_ERROR_DSP_EMIF 1018
61 #define hpi6205_error(dsp_index, err) (err)
62 /*****************************************************************************/
63 /* for C6205 PCI i/f */
64 /* Host Status Register (HSR) bitfields */
65 #define C6205_HSR_INTSRC 0x01
66 #define C6205_HSR_INTAVAL 0x02
67 #define C6205_HSR_INTAM 0x04
68 #define C6205_HSR_CFGERR 0x08
69 #define C6205_HSR_EEREAD 0x10
70 /* Host-to-DSP Control Register (HDCR) bitfields */
71 #define C6205_HDCR_WARMRESET 0x01
72 #define C6205_HDCR_DSPINT 0x02
73 #define C6205_HDCR_PCIBOOT 0x04
74 /* DSP Page Register (DSPP) bitfields, */
75 /* defines 4 Mbyte page that BAR0 points to */
76 #define C6205_DSPP_MAP1 0x400
78 /* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
79 * BAR1 maps to non-prefetchable 8 Mbyte memory block
80 * of DSP memory mapped registers (starting at 0x01800000).
81 * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
82 * needs to be added to the BAR1 base address set in the PCI config reg
84 #define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
85 #define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
86 #define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
87 #define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
89 /* used to control LED (revA) and reset C6713 (revB) */
90 #define C6205_BAR0_TIMER1_CTL (0x01980000L)
92 /* For first 6713 in CE1 space, using DA17,16,2 */
93 #define HPICL_ADDR 0x01400000L
94 #define HPICH_ADDR 0x01400004L
95 #define HPIAL_ADDR 0x01410000L
96 #define HPIAH_ADDR 0x01410004L
97 #define HPIDIL_ADDR 0x01420000L
98 #define HPIDIH_ADDR 0x01420004L
99 #define HPIDL_ADDR 0x01430000L
100 #define HPIDH_ADDR 0x01430004L
102 #define C6713_EMIF_GCTL 0x01800000
103 #define C6713_EMIF_CE1 0x01800004
104 #define C6713_EMIF_CE0 0x01800008
105 #define C6713_EMIF_CE2 0x01800010
106 #define C6713_EMIF_CE3 0x01800014
107 #define C6713_EMIF_SDRAMCTL 0x01800018
108 #define C6713_EMIF_SDRAMTIMING 0x0180001C
109 #define C6713_EMIF_SDRAMEXT 0x01800020
111 struct hpi_hw_obj {
112 /* PCI registers */
113 __iomem u32 *prHSR;
114 __iomem u32 *prHDCR;
115 __iomem u32 *prDSPP;
117 u32 dsp_page;
119 struct consistent_dma_area h_locked_mem;
120 struct bus_master_interface *p_interface_buffer;
122 u16 flag_outstream_just_reset[HPI_MAX_STREAMS];
123 /* a non-NULL handle means there is an HPI allocated buffer */
124 struct consistent_dma_area instream_host_buffers[HPI_MAX_STREAMS];
125 struct consistent_dma_area outstream_host_buffers[HPI_MAX_STREAMS];
126 /* non-zero size means a buffer exists, may be external */
127 u32 instream_host_buffer_size[HPI_MAX_STREAMS];
128 u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
130 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;
137 /*****************************************************************************/
138 /* local prototypes */
140 #define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
142 static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
144 static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
146 static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
147 u32 *pos_error_code);
149 static u16 message_response_sequence(struct hpi_adapter_obj *pao,
150 struct hpi_message *phm, struct hpi_response *phr);
152 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
153 struct hpi_response *phr);
155 #define HPI6205_TIMEOUT 1000000
157 static void subsys_create_adapter(struct hpi_message *phm,
158 struct hpi_response *phr);
159 static void subsys_delete_adapter(struct hpi_message *phm,
160 struct hpi_response *phr);
162 static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code);
165 static void delete_adapter_obj(struct hpi_adapter_obj *pao);
167 static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
168 struct hpi_message *phm, struct hpi_response *phr);
170 static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
171 struct hpi_message *phm, struct hpi_response *phr);
173 static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
174 struct hpi_message *phm, struct hpi_response *phr);
175 static void outstream_write(struct hpi_adapter_obj *pao,
176 struct hpi_message *phm, struct hpi_response *phr);
178 static void outstream_get_info(struct hpi_adapter_obj *pao,
179 struct hpi_message *phm, struct hpi_response *phr);
181 static void outstream_start(struct hpi_adapter_obj *pao,
182 struct hpi_message *phm, struct hpi_response *phr);
184 static void outstream_open(struct hpi_adapter_obj *pao,
185 struct hpi_message *phm, struct hpi_response *phr);
187 static void outstream_reset(struct hpi_adapter_obj *pao,
188 struct hpi_message *phm, struct hpi_response *phr);
190 static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
191 struct hpi_message *phm, struct hpi_response *phr);
193 static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
194 struct hpi_message *phm, struct hpi_response *phr);
196 static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
197 struct hpi_message *phm, struct hpi_response *phr);
199 static void instream_read(struct hpi_adapter_obj *pao,
200 struct hpi_message *phm, struct hpi_response *phr);
202 static void instream_get_info(struct hpi_adapter_obj *pao,
203 struct hpi_message *phm, struct hpi_response *phr);
205 static void instream_start(struct hpi_adapter_obj *pao,
206 struct hpi_message *phm, struct hpi_response *phr);
208 static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209 u32 address);
211 static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
212 u32 address, u32 data);
214 static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215 int dsp_index);
217 static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
218 u32 address, u32 length);
220 static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
221 int dsp_index);
223 static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
224 int dsp_index);
226 static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
228 /*****************************************************************************/
230 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
233 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:
244 subsys_create_adapter(phm, phr);
245 break;
246 case HPI_SUBSYS_DELETE_ADAPTER:
247 subsys_delete_adapter(phm, phr);
248 break;
249 default:
250 phr->error = HPI_ERROR_INVALID_FUNC;
251 break;
255 static void control_message(struct hpi_adapter_obj *pao,
256 struct hpi_message *phm, struct hpi_response *phr)
259 struct hpi_hw_obj *phw = pao->priv;
261 switch (phm->function) {
262 case HPI_CONTROL_GET_STATE:
263 if (pao->has_control_cache) {
264 rmb(); /* make sure we see updates DM_aed from DSP */
265 if (hpi_check_control_cache(phw->p_cache, phm, phr))
266 break;
268 hw_message(pao, phm, phr);
269 break;
270 case HPI_CONTROL_GET_INFO:
271 hw_message(pao, phm, phr);
272 break;
273 case HPI_CONTROL_SET_STATE:
274 hw_message(pao, phm, phr);
275 if (pao->has_control_cache)
276 hpi_sync_control_cache(phw->p_cache, phm, phr);
277 break;
278 default:
279 phr->error = HPI_ERROR_INVALID_FUNC;
280 break;
284 static void adapter_message(struct hpi_adapter_obj *pao,
285 struct hpi_message *phm, struct hpi_response *phr)
287 switch (phm->function) {
288 default:
289 hw_message(pao, phm, phr);
290 break;
294 static void outstream_message(struct hpi_adapter_obj *pao,
295 struct hpi_message *phm, struct hpi_response *phr)
298 if (phm->obj_index >= HPI_MAX_STREAMS) {
299 phr->error = HPI_ERROR_INVALID_STREAM;
300 HPI_DEBUG_LOG(WARNING,
301 "message referencing invalid stream %d "
302 "on adapter index %d\n", phm->obj_index,
303 phm->adapter_index);
304 return;
307 switch (phm->function) {
308 case HPI_OSTREAM_WRITE:
309 outstream_write(pao, phm, phr);
310 break;
311 case HPI_OSTREAM_GET_INFO:
312 outstream_get_info(pao, phm, phr);
313 break;
314 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
315 outstream_host_buffer_allocate(pao, phm, phr);
316 break;
317 case HPI_OSTREAM_HOSTBUFFER_GET_INFO:
318 outstream_host_buffer_get_info(pao, phm, phr);
319 break;
320 case HPI_OSTREAM_HOSTBUFFER_FREE:
321 outstream_host_buffer_free(pao, phm, phr);
322 break;
323 case HPI_OSTREAM_START:
324 outstream_start(pao, phm, phr);
325 break;
326 case HPI_OSTREAM_OPEN:
327 outstream_open(pao, phm, phr);
328 break;
329 case HPI_OSTREAM_RESET:
330 outstream_reset(pao, phm, phr);
331 break;
332 default:
333 hw_message(pao, phm, phr);
334 break;
338 static void instream_message(struct hpi_adapter_obj *pao,
339 struct hpi_message *phm, struct hpi_response *phr)
342 if (phm->obj_index >= HPI_MAX_STREAMS) {
343 phr->error = HPI_ERROR_INVALID_STREAM;
344 HPI_DEBUG_LOG(WARNING,
345 "message referencing invalid stream %d "
346 "on adapter index %d\n", phm->obj_index,
347 phm->adapter_index);
348 return;
351 switch (phm->function) {
352 case HPI_ISTREAM_READ:
353 instream_read(pao, phm, phr);
354 break;
355 case HPI_ISTREAM_GET_INFO:
356 instream_get_info(pao, phm, phr);
357 break;
358 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
359 instream_host_buffer_allocate(pao, phm, phr);
360 break;
361 case HPI_ISTREAM_HOSTBUFFER_GET_INFO:
362 instream_host_buffer_get_info(pao, phm, phr);
363 break;
364 case HPI_ISTREAM_HOSTBUFFER_FREE:
365 instream_host_buffer_free(pao, phm, phr);
366 break;
367 case HPI_ISTREAM_START:
368 instream_start(pao, phm, phr);
369 break;
370 default:
371 hw_message(pao, phm, phr);
372 break;
376 /*****************************************************************************/
377 /** Entry point to this HPI backend
378 * All calls to the HPI start here
380 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
382 struct hpi_adapter_obj *pao = NULL;
384 /* subsytem messages are processed by every HPI.
385 * All other messages are ignored unless the adapter index matches
386 * an adapter in the HPI
388 HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
389 phm->function);
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;
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;
412 /* Init default response */
413 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
414 hpi_init_response(phr, phm->object, phm->function,
415 HPI_ERROR_PROCESSING_MESSAGE);
417 HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
418 switch (phm->type) {
419 case HPI_TYPE_MESSAGE:
420 switch (phm->object) {
421 case HPI_OBJ_SUBSYSTEM:
422 subsys_message(phm, phr);
423 break;
425 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);
430 break;
432 case HPI_OBJ_CONTROLEX:
433 case HPI_OBJ_CONTROL:
434 control_message(pao, phm, phr);
435 break;
437 case HPI_OBJ_OSTREAM:
438 outstream_message(pao, phm, phr);
439 break;
441 case HPI_OBJ_ISTREAM:
442 instream_message(pao, phm, phr);
443 break;
445 default:
446 hw_message(pao, phm, phr);
447 break;
449 break;
451 default:
452 phr->error = HPI_ERROR_INVALID_TYPE;
453 break;
457 /*****************************************************************************/
458 /* SUBSYSTEM */
460 /** Create an adapter object and initialise it based on resource information
461 * passed in in the message
462 * *** NOTE - you cannot use this function AND the FindAdapters function at the
463 * same time, the application must use only one of them to get the adapters ***
465 static void subsys_create_adapter(struct hpi_message *phm,
466 struct hpi_response *phr)
468 /* create temp adapter obj, because we don't know what index yet */
469 struct hpi_adapter_obj ao;
470 u32 os_error_code;
471 u16 err;
473 HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
475 memset(&ao, 0, sizeof(ao));
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;
485 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
486 if (!ao.priv) {
487 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
488 phr->error = HPI_ERROR_MEMORY_ALLOC;
489 return;
492 ao.pci = *phm->u.s.resource.r.pci;
493 err = create_adapter_obj(&ao, &os_error_code);
494 if (!err)
495 err = hpi_add_adapter(&ao);
496 if (err) {
497 phr->u.s.data = os_error_code;
498 delete_adapter_obj(&ao);
499 phr->error = err;
500 return;
503 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
504 phr->u.s.adapter_index = ao.index;
505 phr->u.s.num_adapters++;
506 phr->error = 0;
509 /** delete an adapter - required by WDM driver */
510 static void subsys_delete_adapter(struct hpi_message *phm,
511 struct hpi_response *phr)
513 struct hpi_adapter_obj *pao;
514 struct hpi_hw_obj *phw;
516 pao = hpi_find_adapter(phm->adapter_index);
517 if (!pao) {
518 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519 return;
521 phw = (struct hpi_hw_obj *)pao->priv;
522 /* reset adapter h/w */
523 /* Reset C6713 #1 */
524 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
525 /* reset C6205 */
526 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
528 delete_adapter_obj(pao);
529 phr->error = 0;
532 /** Create adapter object
533 allocate buffers, bootload DSPs, initialise control cache
535 static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
536 u32 *pos_error_code)
538 struct hpi_hw_obj *phw = pao->priv;
539 struct bus_master_interface *interface;
540 u32 phys_addr;
541 #ifndef HPI6205_NO_HSR_POLL
542 u32 time_out = HPI6205_TIMEOUT;
543 u32 temp1;
544 #endif
545 int i;
546 u16 err;
548 /* init error reporting */
549 pao->dsp_crashed = 0;
551 for (i = 0; i < HPI_MAX_STREAMS; i++)
552 phw->flag_outstream_just_reset[i] = 1;
554 /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
555 phw->prHSR =
556 pao->pci.ap_mem_base[1] +
557 C6205_BAR1_HSR / sizeof(*pao->pci.ap_mem_base[1]);
558 phw->prHDCR =
559 pao->pci.ap_mem_base[1] +
560 C6205_BAR1_HDCR / sizeof(*pao->pci.ap_mem_base[1]);
561 phw->prDSPP =
562 pao->pci.ap_mem_base[1] +
563 C6205_BAR1_DSPP / sizeof(*pao->pci.ap_mem_base[1]);
565 pao->has_control_cache = 0;
567 if (hpios_locked_mem_alloc(&phw->h_locked_mem,
568 sizeof(struct bus_master_interface),
569 pao->pci.p_os_data))
570 phw->p_interface_buffer = NULL;
571 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
572 (void *)&phw->p_interface_buffer))
573 phw->p_interface_buffer = NULL;
575 HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
576 phw->p_interface_buffer);
578 if (phw->p_interface_buffer) {
579 memset((void *)phw->p_interface_buffer, 0,
580 sizeof(struct bus_master_interface));
581 phw->p_interface_buffer->dsp_ack = H620_HIF_UNKNOWN;
584 err = adapter_boot_load_dsp(pao, pos_error_code);
585 if (err)
586 /* no need to clean up as SubSysCreateAdapter */
587 /* calls DeleteAdapter on error. */
588 return err;
590 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
592 /* allow boot load even if mem alloc wont work */
593 if (!phw->p_interface_buffer)
594 return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC);
596 interface = phw->p_interface_buffer;
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);
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);
615 /* reset the interrupt */
616 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617 #endif
619 /* make sure the DSP has started ok */
620 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
621 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
622 return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED);
624 /* Note that *pao, *phw are zeroed after allocation,
625 * so pointers and flags are NULL by default.
626 * Allocate bus mastering control cache buffer and tell the DSP about it
628 if (interface->control_cache.number_of_controls) {
629 void *p_control_cache_virtual;
631 err = hpios_locked_mem_alloc(&phw->h_control_cache,
632 interface->control_cache.size_in_bytes,
633 pao->pci.p_os_data);
634 if (!err)
635 err = hpios_locked_mem_get_virt_addr(&phw->
636 h_control_cache, &p_control_cache_virtual);
637 if (!err) {
638 memset(p_control_cache_virtual, 0,
639 interface->control_cache.size_in_bytes);
641 phw->p_cache =
642 hpi_alloc_control_cache(interface->
643 control_cache.number_of_controls,
644 interface->control_cache.size_in_bytes,
645 (struct hpi_control_cache_info *)
646 p_control_cache_virtual);
648 if (!err) {
649 err = hpios_locked_mem_get_phys_addr(&phw->
650 h_control_cache, &phys_addr);
651 interface->control_cache.physical_address32 =
652 phys_addr;
655 if (!err)
656 pao->has_control_cache = 1;
657 else {
658 if (hpios_locked_mem_valid(&phw->h_control_cache))
659 hpios_locked_mem_free(&phw->h_control_cache);
660 pao->has_control_cache = 0;
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;
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;
691 send_dsp_command(phw, H620_HIF_IDLE);
694 struct hpi_message hM;
695 struct hpi_response hR;
696 u32 max_streams;
698 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
699 memset(&hM, 0, sizeof(hM));
700 hM.type = HPI_TYPE_MESSAGE;
701 hM.size = sizeof(hM);
702 hM.object = HPI_OBJ_ADAPTER;
703 hM.function = HPI_ADAPTER_GET_INFO;
704 hM.adapter_index = 0;
705 memset(&hR, 0, sizeof(hR));
706 hR.size = sizeof(hR);
708 err = message_response_sequence(pao, &hM, &hR);
709 if (err) {
710 HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
711 err);
712 return err;
714 if (hR.error)
715 return hR.error;
717 pao->adapter_type = hR.u.a.adapter_type;
718 pao->index = hR.u.a.adapter_index;
720 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
722 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
723 65536, pao->pci.p_os_data);
725 HPI_DEBUG_LOG(VERBOSE,
726 "got adapter info type %x index %d serial %d\n",
727 hR.u.a.adapter_type, hR.u.a.adapter_index,
728 hR.u.a.serial_number);
731 pao->open = 0; /* upon creation the adapter is closed */
733 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
734 return 0;
737 /** Free memory areas allocated by adapter
738 * this routine is called from SubSysDeleteAdapter,
739 * and SubSysCreateAdapter if duplicate index
741 static void delete_adapter_obj(struct hpi_adapter_obj *pao)
743 struct hpi_hw_obj *phw;
744 int i;
746 phw = pao->priv;
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;
753 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
754 hpios_locked_mem_free(&phw->h_control_cache);
755 hpi_free_control_cache(phw->p_cache);
758 if (hpios_locked_mem_valid(&phw->h_locked_mem)) {
759 hpios_locked_mem_free(&phw->h_locked_mem);
760 phw->p_interface_buffer = NULL;
763 for (i = 0; i < HPI_MAX_STREAMS; i++)
764 if (hpios_locked_mem_valid(&phw->instream_host_buffers[i])) {
765 hpios_locked_mem_free(&phw->instream_host_buffers[i]);
766 /*?phw->InStreamHostBuffers[i] = NULL; */
767 phw->instream_host_buffer_size[i] = 0;
770 for (i = 0; i < HPI_MAX_STREAMS; i++)
771 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[i])) {
772 hpios_locked_mem_free(&phw->outstream_host_buffers
773 [i]);
774 phw->outstream_host_buffer_size[i] = 0;
777 hpios_locked_mem_unprepare(pao->pci.p_os_data);
779 hpi_delete_adapter(pao);
780 kfree(phw);
783 /*****************************************************************************/
784 /* OutStream Host buffer functions */
786 /** Allocate or attach buffer for busmastering
788 static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
789 struct hpi_message *phm, struct hpi_response *phr)
791 u16 err = 0;
792 u32 command = phm->u.d.u.buffer.command;
793 struct hpi_hw_obj *phw = pao->priv;
794 struct bus_master_interface *interface = phw->p_interface_buffer;
796 hpi_init_response(phr, phm->object, phm->function, 0);
798 if (command == HPI_BUFFER_CMD_EXTERNAL
799 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
800 /* ALLOC phase, allocate a buffer with power of 2 size,
801 get its bus address for PCI bus mastering
803 phm->u.d.u.buffer.buffer_size =
804 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
805 /* return old size and allocated size,
806 so caller can detect change */
807 phr->u.d.u.stream_info.data_available =
808 phw->outstream_host_buffer_size[phm->obj_index];
809 phr->u.d.u.stream_info.buffer_size =
810 phm->u.d.u.buffer.buffer_size;
812 if (phw->outstream_host_buffer_size[phm->obj_index] ==
813 phm->u.d.u.buffer.buffer_size) {
814 /* Same size, no action required */
815 return;
818 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
819 obj_index]))
820 hpios_locked_mem_free(&phw->outstream_host_buffers
821 [phm->obj_index]);
823 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
824 [phm->obj_index], phm->u.d.u.buffer.buffer_size,
825 pao->pci.p_os_data);
827 if (err) {
828 phr->error = HPI_ERROR_INVALID_DATASIZE;
829 phw->outstream_host_buffer_size[phm->obj_index] = 0;
830 return;
833 err = hpios_locked_mem_get_phys_addr
834 (&phw->outstream_host_buffers[phm->obj_index],
835 &phm->u.d.u.buffer.pci_address);
836 /* get the phys addr into msg for single call alloc caller
837 * needs to do this for split alloc (or use the same message)
838 * return the phy address for split alloc in the respose too
840 phr->u.d.u.stream_info.auxiliary_data_available =
841 phm->u.d.u.buffer.pci_address;
843 if (err) {
844 hpios_locked_mem_free(&phw->outstream_host_buffers
845 [phm->obj_index]);
846 phw->outstream_host_buffer_size[phm->obj_index] = 0;
847 phr->error = HPI_ERROR_MEMORY_ALLOC;
848 return;
852 if (command == HPI_BUFFER_CMD_EXTERNAL
853 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
854 /* GRANT phase. Set up the BBM status, tell the DSP about
855 the buffer so it can start using BBM.
857 struct hpi_hostbuffer_status *status;
859 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
860 buffer_size - 1)) {
861 HPI_DEBUG_LOG(ERROR,
862 "buffer size must be 2^N not %d\n",
863 phm->u.d.u.buffer.buffer_size);
864 phr->error = HPI_ERROR_INVALID_DATASIZE;
865 return;
867 phw->outstream_host_buffer_size[phm->obj_index] =
868 phm->u.d.u.buffer.buffer_size;
869 status = &interface->outstream_host_buffer_status[phm->
870 obj_index];
871 status->samples_processed = 0;
872 status->stream_state = HPI_STATE_STOPPED;
873 status->dSP_index = 0;
874 status->host_index = status->dSP_index;
875 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
877 hw_message(pao, phm, phr);
879 if (phr->error
880 && hpios_locked_mem_valid(&phw->
881 outstream_host_buffers[phm->obj_index])) {
882 hpios_locked_mem_free(&phw->outstream_host_buffers
883 [phm->obj_index]);
884 phw->outstream_host_buffer_size[phm->obj_index] = 0;
889 static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
890 struct hpi_message *phm, struct hpi_response *phr)
892 struct hpi_hw_obj *phw = pao->priv;
893 struct bus_master_interface *interface = phw->p_interface_buffer;
894 struct hpi_hostbuffer_status *status;
895 u8 *p_bbm_data;
897 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
898 obj_index])) {
899 if (hpios_locked_mem_get_virt_addr(&phw->
900 outstream_host_buffers[phm->obj_index],
901 (void *)&p_bbm_data)) {
902 phr->error = HPI_ERROR_INVALID_OPERATION;
903 return;
905 status = &interface->outstream_host_buffer_status[phm->
906 obj_index];
907 hpi_init_response(phr, HPI_OBJ_OSTREAM,
908 HPI_OSTREAM_HOSTBUFFER_GET_INFO, 0);
909 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
910 phr->u.d.u.hostbuffer_info.p_status = status;
911 } else {
912 hpi_init_response(phr, HPI_OBJ_OSTREAM,
913 HPI_OSTREAM_HOSTBUFFER_GET_INFO,
914 HPI_ERROR_INVALID_OPERATION);
918 static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
919 struct hpi_message *phm, struct hpi_response *phr)
921 struct hpi_hw_obj *phw = pao->priv;
922 u32 command = phm->u.d.u.buffer.command;
924 if (phw->outstream_host_buffer_size[phm->obj_index]) {
925 if (command == HPI_BUFFER_CMD_EXTERNAL
926 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
927 phw->outstream_host_buffer_size[phm->obj_index] = 0;
928 hw_message(pao, phm, phr);
929 /* Tell adapter to stop using the host buffer. */
931 if (command == HPI_BUFFER_CMD_EXTERNAL
932 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
933 hpios_locked_mem_free(&phw->outstream_host_buffers
934 [phm->obj_index]);
936 /* Should HPI_ERROR_INVALID_OPERATION be returned
937 if no host buffer is allocated? */
938 else
939 hpi_init_response(phr, HPI_OBJ_OSTREAM,
940 HPI_OSTREAM_HOSTBUFFER_FREE, 0);
944 static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
946 return status->size_in_bytes - (status->host_index -
947 status->dSP_index);
950 static void outstream_write(struct hpi_adapter_obj *pao,
951 struct hpi_message *phm, struct hpi_response *phr)
953 struct hpi_hw_obj *phw = pao->priv;
954 struct bus_master_interface *interface = phw->p_interface_buffer;
955 struct hpi_hostbuffer_status *status;
956 u32 space_available;
958 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
959 /* there is no BBM buffer, write via message */
960 hw_message(pao, phm, phr);
961 return;
964 hpi_init_response(phr, phm->object, phm->function, 0);
965 status = &interface->outstream_host_buffer_status[phm->obj_index];
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.
973 int partial_write = 0;
974 unsigned int original_size = 0;
976 phw->flag_outstream_just_reset[phm->obj_index] = 0;
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;
986 /* write it */
987 phm->function = HPI_OSTREAM_WRITE;
988 hw_message(pao, phm, phr);
990 if (phr->error)
991 return;
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)
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;
1001 /* if we did a full write, we can return from here. */
1002 if (!partial_write)
1003 return;
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;
1012 space_available = outstream_get_space_available(status);
1013 if (space_available < phm->u.d.u.data.data_size) {
1014 phr->error = HPI_ERROR_INVALID_DATASIZE;
1015 return;
1018 /* HostBuffers is used to indicate host buffer is internally allocated.
1019 otherwise, assumed external, data written externally */
1020 if (phm->u.d.u.data.pb_data
1021 && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
1022 obj_index])) {
1023 u8 *p_bbm_data;
1024 u32 l_first_write;
1025 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1027 if (hpios_locked_mem_get_virt_addr(&phw->
1028 outstream_host_buffers[phm->obj_index],
1029 (void *)&p_bbm_data)) {
1030 phr->error = HPI_ERROR_INVALID_OPERATION;
1031 return;
1034 /* either all data,
1035 or enough to fit from current to end of BBM buffer */
1036 l_first_write =
1037 min(phm->u.d.u.data.data_size,
1038 status->size_in_bytes -
1039 (status->host_index & (status->size_in_bytes - 1)));
1041 memcpy(p_bbm_data +
1042 (status->host_index & (status->size_in_bytes - 1)),
1043 p_app_data, l_first_write);
1044 /* remaining data if any */
1045 memcpy(p_bbm_data, p_app_data + l_first_write,
1046 phm->u.d.u.data.data_size - l_first_write);
1048 status->host_index += phm->u.d.u.data.data_size;
1051 static void outstream_get_info(struct hpi_adapter_obj *pao,
1052 struct hpi_message *phm, struct hpi_response *phr)
1054 struct hpi_hw_obj *phw = pao->priv;
1055 struct bus_master_interface *interface = phw->p_interface_buffer;
1056 struct hpi_hostbuffer_status *status;
1058 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1059 hw_message(pao, phm, phr);
1060 return;
1063 hpi_init_response(phr, phm->object, phm->function, 0);
1065 status = &interface->outstream_host_buffer_status[phm->obj_index];
1067 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1068 phr->u.d.u.stream_info.samples_transferred =
1069 status->samples_processed;
1070 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1071 phr->u.d.u.stream_info.data_available =
1072 status->size_in_bytes - outstream_get_space_available(status);
1073 phr->u.d.u.stream_info.auxiliary_data_available =
1074 status->auxiliary_data_available;
1077 static void outstream_start(struct hpi_adapter_obj *pao,
1078 struct hpi_message *phm, struct hpi_response *phr)
1080 hw_message(pao, phm, phr);
1083 static void outstream_reset(struct hpi_adapter_obj *pao,
1084 struct hpi_message *phm, struct hpi_response *phr)
1086 struct hpi_hw_obj *phw = pao->priv;
1087 phw->flag_outstream_just_reset[phm->obj_index] = 1;
1088 hw_message(pao, phm, phr);
1091 static void outstream_open(struct hpi_adapter_obj *pao,
1092 struct hpi_message *phm, struct hpi_response *phr)
1094 outstream_reset(pao, phm, phr);
1097 /*****************************************************************************/
1098 /* InStream Host buffer functions */
1100 static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1101 struct hpi_message *phm, struct hpi_response *phr)
1103 u16 err = 0;
1104 u32 command = phm->u.d.u.buffer.command;
1105 struct hpi_hw_obj *phw = pao->priv;
1106 struct bus_master_interface *interface = phw->p_interface_buffer;
1108 hpi_init_response(phr, phm->object, phm->function, 0);
1110 if (command == HPI_BUFFER_CMD_EXTERNAL
1111 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1113 phm->u.d.u.buffer.buffer_size =
1114 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
1115 phr->u.d.u.stream_info.data_available =
1116 phw->instream_host_buffer_size[phm->obj_index];
1117 phr->u.d.u.stream_info.buffer_size =
1118 phm->u.d.u.buffer.buffer_size;
1120 if (phw->instream_host_buffer_size[phm->obj_index] ==
1121 phm->u.d.u.buffer.buffer_size) {
1122 /* Same size, no action required */
1123 return;
1126 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1127 obj_index]))
1128 hpios_locked_mem_free(&phw->instream_host_buffers
1129 [phm->obj_index]);
1131 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1132 obj_index], phm->u.d.u.buffer.buffer_size,
1133 pao->pci.p_os_data);
1135 if (err) {
1136 phr->error = HPI_ERROR_INVALID_DATASIZE;
1137 phw->instream_host_buffer_size[phm->obj_index] = 0;
1138 return;
1141 err = hpios_locked_mem_get_phys_addr
1142 (&phw->instream_host_buffers[phm->obj_index],
1143 &phm->u.d.u.buffer.pci_address);
1144 /* get the phys addr into msg for single call alloc. Caller
1145 needs to do this for split alloc so return the phy address */
1146 phr->u.d.u.stream_info.auxiliary_data_available =
1147 phm->u.d.u.buffer.pci_address;
1148 if (err) {
1149 hpios_locked_mem_free(&phw->instream_host_buffers
1150 [phm->obj_index]);
1151 phw->instream_host_buffer_size[phm->obj_index] = 0;
1152 phr->error = HPI_ERROR_MEMORY_ALLOC;
1153 return;
1157 if (command == HPI_BUFFER_CMD_EXTERNAL
1158 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1159 struct hpi_hostbuffer_status *status;
1161 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1162 buffer_size - 1)) {
1163 HPI_DEBUG_LOG(ERROR,
1164 "buffer size must be 2^N not %d\n",
1165 phm->u.d.u.buffer.buffer_size);
1166 phr->error = HPI_ERROR_INVALID_DATASIZE;
1167 return;
1170 phw->instream_host_buffer_size[phm->obj_index] =
1171 phm->u.d.u.buffer.buffer_size;
1172 status = &interface->instream_host_buffer_status[phm->
1173 obj_index];
1174 status->samples_processed = 0;
1175 status->stream_state = HPI_STATE_STOPPED;
1176 status->dSP_index = 0;
1177 status->host_index = status->dSP_index;
1178 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1180 hw_message(pao, phm, phr);
1181 if (phr->error
1182 && hpios_locked_mem_valid(&phw->
1183 instream_host_buffers[phm->obj_index])) {
1184 hpios_locked_mem_free(&phw->instream_host_buffers
1185 [phm->obj_index]);
1186 phw->instream_host_buffer_size[phm->obj_index] = 0;
1191 static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1192 struct hpi_message *phm, struct hpi_response *phr)
1194 struct hpi_hw_obj *phw = pao->priv;
1195 struct bus_master_interface *interface = phw->p_interface_buffer;
1196 struct hpi_hostbuffer_status *status;
1197 u8 *p_bbm_data;
1199 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1200 obj_index])) {
1201 if (hpios_locked_mem_get_virt_addr(&phw->
1202 instream_host_buffers[phm->obj_index],
1203 (void *)&p_bbm_data)) {
1204 phr->error = HPI_ERROR_INVALID_OPERATION;
1205 return;
1207 status = &interface->instream_host_buffer_status[phm->
1208 obj_index];
1209 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1210 HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
1211 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
1212 phr->u.d.u.hostbuffer_info.p_status = status;
1213 } else {
1214 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1215 HPI_ISTREAM_HOSTBUFFER_GET_INFO,
1216 HPI_ERROR_INVALID_OPERATION);
1220 static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1221 struct hpi_message *phm, struct hpi_response *phr)
1223 struct hpi_hw_obj *phw = pao->priv;
1224 u32 command = phm->u.d.u.buffer.command;
1226 if (phw->instream_host_buffer_size[phm->obj_index]) {
1227 if (command == HPI_BUFFER_CMD_EXTERNAL
1228 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
1229 phw->instream_host_buffer_size[phm->obj_index] = 0;
1230 hw_message(pao, phm, phr);
1233 if (command == HPI_BUFFER_CMD_EXTERNAL
1234 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
1235 hpios_locked_mem_free(&phw->instream_host_buffers
1236 [phm->obj_index]);
1238 } else {
1239 /* Should HPI_ERROR_INVALID_OPERATION be returned
1240 if no host buffer is allocated? */
1241 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1242 HPI_ISTREAM_HOSTBUFFER_FREE, 0);
1248 static void instream_start(struct hpi_adapter_obj *pao,
1249 struct hpi_message *phm, struct hpi_response *phr)
1251 hw_message(pao, phm, phr);
1254 static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1256 return status->dSP_index - status->host_index;
1259 static void instream_read(struct hpi_adapter_obj *pao,
1260 struct hpi_message *phm, struct hpi_response *phr)
1262 struct hpi_hw_obj *phw = pao->priv;
1263 struct bus_master_interface *interface = phw->p_interface_buffer;
1264 struct hpi_hostbuffer_status *status;
1265 u32 data_available;
1266 u8 *p_bbm_data;
1267 u32 l_first_read;
1268 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1270 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1271 hw_message(pao, phm, phr);
1272 return;
1274 hpi_init_response(phr, phm->object, phm->function, 0);
1276 status = &interface->instream_host_buffer_status[phm->obj_index];
1277 data_available = instream_get_bytes_available(status);
1278 if (data_available < phm->u.d.u.data.data_size) {
1279 phr->error = HPI_ERROR_INVALID_DATASIZE;
1280 return;
1283 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1284 obj_index])) {
1285 if (hpios_locked_mem_get_virt_addr(&phw->
1286 instream_host_buffers[phm->obj_index],
1287 (void *)&p_bbm_data)) {
1288 phr->error = HPI_ERROR_INVALID_OPERATION;
1289 return;
1292 /* either all data,
1293 or enough to fit from current to end of BBM buffer */
1294 l_first_read =
1295 min(phm->u.d.u.data.data_size,
1296 status->size_in_bytes -
1297 (status->host_index & (status->size_in_bytes - 1)));
1299 memcpy(p_app_data,
1300 p_bbm_data +
1301 (status->host_index & (status->size_in_bytes - 1)),
1302 l_first_read);
1303 /* remaining data if any */
1304 memcpy(p_app_data + l_first_read, p_bbm_data,
1305 phm->u.d.u.data.data_size - l_first_read);
1307 status->host_index += phm->u.d.u.data.data_size;
1310 static void instream_get_info(struct hpi_adapter_obj *pao,
1311 struct hpi_message *phm, struct hpi_response *phr)
1313 struct hpi_hw_obj *phw = pao->priv;
1314 struct bus_master_interface *interface = phw->p_interface_buffer;
1315 struct hpi_hostbuffer_status *status;
1316 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1317 hw_message(pao, phm, phr);
1318 return;
1321 status = &interface->instream_host_buffer_status[phm->obj_index];
1323 hpi_init_response(phr, phm->object, phm->function, 0);
1325 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1326 phr->u.d.u.stream_info.samples_transferred =
1327 status->samples_processed;
1328 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1329 phr->u.d.u.stream_info.data_available =
1330 instream_get_bytes_available(status);
1331 phr->u.d.u.stream_info.auxiliary_data_available =
1332 status->auxiliary_data_available;
1335 /*****************************************************************************/
1336 /* LOW-LEVEL */
1337 #define HPI6205_MAX_FILES_TO_LOAD 2
1339 static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1340 u32 *pos_error_code)
1342 struct hpi_hw_obj *phw = pao->priv;
1343 struct dsp_code dsp_code;
1344 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1345 u16 firmware_id = pao->pci.subsys_device_id;
1346 u32 temp;
1347 int dsp = 0, i = 0;
1348 u16 err = 0;
1350 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1352 /* special cases where firmware_id != subsys ID */
1353 switch (firmware_id) {
1354 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1355 boot_code_id[0] = firmware_id;
1356 firmware_id = 0;
1357 break;
1358 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1359 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1360 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1361 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400);
1362 break;
1363 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1364 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1365 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600);
1366 break;
1367 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1368 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900);
1369 break;
1371 boot_code_id[1] = firmware_id;
1373 /* reset DSP by writing a 1 to the WARMRESET bit */
1374 temp = C6205_HDCR_WARMRESET;
1375 iowrite32(temp, phw->prHDCR);
1376 hpios_delay_micro_seconds(1000);
1378 /* check that PCI i/f was configured by EEPROM */
1379 temp = ioread32(phw->prHSR);
1380 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1381 C6205_HSR_EEREAD)
1382 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
1383 temp |= 0x04;
1384 /* disable PINTA interrupt */
1385 iowrite32(temp, phw->prHSR);
1387 /* check control register reports PCI boot mode */
1388 temp = ioread32(phw->prHDCR);
1389 if (!(temp & C6205_HDCR_PCIBOOT))
1390 return hpi6205_error(0, HPI6205_ERROR_6205_REG);
1392 /* try writing a couple of numbers to the DSP page register */
1393 /* and reading them back. */
1394 temp = 1;
1395 iowrite32(temp, phw->prDSPP);
1396 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1397 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1398 temp = 2;
1399 iowrite32(temp, phw->prDSPP);
1400 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1401 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1402 temp = 3;
1403 iowrite32(temp, phw->prDSPP);
1404 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1405 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1406 /* reset DSP page to the correct number */
1407 temp = 0;
1408 iowrite32(temp, phw->prDSPP);
1409 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1410 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1411 phw->dsp_page = 0;
1413 /* release 6713 from reset before 6205 is bootloaded.
1414 This ensures that the EMIF is inactive,
1415 and the 6713 HPI gets the correct bootmode etc
1417 if (boot_code_id[1] != 0) {
1418 /* DSP 1 is a C6713 */
1419 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1420 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
1421 hpios_delay_micro_seconds(100);
1422 /* Reset the 6713 #1 - revB */
1423 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
1425 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1426 boot_loader_read_mem32(pao, 0, 0);
1428 hpios_delay_micro_seconds(100);
1429 /* Release C6713 from reset - revB */
1430 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
1431 hpios_delay_micro_seconds(100);
1434 for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
1435 /* is there a DSP to load? */
1436 if (boot_code_id[dsp] == 0)
1437 continue;
1439 err = boot_loader_config_emif(pao, dsp);
1440 if (err)
1441 return err;
1443 err = boot_loader_test_internal_memory(pao, dsp);
1444 if (err)
1445 return err;
1447 err = boot_loader_test_external_memory(pao, dsp);
1448 if (err)
1449 return err;
1451 err = boot_loader_test_pld(pao, dsp);
1452 if (err)
1453 return err;
1455 /* write the DSP code down into the DSPs memory */
1456 dsp_code.ps_dev = pao->pci.p_os_data;
1457 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1458 pos_error_code);
1459 if (err)
1460 return err;
1462 while (1) {
1463 u32 length;
1464 u32 address;
1465 u32 type;
1466 u32 *pcode;
1468 err = hpi_dsp_code_read_word(&dsp_code, &length);
1469 if (err)
1470 break;
1471 if (length == 0xFFFFFFFF)
1472 break; /* end of code */
1474 err = hpi_dsp_code_read_word(&dsp_code, &address);
1475 if (err)
1476 break;
1477 err = hpi_dsp_code_read_word(&dsp_code, &type);
1478 if (err)
1479 break;
1480 err = hpi_dsp_code_read_block(length, &dsp_code,
1481 &pcode);
1482 if (err)
1483 break;
1484 for (i = 0; i < (int)length; i++) {
1485 err = boot_loader_write_mem32(pao, dsp,
1486 address, *pcode);
1487 if (err)
1488 break;
1489 /* dummy read every 4 words */
1490 /* for 6205 advisory 1.4.4 */
1491 if (i % 4 == 0)
1492 boot_loader_read_mem32(pao, dsp,
1493 address);
1494 pcode++;
1495 address += 4;
1499 if (err) {
1500 hpi_dsp_code_close(&dsp_code);
1501 return err;
1504 /* verify code */
1505 hpi_dsp_code_rewind(&dsp_code);
1506 while (1) {
1507 u32 length = 0;
1508 u32 address = 0;
1509 u32 type = 0;
1510 u32 *pcode = NULL;
1511 u32 data = 0;
1513 hpi_dsp_code_read_word(&dsp_code, &length);
1514 if (length == 0xFFFFFFFF)
1515 break; /* end of code */
1517 hpi_dsp_code_read_word(&dsp_code, &address);
1518 hpi_dsp_code_read_word(&dsp_code, &type);
1519 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1521 for (i = 0; i < (int)length; i++) {
1522 data = boot_loader_read_mem32(pao, dsp,
1523 address);
1524 if (data != *pcode) {
1525 err = 0;
1526 break;
1528 pcode++;
1529 address += 4;
1531 if (err)
1532 break;
1534 hpi_dsp_code_close(&dsp_code);
1535 if (err)
1536 return err;
1539 /* After bootloading all DSPs, start DSP0 running
1540 * The DSP0 code will handle starting and synchronizing with its slaves
1542 if (phw->p_interface_buffer) {
1543 /* we need to tell the card the physical PCI address */
1544 u32 physicalPC_iaddress;
1545 struct bus_master_interface *interface =
1546 phw->p_interface_buffer;
1547 u32 host_mailbox_address_on_dsp;
1548 u32 physicalPC_iaddress_verify = 0;
1549 int time_out = 10;
1550 /* set ack so we know when DSP is ready to go */
1551 /* (dwDspAck will be changed to HIF_RESET) */
1552 interface->dsp_ack = H620_HIF_UNKNOWN;
1553 wmb(); /* ensure ack is written before dsp writes back */
1555 err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1556 &physicalPC_iaddress);
1558 /* locate the host mailbox on the DSP. */
1559 host_mailbox_address_on_dsp = 0x80000000;
1560 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1561 && time_out--) {
1562 err = boot_loader_write_mem32(pao, 0,
1563 host_mailbox_address_on_dsp,
1564 physicalPC_iaddress);
1565 physicalPC_iaddress_verify =
1566 boot_loader_read_mem32(pao, 0,
1567 host_mailbox_address_on_dsp);
1570 HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
1571 /* enable interrupts */
1572 temp = ioread32(phw->prHSR);
1573 temp &= ~(u32)C6205_HSR_INTAM;
1574 iowrite32(temp, phw->prHSR);
1576 /* start code running... */
1577 temp = ioread32(phw->prHDCR);
1578 temp |= (u32)C6205_HDCR_DSPINT;
1579 iowrite32(temp, phw->prHDCR);
1581 /* give the DSP 10ms to start up */
1582 hpios_delay_micro_seconds(10000);
1583 return err;
1587 /*****************************************************************************/
1588 /* Bootloader utility functions */
1590 static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1591 u32 address)
1593 struct hpi_hw_obj *phw = pao->priv;
1594 u32 data = 0;
1595 __iomem u32 *p_data;
1597 if (dsp_index == 0) {
1598 /* DSP 0 is always C6205 */
1599 if ((address >= 0x01800000) & (address < 0x02000000)) {
1600 /* BAR1 register access */
1601 p_data = pao->pci.ap_mem_base[1] +
1602 (address & 0x007fffff) /
1603 sizeof(*pao->pci.ap_mem_base[1]);
1604 /* HPI_DEBUG_LOG(WARNING,
1605 "BAR1 access %08x\n", dwAddress); */
1606 } else {
1607 u32 dw4M_page = address >> 22L;
1608 if (dw4M_page != phw->dsp_page) {
1609 phw->dsp_page = dw4M_page;
1610 /* *INDENT OFF* */
1611 iowrite32(phw->dsp_page, phw->prDSPP);
1612 /* *INDENT-ON* */
1614 address &= 0x3fffff; /* address within 4M page */
1615 /* BAR0 memory access */
1616 p_data = pao->pci.ap_mem_base[0] +
1617 address / sizeof(u32);
1619 data = ioread32(p_data);
1620 } else if (dsp_index == 1) {
1621 /* DSP 1 is a C6713 */
1622 u32 lsb;
1623 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1624 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1625 lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
1626 data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
1627 data = (data << 16) | (lsb & 0xFFFF);
1629 return data;
1632 static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1633 u32 address, u32 data)
1635 struct hpi_hw_obj *phw = pao->priv;
1636 u16 err = 0;
1637 __iomem u32 *p_data;
1638 /* u32 dwVerifyData=0; */
1640 if (dsp_index == 0) {
1641 /* DSP 0 is always C6205 */
1642 if ((address >= 0x01800000) & (address < 0x02000000)) {
1643 /* BAR1 - DSP register access using */
1644 /* Non-prefetchable PCI access */
1645 p_data = pao->pci.ap_mem_base[1] +
1646 (address & 0x007fffff) /
1647 sizeof(*pao->pci.ap_mem_base[1]);
1648 } else {
1649 /* BAR0 access - all of DSP memory using */
1650 /* pre-fetchable PCI access */
1651 u32 dw4M_page = address >> 22L;
1652 if (dw4M_page != phw->dsp_page) {
1653 phw->dsp_page = dw4M_page;
1654 /* *INDENT-OFF* */
1655 iowrite32(phw->dsp_page, phw->prDSPP);
1656 /* *INDENT-ON* */
1658 address &= 0x3fffff; /* address within 4M page */
1659 p_data = pao->pci.ap_mem_base[0] +
1660 address / sizeof(u32);
1662 iowrite32(data, p_data);
1663 } else if (dsp_index == 1) {
1664 /* DSP 1 is a C6713 */
1665 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1666 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1668 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1669 boot_loader_read_mem32(pao, 0, 0);
1671 boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1672 boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1674 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1675 boot_loader_read_mem32(pao, 0, 0);
1676 } else
1677 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1678 return err;
1681 static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1683 u16 err = 0;
1685 if (dsp_index == 0) {
1686 u32 setting;
1688 /* DSP 0 is always C6205 */
1690 /* Set the EMIF */
1691 /* memory map of C6205 */
1692 /* 00000000-0000FFFF 16Kx32 internal program */
1693 /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
1695 /* EMIF config */
1696 /*------------ */
1697 /* Global EMIF control */
1698 boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
1699 #define WS_OFS 28
1700 #define WST_OFS 22
1701 #define WH_OFS 20
1702 #define RS_OFS 16
1703 #define RST_OFS 8
1704 #define MTYPE_OFS 4
1705 #define RH_OFS 0
1707 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1708 setting = 0x00000030;
1709 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1710 if (setting != boot_loader_read_mem32(pao, dsp_index,
1711 0x01800008))
1712 return hpi6205_error(dsp_index,
1713 HPI6205_ERROR_DSP_EMIF);
1715 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1716 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1717 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1718 /* WST should be 71, but 63 is max possible */
1719 setting =
1720 (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
1721 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1722 (2L << MTYPE_OFS);
1723 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1724 if (setting != boot_loader_read_mem32(pao, dsp_index,
1725 0x01800004))
1726 return hpi6205_error(dsp_index,
1727 HPI6205_ERROR_DSP_EMIF);
1729 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1730 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1731 /* plenty of wait states */
1732 setting =
1733 (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
1734 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1735 (2L << MTYPE_OFS);
1736 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1737 if (setting != boot_loader_read_mem32(pao, dsp_index,
1738 0x01800010))
1739 return hpi6205_error(dsp_index,
1740 HPI6205_ERROR_DSP_EMIF);
1742 /* EMIF CE3 setup - 32 bit async. */
1743 /* This is the PLD on the ASI5000 cards only */
1744 setting =
1745 (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
1746 (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
1747 (2L << MTYPE_OFS);
1748 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1749 if (setting != boot_loader_read_mem32(pao, dsp_index,
1750 0x01800014))
1751 return hpi6205_error(dsp_index,
1752 HPI6205_ERROR_DSP_EMIF);
1754 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1755 /* need to use this else DSP code crashes? */
1756 boot_loader_write_mem32(pao, dsp_index, 0x01800018,
1757 0x07117000);
1759 /* EMIF SDRAM Refresh Timing */
1760 /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
1761 boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1762 0x00000410);
1764 } else if (dsp_index == 1) {
1765 /* test access to the C6713s HPI registers */
1766 u32 write_data = 0, read_data = 0, i = 0;
1768 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1769 write_data = 1;
1770 boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
1771 boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
1772 /* C67 HPI is on lower 16bits of 32bit EMIF */
1773 read_data =
1774 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1775 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,
1779 read_data);
1781 return err;
1783 /* HPIA - walking ones test */
1784 write_data = 1;
1785 for (i = 0; i < 32; i++) {
1786 boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
1787 write_data);
1788 boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
1789 (write_data >> 16));
1790 read_data =
1791 0xFFFF & boot_loader_read_mem32(pao, 0,
1792 HPIAL_ADDR);
1793 read_data =
1794 read_data | ((0xFFFF &
1795 boot_loader_read_mem32(pao, 0,
1796 HPIAH_ADDR))
1797 << 16);
1798 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",
1802 write_data, read_data);
1803 return err;
1805 write_data = write_data << 1;
1808 /* setup C67x PLL
1809 * ** C6713 datasheet says we cannot program PLL from HPI,
1810 * and indeed if we try to set the PLL multiply from the HPI,
1811 * the PLL does not seem to lock, so we enable the PLL and
1812 * use the default multiply of x 7, which for a 27MHz clock
1813 * gives a DSP speed of 189MHz
1815 /* bypass PLL */
1816 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
1817 hpios_delay_micro_seconds(1000);
1818 /* EMIF = 189/3=63MHz */
1819 boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
1820 /* peri = 189/2 */
1821 boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
1822 /* cpu = 189/1 */
1823 boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
1824 hpios_delay_micro_seconds(1000);
1825 /* ** SGT test to take GPO3 high when we start the PLL */
1826 /* and low when the delay is completed */
1827 /* FSX0 <- '1' (GPO3) */
1828 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
1829 /* PLL not bypassed */
1830 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
1831 hpios_delay_micro_seconds(1000);
1832 /* FSX0 <- '0' (GPO3) */
1833 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
1835 /* 6205 EMIF CE1 resetup - 32 bit async. */
1836 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1837 boot_loader_write_mem32(pao, 0, 0x01800004, /* CE1 */
1838 (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
1839 (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
1840 (2L << MTYPE_OFS));
1842 hpios_delay_micro_seconds(1000);
1844 /* check that we can read one of the PLL registers */
1845 /* PLL should not be bypassed! */
1846 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1847 != 0x0001) {
1848 err = hpi6205_error(dsp_index,
1849 HPI6205_ERROR_C6713_PLL);
1850 return err;
1852 /* setup C67x EMIF (note this is the only use of
1853 BAR1 via BootLoader_WriteMem32) */
1854 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1855 0x000034A8);
1856 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1857 0x00000030);
1858 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1859 0x001BDF29);
1860 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1861 0x47117000);
1862 boot_loader_write_mem32(pao, dsp_index,
1863 C6713_EMIF_SDRAMTIMING, 0x00000410);
1865 hpios_delay_micro_seconds(1000);
1866 } else if (dsp_index == 2) {
1867 /* DSP 2 is a C6713 */
1869 } else
1870 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1871 return err;
1874 static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1875 u32 start_address, u32 length)
1877 u32 i = 0, j = 0;
1878 u32 test_addr = 0;
1879 u32 test_data = 0, data = 0;
1881 length = 1000;
1883 /* for 1st word, test each bit in the 32bit word, */
1884 /* dwLength specifies number of 32bit words to test */
1885 /*for(i=0; i<dwLength; i++) */
1886 i = 0;
1888 test_addr = start_address + i * 4;
1889 test_data = 0x00000001;
1890 for (j = 0; j < 32; j++) {
1891 boot_loader_write_mem32(pao, dsp_index, test_addr,
1892 test_data);
1893 data = boot_loader_read_mem32(pao, dsp_index,
1894 test_addr);
1895 if (data != test_data) {
1896 HPI_DEBUG_LOG(VERBOSE,
1897 "memtest error details "
1898 "%08x %08x %08x %i\n", test_addr,
1899 test_data, data, dsp_index);
1900 return 1; /* error */
1902 test_data = test_data << 1;
1903 } /* for(j) */
1904 } /* for(i) */
1906 /* for the next 100 locations test each location, leaving it as zero */
1907 /* write a zero to the next word in memory before we read */
1908 /* the previous write to make sure every memory location is unique */
1909 for (i = 0; i < 100; i++) {
1910 test_addr = start_address + i * 4;
1911 test_data = 0xA5A55A5A;
1912 boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
1913 boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
1914 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1915 if (data != test_data) {
1916 HPI_DEBUG_LOG(VERBOSE,
1917 "memtest error details "
1918 "%08x %08x %08x %i\n", test_addr, test_data,
1919 data, dsp_index);
1920 return 1; /* error */
1922 /* leave location as zero */
1923 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1926 /* zero out entire memory block */
1927 for (i = 0; i < length; i++) {
1928 test_addr = start_address + i * 4;
1929 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1931 return 0;
1934 static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1935 int dsp_index)
1937 int err = 0;
1938 if (dsp_index == 0) {
1939 /* DSP 0 is a C6205 */
1940 /* 64K prog mem */
1941 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1942 0x10000);
1943 if (!err)
1944 /* 64K data mem */
1945 err = boot_loader_test_memory(pao, dsp_index,
1946 0x80000000, 0x10000);
1947 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1948 /* DSP 1&2 are a C6713 */
1949 /* 192K internal mem */
1950 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1951 0x30000);
1952 if (!err)
1953 /* 64K internal mem / L2 cache */
1954 err = boot_loader_test_memory(pao, dsp_index,
1955 0x00030000, 0x10000);
1956 } else
1957 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1959 if (err)
1960 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1961 else
1962 return 0;
1965 static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1966 int dsp_index)
1968 u32 dRAM_start_address = 0;
1969 u32 dRAM_size = 0;
1971 if (dsp_index == 0) {
1972 /* only test for SDRAM if an ASI5000 card */
1973 if (pao->pci.subsys_device_id == 0x5000) {
1974 /* DSP 0 is always C6205 */
1975 dRAM_start_address = 0x00400000;
1976 dRAM_size = 0x200000;
1977 /*dwDRAMinc=1024; */
1978 } else
1979 return 0;
1980 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1981 /* DSP 1 is a C6713 */
1982 dRAM_start_address = 0x80000000;
1983 dRAM_size = 0x200000;
1984 /*dwDRAMinc=1024; */
1985 } else
1986 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1988 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1989 dRAM_size))
1990 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
1991 return 0;
1994 static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1996 u32 data = 0;
1997 if (dsp_index == 0) {
1998 /* only test for DSP0 PLD on ASI5000 card */
1999 if (pao->pci.subsys_device_id == 0x5000) {
2000 /* PLD is located at CE3=0x03000000 */
2001 data = boot_loader_read_mem32(pao, dsp_index,
2002 0x03000008);
2003 if ((data & 0xF) != 0x5)
2004 return hpi6205_error(dsp_index,
2005 HPI6205_ERROR_DSP_PLD);
2006 data = boot_loader_read_mem32(pao, dsp_index,
2007 0x0300000C);
2008 if ((data & 0xF) != 0xA)
2009 return hpi6205_error(dsp_index,
2010 HPI6205_ERROR_DSP_PLD);
2012 } else if (dsp_index == 1) {
2013 /* DSP 1 is a C6713 */
2014 if (pao->pci.subsys_device_id == 0x8700) {
2015 /* PLD is located at CE1=0x90000000 */
2016 data = boot_loader_read_mem32(pao, dsp_index,
2017 0x90000010);
2018 if ((data & 0xFF) != 0xAA)
2019 return hpi6205_error(dsp_index,
2020 HPI6205_ERROR_DSP_PLD);
2021 /* 8713 - LED on */
2022 boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2023 0x02);
2026 return 0;
2029 /** Transfer data to or from DSP
2030 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2032 static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2033 u32 data_size, int operation)
2035 struct hpi_hw_obj *phw = pao->priv;
2036 u32 data_transferred = 0;
2037 u16 err = 0;
2038 #ifndef HPI6205_NO_HSR_POLL
2039 u32 time_out;
2040 #endif
2041 u32 temp2;
2042 struct bus_master_interface *interface = phw->p_interface_buffer;
2044 if (!p_data)
2045 return HPI_ERROR_INVALID_DATA_TRANSFER;
2047 data_size &= ~3L; /* round data_size down to nearest 4 bytes */
2049 /* make sure state is IDLE */
2050 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2051 return HPI_ERROR_DSP_HARDWARE;
2053 while (data_transferred < data_size) {
2054 u32 this_copy = data_size - data_transferred;
2056 if (this_copy > HPI6205_SIZEOF_DATA)
2057 this_copy = HPI6205_SIZEOF_DATA;
2059 if (operation == H620_HIF_SEND_DATA)
2060 memcpy((void *)&interface->u.b_data[0],
2061 &p_data[data_transferred], this_copy);
2063 interface->transfer_size_in_bytes = this_copy;
2065 #ifdef HPI6205_NO_HSR_POLL
2066 /* DSP must change this back to nOperation */
2067 interface->dsp_ack = H620_HIF_IDLE;
2068 #endif
2070 send_dsp_command(phw, operation);
2072 #ifdef HPI6205_NO_HSR_POLL
2073 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2074 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2075 HPI6205_TIMEOUT - temp2, this_copy);
2077 if (!temp2) {
2078 /* timed out */
2079 HPI_DEBUG_LOG(ERROR,
2080 "timed out waiting for " "state %d got %d\n",
2081 operation, interface->dsp_ack);
2083 break;
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;
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");
2102 if(interface->dwDspAck != nOperation) {
2103 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2104 expected %d \n",
2105 interface->dwDspAck,nOperation);
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;
2116 /* reset the interrupt from the DSP */
2117 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2118 #endif
2119 if (operation == H620_HIF_GET_DATA)
2120 memcpy(&p_data[data_transferred],
2121 (void *)&interface->u.b_data[0], this_copy);
2123 data_transferred += this_copy;
2125 if (interface->dsp_ack != operation)
2126 HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
2127 interface->dsp_ack, operation);
2128 /* err=HPI_ERROR_DSP_HARDWARE; */
2130 send_dsp_command(phw, H620_HIF_IDLE);
2132 return err;
2135 /* wait for up to timeout_us microseconds for the DSP
2136 to signal state by DMA into dwDspAck
2138 static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2140 struct bus_master_interface *interface = phw->p_interface_buffer;
2141 int t = timeout_us / 4;
2143 rmb(); /* ensure interface->dsp_ack is up to date */
2144 while ((interface->dsp_ack != state) && --t) {
2145 hpios_delay_micro_seconds(4);
2146 rmb(); /* DSP changes dsp_ack by DMA */
2149 /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2150 return t * 4;
2153 /* set the busmaster interface to cmd, then interrupt the DSP */
2154 static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2156 struct bus_master_interface *interface = phw->p_interface_buffer;
2158 u32 r;
2160 interface->host_cmd = cmd;
2161 wmb(); /* DSP gets state by DMA, make sure it is written to memory */
2162 /* before we interrupt the DSP */
2163 r = ioread32(phw->prHDCR);
2164 r |= (u32)C6205_HDCR_DSPINT;
2165 iowrite32(r, phw->prHDCR);
2166 r &= ~(u32)C6205_HDCR_DSPINT;
2167 iowrite32(r, phw->prHDCR);
2170 static unsigned int message_count;
2172 static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2173 struct hpi_message *phm, struct hpi_response *phr)
2175 #ifndef HPI6205_NO_HSR_POLL
2176 u32 temp2;
2177 #endif
2178 u32 time_out, time_out2;
2179 struct hpi_hw_obj *phw = pao->priv;
2180 struct bus_master_interface *interface = phw->p_interface_buffer;
2181 u16 err = 0;
2183 message_count++;
2184 /* Assume buffer of type struct bus_master_interface
2185 is allocated "noncacheable" */
2187 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2188 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2189 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2191 interface->u.message_buffer = *phm;
2192 /* signal we want a response */
2193 send_dsp_command(phw, H620_HIF_GET_RESP);
2195 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2197 if (time_out2 == 0) {
2198 HPI_DEBUG_LOG(ERROR,
2199 "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2200 message_count, interface->dsp_ack);
2201 } else {
2202 HPI_DEBUG_LOG(VERBOSE,
2203 "(%u) transition to GET_RESP after %u\n",
2204 message_count, HPI6205_TIMEOUT - time_out2);
2206 /* spin waiting on HIF interrupt flag (end of msg process) */
2207 time_out = HPI6205_TIMEOUT;
2209 #ifndef HPI6205_NO_HSR_POLL
2210 temp2 = 0;
2211 while ((temp2 == 0) && --time_out) {
2212 temp2 = ioread32(phw->prHSR);
2213 temp2 &= C6205_HSR_INTSRC;
2214 hpios_delay_micro_seconds(1);
2216 if (temp2 == C6205_HSR_INTSRC) {
2217 rmb(); /* ensure we see latest value for dsp_ack */
2218 if ((interface->dsp_ack != H620_HIF_GET_RESP)) {
2219 HPI_DEBUG_LOG(DEBUG,
2220 "(%u)interface->dsp_ack(0x%x) != "
2221 "H620_HIF_GET_RESP, t=%u\n", message_count,
2222 interface->dsp_ack,
2223 HPI6205_TIMEOUT - time_out);
2224 } else {
2225 HPI_DEBUG_LOG(VERBOSE,
2226 "(%u)int with GET_RESP after %u\n",
2227 message_count, HPI6205_TIMEOUT - time_out);
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);
2237 /* reset the interrupt from the DSP */
2238 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2239 #endif
2241 /* read the result */
2242 if (time_out != 0)
2243 *phr = interface->u.response_buffer;
2245 /* set interface back to idle */
2246 send_dsp_command(phw, H620_HIF_IDLE);
2248 if ((time_out == 0) || (time_out2 == 0)) {
2249 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2250 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
2252 /* special case for adapter close - */
2253 /* wait for the DSP to indicate it is idle */
2254 if (phm->function == HPI_ADAPTER_CLOSE) {
2255 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2256 HPI_DEBUG_LOG(DEBUG,
2257 "timeout waiting for idle "
2258 "(on adapter_close)\n");
2259 return hpi6205_error(0,
2260 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2263 err = hpi_validate_response(phm, phr);
2264 return err;
2267 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2268 struct hpi_response *phr)
2271 u16 err = 0;
2273 hpios_dsplock_lock(pao);
2275 err = message_response_sequence(pao, phm, phr);
2277 /* maybe an error response */
2278 if (err) {
2279 /* something failed in the HPI/DSP interface */
2280 phr->error = err;
2281 pao->dsp_crashed++;
2283 /* just the header of the response is valid */
2284 phr->size = sizeof(struct hpi_response_header);
2285 goto err;
2286 } else
2287 pao->dsp_crashed = 0;
2289 if (phr->error != 0) /* something failed in the DSP */
2290 goto err;
2292 switch (phm->function) {
2293 case HPI_OSTREAM_WRITE:
2294 case HPI_ISTREAM_ANC_WRITE:
2295 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2296 phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
2297 break;
2299 case HPI_ISTREAM_READ:
2300 case HPI_OSTREAM_ANC_READ:
2301 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2302 phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2303 break;
2305 case HPI_CONTROL_SET_STATE:
2306 if (phm->object == HPI_OBJ_CONTROLEX
2307 && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2308 err = hpi6205_transfer_data(pao,
2309 phm->u.cx.u.cobranet_bigdata.pb_data,
2310 phm->u.cx.u.cobranet_bigdata.byte_count,
2311 H620_HIF_SEND_DATA);
2312 break;
2314 case HPI_CONTROL_GET_STATE:
2315 if (phm->object == HPI_OBJ_CONTROLEX
2316 && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2317 err = hpi6205_transfer_data(pao,
2318 phm->u.cx.u.cobranet_bigdata.pb_data,
2319 phr->u.cx.u.cobranet_data.byte_count,
2320 H620_HIF_GET_DATA);
2321 break;
2323 phr->error = err;
2325 err:
2326 hpios_dsplock_unlock(pao);
2328 return;