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