Merge branch 'fix/asoc' into for-linus
[pandora-kernel.git] / sound / pci / asihpi / hpi6205.c
1 /******************************************************************************
2
3     AudioScience HPI driver
4     Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
5
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;
9
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.
14
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
18
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
24
25  Exported function:
26  void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
27
28 (C) Copyright AudioScience Inc. 1998-2010
29 *******************************************************************************/
30 #define SOURCEFILE_NAME "hpi6205.c"
31
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"
38
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
60
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
77
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
83  */
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)
88
89 /* used to control LED (revA) and reset C6713 (revB) */
90 #define C6205_BAR0_TIMER1_CTL (0x01980000L)
91
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
101
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
110
111 struct hpi_hw_obj {
112         /* PCI registers */
113         __iomem u32 *prHSR;
114         __iomem u32 *prHDCR;
115         __iomem u32 *prDSPP;
116
117         u32 dsp_page;
118
119         struct consistent_dma_area h_locked_mem;
120         struct bus_master_interface *p_interface_buffer;
121
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];
129
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;
135 };
136
137 /*****************************************************************************/
138 /* local prototypes */
139
140 #define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
141
142 static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
143
144 static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
145
146 static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
147         u32 *pos_error_code);
148
149 static u16 message_response_sequence(struct hpi_adapter_obj *pao,
150         struct hpi_message *phm, struct hpi_response *phr);
151
152 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
153         struct hpi_response *phr);
154
155 #define HPI6205_TIMEOUT 1000000
156
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);
161
162 static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
163         u32 *pos_error_code);
164
165 static void delete_adapter_obj(struct hpi_adapter_obj *pao);
166
167 static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
168         struct hpi_message *phm, struct hpi_response *phr);
169
170 static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
171         struct hpi_message *phm, struct hpi_response *phr);
172
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);
177
178 static void outstream_get_info(struct hpi_adapter_obj *pao,
179         struct hpi_message *phm, struct hpi_response *phr);
180
181 static void outstream_start(struct hpi_adapter_obj *pao,
182         struct hpi_message *phm, struct hpi_response *phr);
183
184 static void outstream_open(struct hpi_adapter_obj *pao,
185         struct hpi_message *phm, struct hpi_response *phr);
186
187 static void outstream_reset(struct hpi_adapter_obj *pao,
188         struct hpi_message *phm, struct hpi_response *phr);
189
190 static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
191         struct hpi_message *phm, struct hpi_response *phr);
192
193 static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
194         struct hpi_message *phm, struct hpi_response *phr);
195
196 static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
197         struct hpi_message *phm, struct hpi_response *phr);
198
199 static void instream_read(struct hpi_adapter_obj *pao,
200         struct hpi_message *phm, struct hpi_response *phr);
201
202 static void instream_get_info(struct hpi_adapter_obj *pao,
203         struct hpi_message *phm, struct hpi_response *phr);
204
205 static void instream_start(struct hpi_adapter_obj *pao,
206         struct hpi_message *phm, struct hpi_response *phr);
207
208 static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209         u32 address);
210
211 static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
212         u32 address, u32 data);
213
214 static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215         int dsp_index);
216
217 static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
218         u32 address, u32 length);
219
220 static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
221         int dsp_index);
222
223 static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
224         int dsp_index);
225
226 static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
227
228 /*****************************************************************************/
229
230 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
231 {
232
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;
252         }
253 }
254
255 static void control_message(struct hpi_adapter_obj *pao,
256         struct hpi_message *phm, struct hpi_response *phr)
257 {
258
259         struct hpi_hw_obj *phw = pao->priv;
260
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;
267                 }
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;
281         }
282 }
283
284 static void adapter_message(struct hpi_adapter_obj *pao,
285         struct hpi_message *phm, struct hpi_response *phr)
286 {
287         switch (phm->function) {
288         default:
289                 hw_message(pao, phm, phr);
290                 break;
291         }
292 }
293
294 static void outstream_message(struct hpi_adapter_obj *pao,
295         struct hpi_message *phm, struct hpi_response *phr)
296 {
297
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;
305         }
306
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;
335         }
336 }
337
338 static void instream_message(struct hpi_adapter_obj *pao,
339         struct hpi_message *phm, struct hpi_response *phr)
340 {
341
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;
349         }
350
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;
373         }
374 }
375
376 /*****************************************************************************/
377 /** Entry point to this HPI backend
378  * All calls to the HPI start here
379  */
380 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
381 {
382         struct hpi_adapter_obj *pao = NULL;
383
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
387          */
388         HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
389                 phm->function);
390
391         /* if Dsp has crashed then do not communicate with it any more */
392         if (phm->object != HPI_OBJ_SUBSYSTEM) {
393                 pao = hpi_find_adapter(phm->adapter_index);
394                 if (!pao) {
395                         HPI_DEBUG_LOG(DEBUG,
396                                 " %d,%d refused, for another HPI?\n",
397                                 phm->object, phm->function);
398                         return;
399                 }
400
401                 if ((pao->dsp_crashed >= 10)
402                         && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
403                         /* allow last resort debug read even after crash */
404                         hpi_init_response(phr, phm->object, phm->function,
405                                 HPI_ERROR_DSP_HARDWARE);
406                         HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
407                                 phm->object, phm->function);
408                         return;
409                 }
410         }
411
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);
416
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;
424
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;
431
432                 case HPI_OBJ_CONTROLEX:
433                 case HPI_OBJ_CONTROL:
434                         control_message(pao, phm, phr);
435                         break;
436
437                 case HPI_OBJ_OSTREAM:
438                         outstream_message(pao, phm, phr);
439                         break;
440
441                 case HPI_OBJ_ISTREAM:
442                         instream_message(pao, phm, phr);
443                         break;
444
445                 default:
446                         hw_message(pao, phm, phr);
447                         break;
448                 }
449                 break;
450
451         default:
452                 phr->error = HPI_ERROR_INVALID_TYPE;
453                 break;
454         }
455 }
456
457 /*****************************************************************************/
458 /* SUBSYSTEM */
459
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 ***
464  */
465 static void subsys_create_adapter(struct hpi_message *phm,
466         struct hpi_response *phr)
467 {
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;
472
473         HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
474
475         memset(&ao, 0, sizeof(ao));
476
477         /* this HPI only creates adapters for TI/PCI devices */
478         if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
479                 return;
480         if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
481                 return;
482         if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
483                 return;
484
485         ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
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;
490         }
491
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;
501         }
502
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;
507 }
508
509 /** delete an adapter - required by WDM driver */
510 static void subsys_delete_adapter(struct hpi_message *phm,
511         struct hpi_response *phr)
512 {
513         struct hpi_adapter_obj *pao;
514         struct hpi_hw_obj *phw;
515
516         pao = hpi_find_adapter(phm->adapter_index);
517         if (!pao) {
518                 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519                 return;
520         }
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);
527
528         delete_adapter_obj(pao);
529         phr->error = 0;
530 }
531
532 /** Create adapter object
533   allocate buffers, bootload DSPs, initialise control cache
534 */
535 static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
536         u32 *pos_error_code)
537 {
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;
547
548         /* init error reporting */
549         pao->dsp_crashed = 0;
550
551         for (i = 0; i < HPI_MAX_STREAMS; i++)
552                 phw->flag_outstream_just_reset[i] = 1;
553
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]);
564
565         pao->has_control_cache = 0;
566
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;
574
575         HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
576                 phw->p_interface_buffer);
577
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;
582         }
583
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;
589
590         HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
591
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);
595
596         interface = phw->p_interface_buffer;
597
598 #ifndef HPI6205_NO_HSR_POLL
599         /* wait for first interrupt indicating the DSP init is done */
600         time_out = HPI6205_TIMEOUT * 10;
601         temp1 = 0;
602         while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
603                 temp1 = ioread32(phw->prHSR);
604
605         if (temp1 & C6205_HSR_INTSRC)
606                 HPI_DEBUG_LOG(INFO,
607                         "interrupt confirming DSP code running OK\n");
608         else {
609                 HPI_DEBUG_LOG(ERROR,
610                         "timed out waiting for interrupt "
611                         "confirming DSP code running\n");
612                 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
613         }
614
615         /* reset the interrupt */
616         iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617 #endif
618
619         /* make sure the DSP has started ok */
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);
623         }
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
627          */
628         if (interface->control_cache.number_of_controls) {
629                 void *p_control_cache_virtual;
630
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);
640
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;
649                 }
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;
655                 }
656
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;
663                 }
664         }
665         /* allocate bus mastering async buffer and tell the DSP about it */
666         if (interface->async_buffer.b.size) {
667                 err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
668                         interface->async_buffer.b.size *
669                         sizeof(struct hpi_async_event), pao->pci.p_os_data);
670                 if (!err)
671                         err = hpios_locked_mem_get_virt_addr
672                                 (&phw->h_async_event_buffer, (void *)
673                                 &phw->p_async_event_buffer);
674                 if (!err)
675                         memset((void *)phw->p_async_event_buffer, 0,
676                                 interface->async_buffer.b.size *
677                                 sizeof(struct hpi_async_event));
678                 if (!err) {
679                         err = hpios_locked_mem_get_phys_addr
680                                 (&phw->h_async_event_buffer, &phys_addr);
681                         interface->async_buffer.physical_address32 =
682                                 phys_addr;
683                 }
684                 if (err) {
685                         if (hpios_locked_mem_valid(&phw->
686                                         h_async_event_buffer)) {
687                                 hpios_locked_mem_free
688                                         (&phw->h_async_event_buffer);
689                                 phw->p_async_event_buffer = NULL;
690                         }
691                 }
692         }
693         send_dsp_command(phw, H620_HIF_IDLE);
694
695         {
696                 struct hpi_message hM;
697                 struct hpi_response hR;
698                 u32 max_streams;
699
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);
709
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;
715                 }
716                 if (hR.error)
717                         return hR.error;
718
719                 pao->adapter_type = hR.u.a.adapter_type;
720                 pao->index = hR.u.a.adapter_index;
721
722                 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
723
724                 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
725                         65536, pao->pci.p_os_data);
726
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);
731         }
732
733         pao->open = 0;  /* upon creation the adapter is closed */
734
735         HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
736         return 0;
737 }
738
739 /** Free memory areas allocated by adapter
740  * this routine is called from SubSysDeleteAdapter,
741   * and SubSysCreateAdapter if duplicate index
742 */
743 static void delete_adapter_obj(struct hpi_adapter_obj *pao)
744 {
745         struct hpi_hw_obj *phw;
746         int i;
747
748         phw = pao->priv;
749
750         if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
751                 hpios_locked_mem_free(&phw->h_async_event_buffer);
752                 phw->p_async_event_buffer = NULL;
753         }
754
755         if (hpios_locked_mem_valid(&phw->h_control_cache)) {
756                 hpios_locked_mem_free(&phw->h_control_cache);
757                 hpi_free_control_cache(phw->p_cache);
758         }
759
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;
763         }
764
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;
770                 }
771
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;
777                 }
778
779         hpios_locked_mem_unprepare(pao->pci.p_os_data);
780
781         hpi_delete_adapter(pao);
782         kfree(phw);
783 }
784
785 /*****************************************************************************/
786 /* OutStream Host buffer functions */
787
788 /** Allocate or attach buffer for busmastering
789 */
790 static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
791         struct hpi_message *phm, struct hpi_response *phr)
792 {
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;
797
798         hpi_init_response(phr, phm->object, phm->function, 0);
799
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
804                  */
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;
813
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;
818                 }
819
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]);
824
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);
828
829                 if (err) {
830                         phr->error = HPI_ERROR_INVALID_DATASIZE;
831                         phw->outstream_host_buffer_size[phm->obj_index] = 0;
832                         return;
833                 }
834
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
841                  */
842                 phr->u.d.u.stream_info.auxiliary_data_available =
843                         phm->u.d.u.buffer.pci_address;
844
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;
851                 }
852         }
853
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.
858                  */
859                 struct hpi_hostbuffer_status *status;
860
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;
868                 }
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;
878
879                 hw_message(pao, phm, phr);
880
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;
887                 }
888         }
889 }
890
891 static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
892         struct hpi_message *phm, struct hpi_response *phr)
893 {
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;
898
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;
906                 }
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);
917         }
918 }
919
920 static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
921         struct hpi_message *phm, struct hpi_response *phr)
922 {
923         struct hpi_hw_obj *phw = pao->priv;
924         u32 command = phm->u.d.u.buffer.command;
925
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. */
932                 }
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]);
937         }
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);
943
944 }
945
946 static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
947 {
948         return status->size_in_bytes - (status->host_index -
949                 status->dSP_index);
950 }
951
952 static void outstream_write(struct hpi_adapter_obj *pao,
953         struct hpi_message *phm, struct hpi_response *phr)
954 {
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;
959
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;
964         }
965
966         hpi_init_response(phr, phm->object, phm->function, 0);
967         status = &interface->outstream_host_buffer_status[phm->obj_index];
968
969         if (phw->flag_outstream_just_reset[phm->obj_index]) {
970                 /* First OutStremWrite() call following reset will write data to the
971                    adapter's buffers, reducing delay before stream can start. The DSP
972                    takes care of setting the stream data format using format information
973                    embedded in phm.
974                  */
975                 int partial_write = 0;
976                 unsigned int original_size = 0;
977
978                 phw->flag_outstream_just_reset[phm->obj_index] = 0;
979
980                 /* Send the first buffer to the DSP the old way. */
981                 /* Limit size of first transfer - */
982                 /* expect that this will not usually be triggered. */
983                 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
984                         partial_write = 1;
985                         original_size = phm->u.d.u.data.data_size;
986                         phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
987                 }
988                 /* write it */
989                 phm->function = HPI_OSTREAM_WRITE;
990                 hw_message(pao, phm, phr);
991
992                 if (phr->error)
993                         return;
994
995                 /* update status information that the DSP would typically
996                  * update (and will update next time the DSP
997                  * buffer update task reads data from the host BBM buffer)
998                  */
999                 status->auxiliary_data_available = phm->u.d.u.data.data_size;
1000                 status->host_index += phm->u.d.u.data.data_size;
1001                 status->dSP_index += phm->u.d.u.data.data_size;
1002
1003                 /* if we did a full write, we can return from here. */
1004                 if (!partial_write)
1005                         return;
1006
1007                 /* tweak buffer parameters and let the rest of the */
1008                 /* buffer land in internal BBM buffer */
1009                 phm->u.d.u.data.data_size =
1010                         original_size - HPI6205_SIZEOF_DATA;
1011                 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1012         }
1013
1014         space_available = outstream_get_space_available(status);
1015         if (space_available < phm->u.d.u.data.data_size) {
1016                 phr->error = HPI_ERROR_INVALID_DATASIZE;
1017                 return;
1018         }
1019
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;
1028
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;
1034                 }
1035
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)));
1042
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);
1049         }
1050         status->host_index += phm->u.d.u.data.data_size;
1051 }
1052
1053 static void outstream_get_info(struct hpi_adapter_obj *pao,
1054         struct hpi_message *phm, struct hpi_response *phr)
1055 {
1056         struct hpi_hw_obj *phw = pao->priv;
1057         struct bus_master_interface *interface = phw->p_interface_buffer;
1058         struct hpi_hostbuffer_status *status;
1059
1060         if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1061                 hw_message(pao, phm, phr);
1062                 return;
1063         }
1064
1065         hpi_init_response(phr, phm->object, phm->function, 0);
1066
1067         status = &interface->outstream_host_buffer_status[phm->obj_index];
1068
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;
1077 }
1078
1079 static void outstream_start(struct hpi_adapter_obj *pao,
1080         struct hpi_message *phm, struct hpi_response *phr)
1081 {
1082         hw_message(pao, phm, phr);
1083 }
1084
1085 static void outstream_reset(struct hpi_adapter_obj *pao,
1086         struct hpi_message *phm, struct hpi_response *phr)
1087 {
1088         struct hpi_hw_obj *phw = pao->priv;
1089         phw->flag_outstream_just_reset[phm->obj_index] = 1;
1090         hw_message(pao, phm, phr);
1091 }
1092
1093 static void outstream_open(struct hpi_adapter_obj *pao,
1094         struct hpi_message *phm, struct hpi_response *phr)
1095 {
1096         outstream_reset(pao, phm, phr);
1097 }
1098
1099 /*****************************************************************************/
1100 /* InStream Host buffer functions */
1101
1102 static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1103         struct hpi_message *phm, struct hpi_response *phr)
1104 {
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;
1109
1110         hpi_init_response(phr, phm->object, phm->function, 0);
1111
1112         if (command == HPI_BUFFER_CMD_EXTERNAL
1113                 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1114
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;
1121
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;
1126                 }
1127
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]);
1132
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);
1136
1137                 if (err) {
1138                         phr->error = HPI_ERROR_INVALID_DATASIZE;
1139                         phw->instream_host_buffer_size[phm->obj_index] = 0;
1140                         return;
1141                 }
1142
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;
1156                 }
1157         }
1158
1159         if (command == HPI_BUFFER_CMD_EXTERNAL
1160                 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1161                 struct hpi_hostbuffer_status *status;
1162
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;
1170                 }
1171
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;
1181
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;
1189                 }
1190         }
1191 }
1192
1193 static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1194         struct hpi_message *phm, struct hpi_response *phr)
1195 {
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;
1200
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;
1208                 }
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);
1219         }
1220 }
1221
1222 static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1223         struct hpi_message *phm, struct hpi_response *phr)
1224 {
1225         struct hpi_hw_obj *phw = pao->priv;
1226         u32 command = phm->u.d.u.buffer.command;
1227
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);
1233                 }
1234
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]);
1239
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);
1245
1246         }
1247
1248 }
1249
1250 static void instream_start(struct hpi_adapter_obj *pao,
1251         struct hpi_message *phm, struct hpi_response *phr)
1252 {
1253         hw_message(pao, phm, phr);
1254 }
1255
1256 static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1257 {
1258         return status->dSP_index - status->host_index;
1259 }
1260
1261 static void instream_read(struct hpi_adapter_obj *pao,
1262         struct hpi_message *phm, struct hpi_response *phr)
1263 {
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;
1271
1272         if (!phw->instream_host_buffer_size[phm->obj_index]) {
1273                 hw_message(pao, phm, phr);
1274                 return;
1275         }
1276         hpi_init_response(phr, phm->object, phm->function, 0);
1277
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;
1283         }
1284
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;
1292                 }
1293
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)));
1300
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);
1308         }
1309         status->host_index += phm->u.d.u.data.data_size;
1310 }
1311
1312 static void instream_get_info(struct hpi_adapter_obj *pao,
1313         struct hpi_message *phm, struct hpi_response *phr)
1314 {
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;
1321         }
1322
1323         status = &interface->instream_host_buffer_status[phm->obj_index];
1324
1325         hpi_init_response(phr, phm->object, phm->function, 0);
1326
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;
1335 }
1336
1337 /*****************************************************************************/
1338 /* LOW-LEVEL */
1339 #define HPI6205_MAX_FILES_TO_LOAD 2
1340
1341 static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1342         u32 *pos_error_code)
1343 {
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;
1351
1352         boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1353
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;
1372         }
1373         boot_code_id[1] = firmware_id;
1374
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);
1379
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);
1388
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);
1393
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;
1414
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
1418          */
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);
1426
1427                 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1428                 boot_loader_read_mem32(pao, 0, 0);
1429
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);
1434         }
1435
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;
1440
1441                 err = boot_loader_config_emif(pao, dsp);
1442                 if (err)
1443                         return err;
1444
1445                 err = boot_loader_test_internal_memory(pao, dsp);
1446                 if (err)
1447                         return err;
1448
1449                 err = boot_loader_test_external_memory(pao, dsp);
1450                 if (err)
1451                         return err;
1452
1453                 err = boot_loader_test_pld(pao, dsp);
1454                 if (err)
1455                         return err;
1456
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;
1463
1464                 while (1) {
1465                         u32 length;
1466                         u32 address;
1467                         u32 type;
1468                         u32 *pcode;
1469
1470                         err = hpi_dsp_code_read_word(&dsp_code, &length);
1471                         if (err)
1472                                 break;
1473                         if (length == 0xFFFFFFFF)
1474                                 break;  /* end of code */
1475
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;
1498                         }
1499
1500                 }
1501                 if (err) {
1502                         hpi_dsp_code_close(&dsp_code);
1503                         return err;
1504                 }
1505
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;
1514
1515                         hpi_dsp_code_read_word(&dsp_code, &length);
1516                         if (length == 0xFFFFFFFF)
1517                                 break;  /* end of code */
1518
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);
1522
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;
1529                                 }
1530                                 pcode++;
1531                                 address += 4;
1532                         }
1533                         if (err)
1534                                 break;
1535                 }
1536                 hpi_dsp_code_close(&dsp_code);
1537                 if (err)
1538                         return err;
1539         }
1540
1541         /* After bootloading all DSPs, start DSP0 running
1542          * The DSP0 code will handle starting and synchronizing with its slaves
1543          */
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 */
1556
1557                 err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1558                         &physicalPC_iaddress);
1559
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);
1570                 }
1571         }
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);
1577
1578         /* start code running... */
1579         temp = ioread32(phw->prHDCR);
1580         temp |= (u32)C6205_HDCR_DSPINT;
1581         iowrite32(temp, phw->prHDCR);
1582
1583         /* give the DSP 10ms to start up */
1584         hpios_delay_micro_seconds(10000);
1585         return err;
1586
1587 }
1588
1589 /*****************************************************************************/
1590 /* Bootloader utility functions */
1591
1592 static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1593         u32 address)
1594 {
1595         struct hpi_hw_obj *phw = pao->priv;
1596         u32 data = 0;
1597         __iomem u32 *p_data;
1598
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* */
1615                         }
1616                         address &= 0x3fffff;    /* address within 4M page */
1617                         /* BAR0 memory access */
1618                         p_data = pao->pci.ap_mem_base[0] +
1619                                 address / sizeof(u32);
1620                 }
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);
1630         }
1631         return data;
1632 }
1633
1634 static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1635         u32 address, u32 data)
1636 {
1637         struct hpi_hw_obj *phw = pao->priv;
1638         u16 err = 0;
1639         __iomem u32 *p_data;
1640         /*      u32 dwVerifyData=0; */
1641
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* */
1659                         }
1660                         address &= 0x3fffff;    /* address within 4M page */
1661                         p_data = pao->pci.ap_mem_base[0] +
1662                                 address / sizeof(u32);
1663                 }
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);
1669
1670                 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1671                 boot_loader_read_mem32(pao, 0, 0);
1672
1673                 boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1674                 boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1675
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;
1681 }
1682
1683 static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1684 {
1685         u16 err = 0;
1686
1687         if (dsp_index == 0) {
1688                 u32 setting;
1689
1690                 /* DSP 0 is always C6205 */
1691
1692                 /* Set the EMIF */
1693                 /* memory map of C6205 */
1694                 /* 00000000-0000FFFF    16Kx32 internal program */
1695                 /* 00400000-00BFFFFF    CE0     2Mx32 SDRAM running @ 100MHz */
1696
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
1708
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);
1716
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);
1730
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);
1743
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);
1755
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);
1760
1761                 /* EMIF SDRAM Refresh Timing */
1762                 /* EMIF SDRAM timing  (orig = 0x410, emulator = 0x61a) */
1763                 boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1764                         0x00000410);
1765
1766         } else if (dsp_index == 1) {
1767                 /* test access to the C6713s HPI registers */
1768                 u32 write_data = 0, read_data = 0, i = 0;
1769
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);
1782
1783                         return err;
1784                 }
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;
1806                         }
1807                         write_data = write_data << 1;
1808                 }
1809
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
1816                  */
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);
1836
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));
1843
1844                 hpios_delay_micro_seconds(1000);
1845
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;
1853                 }
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);
1866
1867                 hpios_delay_micro_seconds(1000);
1868         } else if (dsp_index == 2) {
1869                 /* DSP 2 is a C6713 */
1870
1871         } else
1872                 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1873         return err;
1874 }
1875
1876 static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1877         u32 start_address, u32 length)
1878 {
1879         u32 i = 0, j = 0;
1880         u32 test_addr = 0;
1881         u32 test_data = 0, data = 0;
1882
1883         length = 1000;
1884
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;
1889         {
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 */
1903                         }
1904                         test_data = test_data << 1;
1905                 }       /* for(j) */
1906         }       /* for(i) */
1907
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 */
1923                 }
1924                 /* leave location as zero */
1925                 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1926         }
1927
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);
1932         }
1933         return 0;
1934 }
1935
1936 static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1937         int dsp_index)
1938 {
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);
1960
1961         if (err)
1962                 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1963         else
1964                 return 0;
1965 }
1966
1967 static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1968         int dsp_index)
1969 {
1970         u32 dRAM_start_address = 0;
1971         u32 dRAM_size = 0;
1972
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);
1989
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;
1994 }
1995
1996 static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1997 {
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);
2013                 }
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);
2026                 }
2027         }
2028         return 0;
2029 }
2030
2031 /** Transfer data to or from DSP
2032  nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2033 */
2034 static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2035         u32 data_size, int operation)
2036 {
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;
2045
2046         if (!p_data)
2047                 return HPI_ERROR_INVALID_DATA_TRANSFER;
2048
2049         data_size &= ~3L;       /* round data_size down to nearest 4 bytes */
2050
2051         /* make sure state is IDLE */
2052         if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2053                 return HPI_ERROR_DSP_HARDWARE;
2054
2055         while (data_transferred < data_size) {
2056                 u32 this_copy = data_size - data_transferred;
2057
2058                 if (this_copy > HPI6205_SIZEOF_DATA)
2059                         this_copy = HPI6205_SIZEOF_DATA;
2060
2061                 if (operation == H620_HIF_SEND_DATA)
2062                         memcpy((void *)&interface->u.b_data[0],
2063                                 &p_data[data_transferred], this_copy);
2064
2065                 interface->transfer_size_in_bytes = this_copy;
2066
2067 #ifdef HPI6205_NO_HSR_POLL
2068                 /* DSP must change this back to nOperation */
2069                 interface->dsp_ack = H620_HIF_IDLE;
2070 #endif
2071
2072                 send_dsp_command(phw, operation);
2073
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);
2078
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);
2084
2085                         break;
2086                 }
2087 #else
2088                 /* spin waiting on the result */
2089                 time_out = HPI6205_TIMEOUT;
2090                 temp2 = 0;
2091                 while ((temp2 == 0) && time_out--) {
2092                         /* give 16k bus mastering transfer time to happen */
2093                         /*(16k / 132Mbytes/s = 122usec) */
2094                         hpios_delay_micro_seconds(20);
2095                         temp2 = ioread32(phw->prHSR);
2096                         temp2 &= C6205_HSR_INTSRC;
2097                 }
2098                 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2099                         HPI6205_TIMEOUT - time_out, this_copy);
2100                 if (temp2 == C6205_HSR_INTSRC) {
2101                         HPI_DEBUG_LOG(VERBOSE,
2102                                 "interrupt from HIF <data> OK\n");
2103                         /*
2104                            if(interface->dwDspAck != nOperation) {
2105                            HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2106                            expected %d \n",
2107                            interface->dwDspAck,nOperation);
2108                            }
2109                          */
2110                 }
2111 /* need to handle this differently... */
2112                 else {
2113                         HPI_DEBUG_LOG(ERROR,
2114                                 "interrupt from HIF <data> BAD\n");
2115                         err = HPI_ERROR_DSP_HARDWARE;
2116                 }
2117
2118                 /* reset the interrupt from the DSP */
2119                 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2120 #endif
2121                 if (operation == H620_HIF_GET_DATA)
2122                         memcpy(&p_data[data_transferred],
2123                                 (void *)&interface->u.b_data[0], this_copy);
2124
2125                 data_transferred += this_copy;
2126         }
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; */
2131
2132         send_dsp_command(phw, H620_HIF_IDLE);
2133
2134         return err;
2135 }
2136
2137 /* wait for up to timeout_us microseconds for the DSP
2138    to signal state by DMA into dwDspAck
2139 */
2140 static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2141 {
2142         struct bus_master_interface *interface = phw->p_interface_buffer;
2143         int t = timeout_us / 4;
2144
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 */
2149         }
2150
2151         /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2152         return t * 4;
2153 }
2154
2155 /* set the busmaster interface to cmd, then interrupt the DSP */
2156 static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2157 {
2158         struct bus_master_interface *interface = phw->p_interface_buffer;
2159
2160         u32 r;
2161
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);
2170 }
2171
2172 static unsigned int message_count;
2173
2174 static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2175         struct hpi_message *phm, struct hpi_response *phr)
2176 {
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;
2184
2185         message_count++;
2186         /* Assume buffer of type struct bus_master_interface
2187            is allocated "noncacheable" */
2188
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);
2192         }
2193         interface->u.message_buffer = *phm;
2194         /* signal we want a response */
2195         send_dsp_command(phw, H620_HIF_GET_RESP);
2196
2197         time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2198
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);
2207         }
2208         /* spin waiting on HIF interrupt flag (end of msg process) */
2209         time_out = HPI6205_TIMEOUT;
2210
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);
2217         }
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);
2230                 }
2231
2232         } else {
2233                 /* can we do anything else in response to the error ? */
2234                 HPI_DEBUG_LOG(ERROR,
2235                         "interrupt from HIF module BAD (function %x)\n",
2236                         phm->function);
2237         }
2238
2239         /* reset the interrupt from the DSP */
2240         iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2241 #endif
2242
2243         /* read the result */
2244         if (time_out != 0)
2245                 *phr = interface->u.response_buffer;
2246
2247         /* set interface back to idle */
2248         send_dsp_command(phw, H620_HIF_IDLE);
2249
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);
2253         }
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);
2263                 }
2264         }
2265         err = hpi_validate_response(phm, phr);
2266         return err;
2267 }
2268
2269 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2270         struct hpi_response *phr)
2271 {
2272
2273         u16 err = 0;
2274
2275         hpios_dsplock_lock(pao);
2276
2277         err = message_response_sequence(pao, phm, phr);
2278
2279         /* maybe an error response */
2280         if (err) {
2281                 /* something failed in the HPI/DSP interface */
2282                 phr->error = err;
2283                 pao->dsp_crashed++;
2284
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;
2290
2291         if (phr->error != 0)    /* something failed in the DSP */
2292                 goto err;
2293
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;
2300
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;
2306
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;
2315
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;
2324         }
2325         phr->error = err;
2326
2327 err:
2328         hpios_dsplock_unlock(pao);
2329
2330         return;
2331 }