Staging: samsung-laptop: Added support for Samsung NC10 laptop
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / asihpi / hpi6205.c
blob2672f6591ceb7246b9a0a24ecbfa8f4cf2c46288
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);
647 if (!phw->p_cache)
648 err = HPI_ERROR_MEMORY_ALLOC;
650 if (!err) {
651 err = hpios_locked_mem_get_phys_addr(&phw->
652 h_control_cache, &phys_addr);
653 interface->control_cache.physical_address32 =
654 phys_addr;
657 if (!err)
658 pao->has_control_cache = 1;
659 else {
660 if (hpios_locked_mem_valid(&phw->h_control_cache))
661 hpios_locked_mem_free(&phw->h_control_cache);
662 pao->has_control_cache = 0;
665 /* allocate bus mastering async buffer and tell the DSP about it */
666 if (interface->async_buffer.b.size) {
667 err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
668 interface->async_buffer.b.size *
669 sizeof(struct hpi_async_event), pao->pci.p_os_data);
670 if (!err)
671 err = hpios_locked_mem_get_virt_addr
672 (&phw->h_async_event_buffer, (void *)
673 &phw->p_async_event_buffer);
674 if (!err)
675 memset((void *)phw->p_async_event_buffer, 0,
676 interface->async_buffer.b.size *
677 sizeof(struct hpi_async_event));
678 if (!err) {
679 err = hpios_locked_mem_get_phys_addr
680 (&phw->h_async_event_buffer, &phys_addr);
681 interface->async_buffer.physical_address32 =
682 phys_addr;
684 if (err) {
685 if (hpios_locked_mem_valid(&phw->
686 h_async_event_buffer)) {
687 hpios_locked_mem_free
688 (&phw->h_async_event_buffer);
689 phw->p_async_event_buffer = NULL;
693 send_dsp_command(phw, H620_HIF_IDLE);
696 struct hpi_message hM;
697 struct hpi_response hR;
698 u32 max_streams;
700 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
701 memset(&hM, 0, sizeof(hM));
702 hM.type = HPI_TYPE_MESSAGE;
703 hM.size = sizeof(hM);
704 hM.object = HPI_OBJ_ADAPTER;
705 hM.function = HPI_ADAPTER_GET_INFO;
706 hM.adapter_index = 0;
707 memset(&hR, 0, sizeof(hR));
708 hR.size = sizeof(hR);
710 err = message_response_sequence(pao, &hM, &hR);
711 if (err) {
712 HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
713 err);
714 return err;
716 if (hR.error)
717 return hR.error;
719 pao->adapter_type = hR.u.a.adapter_type;
720 pao->index = hR.u.a.adapter_index;
722 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
724 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
725 65536, pao->pci.p_os_data);
727 HPI_DEBUG_LOG(VERBOSE,
728 "got adapter info type %x index %d serial %d\n",
729 hR.u.a.adapter_type, hR.u.a.adapter_index,
730 hR.u.a.serial_number);
733 pao->open = 0; /* upon creation the adapter is closed */
735 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
736 return 0;
739 /** Free memory areas allocated by adapter
740 * this routine is called from SubSysDeleteAdapter,
741 * and SubSysCreateAdapter if duplicate index
743 static void delete_adapter_obj(struct hpi_adapter_obj *pao)
745 struct hpi_hw_obj *phw;
746 int i;
748 phw = pao->priv;
750 if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
751 hpios_locked_mem_free(&phw->h_async_event_buffer);
752 phw->p_async_event_buffer = NULL;
755 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
756 hpios_locked_mem_free(&phw->h_control_cache);
757 hpi_free_control_cache(phw->p_cache);
760 if (hpios_locked_mem_valid(&phw->h_locked_mem)) {
761 hpios_locked_mem_free(&phw->h_locked_mem);
762 phw->p_interface_buffer = NULL;
765 for (i = 0; i < HPI_MAX_STREAMS; i++)
766 if (hpios_locked_mem_valid(&phw->instream_host_buffers[i])) {
767 hpios_locked_mem_free(&phw->instream_host_buffers[i]);
768 /*?phw->InStreamHostBuffers[i] = NULL; */
769 phw->instream_host_buffer_size[i] = 0;
772 for (i = 0; i < HPI_MAX_STREAMS; i++)
773 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[i])) {
774 hpios_locked_mem_free(&phw->outstream_host_buffers
775 [i]);
776 phw->outstream_host_buffer_size[i] = 0;
779 hpios_locked_mem_unprepare(pao->pci.p_os_data);
781 hpi_delete_adapter(pao);
782 kfree(phw);
785 /*****************************************************************************/
786 /* OutStream Host buffer functions */
788 /** Allocate or attach buffer for busmastering
790 static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
791 struct hpi_message *phm, struct hpi_response *phr)
793 u16 err = 0;
794 u32 command = phm->u.d.u.buffer.command;
795 struct hpi_hw_obj *phw = pao->priv;
796 struct bus_master_interface *interface = phw->p_interface_buffer;
798 hpi_init_response(phr, phm->object, phm->function, 0);
800 if (command == HPI_BUFFER_CMD_EXTERNAL
801 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
802 /* ALLOC phase, allocate a buffer with power of 2 size,
803 get its bus address for PCI bus mastering
805 phm->u.d.u.buffer.buffer_size =
806 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
807 /* return old size and allocated size,
808 so caller can detect change */
809 phr->u.d.u.stream_info.data_available =
810 phw->outstream_host_buffer_size[phm->obj_index];
811 phr->u.d.u.stream_info.buffer_size =
812 phm->u.d.u.buffer.buffer_size;
814 if (phw->outstream_host_buffer_size[phm->obj_index] ==
815 phm->u.d.u.buffer.buffer_size) {
816 /* Same size, no action required */
817 return;
820 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
821 obj_index]))
822 hpios_locked_mem_free(&phw->outstream_host_buffers
823 [phm->obj_index]);
825 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
826 [phm->obj_index], phm->u.d.u.buffer.buffer_size,
827 pao->pci.p_os_data);
829 if (err) {
830 phr->error = HPI_ERROR_INVALID_DATASIZE;
831 phw->outstream_host_buffer_size[phm->obj_index] = 0;
832 return;
835 err = hpios_locked_mem_get_phys_addr
836 (&phw->outstream_host_buffers[phm->obj_index],
837 &phm->u.d.u.buffer.pci_address);
838 /* get the phys addr into msg for single call alloc caller
839 * needs to do this for split alloc (or use the same message)
840 * return the phy address for split alloc in the respose too
842 phr->u.d.u.stream_info.auxiliary_data_available =
843 phm->u.d.u.buffer.pci_address;
845 if (err) {
846 hpios_locked_mem_free(&phw->outstream_host_buffers
847 [phm->obj_index]);
848 phw->outstream_host_buffer_size[phm->obj_index] = 0;
849 phr->error = HPI_ERROR_MEMORY_ALLOC;
850 return;
854 if (command == HPI_BUFFER_CMD_EXTERNAL
855 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
856 /* GRANT phase. Set up the BBM status, tell the DSP about
857 the buffer so it can start using BBM.
859 struct hpi_hostbuffer_status *status;
861 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
862 buffer_size - 1)) {
863 HPI_DEBUG_LOG(ERROR,
864 "buffer size must be 2^N not %d\n",
865 phm->u.d.u.buffer.buffer_size);
866 phr->error = HPI_ERROR_INVALID_DATASIZE;
867 return;
869 phw->outstream_host_buffer_size[phm->obj_index] =
870 phm->u.d.u.buffer.buffer_size;
871 status = &interface->outstream_host_buffer_status[phm->
872 obj_index];
873 status->samples_processed = 0;
874 status->stream_state = HPI_STATE_STOPPED;
875 status->dSP_index = 0;
876 status->host_index = status->dSP_index;
877 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
879 hw_message(pao, phm, phr);
881 if (phr->error
882 && hpios_locked_mem_valid(&phw->
883 outstream_host_buffers[phm->obj_index])) {
884 hpios_locked_mem_free(&phw->outstream_host_buffers
885 [phm->obj_index]);
886 phw->outstream_host_buffer_size[phm->obj_index] = 0;
891 static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
892 struct hpi_message *phm, struct hpi_response *phr)
894 struct hpi_hw_obj *phw = pao->priv;
895 struct bus_master_interface *interface = phw->p_interface_buffer;
896 struct hpi_hostbuffer_status *status;
897 u8 *p_bbm_data;
899 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
900 obj_index])) {
901 if (hpios_locked_mem_get_virt_addr(&phw->
902 outstream_host_buffers[phm->obj_index],
903 (void *)&p_bbm_data)) {
904 phr->error = HPI_ERROR_INVALID_OPERATION;
905 return;
907 status = &interface->outstream_host_buffer_status[phm->
908 obj_index];
909 hpi_init_response(phr, HPI_OBJ_OSTREAM,
910 HPI_OSTREAM_HOSTBUFFER_GET_INFO, 0);
911 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
912 phr->u.d.u.hostbuffer_info.p_status = status;
913 } else {
914 hpi_init_response(phr, HPI_OBJ_OSTREAM,
915 HPI_OSTREAM_HOSTBUFFER_GET_INFO,
916 HPI_ERROR_INVALID_OPERATION);
920 static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
921 struct hpi_message *phm, struct hpi_response *phr)
923 struct hpi_hw_obj *phw = pao->priv;
924 u32 command = phm->u.d.u.buffer.command;
926 if (phw->outstream_host_buffer_size[phm->obj_index]) {
927 if (command == HPI_BUFFER_CMD_EXTERNAL
928 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
929 phw->outstream_host_buffer_size[phm->obj_index] = 0;
930 hw_message(pao, phm, phr);
931 /* Tell adapter to stop using the host buffer. */
933 if (command == HPI_BUFFER_CMD_EXTERNAL
934 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
935 hpios_locked_mem_free(&phw->outstream_host_buffers
936 [phm->obj_index]);
938 /* Should HPI_ERROR_INVALID_OPERATION be returned
939 if no host buffer is allocated? */
940 else
941 hpi_init_response(phr, HPI_OBJ_OSTREAM,
942 HPI_OSTREAM_HOSTBUFFER_FREE, 0);
946 static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
948 return status->size_in_bytes - (status->host_index -
949 status->dSP_index);
952 static void outstream_write(struct hpi_adapter_obj *pao,
953 struct hpi_message *phm, struct hpi_response *phr)
955 struct hpi_hw_obj *phw = pao->priv;
956 struct bus_master_interface *interface = phw->p_interface_buffer;
957 struct hpi_hostbuffer_status *status;
958 u32 space_available;
960 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
961 /* there is no BBM buffer, write via message */
962 hw_message(pao, phm, phr);
963 return;
966 hpi_init_response(phr, phm->object, phm->function, 0);
967 status = &interface->outstream_host_buffer_status[phm->obj_index];
969 if (phw->flag_outstream_just_reset[phm->obj_index]) {
970 /* First OutStremWrite() call following reset will write data to the
971 adapter's buffers, reducing delay before stream can start. The DSP
972 takes care of setting the stream data format using format information
973 embedded in phm.
975 int partial_write = 0;
976 unsigned int original_size = 0;
978 phw->flag_outstream_just_reset[phm->obj_index] = 0;
980 /* Send the first buffer to the DSP the old way. */
981 /* Limit size of first transfer - */
982 /* expect that this will not usually be triggered. */
983 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
984 partial_write = 1;
985 original_size = phm->u.d.u.data.data_size;
986 phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
988 /* write it */
989 phm->function = HPI_OSTREAM_WRITE;
990 hw_message(pao, phm, phr);
992 if (phr->error)
993 return;
995 /* update status information that the DSP would typically
996 * update (and will update next time the DSP
997 * buffer update task reads data from the host BBM buffer)
999 status->auxiliary_data_available = phm->u.d.u.data.data_size;
1000 status->host_index += phm->u.d.u.data.data_size;
1001 status->dSP_index += phm->u.d.u.data.data_size;
1003 /* if we did a full write, we can return from here. */
1004 if (!partial_write)
1005 return;
1007 /* tweak buffer parameters and let the rest of the */
1008 /* buffer land in internal BBM buffer */
1009 phm->u.d.u.data.data_size =
1010 original_size - HPI6205_SIZEOF_DATA;
1011 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1014 space_available = outstream_get_space_available(status);
1015 if (space_available < phm->u.d.u.data.data_size) {
1016 phr->error = HPI_ERROR_INVALID_DATASIZE;
1017 return;
1020 /* HostBuffers is used to indicate host buffer is internally allocated.
1021 otherwise, assumed external, data written externally */
1022 if (phm->u.d.u.data.pb_data
1023 && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
1024 obj_index])) {
1025 u8 *p_bbm_data;
1026 u32 l_first_write;
1027 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1029 if (hpios_locked_mem_get_virt_addr(&phw->
1030 outstream_host_buffers[phm->obj_index],
1031 (void *)&p_bbm_data)) {
1032 phr->error = HPI_ERROR_INVALID_OPERATION;
1033 return;
1036 /* either all data,
1037 or enough to fit from current to end of BBM buffer */
1038 l_first_write =
1039 min(phm->u.d.u.data.data_size,
1040 status->size_in_bytes -
1041 (status->host_index & (status->size_in_bytes - 1)));
1043 memcpy(p_bbm_data +
1044 (status->host_index & (status->size_in_bytes - 1)),
1045 p_app_data, l_first_write);
1046 /* remaining data if any */
1047 memcpy(p_bbm_data, p_app_data + l_first_write,
1048 phm->u.d.u.data.data_size - l_first_write);
1050 status->host_index += phm->u.d.u.data.data_size;
1053 static void outstream_get_info(struct hpi_adapter_obj *pao,
1054 struct hpi_message *phm, struct hpi_response *phr)
1056 struct hpi_hw_obj *phw = pao->priv;
1057 struct bus_master_interface *interface = phw->p_interface_buffer;
1058 struct hpi_hostbuffer_status *status;
1060 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1061 hw_message(pao, phm, phr);
1062 return;
1065 hpi_init_response(phr, phm->object, phm->function, 0);
1067 status = &interface->outstream_host_buffer_status[phm->obj_index];
1069 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1070 phr->u.d.u.stream_info.samples_transferred =
1071 status->samples_processed;
1072 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1073 phr->u.d.u.stream_info.data_available =
1074 status->size_in_bytes - outstream_get_space_available(status);
1075 phr->u.d.u.stream_info.auxiliary_data_available =
1076 status->auxiliary_data_available;
1079 static void outstream_start(struct hpi_adapter_obj *pao,
1080 struct hpi_message *phm, struct hpi_response *phr)
1082 hw_message(pao, phm, phr);
1085 static void outstream_reset(struct hpi_adapter_obj *pao,
1086 struct hpi_message *phm, struct hpi_response *phr)
1088 struct hpi_hw_obj *phw = pao->priv;
1089 phw->flag_outstream_just_reset[phm->obj_index] = 1;
1090 hw_message(pao, phm, phr);
1093 static void outstream_open(struct hpi_adapter_obj *pao,
1094 struct hpi_message *phm, struct hpi_response *phr)
1096 outstream_reset(pao, phm, phr);
1099 /*****************************************************************************/
1100 /* InStream Host buffer functions */
1102 static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1103 struct hpi_message *phm, struct hpi_response *phr)
1105 u16 err = 0;
1106 u32 command = phm->u.d.u.buffer.command;
1107 struct hpi_hw_obj *phw = pao->priv;
1108 struct bus_master_interface *interface = phw->p_interface_buffer;
1110 hpi_init_response(phr, phm->object, phm->function, 0);
1112 if (command == HPI_BUFFER_CMD_EXTERNAL
1113 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1115 phm->u.d.u.buffer.buffer_size =
1116 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
1117 phr->u.d.u.stream_info.data_available =
1118 phw->instream_host_buffer_size[phm->obj_index];
1119 phr->u.d.u.stream_info.buffer_size =
1120 phm->u.d.u.buffer.buffer_size;
1122 if (phw->instream_host_buffer_size[phm->obj_index] ==
1123 phm->u.d.u.buffer.buffer_size) {
1124 /* Same size, no action required */
1125 return;
1128 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1129 obj_index]))
1130 hpios_locked_mem_free(&phw->instream_host_buffers
1131 [phm->obj_index]);
1133 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1134 obj_index], phm->u.d.u.buffer.buffer_size,
1135 pao->pci.p_os_data);
1137 if (err) {
1138 phr->error = HPI_ERROR_INVALID_DATASIZE;
1139 phw->instream_host_buffer_size[phm->obj_index] = 0;
1140 return;
1143 err = hpios_locked_mem_get_phys_addr
1144 (&phw->instream_host_buffers[phm->obj_index],
1145 &phm->u.d.u.buffer.pci_address);
1146 /* get the phys addr into msg for single call alloc. Caller
1147 needs to do this for split alloc so return the phy address */
1148 phr->u.d.u.stream_info.auxiliary_data_available =
1149 phm->u.d.u.buffer.pci_address;
1150 if (err) {
1151 hpios_locked_mem_free(&phw->instream_host_buffers
1152 [phm->obj_index]);
1153 phw->instream_host_buffer_size[phm->obj_index] = 0;
1154 phr->error = HPI_ERROR_MEMORY_ALLOC;
1155 return;
1159 if (command == HPI_BUFFER_CMD_EXTERNAL
1160 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1161 struct hpi_hostbuffer_status *status;
1163 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1164 buffer_size - 1)) {
1165 HPI_DEBUG_LOG(ERROR,
1166 "buffer size must be 2^N not %d\n",
1167 phm->u.d.u.buffer.buffer_size);
1168 phr->error = HPI_ERROR_INVALID_DATASIZE;
1169 return;
1172 phw->instream_host_buffer_size[phm->obj_index] =
1173 phm->u.d.u.buffer.buffer_size;
1174 status = &interface->instream_host_buffer_status[phm->
1175 obj_index];
1176 status->samples_processed = 0;
1177 status->stream_state = HPI_STATE_STOPPED;
1178 status->dSP_index = 0;
1179 status->host_index = status->dSP_index;
1180 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1182 hw_message(pao, phm, phr);
1183 if (phr->error
1184 && hpios_locked_mem_valid(&phw->
1185 instream_host_buffers[phm->obj_index])) {
1186 hpios_locked_mem_free(&phw->instream_host_buffers
1187 [phm->obj_index]);
1188 phw->instream_host_buffer_size[phm->obj_index] = 0;
1193 static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1194 struct hpi_message *phm, struct hpi_response *phr)
1196 struct hpi_hw_obj *phw = pao->priv;
1197 struct bus_master_interface *interface = phw->p_interface_buffer;
1198 struct hpi_hostbuffer_status *status;
1199 u8 *p_bbm_data;
1201 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1202 obj_index])) {
1203 if (hpios_locked_mem_get_virt_addr(&phw->
1204 instream_host_buffers[phm->obj_index],
1205 (void *)&p_bbm_data)) {
1206 phr->error = HPI_ERROR_INVALID_OPERATION;
1207 return;
1209 status = &interface->instream_host_buffer_status[phm->
1210 obj_index];
1211 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1212 HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
1213 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
1214 phr->u.d.u.hostbuffer_info.p_status = status;
1215 } else {
1216 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1217 HPI_ISTREAM_HOSTBUFFER_GET_INFO,
1218 HPI_ERROR_INVALID_OPERATION);
1222 static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1223 struct hpi_message *phm, struct hpi_response *phr)
1225 struct hpi_hw_obj *phw = pao->priv;
1226 u32 command = phm->u.d.u.buffer.command;
1228 if (phw->instream_host_buffer_size[phm->obj_index]) {
1229 if (command == HPI_BUFFER_CMD_EXTERNAL
1230 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
1231 phw->instream_host_buffer_size[phm->obj_index] = 0;
1232 hw_message(pao, phm, phr);
1235 if (command == HPI_BUFFER_CMD_EXTERNAL
1236 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
1237 hpios_locked_mem_free(&phw->instream_host_buffers
1238 [phm->obj_index]);
1240 } else {
1241 /* Should HPI_ERROR_INVALID_OPERATION be returned
1242 if no host buffer is allocated? */
1243 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1244 HPI_ISTREAM_HOSTBUFFER_FREE, 0);
1250 static void instream_start(struct hpi_adapter_obj *pao,
1251 struct hpi_message *phm, struct hpi_response *phr)
1253 hw_message(pao, phm, phr);
1256 static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1258 return status->dSP_index - status->host_index;
1261 static void instream_read(struct hpi_adapter_obj *pao,
1262 struct hpi_message *phm, struct hpi_response *phr)
1264 struct hpi_hw_obj *phw = pao->priv;
1265 struct bus_master_interface *interface = phw->p_interface_buffer;
1266 struct hpi_hostbuffer_status *status;
1267 u32 data_available;
1268 u8 *p_bbm_data;
1269 u32 l_first_read;
1270 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1272 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1273 hw_message(pao, phm, phr);
1274 return;
1276 hpi_init_response(phr, phm->object, phm->function, 0);
1278 status = &interface->instream_host_buffer_status[phm->obj_index];
1279 data_available = instream_get_bytes_available(status);
1280 if (data_available < phm->u.d.u.data.data_size) {
1281 phr->error = HPI_ERROR_INVALID_DATASIZE;
1282 return;
1285 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1286 obj_index])) {
1287 if (hpios_locked_mem_get_virt_addr(&phw->
1288 instream_host_buffers[phm->obj_index],
1289 (void *)&p_bbm_data)) {
1290 phr->error = HPI_ERROR_INVALID_OPERATION;
1291 return;
1294 /* either all data,
1295 or enough to fit from current to end of BBM buffer */
1296 l_first_read =
1297 min(phm->u.d.u.data.data_size,
1298 status->size_in_bytes -
1299 (status->host_index & (status->size_in_bytes - 1)));
1301 memcpy(p_app_data,
1302 p_bbm_data +
1303 (status->host_index & (status->size_in_bytes - 1)),
1304 l_first_read);
1305 /* remaining data if any */
1306 memcpy(p_app_data + l_first_read, p_bbm_data,
1307 phm->u.d.u.data.data_size - l_first_read);
1309 status->host_index += phm->u.d.u.data.data_size;
1312 static void instream_get_info(struct hpi_adapter_obj *pao,
1313 struct hpi_message *phm, struct hpi_response *phr)
1315 struct hpi_hw_obj *phw = pao->priv;
1316 struct bus_master_interface *interface = phw->p_interface_buffer;
1317 struct hpi_hostbuffer_status *status;
1318 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1319 hw_message(pao, phm, phr);
1320 return;
1323 status = &interface->instream_host_buffer_status[phm->obj_index];
1325 hpi_init_response(phr, phm->object, phm->function, 0);
1327 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1328 phr->u.d.u.stream_info.samples_transferred =
1329 status->samples_processed;
1330 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1331 phr->u.d.u.stream_info.data_available =
1332 instream_get_bytes_available(status);
1333 phr->u.d.u.stream_info.auxiliary_data_available =
1334 status->auxiliary_data_available;
1337 /*****************************************************************************/
1338 /* LOW-LEVEL */
1339 #define HPI6205_MAX_FILES_TO_LOAD 2
1341 static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1342 u32 *pos_error_code)
1344 struct hpi_hw_obj *phw = pao->priv;
1345 struct dsp_code dsp_code;
1346 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1347 u16 firmware_id = pao->pci.subsys_device_id;
1348 u32 temp;
1349 int dsp = 0, i = 0;
1350 u16 err = 0;
1352 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1354 /* special cases where firmware_id != subsys ID */
1355 switch (firmware_id) {
1356 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1357 boot_code_id[0] = firmware_id;
1358 firmware_id = 0;
1359 break;
1360 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1361 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1362 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1363 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400);
1364 break;
1365 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1366 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1367 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600);
1368 break;
1369 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1370 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900);
1371 break;
1373 boot_code_id[1] = firmware_id;
1375 /* reset DSP by writing a 1 to the WARMRESET bit */
1376 temp = C6205_HDCR_WARMRESET;
1377 iowrite32(temp, phw->prHDCR);
1378 hpios_delay_micro_seconds(1000);
1380 /* check that PCI i/f was configured by EEPROM */
1381 temp = ioread32(phw->prHSR);
1382 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1383 C6205_HSR_EEREAD)
1384 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
1385 temp |= 0x04;
1386 /* disable PINTA interrupt */
1387 iowrite32(temp, phw->prHSR);
1389 /* check control register reports PCI boot mode */
1390 temp = ioread32(phw->prHDCR);
1391 if (!(temp & C6205_HDCR_PCIBOOT))
1392 return hpi6205_error(0, HPI6205_ERROR_6205_REG);
1394 /* try writing a couple of numbers to the DSP page register */
1395 /* and reading them back. */
1396 temp = 1;
1397 iowrite32(temp, phw->prDSPP);
1398 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1399 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1400 temp = 2;
1401 iowrite32(temp, phw->prDSPP);
1402 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1403 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1404 temp = 3;
1405 iowrite32(temp, phw->prDSPP);
1406 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1407 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1408 /* reset DSP page to the correct number */
1409 temp = 0;
1410 iowrite32(temp, phw->prDSPP);
1411 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1412 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1413 phw->dsp_page = 0;
1415 /* release 6713 from reset before 6205 is bootloaded.
1416 This ensures that the EMIF is inactive,
1417 and the 6713 HPI gets the correct bootmode etc
1419 if (boot_code_id[1] != 0) {
1420 /* DSP 1 is a C6713 */
1421 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1422 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
1423 hpios_delay_micro_seconds(100);
1424 /* Reset the 6713 #1 - revB */
1425 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
1427 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1428 boot_loader_read_mem32(pao, 0, 0);
1430 hpios_delay_micro_seconds(100);
1431 /* Release C6713 from reset - revB */
1432 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
1433 hpios_delay_micro_seconds(100);
1436 for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
1437 /* is there a DSP to load? */
1438 if (boot_code_id[dsp] == 0)
1439 continue;
1441 err = boot_loader_config_emif(pao, dsp);
1442 if (err)
1443 return err;
1445 err = boot_loader_test_internal_memory(pao, dsp);
1446 if (err)
1447 return err;
1449 err = boot_loader_test_external_memory(pao, dsp);
1450 if (err)
1451 return err;
1453 err = boot_loader_test_pld(pao, dsp);
1454 if (err)
1455 return err;
1457 /* write the DSP code down into the DSPs memory */
1458 dsp_code.ps_dev = pao->pci.p_os_data;
1459 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1460 pos_error_code);
1461 if (err)
1462 return err;
1464 while (1) {
1465 u32 length;
1466 u32 address;
1467 u32 type;
1468 u32 *pcode;
1470 err = hpi_dsp_code_read_word(&dsp_code, &length);
1471 if (err)
1472 break;
1473 if (length == 0xFFFFFFFF)
1474 break; /* end of code */
1476 err = hpi_dsp_code_read_word(&dsp_code, &address);
1477 if (err)
1478 break;
1479 err = hpi_dsp_code_read_word(&dsp_code, &type);
1480 if (err)
1481 break;
1482 err = hpi_dsp_code_read_block(length, &dsp_code,
1483 &pcode);
1484 if (err)
1485 break;
1486 for (i = 0; i < (int)length; i++) {
1487 err = boot_loader_write_mem32(pao, dsp,
1488 address, *pcode);
1489 if (err)
1490 break;
1491 /* dummy read every 4 words */
1492 /* for 6205 advisory 1.4.4 */
1493 if (i % 4 == 0)
1494 boot_loader_read_mem32(pao, dsp,
1495 address);
1496 pcode++;
1497 address += 4;
1501 if (err) {
1502 hpi_dsp_code_close(&dsp_code);
1503 return err;
1506 /* verify code */
1507 hpi_dsp_code_rewind(&dsp_code);
1508 while (1) {
1509 u32 length = 0;
1510 u32 address = 0;
1511 u32 type = 0;
1512 u32 *pcode = NULL;
1513 u32 data = 0;
1515 hpi_dsp_code_read_word(&dsp_code, &length);
1516 if (length == 0xFFFFFFFF)
1517 break; /* end of code */
1519 hpi_dsp_code_read_word(&dsp_code, &address);
1520 hpi_dsp_code_read_word(&dsp_code, &type);
1521 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1523 for (i = 0; i < (int)length; i++) {
1524 data = boot_loader_read_mem32(pao, dsp,
1525 address);
1526 if (data != *pcode) {
1527 err = 0;
1528 break;
1530 pcode++;
1531 address += 4;
1533 if (err)
1534 break;
1536 hpi_dsp_code_close(&dsp_code);
1537 if (err)
1538 return err;
1541 /* After bootloading all DSPs, start DSP0 running
1542 * The DSP0 code will handle starting and synchronizing with its slaves
1544 if (phw->p_interface_buffer) {
1545 /* we need to tell the card the physical PCI address */
1546 u32 physicalPC_iaddress;
1547 struct bus_master_interface *interface =
1548 phw->p_interface_buffer;
1549 u32 host_mailbox_address_on_dsp;
1550 u32 physicalPC_iaddress_verify = 0;
1551 int time_out = 10;
1552 /* set ack so we know when DSP is ready to go */
1553 /* (dwDspAck will be changed to HIF_RESET) */
1554 interface->dsp_ack = H620_HIF_UNKNOWN;
1555 wmb(); /* ensure ack is written before dsp writes back */
1557 err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1558 &physicalPC_iaddress);
1560 /* locate the host mailbox on the DSP. */
1561 host_mailbox_address_on_dsp = 0x80000000;
1562 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1563 && time_out--) {
1564 err = boot_loader_write_mem32(pao, 0,
1565 host_mailbox_address_on_dsp,
1566 physicalPC_iaddress);
1567 physicalPC_iaddress_verify =
1568 boot_loader_read_mem32(pao, 0,
1569 host_mailbox_address_on_dsp);
1572 HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
1573 /* enable interrupts */
1574 temp = ioread32(phw->prHSR);
1575 temp &= ~(u32)C6205_HSR_INTAM;
1576 iowrite32(temp, phw->prHSR);
1578 /* start code running... */
1579 temp = ioread32(phw->prHDCR);
1580 temp |= (u32)C6205_HDCR_DSPINT;
1581 iowrite32(temp, phw->prHDCR);
1583 /* give the DSP 10ms to start up */
1584 hpios_delay_micro_seconds(10000);
1585 return err;
1589 /*****************************************************************************/
1590 /* Bootloader utility functions */
1592 static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1593 u32 address)
1595 struct hpi_hw_obj *phw = pao->priv;
1596 u32 data = 0;
1597 __iomem u32 *p_data;
1599 if (dsp_index == 0) {
1600 /* DSP 0 is always C6205 */
1601 if ((address >= 0x01800000) & (address < 0x02000000)) {
1602 /* BAR1 register access */
1603 p_data = pao->pci.ap_mem_base[1] +
1604 (address & 0x007fffff) /
1605 sizeof(*pao->pci.ap_mem_base[1]);
1606 /* HPI_DEBUG_LOG(WARNING,
1607 "BAR1 access %08x\n", dwAddress); */
1608 } else {
1609 u32 dw4M_page = address >> 22L;
1610 if (dw4M_page != phw->dsp_page) {
1611 phw->dsp_page = dw4M_page;
1612 /* *INDENT OFF* */
1613 iowrite32(phw->dsp_page, phw->prDSPP);
1614 /* *INDENT-ON* */
1616 address &= 0x3fffff; /* address within 4M page */
1617 /* BAR0 memory access */
1618 p_data = pao->pci.ap_mem_base[0] +
1619 address / sizeof(u32);
1621 data = ioread32(p_data);
1622 } else if (dsp_index == 1) {
1623 /* DSP 1 is a C6713 */
1624 u32 lsb;
1625 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1626 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1627 lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
1628 data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
1629 data = (data << 16) | (lsb & 0xFFFF);
1631 return data;
1634 static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1635 u32 address, u32 data)
1637 struct hpi_hw_obj *phw = pao->priv;
1638 u16 err = 0;
1639 __iomem u32 *p_data;
1640 /* u32 dwVerifyData=0; */
1642 if (dsp_index == 0) {
1643 /* DSP 0 is always C6205 */
1644 if ((address >= 0x01800000) & (address < 0x02000000)) {
1645 /* BAR1 - DSP register access using */
1646 /* Non-prefetchable PCI access */
1647 p_data = pao->pci.ap_mem_base[1] +
1648 (address & 0x007fffff) /
1649 sizeof(*pao->pci.ap_mem_base[1]);
1650 } else {
1651 /* BAR0 access - all of DSP memory using */
1652 /* pre-fetchable PCI access */
1653 u32 dw4M_page = address >> 22L;
1654 if (dw4M_page != phw->dsp_page) {
1655 phw->dsp_page = dw4M_page;
1656 /* *INDENT-OFF* */
1657 iowrite32(phw->dsp_page, phw->prDSPP);
1658 /* *INDENT-ON* */
1660 address &= 0x3fffff; /* address within 4M page */
1661 p_data = pao->pci.ap_mem_base[0] +
1662 address / sizeof(u32);
1664 iowrite32(data, p_data);
1665 } else if (dsp_index == 1) {
1666 /* DSP 1 is a C6713 */
1667 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1668 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1670 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1671 boot_loader_read_mem32(pao, 0, 0);
1673 boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1674 boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1676 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1677 boot_loader_read_mem32(pao, 0, 0);
1678 } else
1679 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1680 return err;
1683 static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1685 u16 err = 0;
1687 if (dsp_index == 0) {
1688 u32 setting;
1690 /* DSP 0 is always C6205 */
1692 /* Set the EMIF */
1693 /* memory map of C6205 */
1694 /* 00000000-0000FFFF 16Kx32 internal program */
1695 /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
1697 /* EMIF config */
1698 /*------------ */
1699 /* Global EMIF control */
1700 boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
1701 #define WS_OFS 28
1702 #define WST_OFS 22
1703 #define WH_OFS 20
1704 #define RS_OFS 16
1705 #define RST_OFS 8
1706 #define MTYPE_OFS 4
1707 #define RH_OFS 0
1709 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1710 setting = 0x00000030;
1711 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1712 if (setting != boot_loader_read_mem32(pao, dsp_index,
1713 0x01800008))
1714 return hpi6205_error(dsp_index,
1715 HPI6205_ERROR_DSP_EMIF);
1717 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1718 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1719 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1720 /* WST should be 71, but 63 is max possible */
1721 setting =
1722 (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
1723 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1724 (2L << MTYPE_OFS);
1725 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1726 if (setting != boot_loader_read_mem32(pao, dsp_index,
1727 0x01800004))
1728 return hpi6205_error(dsp_index,
1729 HPI6205_ERROR_DSP_EMIF);
1731 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1732 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1733 /* plenty of wait states */
1734 setting =
1735 (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
1736 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1737 (2L << MTYPE_OFS);
1738 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1739 if (setting != boot_loader_read_mem32(pao, dsp_index,
1740 0x01800010))
1741 return hpi6205_error(dsp_index,
1742 HPI6205_ERROR_DSP_EMIF);
1744 /* EMIF CE3 setup - 32 bit async. */
1745 /* This is the PLD on the ASI5000 cards only */
1746 setting =
1747 (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
1748 (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
1749 (2L << MTYPE_OFS);
1750 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1751 if (setting != boot_loader_read_mem32(pao, dsp_index,
1752 0x01800014))
1753 return hpi6205_error(dsp_index,
1754 HPI6205_ERROR_DSP_EMIF);
1756 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1757 /* need to use this else DSP code crashes? */
1758 boot_loader_write_mem32(pao, dsp_index, 0x01800018,
1759 0x07117000);
1761 /* EMIF SDRAM Refresh Timing */
1762 /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
1763 boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1764 0x00000410);
1766 } else if (dsp_index == 1) {
1767 /* test access to the C6713s HPI registers */
1768 u32 write_data = 0, read_data = 0, i = 0;
1770 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1771 write_data = 1;
1772 boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
1773 boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
1774 /* C67 HPI is on lower 16bits of 32bit EMIF */
1775 read_data =
1776 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1777 if (write_data != read_data) {
1778 err = hpi6205_error(dsp_index,
1779 HPI6205_ERROR_C6713_HPIC);
1780 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1781 read_data);
1783 return err;
1785 /* HPIA - walking ones test */
1786 write_data = 1;
1787 for (i = 0; i < 32; i++) {
1788 boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
1789 write_data);
1790 boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
1791 (write_data >> 16));
1792 read_data =
1793 0xFFFF & boot_loader_read_mem32(pao, 0,
1794 HPIAL_ADDR);
1795 read_data =
1796 read_data | ((0xFFFF &
1797 boot_loader_read_mem32(pao, 0,
1798 HPIAH_ADDR))
1799 << 16);
1800 if (read_data != write_data) {
1801 err = hpi6205_error(dsp_index,
1802 HPI6205_ERROR_C6713_HPIA);
1803 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1804 write_data, read_data);
1805 return err;
1807 write_data = write_data << 1;
1810 /* setup C67x PLL
1811 * ** C6713 datasheet says we cannot program PLL from HPI,
1812 * and indeed if we try to set the PLL multiply from the HPI,
1813 * the PLL does not seem to lock, so we enable the PLL and
1814 * use the default multiply of x 7, which for a 27MHz clock
1815 * gives a DSP speed of 189MHz
1817 /* bypass PLL */
1818 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
1819 hpios_delay_micro_seconds(1000);
1820 /* EMIF = 189/3=63MHz */
1821 boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
1822 /* peri = 189/2 */
1823 boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
1824 /* cpu = 189/1 */
1825 boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
1826 hpios_delay_micro_seconds(1000);
1827 /* ** SGT test to take GPO3 high when we start the PLL */
1828 /* and low when the delay is completed */
1829 /* FSX0 <- '1' (GPO3) */
1830 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
1831 /* PLL not bypassed */
1832 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
1833 hpios_delay_micro_seconds(1000);
1834 /* FSX0 <- '0' (GPO3) */
1835 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
1837 /* 6205 EMIF CE1 resetup - 32 bit async. */
1838 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1839 boot_loader_write_mem32(pao, 0, 0x01800004, /* CE1 */
1840 (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
1841 (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
1842 (2L << MTYPE_OFS));
1844 hpios_delay_micro_seconds(1000);
1846 /* check that we can read one of the PLL registers */
1847 /* PLL should not be bypassed! */
1848 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1849 != 0x0001) {
1850 err = hpi6205_error(dsp_index,
1851 HPI6205_ERROR_C6713_PLL);
1852 return err;
1854 /* setup C67x EMIF (note this is the only use of
1855 BAR1 via BootLoader_WriteMem32) */
1856 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1857 0x000034A8);
1858 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1859 0x00000030);
1860 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1861 0x001BDF29);
1862 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1863 0x47117000);
1864 boot_loader_write_mem32(pao, dsp_index,
1865 C6713_EMIF_SDRAMTIMING, 0x00000410);
1867 hpios_delay_micro_seconds(1000);
1868 } else if (dsp_index == 2) {
1869 /* DSP 2 is a C6713 */
1871 } else
1872 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1873 return err;
1876 static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1877 u32 start_address, u32 length)
1879 u32 i = 0, j = 0;
1880 u32 test_addr = 0;
1881 u32 test_data = 0, data = 0;
1883 length = 1000;
1885 /* for 1st word, test each bit in the 32bit word, */
1886 /* dwLength specifies number of 32bit words to test */
1887 /*for(i=0; i<dwLength; i++) */
1888 i = 0;
1890 test_addr = start_address + i * 4;
1891 test_data = 0x00000001;
1892 for (j = 0; j < 32; j++) {
1893 boot_loader_write_mem32(pao, dsp_index, test_addr,
1894 test_data);
1895 data = boot_loader_read_mem32(pao, dsp_index,
1896 test_addr);
1897 if (data != test_data) {
1898 HPI_DEBUG_LOG(VERBOSE,
1899 "memtest error details "
1900 "%08x %08x %08x %i\n", test_addr,
1901 test_data, data, dsp_index);
1902 return 1; /* error */
1904 test_data = test_data << 1;
1905 } /* for(j) */
1906 } /* for(i) */
1908 /* for the next 100 locations test each location, leaving it as zero */
1909 /* write a zero to the next word in memory before we read */
1910 /* the previous write to make sure every memory location is unique */
1911 for (i = 0; i < 100; i++) {
1912 test_addr = start_address + i * 4;
1913 test_data = 0xA5A55A5A;
1914 boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
1915 boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
1916 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1917 if (data != test_data) {
1918 HPI_DEBUG_LOG(VERBOSE,
1919 "memtest error details "
1920 "%08x %08x %08x %i\n", test_addr, test_data,
1921 data, dsp_index);
1922 return 1; /* error */
1924 /* leave location as zero */
1925 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1928 /* zero out entire memory block */
1929 for (i = 0; i < length; i++) {
1930 test_addr = start_address + i * 4;
1931 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1933 return 0;
1936 static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1937 int dsp_index)
1939 int err = 0;
1940 if (dsp_index == 0) {
1941 /* DSP 0 is a C6205 */
1942 /* 64K prog mem */
1943 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1944 0x10000);
1945 if (!err)
1946 /* 64K data mem */
1947 err = boot_loader_test_memory(pao, dsp_index,
1948 0x80000000, 0x10000);
1949 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1950 /* DSP 1&2 are a C6713 */
1951 /* 192K internal mem */
1952 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1953 0x30000);
1954 if (!err)
1955 /* 64K internal mem / L2 cache */
1956 err = boot_loader_test_memory(pao, dsp_index,
1957 0x00030000, 0x10000);
1958 } else
1959 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1961 if (err)
1962 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1963 else
1964 return 0;
1967 static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1968 int dsp_index)
1970 u32 dRAM_start_address = 0;
1971 u32 dRAM_size = 0;
1973 if (dsp_index == 0) {
1974 /* only test for SDRAM if an ASI5000 card */
1975 if (pao->pci.subsys_device_id == 0x5000) {
1976 /* DSP 0 is always C6205 */
1977 dRAM_start_address = 0x00400000;
1978 dRAM_size = 0x200000;
1979 /*dwDRAMinc=1024; */
1980 } else
1981 return 0;
1982 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1983 /* DSP 1 is a C6713 */
1984 dRAM_start_address = 0x80000000;
1985 dRAM_size = 0x200000;
1986 /*dwDRAMinc=1024; */
1987 } else
1988 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1990 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1991 dRAM_size))
1992 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
1993 return 0;
1996 static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1998 u32 data = 0;
1999 if (dsp_index == 0) {
2000 /* only test for DSP0 PLD on ASI5000 card */
2001 if (pao->pci.subsys_device_id == 0x5000) {
2002 /* PLD is located at CE3=0x03000000 */
2003 data = boot_loader_read_mem32(pao, dsp_index,
2004 0x03000008);
2005 if ((data & 0xF) != 0x5)
2006 return hpi6205_error(dsp_index,
2007 HPI6205_ERROR_DSP_PLD);
2008 data = boot_loader_read_mem32(pao, dsp_index,
2009 0x0300000C);
2010 if ((data & 0xF) != 0xA)
2011 return hpi6205_error(dsp_index,
2012 HPI6205_ERROR_DSP_PLD);
2014 } else if (dsp_index == 1) {
2015 /* DSP 1 is a C6713 */
2016 if (pao->pci.subsys_device_id == 0x8700) {
2017 /* PLD is located at CE1=0x90000000 */
2018 data = boot_loader_read_mem32(pao, dsp_index,
2019 0x90000010);
2020 if ((data & 0xFF) != 0xAA)
2021 return hpi6205_error(dsp_index,
2022 HPI6205_ERROR_DSP_PLD);
2023 /* 8713 - LED on */
2024 boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2025 0x02);
2028 return 0;
2031 /** Transfer data to or from DSP
2032 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2034 static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2035 u32 data_size, int operation)
2037 struct hpi_hw_obj *phw = pao->priv;
2038 u32 data_transferred = 0;
2039 u16 err = 0;
2040 #ifndef HPI6205_NO_HSR_POLL
2041 u32 time_out;
2042 #endif
2043 u32 temp2;
2044 struct bus_master_interface *interface = phw->p_interface_buffer;
2046 if (!p_data)
2047 return HPI_ERROR_INVALID_DATA_TRANSFER;
2049 data_size &= ~3L; /* round data_size down to nearest 4 bytes */
2051 /* make sure state is IDLE */
2052 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2053 return HPI_ERROR_DSP_HARDWARE;
2055 while (data_transferred < data_size) {
2056 u32 this_copy = data_size - data_transferred;
2058 if (this_copy > HPI6205_SIZEOF_DATA)
2059 this_copy = HPI6205_SIZEOF_DATA;
2061 if (operation == H620_HIF_SEND_DATA)
2062 memcpy((void *)&interface->u.b_data[0],
2063 &p_data[data_transferred], this_copy);
2065 interface->transfer_size_in_bytes = this_copy;
2067 #ifdef HPI6205_NO_HSR_POLL
2068 /* DSP must change this back to nOperation */
2069 interface->dsp_ack = H620_HIF_IDLE;
2070 #endif
2072 send_dsp_command(phw, operation);
2074 #ifdef HPI6205_NO_HSR_POLL
2075 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2076 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2077 HPI6205_TIMEOUT - temp2, this_copy);
2079 if (!temp2) {
2080 /* timed out */
2081 HPI_DEBUG_LOG(ERROR,
2082 "timed out waiting for " "state %d got %d\n",
2083 operation, interface->dsp_ack);
2085 break;
2087 #else
2088 /* spin waiting on the result */
2089 time_out = HPI6205_TIMEOUT;
2090 temp2 = 0;
2091 while ((temp2 == 0) && time_out--) {
2092 /* give 16k bus mastering transfer time to happen */
2093 /*(16k / 132Mbytes/s = 122usec) */
2094 hpios_delay_micro_seconds(20);
2095 temp2 = ioread32(phw->prHSR);
2096 temp2 &= C6205_HSR_INTSRC;
2098 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2099 HPI6205_TIMEOUT - time_out, this_copy);
2100 if (temp2 == C6205_HSR_INTSRC) {
2101 HPI_DEBUG_LOG(VERBOSE,
2102 "interrupt from HIF <data> OK\n");
2104 if(interface->dwDspAck != nOperation) {
2105 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2106 expected %d \n",
2107 interface->dwDspAck,nOperation);
2111 /* need to handle this differently... */
2112 else {
2113 HPI_DEBUG_LOG(ERROR,
2114 "interrupt from HIF <data> BAD\n");
2115 err = HPI_ERROR_DSP_HARDWARE;
2118 /* reset the interrupt from the DSP */
2119 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2120 #endif
2121 if (operation == H620_HIF_GET_DATA)
2122 memcpy(&p_data[data_transferred],
2123 (void *)&interface->u.b_data[0], this_copy);
2125 data_transferred += this_copy;
2127 if (interface->dsp_ack != operation)
2128 HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
2129 interface->dsp_ack, operation);
2130 /* err=HPI_ERROR_DSP_HARDWARE; */
2132 send_dsp_command(phw, H620_HIF_IDLE);
2134 return err;
2137 /* wait for up to timeout_us microseconds for the DSP
2138 to signal state by DMA into dwDspAck
2140 static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2142 struct bus_master_interface *interface = phw->p_interface_buffer;
2143 int t = timeout_us / 4;
2145 rmb(); /* ensure interface->dsp_ack is up to date */
2146 while ((interface->dsp_ack != state) && --t) {
2147 hpios_delay_micro_seconds(4);
2148 rmb(); /* DSP changes dsp_ack by DMA */
2151 /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2152 return t * 4;
2155 /* set the busmaster interface to cmd, then interrupt the DSP */
2156 static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2158 struct bus_master_interface *interface = phw->p_interface_buffer;
2160 u32 r;
2162 interface->host_cmd = cmd;
2163 wmb(); /* DSP gets state by DMA, make sure it is written to memory */
2164 /* before we interrupt the DSP */
2165 r = ioread32(phw->prHDCR);
2166 r |= (u32)C6205_HDCR_DSPINT;
2167 iowrite32(r, phw->prHDCR);
2168 r &= ~(u32)C6205_HDCR_DSPINT;
2169 iowrite32(r, phw->prHDCR);
2172 static unsigned int message_count;
2174 static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2175 struct hpi_message *phm, struct hpi_response *phr)
2177 #ifndef HPI6205_NO_HSR_POLL
2178 u32 temp2;
2179 #endif
2180 u32 time_out, time_out2;
2181 struct hpi_hw_obj *phw = pao->priv;
2182 struct bus_master_interface *interface = phw->p_interface_buffer;
2183 u16 err = 0;
2185 message_count++;
2186 /* Assume buffer of type struct bus_master_interface
2187 is allocated "noncacheable" */
2189 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2190 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2191 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2193 interface->u.message_buffer = *phm;
2194 /* signal we want a response */
2195 send_dsp_command(phw, H620_HIF_GET_RESP);
2197 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2199 if (time_out2 == 0) {
2200 HPI_DEBUG_LOG(ERROR,
2201 "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2202 message_count, interface->dsp_ack);
2203 } else {
2204 HPI_DEBUG_LOG(VERBOSE,
2205 "(%u) transition to GET_RESP after %u\n",
2206 message_count, HPI6205_TIMEOUT - time_out2);
2208 /* spin waiting on HIF interrupt flag (end of msg process) */
2209 time_out = HPI6205_TIMEOUT;
2211 #ifndef HPI6205_NO_HSR_POLL
2212 temp2 = 0;
2213 while ((temp2 == 0) && --time_out) {
2214 temp2 = ioread32(phw->prHSR);
2215 temp2 &= C6205_HSR_INTSRC;
2216 hpios_delay_micro_seconds(1);
2218 if (temp2 == C6205_HSR_INTSRC) {
2219 rmb(); /* ensure we see latest value for dsp_ack */
2220 if ((interface->dsp_ack != H620_HIF_GET_RESP)) {
2221 HPI_DEBUG_LOG(DEBUG,
2222 "(%u)interface->dsp_ack(0x%x) != "
2223 "H620_HIF_GET_RESP, t=%u\n", message_count,
2224 interface->dsp_ack,
2225 HPI6205_TIMEOUT - time_out);
2226 } else {
2227 HPI_DEBUG_LOG(VERBOSE,
2228 "(%u)int with GET_RESP after %u\n",
2229 message_count, HPI6205_TIMEOUT - time_out);
2232 } else {
2233 /* can we do anything else in response to the error ? */
2234 HPI_DEBUG_LOG(ERROR,
2235 "interrupt from HIF module BAD (function %x)\n",
2236 phm->function);
2239 /* reset the interrupt from the DSP */
2240 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2241 #endif
2243 /* read the result */
2244 if (time_out != 0)
2245 *phr = interface->u.response_buffer;
2247 /* set interface back to idle */
2248 send_dsp_command(phw, H620_HIF_IDLE);
2250 if ((time_out == 0) || (time_out2 == 0)) {
2251 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2252 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
2254 /* special case for adapter close - */
2255 /* wait for the DSP to indicate it is idle */
2256 if (phm->function == HPI_ADAPTER_CLOSE) {
2257 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2258 HPI_DEBUG_LOG(DEBUG,
2259 "timeout waiting for idle "
2260 "(on adapter_close)\n");
2261 return hpi6205_error(0,
2262 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2265 err = hpi_validate_response(phm, phr);
2266 return err;
2269 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2270 struct hpi_response *phr)
2273 u16 err = 0;
2275 hpios_dsplock_lock(pao);
2277 err = message_response_sequence(pao, phm, phr);
2279 /* maybe an error response */
2280 if (err) {
2281 /* something failed in the HPI/DSP interface */
2282 phr->error = err;
2283 pao->dsp_crashed++;
2285 /* just the header of the response is valid */
2286 phr->size = sizeof(struct hpi_response_header);
2287 goto err;
2288 } else
2289 pao->dsp_crashed = 0;
2291 if (phr->error != 0) /* something failed in the DSP */
2292 goto err;
2294 switch (phm->function) {
2295 case HPI_OSTREAM_WRITE:
2296 case HPI_ISTREAM_ANC_WRITE:
2297 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2298 phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
2299 break;
2301 case HPI_ISTREAM_READ:
2302 case HPI_OSTREAM_ANC_READ:
2303 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2304 phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2305 break;
2307 case HPI_CONTROL_SET_STATE:
2308 if (phm->object == HPI_OBJ_CONTROLEX
2309 && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2310 err = hpi6205_transfer_data(pao,
2311 phm->u.cx.u.cobranet_bigdata.pb_data,
2312 phm->u.cx.u.cobranet_bigdata.byte_count,
2313 H620_HIF_SEND_DATA);
2314 break;
2316 case HPI_CONTROL_GET_STATE:
2317 if (phm->object == HPI_OBJ_CONTROLEX
2318 && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2319 err = hpi6205_transfer_data(pao,
2320 phm->u.cx.u.cobranet_bigdata.pb_data,
2321 phr->u.cx.u.cobranet_data.byte_count,
2322 H620_HIF_GET_DATA);
2323 break;
2325 phr->error = err;
2327 err:
2328 hpios_dsplock_unlock(pao);
2330 return;