Linux 2.6.37-rc1
[pandora-kernel.git] / sound / pci / asihpi / hpi6205.c
1 /******************************************************************************
2
3     AudioScience HPI driver
4     Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of version 2 of the GNU General Public License as
8     published by the Free Software Foundation;
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19  Hardware Programming Interface (HPI) for AudioScience
20  ASI50xx, AS51xx, ASI6xxx, ASI87xx ASI89xx series adapters.
21  These PCI and PCIe bus adapters are based on a
22  TMS320C6205 PCI bus mastering DSP,
23  and (except ASI50xx) TI TMS320C6xxx floating point DSP
24
25  Exported function:
26  void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
27
28 (C) Copyright AudioScience Inc. 1998-2010
29 *******************************************************************************/
30 #define SOURCEFILE_NAME "hpi6205.c"
31
32 #include "hpi_internal.h"
33 #include "hpimsginit.h"
34 #include "hpidebug.h"
35 #include "hpi6205.h"
36 #include "hpidspcd.h"
37 #include "hpicmn.h"
38
39 /*****************************************************************************/
40 /* HPI6205 specific error codes */
41 #define HPI6205_ERROR_BASE                      1000
42 /*#define HPI6205_ERROR_MEM_ALLOC 1001 */
43 #define HPI6205_ERROR_6205_NO_IRQ               1002
44 #define HPI6205_ERROR_6205_INIT_FAILED          1003
45 /*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
46 #define HPI6205_ERROR_UNKNOWN_PCI_DEVICE        1005
47 #define HPI6205_ERROR_6205_REG                  1006
48 #define HPI6205_ERROR_6205_DSPPAGE              1007
49 #define HPI6205_ERROR_BAD_DSPINDEX              1008
50 #define HPI6205_ERROR_C6713_HPIC                1009
51 #define HPI6205_ERROR_C6713_HPIA                1010
52 #define HPI6205_ERROR_C6713_PLL                 1011
53 #define HPI6205_ERROR_DSP_INTMEM                1012
54 #define HPI6205_ERROR_DSP_EXTMEM                1013
55 #define HPI6205_ERROR_DSP_PLD                   1014
56 #define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT     1015
57 #define HPI6205_ERROR_MSG_RESP_TIMEOUT          1016
58 #define HPI6205_ERROR_6205_EEPROM               1017
59 #define HPI6205_ERROR_DSP_EMIF                  1018
60
61 #define hpi6205_error(dsp_index, err) (err)
62 /*****************************************************************************/
63 /* for C6205 PCI i/f */
64 /* Host Status Register (HSR) bitfields */
65 #define C6205_HSR_INTSRC        0x01
66 #define C6205_HSR_INTAVAL       0x02
67 #define C6205_HSR_INTAM         0x04
68 #define C6205_HSR_CFGERR        0x08
69 #define C6205_HSR_EEREAD        0x10
70 /* Host-to-DSP Control Register (HDCR) bitfields */
71 #define C6205_HDCR_WARMRESET    0x01
72 #define C6205_HDCR_DSPINT       0x02
73 #define C6205_HDCR_PCIBOOT      0x04
74 /* DSP Page Register (DSPP) bitfields, */
75 /* defines 4 Mbyte page that BAR0 points to */
76 #define C6205_DSPP_MAP1         0x400
77
78 /* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
79  * BAR1 maps to non-prefetchable 8 Mbyte memory block
80  * of DSP memory mapped registers (starting at 0x01800000).
81  * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
82  * needs to be added to the BAR1 base address set in the PCI config reg
83  */
84 #define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
85 #define C6205_BAR1_HSR  (C6205_BAR1_PCI_IO_OFFSET)
86 #define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
87 #define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
88
89 /* used to control LED (revA) and reset C6713 (revB) */
90 #define C6205_BAR0_TIMER1_CTL (0x01980000L)
91
92 /* For first 6713 in CE1 space, using DA17,16,2 */
93 #define HPICL_ADDR      0x01400000L
94 #define HPICH_ADDR      0x01400004L
95 #define HPIAL_ADDR      0x01410000L
96 #define HPIAH_ADDR      0x01410004L
97 #define HPIDIL_ADDR     0x01420000L
98 #define HPIDIH_ADDR     0x01420004L
99 #define HPIDL_ADDR      0x01430000L
100 #define HPIDH_ADDR      0x01430004L
101
102 #define C6713_EMIF_GCTL         0x01800000
103 #define C6713_EMIF_CE1          0x01800004
104 #define C6713_EMIF_CE0          0x01800008
105 #define C6713_EMIF_CE2          0x01800010
106 #define C6713_EMIF_CE3          0x01800014
107 #define C6713_EMIF_SDRAMCTL     0x01800018
108 #define C6713_EMIF_SDRAMTIMING  0x0180001C
109 #define C6713_EMIF_SDRAMEXT     0x01800020
110
111 struct hpi_hw_obj {
112         /* PCI registers */
113         __iomem u32 *prHSR;
114         __iomem u32 *prHDCR;
115         __iomem u32 *prDSPP;
116
117         u32 dsp_page;
118
119         struct consistent_dma_area h_locked_mem;
120         struct bus_master_interface *p_interface_buffer;
121
122         u16 flag_outstream_just_reset[HPI_MAX_STREAMS];
123         /* a non-NULL handle means there is an HPI allocated buffer */
124         struct consistent_dma_area instream_host_buffers[HPI_MAX_STREAMS];
125         struct consistent_dma_area outstream_host_buffers[HPI_MAX_STREAMS];
126         /* non-zero size means a buffer exists, may be external */
127         u32 instream_host_buffer_size[HPI_MAX_STREAMS];
128         u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
129
130         struct consistent_dma_area h_control_cache;
131         struct consistent_dma_area h_async_event_buffer;
132 /*      struct hpi_control_cache_single *pControlCache; */
133         struct hpi_async_event *p_async_event_buffer;
134         struct hpi_control_cache *p_cache;
135 };
136
137 /*****************************************************************************/
138 /* local prototypes */
139
140 #define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
141
142 static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
143
144 static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
145
146 static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
147         u32 *pos_error_code);
148
149 static u16 message_response_sequence(struct hpi_adapter_obj *pao,
150         struct hpi_message *phm, struct hpi_response *phr);
151
152 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
153         struct hpi_response *phr);
154
155 #define HPI6205_TIMEOUT 1000000
156
157 static void subsys_create_adapter(struct hpi_message *phm,
158         struct hpi_response *phr);
159 static void subsys_delete_adapter(struct hpi_message *phm,
160         struct hpi_response *phr);
161
162 static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
163         u32 *pos_error_code);
164
165 static void delete_adapter_obj(struct hpi_adapter_obj *pao);
166
167 static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
168         struct hpi_message *phm, struct hpi_response *phr);
169
170 static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
171         struct hpi_message *phm, struct hpi_response *phr);
172
173 static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
174         struct hpi_message *phm, struct hpi_response *phr);
175 static void outstream_write(struct hpi_adapter_obj *pao,
176         struct hpi_message *phm, struct hpi_response *phr);
177
178 static void outstream_get_info(struct hpi_adapter_obj *pao,
179         struct hpi_message *phm, struct hpi_response *phr);
180
181 static void outstream_start(struct hpi_adapter_obj *pao,
182         struct hpi_message *phm, struct hpi_response *phr);
183
184 static void outstream_open(struct hpi_adapter_obj *pao,
185         struct hpi_message *phm, struct hpi_response *phr);
186
187 static void outstream_reset(struct hpi_adapter_obj *pao,
188         struct hpi_message *phm, struct hpi_response *phr);
189
190 static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
191         struct hpi_message *phm, struct hpi_response *phr);
192
193 static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
194         struct hpi_message *phm, struct hpi_response *phr);
195
196 static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
197         struct hpi_message *phm, struct hpi_response *phr);
198
199 static void instream_read(struct hpi_adapter_obj *pao,
200         struct hpi_message *phm, struct hpi_response *phr);
201
202 static void instream_get_info(struct hpi_adapter_obj *pao,
203         struct hpi_message *phm, struct hpi_response *phr);
204
205 static void instream_start(struct hpi_adapter_obj *pao,
206         struct hpi_message *phm, struct hpi_response *phr);
207
208 static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209         u32 address);
210
211 static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
212         u32 address, u32 data);
213
214 static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215         int dsp_index);
216
217 static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
218         u32 address, u32 length);
219
220 static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
221         int dsp_index);
222
223 static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
224         int dsp_index);
225
226 static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
227
228 /*****************************************************************************/
229
230 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
231 {
232
233         switch (phm->function) {
234         case HPI_SUBSYS_OPEN:
235         case HPI_SUBSYS_CLOSE:
236         case HPI_SUBSYS_GET_INFO:
237         case HPI_SUBSYS_DRIVER_UNLOAD:
238         case HPI_SUBSYS_DRIVER_LOAD:
239         case HPI_SUBSYS_FIND_ADAPTERS:
240                 /* messages that should not get here */
241                 phr->error = HPI_ERROR_UNIMPLEMENTED;
242                 break;
243         case HPI_SUBSYS_CREATE_ADAPTER:
244                 subsys_create_adapter(phm, phr);
245                 break;
246         case HPI_SUBSYS_DELETE_ADAPTER:
247                 subsys_delete_adapter(phm, phr);
248                 break;
249         default:
250                 phr->error = HPI_ERROR_INVALID_FUNC;
251                 break;
252         }
253 }
254
255 static void control_message(struct hpi_adapter_obj *pao,
256         struct hpi_message *phm, struct hpi_response *phr)
257 {
258
259         struct hpi_hw_obj *phw = pao->priv;
260
261         switch (phm->function) {
262         case HPI_CONTROL_GET_STATE:
263                 if (pao->has_control_cache) {
264                         rmb();  /* make sure we see updates DM_aed from DSP */
265                         if (hpi_check_control_cache(phw->p_cache, phm, phr))
266                                 break;
267                 }
268                 hw_message(pao, phm, phr);
269                 break;
270         case HPI_CONTROL_GET_INFO:
271                 hw_message(pao, phm, phr);
272                 break;
273         case HPI_CONTROL_SET_STATE:
274                 hw_message(pao, phm, phr);
275                 if (pao->has_control_cache)
276                         hpi_sync_control_cache(phw->p_cache, phm, phr);
277                 break;
278         default:
279                 phr->error = HPI_ERROR_INVALID_FUNC;
280                 break;
281         }
282 }
283
284 static void adapter_message(struct hpi_adapter_obj *pao,
285         struct hpi_message *phm, struct hpi_response *phr)
286 {
287         switch (phm->function) {
288         default:
289                 hw_message(pao, phm, phr);
290                 break;
291         }
292 }
293
294 static void outstream_message(struct hpi_adapter_obj *pao,
295         struct hpi_message *phm, struct hpi_response *phr)
296 {
297
298         if (phm->obj_index >= HPI_MAX_STREAMS) {
299                 phr->error = HPI_ERROR_INVALID_STREAM;
300                 HPI_DEBUG_LOG(WARNING,
301                         "message referencing invalid stream %d "
302                         "on adapter index %d\n", phm->obj_index,
303                         phm->adapter_index);
304                 return;
305         }
306
307         switch (phm->function) {
308         case HPI_OSTREAM_WRITE:
309                 outstream_write(pao, phm, phr);
310                 break;
311         case HPI_OSTREAM_GET_INFO:
312                 outstream_get_info(pao, phm, phr);
313                 break;
314         case HPI_OSTREAM_HOSTBUFFER_ALLOC:
315                 outstream_host_buffer_allocate(pao, phm, phr);
316                 break;
317         case HPI_OSTREAM_HOSTBUFFER_GET_INFO:
318                 outstream_host_buffer_get_info(pao, phm, phr);
319                 break;
320         case HPI_OSTREAM_HOSTBUFFER_FREE:
321                 outstream_host_buffer_free(pao, phm, phr);
322                 break;
323         case HPI_OSTREAM_START:
324                 outstream_start(pao, phm, phr);
325                 break;
326         case HPI_OSTREAM_OPEN:
327                 outstream_open(pao, phm, phr);
328                 break;
329         case HPI_OSTREAM_RESET:
330                 outstream_reset(pao, phm, phr);
331                 break;
332         default:
333                 hw_message(pao, phm, phr);
334                 break;
335         }
336 }
337
338 static void instream_message(struct hpi_adapter_obj *pao,
339         struct hpi_message *phm, struct hpi_response *phr)
340 {
341
342         if (phm->obj_index >= HPI_MAX_STREAMS) {
343                 phr->error = HPI_ERROR_INVALID_STREAM;
344                 HPI_DEBUG_LOG(WARNING,
345                         "message referencing invalid stream %d "
346                         "on adapter index %d\n", phm->obj_index,
347                         phm->adapter_index);
348                 return;
349         }
350
351         switch (phm->function) {
352         case HPI_ISTREAM_READ:
353                 instream_read(pao, phm, phr);
354                 break;
355         case HPI_ISTREAM_GET_INFO:
356                 instream_get_info(pao, phm, phr);
357                 break;
358         case HPI_ISTREAM_HOSTBUFFER_ALLOC:
359                 instream_host_buffer_allocate(pao, phm, phr);
360                 break;
361         case HPI_ISTREAM_HOSTBUFFER_GET_INFO:
362                 instream_host_buffer_get_info(pao, phm, phr);
363                 break;
364         case HPI_ISTREAM_HOSTBUFFER_FREE:
365                 instream_host_buffer_free(pao, phm, phr);
366                 break;
367         case HPI_ISTREAM_START:
368                 instream_start(pao, phm, phr);
369                 break;
370         default:
371                 hw_message(pao, phm, phr);
372                 break;
373         }
374 }
375
376 /*****************************************************************************/
377 /** Entry point to this HPI backend
378  * All calls to the HPI start here
379  */
380 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
381 {
382         struct hpi_adapter_obj *pao = NULL;
383
384         /* subsytem messages are processed by every HPI.
385          * All other messages are ignored unless the adapter index matches
386          * an adapter in the HPI
387          */
388         HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
389                 phm->function);
390
391         /* if Dsp has crashed then do not communicate with it any more */
392         if (phm->object != HPI_OBJ_SUBSYSTEM) {
393                 pao = hpi_find_adapter(phm->adapter_index);
394                 if (!pao) {
395                         HPI_DEBUG_LOG(DEBUG,
396                                 " %d,%d refused, for another HPI?\n",
397                                 phm->object, phm->function);
398                         return;
399                 }
400
401                 if ((pao->dsp_crashed >= 10)
402                         && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
403                         /* allow last resort debug read even after crash */
404                         hpi_init_response(phr, phm->object, phm->function,
405                                 HPI_ERROR_DSP_HARDWARE);
406                         HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
407                                 phm->object, phm->function);
408                         return;
409                 }
410         }
411
412         /* Init default response  */
413         if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
414                 hpi_init_response(phr, phm->object, phm->function,
415                         HPI_ERROR_PROCESSING_MESSAGE);
416
417         HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
418         switch (phm->type) {
419         case HPI_TYPE_MESSAGE:
420                 switch (phm->object) {
421                 case HPI_OBJ_SUBSYSTEM:
422                         subsys_message(phm, phr);
423                         break;
424
425                 case HPI_OBJ_ADAPTER:
426                         phr->size =
427                                 sizeof(struct hpi_response_header) +
428                                 sizeof(struct hpi_adapter_res);
429                         adapter_message(pao, phm, phr);
430                         break;
431
432                 case HPI_OBJ_CONTROLEX:
433                 case HPI_OBJ_CONTROL:
434                         control_message(pao, phm, phr);
435                         break;
436
437                 case HPI_OBJ_OSTREAM:
438                         outstream_message(pao, phm, phr);
439                         break;
440
441                 case HPI_OBJ_ISTREAM:
442                         instream_message(pao, phm, phr);
443                         break;
444
445                 default:
446                         hw_message(pao, phm, phr);
447                         break;
448                 }
449                 break;
450
451         default:
452                 phr->error = HPI_ERROR_INVALID_TYPE;
453                 break;
454         }
455 }
456
457 /*****************************************************************************/
458 /* SUBSYSTEM */
459
460 /** Create an adapter object and initialise it based on resource information
461  * passed in in the message
462  * *** NOTE - you cannot use this function AND the FindAdapters function at the
463  * same time, the application must use only one of them to get the adapters ***
464  */
465 static void subsys_create_adapter(struct hpi_message *phm,
466         struct hpi_response *phr)
467 {
468         /* create temp adapter obj, because we don't know what index yet */
469         struct hpi_adapter_obj ao;
470         u32 os_error_code;
471         u16 err;
472
473         HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
474
475         memset(&ao, 0, sizeof(ao));
476
477         /* this HPI only creates adapters for TI/PCI devices */
478         if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
479                 return;
480         if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
481                 return;
482         if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
483                 return;
484
485         ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
486         if (!ao.priv) {
487                 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
488                 phr->error = HPI_ERROR_MEMORY_ALLOC;
489                 return;
490         }
491
492         ao.pci = *phm->u.s.resource.r.pci;
493         err = create_adapter_obj(&ao, &os_error_code);
494         if (!err)
495                 err = hpi_add_adapter(&ao);
496         if (err) {
497                 phr->u.s.data = os_error_code;
498                 delete_adapter_obj(&ao);
499                 phr->error = err;
500                 return;
501         }
502
503         phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
504         phr->u.s.adapter_index = ao.index;
505         phr->u.s.num_adapters++;
506         phr->error = 0;
507 }
508
509 /** delete an adapter - required by WDM driver */
510 static void subsys_delete_adapter(struct hpi_message *phm,
511         struct hpi_response *phr)
512 {
513         struct hpi_adapter_obj *pao;
514         struct hpi_hw_obj *phw;
515
516         pao = hpi_find_adapter(phm->adapter_index);
517         if (!pao) {
518                 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519                 return;
520         }
521         phw = (struct hpi_hw_obj *)pao->priv;
522         /* reset adapter h/w */
523         /* Reset C6713 #1 */
524         boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
525         /* reset C6205 */
526         iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
527
528         delete_adapter_obj(pao);
529         phr->error = 0;
530 }
531
532 /** Create adapter object
533   allocate buffers, bootload DSPs, initialise control cache
534 */
535 static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
536         u32 *pos_error_code)
537 {
538         struct hpi_hw_obj *phw = pao->priv;
539         struct bus_master_interface *interface;
540         u32 phys_addr;
541 #ifndef HPI6205_NO_HSR_POLL
542         u32 time_out = HPI6205_TIMEOUT;
543         u32 temp1;
544 #endif
545         int i;
546         u16 err;
547
548         /* init error reporting */
549         pao->dsp_crashed = 0;
550
551         for (i = 0; i < HPI_MAX_STREAMS; i++)
552                 phw->flag_outstream_just_reset[i] = 1;
553
554         /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
555         phw->prHSR =
556                 pao->pci.ap_mem_base[1] +
557                 C6205_BAR1_HSR / sizeof(*pao->pci.ap_mem_base[1]);
558         phw->prHDCR =
559                 pao->pci.ap_mem_base[1] +
560                 C6205_BAR1_HDCR / sizeof(*pao->pci.ap_mem_base[1]);
561         phw->prDSPP =
562                 pao->pci.ap_mem_base[1] +
563                 C6205_BAR1_DSPP / sizeof(*pao->pci.ap_mem_base[1]);
564
565         pao->has_control_cache = 0;
566
567         if (hpios_locked_mem_alloc(&phw->h_locked_mem,
568                         sizeof(struct bus_master_interface),
569                         pao->pci.p_os_data))
570                 phw->p_interface_buffer = NULL;
571         else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
572                         (void *)&phw->p_interface_buffer))
573                 phw->p_interface_buffer = NULL;
574
575         HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
576                 phw->p_interface_buffer);
577
578         if (phw->p_interface_buffer) {
579                 memset((void *)phw->p_interface_buffer, 0,
580                         sizeof(struct bus_master_interface));
581                 phw->p_interface_buffer->dsp_ack = H620_HIF_UNKNOWN;
582         }
583
584         err = adapter_boot_load_dsp(pao, pos_error_code);
585         if (err)
586                 /* no need to clean up as SubSysCreateAdapter */
587                 /* calls DeleteAdapter on error. */
588                 return err;
589
590         HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
591
592         /* allow boot load even if mem alloc wont work */
593         if (!phw->p_interface_buffer)
594                 return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC);
595
596         interface = phw->p_interface_buffer;
597
598 #ifndef HPI6205_NO_HSR_POLL
599         /* wait for first interrupt indicating the DSP init is done */
600         time_out = HPI6205_TIMEOUT * 10;
601         temp1 = 0;
602         while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
603                 temp1 = ioread32(phw->prHSR);
604
605         if (temp1 & C6205_HSR_INTSRC)
606                 HPI_DEBUG_LOG(INFO,
607                         "interrupt confirming DSP code running OK\n");
608         else {
609                 HPI_DEBUG_LOG(ERROR,
610                         "timed out waiting for interrupt "
611                         "confirming DSP code running\n");
612                 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
613         }
614
615         /* reset the interrupt */
616         iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617 #endif
618
619         /* make sure the DSP has started ok */
620         if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
621                 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
622                 return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED);
623         }
624         /* Note that *pao, *phw are zeroed after allocation,
625          * so pointers and flags are NULL by default.
626          * Allocate bus mastering control cache buffer and tell the DSP about it
627          */
628         if (interface->control_cache.number_of_controls) {
629                 void *p_control_cache_virtual;
630
631                 err = hpios_locked_mem_alloc(&phw->h_control_cache,
632                         interface->control_cache.size_in_bytes,
633                         pao->pci.p_os_data);
634                 if (!err)
635                         err = hpios_locked_mem_get_virt_addr(&phw->
636                                 h_control_cache, &p_control_cache_virtual);
637                 if (!err) {
638                         memset(p_control_cache_virtual, 0,
639                                 interface->control_cache.size_in_bytes);
640
641                         phw->p_cache =
642                                 hpi_alloc_control_cache(interface->
643                                 control_cache.number_of_controls,
644                                 interface->control_cache.size_in_bytes,
645                                 (struct hpi_control_cache_info *)
646                                 p_control_cache_virtual);
647                 }
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 u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
945 {
946         return status->size_in_bytes - (status->host_index -
947                 status->dSP_index);
948 }
949
950 static void outstream_write(struct hpi_adapter_obj *pao,
951         struct hpi_message *phm, struct hpi_response *phr)
952 {
953         struct hpi_hw_obj *phw = pao->priv;
954         struct bus_master_interface *interface = phw->p_interface_buffer;
955         struct hpi_hostbuffer_status *status;
956         u32 space_available;
957
958         if (!phw->outstream_host_buffer_size[phm->obj_index]) {
959                 /* there  is no BBM buffer, write via message */
960                 hw_message(pao, phm, phr);
961                 return;
962         }
963
964         hpi_init_response(phr, phm->object, phm->function, 0);
965         status = &interface->outstream_host_buffer_status[phm->obj_index];
966
967         if (phw->flag_outstream_just_reset[phm->obj_index]) {
968                 /* First OutStremWrite() call following reset will write data to the
969                    adapter's buffers, reducing delay before stream can start. The DSP
970                    takes care of setting the stream data format using format information
971                    embedded in phm.
972                  */
973                 int partial_write = 0;
974                 unsigned int original_size = 0;
975
976                 phw->flag_outstream_just_reset[phm->obj_index] = 0;
977
978                 /* Send the first buffer to the DSP the old way. */
979                 /* Limit size of first transfer - */
980                 /* expect that this will not usually be triggered. */
981                 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
982                         partial_write = 1;
983                         original_size = phm->u.d.u.data.data_size;
984                         phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
985                 }
986                 /* write it */
987                 phm->function = HPI_OSTREAM_WRITE;
988                 hw_message(pao, phm, phr);
989
990                 if (phr->error)
991                         return;
992
993                 /* update status information that the DSP would typically
994                  * update (and will update next time the DSP
995                  * buffer update task reads data from the host BBM buffer)
996                  */
997                 status->auxiliary_data_available = phm->u.d.u.data.data_size;
998                 status->host_index += phm->u.d.u.data.data_size;
999                 status->dSP_index += phm->u.d.u.data.data_size;
1000
1001                 /* if we did a full write, we can return from here. */
1002                 if (!partial_write)
1003                         return;
1004
1005                 /* tweak buffer parameters and let the rest of the */
1006                 /* buffer land in internal BBM buffer */
1007                 phm->u.d.u.data.data_size =
1008                         original_size - HPI6205_SIZEOF_DATA;
1009                 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1010         }
1011
1012         space_available = outstream_get_space_available(status);
1013         if (space_available < phm->u.d.u.data.data_size) {
1014                 phr->error = HPI_ERROR_INVALID_DATASIZE;
1015                 return;
1016         }
1017
1018         /* HostBuffers is used to indicate host buffer is internally allocated.
1019            otherwise, assumed external, data written externally */
1020         if (phm->u.d.u.data.pb_data
1021                 && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
1022                                 obj_index])) {
1023                 u8 *p_bbm_data;
1024                 u32 l_first_write;
1025                 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1026
1027                 if (hpios_locked_mem_get_virt_addr(&phw->
1028                                 outstream_host_buffers[phm->obj_index],
1029                                 (void *)&p_bbm_data)) {
1030                         phr->error = HPI_ERROR_INVALID_OPERATION;
1031                         return;
1032                 }
1033
1034                 /* either all data,
1035                    or enough to fit from current to end of BBM buffer */
1036                 l_first_write =
1037                         min(phm->u.d.u.data.data_size,
1038                         status->size_in_bytes -
1039                         (status->host_index & (status->size_in_bytes - 1)));
1040
1041                 memcpy(p_bbm_data +
1042                         (status->host_index & (status->size_in_bytes - 1)),
1043                         p_app_data, l_first_write);
1044                 /* remaining data if any */
1045                 memcpy(p_bbm_data, p_app_data + l_first_write,
1046                         phm->u.d.u.data.data_size - l_first_write);
1047         }
1048         status->host_index += phm->u.d.u.data.data_size;
1049 }
1050
1051 static void outstream_get_info(struct hpi_adapter_obj *pao,
1052         struct hpi_message *phm, struct hpi_response *phr)
1053 {
1054         struct hpi_hw_obj *phw = pao->priv;
1055         struct bus_master_interface *interface = phw->p_interface_buffer;
1056         struct hpi_hostbuffer_status *status;
1057
1058         if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1059                 hw_message(pao, phm, phr);
1060                 return;
1061         }
1062
1063         hpi_init_response(phr, phm->object, phm->function, 0);
1064
1065         status = &interface->outstream_host_buffer_status[phm->obj_index];
1066
1067         phr->u.d.u.stream_info.state = (u16)status->stream_state;
1068         phr->u.d.u.stream_info.samples_transferred =
1069                 status->samples_processed;
1070         phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1071         phr->u.d.u.stream_info.data_available =
1072                 status->size_in_bytes - outstream_get_space_available(status);
1073         phr->u.d.u.stream_info.auxiliary_data_available =
1074                 status->auxiliary_data_available;
1075 }
1076
1077 static void outstream_start(struct hpi_adapter_obj *pao,
1078         struct hpi_message *phm, struct hpi_response *phr)
1079 {
1080         hw_message(pao, phm, phr);
1081 }
1082
1083 static void outstream_reset(struct hpi_adapter_obj *pao,
1084         struct hpi_message *phm, struct hpi_response *phr)
1085 {
1086         struct hpi_hw_obj *phw = pao->priv;
1087         phw->flag_outstream_just_reset[phm->obj_index] = 1;
1088         hw_message(pao, phm, phr);
1089 }
1090
1091 static void outstream_open(struct hpi_adapter_obj *pao,
1092         struct hpi_message *phm, struct hpi_response *phr)
1093 {
1094         outstream_reset(pao, phm, phr);
1095 }
1096
1097 /*****************************************************************************/
1098 /* InStream Host buffer functions */
1099
1100 static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1101         struct hpi_message *phm, struct hpi_response *phr)
1102 {
1103         u16 err = 0;
1104         u32 command = phm->u.d.u.buffer.command;
1105         struct hpi_hw_obj *phw = pao->priv;
1106         struct bus_master_interface *interface = phw->p_interface_buffer;
1107
1108         hpi_init_response(phr, phm->object, phm->function, 0);
1109
1110         if (command == HPI_BUFFER_CMD_EXTERNAL
1111                 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1112
1113                 phm->u.d.u.buffer.buffer_size =
1114                         roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
1115                 phr->u.d.u.stream_info.data_available =
1116                         phw->instream_host_buffer_size[phm->obj_index];
1117                 phr->u.d.u.stream_info.buffer_size =
1118                         phm->u.d.u.buffer.buffer_size;
1119
1120                 if (phw->instream_host_buffer_size[phm->obj_index] ==
1121                         phm->u.d.u.buffer.buffer_size) {
1122                         /* Same size, no action required */
1123                         return;
1124                 }
1125
1126                 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1127                                         obj_index]))
1128                         hpios_locked_mem_free(&phw->instream_host_buffers
1129                                 [phm->obj_index]);
1130
1131                 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1132                                 obj_index], phm->u.d.u.buffer.buffer_size,
1133                         pao->pci.p_os_data);
1134
1135                 if (err) {
1136                         phr->error = HPI_ERROR_INVALID_DATASIZE;
1137                         phw->instream_host_buffer_size[phm->obj_index] = 0;
1138                         return;
1139                 }
1140
1141                 err = hpios_locked_mem_get_phys_addr
1142                         (&phw->instream_host_buffers[phm->obj_index],
1143                         &phm->u.d.u.buffer.pci_address);
1144                 /* get the phys addr into msg for single call alloc. Caller
1145                    needs to do this for split alloc so return the phy address */
1146                 phr->u.d.u.stream_info.auxiliary_data_available =
1147                         phm->u.d.u.buffer.pci_address;
1148                 if (err) {
1149                         hpios_locked_mem_free(&phw->instream_host_buffers
1150                                 [phm->obj_index]);
1151                         phw->instream_host_buffer_size[phm->obj_index] = 0;
1152                         phr->error = HPI_ERROR_MEMORY_ALLOC;
1153                         return;
1154                 }
1155         }
1156
1157         if (command == HPI_BUFFER_CMD_EXTERNAL
1158                 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1159                 struct hpi_hostbuffer_status *status;
1160
1161                 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1162                                 buffer_size - 1)) {
1163                         HPI_DEBUG_LOG(ERROR,
1164                                 "buffer size must be 2^N not %d\n",
1165                                 phm->u.d.u.buffer.buffer_size);
1166                         phr->error = HPI_ERROR_INVALID_DATASIZE;
1167                         return;
1168                 }
1169
1170                 phw->instream_host_buffer_size[phm->obj_index] =
1171                         phm->u.d.u.buffer.buffer_size;
1172                 status = &interface->instream_host_buffer_status[phm->
1173                         obj_index];
1174                 status->samples_processed = 0;
1175                 status->stream_state = HPI_STATE_STOPPED;
1176                 status->dSP_index = 0;
1177                 status->host_index = status->dSP_index;
1178                 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1179
1180                 hw_message(pao, phm, phr);
1181                 if (phr->error
1182                         && hpios_locked_mem_valid(&phw->
1183                                 instream_host_buffers[phm->obj_index])) {
1184                         hpios_locked_mem_free(&phw->instream_host_buffers
1185                                 [phm->obj_index]);
1186                         phw->instream_host_buffer_size[phm->obj_index] = 0;
1187                 }
1188         }
1189 }
1190
1191 static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1192         struct hpi_message *phm, struct hpi_response *phr)
1193 {
1194         struct hpi_hw_obj *phw = pao->priv;
1195         struct bus_master_interface *interface = phw->p_interface_buffer;
1196         struct hpi_hostbuffer_status *status;
1197         u8 *p_bbm_data;
1198
1199         if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1200                                 obj_index])) {
1201                 if (hpios_locked_mem_get_virt_addr(&phw->
1202                                 instream_host_buffers[phm->obj_index],
1203                                 (void *)&p_bbm_data)) {
1204                         phr->error = HPI_ERROR_INVALID_OPERATION;
1205                         return;
1206                 }
1207                 status = &interface->instream_host_buffer_status[phm->
1208                         obj_index];
1209                 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1210                         HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
1211                 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
1212                 phr->u.d.u.hostbuffer_info.p_status = status;
1213         } else {
1214                 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1215                         HPI_ISTREAM_HOSTBUFFER_GET_INFO,
1216                         HPI_ERROR_INVALID_OPERATION);
1217         }
1218 }
1219
1220 static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1221         struct hpi_message *phm, struct hpi_response *phr)
1222 {
1223         struct hpi_hw_obj *phw = pao->priv;
1224         u32 command = phm->u.d.u.buffer.command;
1225
1226         if (phw->instream_host_buffer_size[phm->obj_index]) {
1227                 if (command == HPI_BUFFER_CMD_EXTERNAL
1228                         || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
1229                         phw->instream_host_buffer_size[phm->obj_index] = 0;
1230                         hw_message(pao, phm, phr);
1231                 }
1232
1233                 if (command == HPI_BUFFER_CMD_EXTERNAL
1234                         || command == HPI_BUFFER_CMD_INTERNAL_FREE)
1235                         hpios_locked_mem_free(&phw->instream_host_buffers
1236                                 [phm->obj_index]);
1237
1238         } else {
1239                 /* Should HPI_ERROR_INVALID_OPERATION be returned
1240                    if no host buffer is allocated? */
1241                 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1242                         HPI_ISTREAM_HOSTBUFFER_FREE, 0);
1243
1244         }
1245
1246 }
1247
1248 static void instream_start(struct hpi_adapter_obj *pao,
1249         struct hpi_message *phm, struct hpi_response *phr)
1250 {
1251         hw_message(pao, phm, phr);
1252 }
1253
1254 static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1255 {
1256         return status->dSP_index - status->host_index;
1257 }
1258
1259 static void instream_read(struct hpi_adapter_obj *pao,
1260         struct hpi_message *phm, struct hpi_response *phr)
1261 {
1262         struct hpi_hw_obj *phw = pao->priv;
1263         struct bus_master_interface *interface = phw->p_interface_buffer;
1264         struct hpi_hostbuffer_status *status;
1265         u32 data_available;
1266         u8 *p_bbm_data;
1267         u32 l_first_read;
1268         u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1269
1270         if (!phw->instream_host_buffer_size[phm->obj_index]) {
1271                 hw_message(pao, phm, phr);
1272                 return;
1273         }
1274         hpi_init_response(phr, phm->object, phm->function, 0);
1275
1276         status = &interface->instream_host_buffer_status[phm->obj_index];
1277         data_available = instream_get_bytes_available(status);
1278         if (data_available < phm->u.d.u.data.data_size) {
1279                 phr->error = HPI_ERROR_INVALID_DATASIZE;
1280                 return;
1281         }
1282
1283         if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1284                                 obj_index])) {
1285                 if (hpios_locked_mem_get_virt_addr(&phw->
1286                                 instream_host_buffers[phm->obj_index],
1287                                 (void *)&p_bbm_data)) {
1288                         phr->error = HPI_ERROR_INVALID_OPERATION;
1289                         return;
1290                 }
1291
1292                 /* either all data,
1293                    or enough to fit from current to end of BBM buffer */
1294                 l_first_read =
1295                         min(phm->u.d.u.data.data_size,
1296                         status->size_in_bytes -
1297                         (status->host_index & (status->size_in_bytes - 1)));
1298
1299                 memcpy(p_app_data,
1300                         p_bbm_data +
1301                         (status->host_index & (status->size_in_bytes - 1)),
1302                         l_first_read);
1303                 /* remaining data if any */
1304                 memcpy(p_app_data + l_first_read, p_bbm_data,
1305                         phm->u.d.u.data.data_size - l_first_read);
1306         }
1307         status->host_index += phm->u.d.u.data.data_size;
1308 }
1309
1310 static void instream_get_info(struct hpi_adapter_obj *pao,
1311         struct hpi_message *phm, struct hpi_response *phr)
1312 {
1313         struct hpi_hw_obj *phw = pao->priv;
1314         struct bus_master_interface *interface = phw->p_interface_buffer;
1315         struct hpi_hostbuffer_status *status;
1316         if (!phw->instream_host_buffer_size[phm->obj_index]) {
1317                 hw_message(pao, phm, phr);
1318                 return;
1319         }
1320
1321         status = &interface->instream_host_buffer_status[phm->obj_index];
1322
1323         hpi_init_response(phr, phm->object, phm->function, 0);
1324
1325         phr->u.d.u.stream_info.state = (u16)status->stream_state;
1326         phr->u.d.u.stream_info.samples_transferred =
1327                 status->samples_processed;
1328         phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1329         phr->u.d.u.stream_info.data_available =
1330                 instream_get_bytes_available(status);
1331         phr->u.d.u.stream_info.auxiliary_data_available =
1332                 status->auxiliary_data_available;
1333 }
1334
1335 /*****************************************************************************/
1336 /* LOW-LEVEL */
1337 #define HPI6205_MAX_FILES_TO_LOAD 2
1338
1339 static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1340         u32 *pos_error_code)
1341 {
1342         struct hpi_hw_obj *phw = pao->priv;
1343         struct dsp_code dsp_code;
1344         u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1345         u16 firmware_id = pao->pci.subsys_device_id;
1346         u32 temp;
1347         int dsp = 0, i = 0;
1348         u16 err = 0;
1349
1350         boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1351
1352         /* special cases where firmware_id != subsys ID */
1353         switch (firmware_id) {
1354         case HPI_ADAPTER_FAMILY_ASI(0x5000):
1355                 boot_code_id[0] = firmware_id;
1356                 firmware_id = 0;
1357                 break;
1358         case HPI_ADAPTER_FAMILY_ASI(0x5300):
1359         case HPI_ADAPTER_FAMILY_ASI(0x5400):
1360         case HPI_ADAPTER_FAMILY_ASI(0x6300):
1361                 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400);
1362                 break;
1363         case HPI_ADAPTER_FAMILY_ASI(0x5600):
1364         case HPI_ADAPTER_FAMILY_ASI(0x6500):
1365                 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600);
1366                 break;
1367         case HPI_ADAPTER_FAMILY_ASI(0x8800):
1368                 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900);
1369                 break;
1370         }
1371         boot_code_id[1] = firmware_id;
1372
1373         /* reset DSP by writing a 1 to the WARMRESET bit */
1374         temp = C6205_HDCR_WARMRESET;
1375         iowrite32(temp, phw->prHDCR);
1376         hpios_delay_micro_seconds(1000);
1377
1378         /* check that PCI i/f was configured by EEPROM */
1379         temp = ioread32(phw->prHSR);
1380         if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1381                 C6205_HSR_EEREAD)
1382                 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
1383         temp |= 0x04;
1384         /* disable PINTA interrupt */
1385         iowrite32(temp, phw->prHSR);
1386
1387         /* check control register reports PCI boot mode */
1388         temp = ioread32(phw->prHDCR);
1389         if (!(temp & C6205_HDCR_PCIBOOT))
1390                 return hpi6205_error(0, HPI6205_ERROR_6205_REG);
1391
1392         /* try writing a couple of numbers to the DSP page register */
1393         /* and reading them back. */
1394         temp = 1;
1395         iowrite32(temp, phw->prDSPP);
1396         if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1397                 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1398         temp = 2;
1399         iowrite32(temp, phw->prDSPP);
1400         if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1401                 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1402         temp = 3;
1403         iowrite32(temp, phw->prDSPP);
1404         if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1405                 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1406         /* reset DSP page to the correct number */
1407         temp = 0;
1408         iowrite32(temp, phw->prDSPP);
1409         if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1410                 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1411         phw->dsp_page = 0;
1412
1413         /* release 6713 from reset before 6205 is bootloaded.
1414            This ensures that the EMIF is inactive,
1415            and the 6713 HPI gets the correct bootmode etc
1416          */
1417         if (boot_code_id[1] != 0) {
1418                 /* DSP 1 is a C6713 */
1419                 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1420                 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
1421                 hpios_delay_micro_seconds(100);
1422                 /* Reset the 6713 #1 - revB */
1423                 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
1424
1425                 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1426                 boot_loader_read_mem32(pao, 0, 0);
1427
1428                 hpios_delay_micro_seconds(100);
1429                 /* Release C6713 from reset - revB */
1430                 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
1431                 hpios_delay_micro_seconds(100);
1432         }
1433
1434         for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
1435                 /* is there a DSP to load? */
1436                 if (boot_code_id[dsp] == 0)
1437                         continue;
1438
1439                 err = boot_loader_config_emif(pao, dsp);
1440                 if (err)
1441                         return err;
1442
1443                 err = boot_loader_test_internal_memory(pao, dsp);
1444                 if (err)
1445                         return err;
1446
1447                 err = boot_loader_test_external_memory(pao, dsp);
1448                 if (err)
1449                         return err;
1450
1451                 err = boot_loader_test_pld(pao, dsp);
1452                 if (err)
1453                         return err;
1454
1455                 /* write the DSP code down into the DSPs memory */
1456                 dsp_code.ps_dev = pao->pci.p_os_data;
1457                 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1458                         pos_error_code);
1459                 if (err)
1460                         return err;
1461
1462                 while (1) {
1463                         u32 length;
1464                         u32 address;
1465                         u32 type;
1466                         u32 *pcode;
1467
1468                         err = hpi_dsp_code_read_word(&dsp_code, &length);
1469                         if (err)
1470                                 break;
1471                         if (length == 0xFFFFFFFF)
1472                                 break;  /* end of code */
1473
1474                         err = hpi_dsp_code_read_word(&dsp_code, &address);
1475                         if (err)
1476                                 break;
1477                         err = hpi_dsp_code_read_word(&dsp_code, &type);
1478                         if (err)
1479                                 break;
1480                         err = hpi_dsp_code_read_block(length, &dsp_code,
1481                                 &pcode);
1482                         if (err)
1483                                 break;
1484                         for (i = 0; i < (int)length; i++) {
1485                                 err = boot_loader_write_mem32(pao, dsp,
1486                                         address, *pcode);
1487                                 if (err)
1488                                         break;
1489                                 /* dummy read every 4 words */
1490                                 /* for 6205 advisory 1.4.4 */
1491                                 if (i % 4 == 0)
1492                                         boot_loader_read_mem32(pao, dsp,
1493                                                 address);
1494                                 pcode++;
1495                                 address += 4;
1496                         }
1497
1498                 }
1499                 if (err) {
1500                         hpi_dsp_code_close(&dsp_code);
1501                         return err;
1502                 }
1503
1504                 /* verify code */
1505                 hpi_dsp_code_rewind(&dsp_code);
1506                 while (1) {
1507                         u32 length = 0;
1508                         u32 address = 0;
1509                         u32 type = 0;
1510                         u32 *pcode = NULL;
1511                         u32 data = 0;
1512
1513                         hpi_dsp_code_read_word(&dsp_code, &length);
1514                         if (length == 0xFFFFFFFF)
1515                                 break;  /* end of code */
1516
1517                         hpi_dsp_code_read_word(&dsp_code, &address);
1518                         hpi_dsp_code_read_word(&dsp_code, &type);
1519                         hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1520
1521                         for (i = 0; i < (int)length; i++) {
1522                                 data = boot_loader_read_mem32(pao, dsp,
1523                                         address);
1524                                 if (data != *pcode) {
1525                                         err = 0;
1526                                         break;
1527                                 }
1528                                 pcode++;
1529                                 address += 4;
1530                         }
1531                         if (err)
1532                                 break;
1533                 }
1534                 hpi_dsp_code_close(&dsp_code);
1535                 if (err)
1536                         return err;
1537         }
1538
1539         /* After bootloading all DSPs, start DSP0 running
1540          * The DSP0 code will handle starting and synchronizing with its slaves
1541          */
1542         if (phw->p_interface_buffer) {
1543                 /* we need to tell the card the physical PCI address */
1544                 u32 physicalPC_iaddress;
1545                 struct bus_master_interface *interface =
1546                         phw->p_interface_buffer;
1547                 u32 host_mailbox_address_on_dsp;
1548                 u32 physicalPC_iaddress_verify = 0;
1549                 int time_out = 10;
1550                 /* set ack so we know when DSP is ready to go */
1551                 /* (dwDspAck will be changed to HIF_RESET) */
1552                 interface->dsp_ack = H620_HIF_UNKNOWN;
1553                 wmb();  /* ensure ack is written before dsp writes back */
1554
1555                 err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1556                         &physicalPC_iaddress);
1557
1558                 /* locate the host mailbox on the DSP. */
1559                 host_mailbox_address_on_dsp = 0x80000000;
1560                 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1561                         && time_out--) {
1562                         err = boot_loader_write_mem32(pao, 0,
1563                                 host_mailbox_address_on_dsp,
1564                                 physicalPC_iaddress);
1565                         physicalPC_iaddress_verify =
1566                                 boot_loader_read_mem32(pao, 0,
1567                                 host_mailbox_address_on_dsp);
1568                 }
1569         }
1570         HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
1571         /* enable interrupts */
1572         temp = ioread32(phw->prHSR);
1573         temp &= ~(u32)C6205_HSR_INTAM;
1574         iowrite32(temp, phw->prHSR);
1575
1576         /* start code running... */
1577         temp = ioread32(phw->prHDCR);
1578         temp |= (u32)C6205_HDCR_DSPINT;
1579         iowrite32(temp, phw->prHDCR);
1580
1581         /* give the DSP 10ms to start up */
1582         hpios_delay_micro_seconds(10000);
1583         return err;
1584
1585 }
1586
1587 /*****************************************************************************/
1588 /* Bootloader utility functions */
1589
1590 static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1591         u32 address)
1592 {
1593         struct hpi_hw_obj *phw = pao->priv;
1594         u32 data = 0;
1595         __iomem u32 *p_data;
1596
1597         if (dsp_index == 0) {
1598                 /* DSP 0 is always C6205 */
1599                 if ((address >= 0x01800000) & (address < 0x02000000)) {
1600                         /* BAR1 register access */
1601                         p_data = pao->pci.ap_mem_base[1] +
1602                                 (address & 0x007fffff) /
1603                                 sizeof(*pao->pci.ap_mem_base[1]);
1604                         /* HPI_DEBUG_LOG(WARNING,
1605                            "BAR1 access %08x\n", dwAddress); */
1606                 } else {
1607                         u32 dw4M_page = address >> 22L;
1608                         if (dw4M_page != phw->dsp_page) {
1609                                 phw->dsp_page = dw4M_page;
1610                                 /* *INDENT OFF* */
1611                                 iowrite32(phw->dsp_page, phw->prDSPP);
1612                                 /* *INDENT-ON* */
1613                         }
1614                         address &= 0x3fffff;    /* address within 4M page */
1615                         /* BAR0 memory access */
1616                         p_data = pao->pci.ap_mem_base[0] +
1617                                 address / sizeof(u32);
1618                 }
1619                 data = ioread32(p_data);
1620         } else if (dsp_index == 1) {
1621                 /* DSP 1 is a C6713 */
1622                 u32 lsb;
1623                 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1624                 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1625                 lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
1626                 data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
1627                 data = (data << 16) | (lsb & 0xFFFF);
1628         }
1629         return data;
1630 }
1631
1632 static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1633         u32 address, u32 data)
1634 {
1635         struct hpi_hw_obj *phw = pao->priv;
1636         u16 err = 0;
1637         __iomem u32 *p_data;
1638         /*      u32 dwVerifyData=0; */
1639
1640         if (dsp_index == 0) {
1641                 /* DSP 0 is always C6205 */
1642                 if ((address >= 0x01800000) & (address < 0x02000000)) {
1643                         /* BAR1 - DSP  register access using */
1644                         /* Non-prefetchable PCI access */
1645                         p_data = pao->pci.ap_mem_base[1] +
1646                                 (address & 0x007fffff) /
1647                                 sizeof(*pao->pci.ap_mem_base[1]);
1648                 } else {
1649                         /* BAR0 access - all of DSP memory using */
1650                         /* pre-fetchable PCI access */
1651                         u32 dw4M_page = address >> 22L;
1652                         if (dw4M_page != phw->dsp_page) {
1653                                 phw->dsp_page = dw4M_page;
1654                                 /* *INDENT-OFF* */
1655                                 iowrite32(phw->dsp_page, phw->prDSPP);
1656                                 /* *INDENT-ON* */
1657                         }
1658                         address &= 0x3fffff;    /* address within 4M page */
1659                         p_data = pao->pci.ap_mem_base[0] +
1660                                 address / sizeof(u32);
1661                 }
1662                 iowrite32(data, p_data);
1663         } else if (dsp_index == 1) {
1664                 /* DSP 1 is a C6713 */
1665                 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1666                 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1667
1668                 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1669                 boot_loader_read_mem32(pao, 0, 0);
1670
1671                 boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1672                 boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1673
1674                 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1675                 boot_loader_read_mem32(pao, 0, 0);
1676         } else
1677                 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1678         return err;
1679 }
1680
1681 static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1682 {
1683         u16 err = 0;
1684
1685         if (dsp_index == 0) {
1686                 u32 setting;
1687
1688                 /* DSP 0 is always C6205 */
1689
1690                 /* Set the EMIF */
1691                 /* memory map of C6205 */
1692                 /* 00000000-0000FFFF    16Kx32 internal program */
1693                 /* 00400000-00BFFFFF    CE0     2Mx32 SDRAM running @ 100MHz */
1694
1695                 /* EMIF config */
1696                 /*------------ */
1697                 /* Global EMIF control */
1698                 boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
1699 #define WS_OFS 28
1700 #define WST_OFS 22
1701 #define WH_OFS 20
1702 #define RS_OFS 16
1703 #define RST_OFS 8
1704 #define MTYPE_OFS 4
1705 #define RH_OFS 0
1706
1707                 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1708                 setting = 0x00000030;
1709                 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1710                 if (setting != boot_loader_read_mem32(pao, dsp_index,
1711                                 0x01800008))
1712                         return hpi6205_error(dsp_index,
1713                                 HPI6205_ERROR_DSP_EMIF);
1714
1715                 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1716                 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1717                 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1718                 /* WST should be 71, but 63  is max possible */
1719                 setting =
1720                         (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
1721                         (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1722                         (2L << MTYPE_OFS);
1723                 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1724                 if (setting != boot_loader_read_mem32(pao, dsp_index,
1725                                 0x01800004))
1726                         return hpi6205_error(dsp_index,
1727                                 HPI6205_ERROR_DSP_EMIF);
1728
1729                 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1730                 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1731                 /* plenty of wait states */
1732                 setting =
1733                         (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
1734                         (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1735                         (2L << MTYPE_OFS);
1736                 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1737                 if (setting != boot_loader_read_mem32(pao, dsp_index,
1738                                 0x01800010))
1739                         return hpi6205_error(dsp_index,
1740                                 HPI6205_ERROR_DSP_EMIF);
1741
1742                 /* EMIF CE3 setup - 32 bit async. */
1743                 /* This is the PLD on the ASI5000 cards only */
1744                 setting =
1745                         (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
1746                         (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
1747                         (2L << MTYPE_OFS);
1748                 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1749                 if (setting != boot_loader_read_mem32(pao, dsp_index,
1750                                 0x01800014))
1751                         return hpi6205_error(dsp_index,
1752                                 HPI6205_ERROR_DSP_EMIF);
1753
1754                 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1755                 /*  need to use this else DSP code crashes? */
1756                 boot_loader_write_mem32(pao, dsp_index, 0x01800018,
1757                         0x07117000);
1758
1759                 /* EMIF SDRAM Refresh Timing */
1760                 /* EMIF SDRAM timing  (orig = 0x410, emulator = 0x61a) */
1761                 boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1762                         0x00000410);
1763
1764         } else if (dsp_index == 1) {
1765                 /* test access to the C6713s HPI registers */
1766                 u32 write_data = 0, read_data = 0, i = 0;
1767
1768                 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1769                 write_data = 1;
1770                 boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
1771                 boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
1772                 /* C67 HPI is on lower 16bits of 32bit EMIF */
1773                 read_data =
1774                         0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1775                 if (write_data != read_data) {
1776                         err = hpi6205_error(dsp_index,
1777                                 HPI6205_ERROR_C6713_HPIC);
1778                         HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1779                                 read_data);
1780
1781                         return err;
1782                 }
1783                 /* HPIA - walking ones test */
1784                 write_data = 1;
1785                 for (i = 0; i < 32; i++) {
1786                         boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
1787                                 write_data);
1788                         boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
1789                                 (write_data >> 16));
1790                         read_data =
1791                                 0xFFFF & boot_loader_read_mem32(pao, 0,
1792                                 HPIAL_ADDR);
1793                         read_data =
1794                                 read_data | ((0xFFFF &
1795                                         boot_loader_read_mem32(pao, 0,
1796                                                 HPIAH_ADDR))
1797                                 << 16);
1798                         if (read_data != write_data) {
1799                                 err = hpi6205_error(dsp_index,
1800                                         HPI6205_ERROR_C6713_HPIA);
1801                                 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1802                                         write_data, read_data);
1803                                 return err;
1804                         }
1805                         write_data = write_data << 1;
1806                 }
1807
1808                 /* setup C67x PLL
1809                  *  ** C6713 datasheet says we cannot program PLL from HPI,
1810                  * and indeed if we try to set the PLL multiply from the HPI,
1811                  * the PLL does not seem to lock, so we enable the PLL and
1812                  * use the default multiply of x 7, which for a 27MHz clock
1813                  * gives a DSP speed of 189MHz
1814                  */
1815                 /* bypass PLL */
1816                 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
1817                 hpios_delay_micro_seconds(1000);
1818                 /* EMIF = 189/3=63MHz */
1819                 boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
1820                 /* peri = 189/2 */
1821                 boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
1822                 /* cpu  = 189/1 */
1823                 boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
1824                 hpios_delay_micro_seconds(1000);
1825                 /* ** SGT test to take GPO3 high when we start the PLL */
1826                 /* and low when the delay is completed */
1827                 /* FSX0 <- '1' (GPO3) */
1828                 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
1829                 /* PLL not bypassed */
1830                 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
1831                 hpios_delay_micro_seconds(1000);
1832                 /* FSX0 <- '0' (GPO3) */
1833                 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
1834
1835                 /* 6205 EMIF CE1 resetup - 32 bit async. */
1836                 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1837                 boot_loader_write_mem32(pao, 0, 0x01800004,     /* CE1 */
1838                         (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
1839                         (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
1840                         (2L << MTYPE_OFS));
1841
1842                 hpios_delay_micro_seconds(1000);
1843
1844                 /* check that we can read one of the PLL registers */
1845                 /* PLL should not be bypassed! */
1846                 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1847                         != 0x0001) {
1848                         err = hpi6205_error(dsp_index,
1849                                 HPI6205_ERROR_C6713_PLL);
1850                         return err;
1851                 }
1852                 /* setup C67x EMIF  (note this is the only use of
1853                    BAR1 via BootLoader_WriteMem32) */
1854                 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1855                         0x000034A8);
1856                 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1857                         0x00000030);
1858                 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1859                         0x001BDF29);
1860                 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1861                         0x47117000);
1862                 boot_loader_write_mem32(pao, dsp_index,
1863                         C6713_EMIF_SDRAMTIMING, 0x00000410);
1864
1865                 hpios_delay_micro_seconds(1000);
1866         } else if (dsp_index == 2) {
1867                 /* DSP 2 is a C6713 */
1868
1869         } else
1870                 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1871         return err;
1872 }
1873
1874 static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1875         u32 start_address, u32 length)
1876 {
1877         u32 i = 0, j = 0;
1878         u32 test_addr = 0;
1879         u32 test_data = 0, data = 0;
1880
1881         length = 1000;
1882
1883         /* for 1st word, test each bit in the 32bit word, */
1884         /* dwLength specifies number of 32bit words to test */
1885         /*for(i=0; i<dwLength; i++) */
1886         i = 0;
1887         {
1888                 test_addr = start_address + i * 4;
1889                 test_data = 0x00000001;
1890                 for (j = 0; j < 32; j++) {
1891                         boot_loader_write_mem32(pao, dsp_index, test_addr,
1892                                 test_data);
1893                         data = boot_loader_read_mem32(pao, dsp_index,
1894                                 test_addr);
1895                         if (data != test_data) {
1896                                 HPI_DEBUG_LOG(VERBOSE,
1897                                         "memtest error details  "
1898                                         "%08x %08x %08x %i\n", test_addr,
1899                                         test_data, data, dsp_index);
1900                                 return 1;       /* error */
1901                         }
1902                         test_data = test_data << 1;
1903                 }       /* for(j) */
1904         }       /* for(i) */
1905
1906         /* for the next 100 locations test each location, leaving it as zero */
1907         /* write a zero to the next word in memory before we read */
1908         /* the previous write to make sure every memory location is unique */
1909         for (i = 0; i < 100; i++) {
1910                 test_addr = start_address + i * 4;
1911                 test_data = 0xA5A55A5A;
1912                 boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
1913                 boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
1914                 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1915                 if (data != test_data) {
1916                         HPI_DEBUG_LOG(VERBOSE,
1917                                 "memtest error details  "
1918                                 "%08x %08x %08x %i\n", test_addr, test_data,
1919                                 data, dsp_index);
1920                         return 1;       /* error */
1921                 }
1922                 /* leave location as zero */
1923                 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1924         }
1925
1926         /* zero out entire memory block */
1927         for (i = 0; i < length; i++) {
1928                 test_addr = start_address + i * 4;
1929                 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1930         }
1931         return 0;
1932 }
1933
1934 static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1935         int dsp_index)
1936 {
1937         int err = 0;
1938         if (dsp_index == 0) {
1939                 /* DSP 0 is a C6205 */
1940                 /* 64K prog mem */
1941                 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1942                         0x10000);
1943                 if (!err)
1944                         /* 64K data mem */
1945                         err = boot_loader_test_memory(pao, dsp_index,
1946                                 0x80000000, 0x10000);
1947         } else if ((dsp_index == 1) || (dsp_index == 2)) {
1948                 /* DSP 1&2 are a C6713 */
1949                 /* 192K internal mem */
1950                 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1951                         0x30000);
1952                 if (!err)
1953                         /* 64K internal mem / L2 cache */
1954                         err = boot_loader_test_memory(pao, dsp_index,
1955                                 0x00030000, 0x10000);
1956         } else
1957                 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1958
1959         if (err)
1960                 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1961         else
1962                 return 0;
1963 }
1964
1965 static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1966         int dsp_index)
1967 {
1968         u32 dRAM_start_address = 0;
1969         u32 dRAM_size = 0;
1970
1971         if (dsp_index == 0) {
1972                 /* only test for SDRAM if an ASI5000 card */
1973                 if (pao->pci.subsys_device_id == 0x5000) {
1974                         /* DSP 0 is always C6205 */
1975                         dRAM_start_address = 0x00400000;
1976                         dRAM_size = 0x200000;
1977                         /*dwDRAMinc=1024; */
1978                 } else
1979                         return 0;
1980         } else if ((dsp_index == 1) || (dsp_index == 2)) {
1981                 /* DSP 1 is a C6713 */
1982                 dRAM_start_address = 0x80000000;
1983                 dRAM_size = 0x200000;
1984                 /*dwDRAMinc=1024; */
1985         } else
1986                 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1987
1988         if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1989                         dRAM_size))
1990                 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
1991         return 0;
1992 }
1993
1994 static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1995 {
1996         u32 data = 0;
1997         if (dsp_index == 0) {
1998                 /* only test for DSP0 PLD on ASI5000 card */
1999                 if (pao->pci.subsys_device_id == 0x5000) {
2000                         /* PLD is located at CE3=0x03000000 */
2001                         data = boot_loader_read_mem32(pao, dsp_index,
2002                                 0x03000008);
2003                         if ((data & 0xF) != 0x5)
2004                                 return hpi6205_error(dsp_index,
2005                                         HPI6205_ERROR_DSP_PLD);
2006                         data = boot_loader_read_mem32(pao, dsp_index,
2007                                 0x0300000C);
2008                         if ((data & 0xF) != 0xA)
2009                                 return hpi6205_error(dsp_index,
2010                                         HPI6205_ERROR_DSP_PLD);
2011                 }
2012         } else if (dsp_index == 1) {
2013                 /* DSP 1 is a C6713 */
2014                 if (pao->pci.subsys_device_id == 0x8700) {
2015                         /* PLD is located at CE1=0x90000000 */
2016                         data = boot_loader_read_mem32(pao, dsp_index,
2017                                 0x90000010);
2018                         if ((data & 0xFF) != 0xAA)
2019                                 return hpi6205_error(dsp_index,
2020                                         HPI6205_ERROR_DSP_PLD);
2021                         /* 8713 - LED on */
2022                         boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2023                                 0x02);
2024                 }
2025         }
2026         return 0;
2027 }
2028
2029 /** Transfer data to or from DSP
2030  nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2031 */
2032 static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2033         u32 data_size, int operation)
2034 {
2035         struct hpi_hw_obj *phw = pao->priv;
2036         u32 data_transferred = 0;
2037         u16 err = 0;
2038 #ifndef HPI6205_NO_HSR_POLL
2039         u32 time_out;
2040 #endif
2041         u32 temp2;
2042         struct bus_master_interface *interface = phw->p_interface_buffer;
2043
2044         if (!p_data)
2045                 return HPI_ERROR_INVALID_DATA_TRANSFER;
2046
2047         data_size &= ~3L;       /* round data_size down to nearest 4 bytes */
2048
2049         /* make sure state is IDLE */
2050         if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2051                 return HPI_ERROR_DSP_HARDWARE;
2052
2053         while (data_transferred < data_size) {
2054                 u32 this_copy = data_size - data_transferred;
2055
2056                 if (this_copy > HPI6205_SIZEOF_DATA)
2057                         this_copy = HPI6205_SIZEOF_DATA;
2058
2059                 if (operation == H620_HIF_SEND_DATA)
2060                         memcpy((void *)&interface->u.b_data[0],
2061                                 &p_data[data_transferred], this_copy);
2062
2063                 interface->transfer_size_in_bytes = this_copy;
2064
2065 #ifdef HPI6205_NO_HSR_POLL
2066                 /* DSP must change this back to nOperation */
2067                 interface->dsp_ack = H620_HIF_IDLE;
2068 #endif
2069
2070                 send_dsp_command(phw, operation);
2071
2072 #ifdef HPI6205_NO_HSR_POLL
2073                 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2074                 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2075                         HPI6205_TIMEOUT - temp2, this_copy);
2076
2077                 if (!temp2) {
2078                         /* timed out */
2079                         HPI_DEBUG_LOG(ERROR,
2080                                 "timed out waiting for " "state %d got %d\n",
2081                                 operation, interface->dsp_ack);
2082
2083                         break;
2084                 }
2085 #else
2086                 /* spin waiting on the result */
2087                 time_out = HPI6205_TIMEOUT;
2088                 temp2 = 0;
2089                 while ((temp2 == 0) && time_out--) {
2090                         /* give 16k bus mastering transfer time to happen */
2091                         /*(16k / 132Mbytes/s = 122usec) */
2092                         hpios_delay_micro_seconds(20);
2093                         temp2 = ioread32(phw->prHSR);
2094                         temp2 &= C6205_HSR_INTSRC;
2095                 }
2096                 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2097                         HPI6205_TIMEOUT - time_out, this_copy);
2098                 if (temp2 == C6205_HSR_INTSRC) {
2099                         HPI_DEBUG_LOG(VERBOSE,
2100                                 "interrupt from HIF <data> OK\n");
2101                         /*
2102                            if(interface->dwDspAck != nOperation) {
2103                            HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2104                            expected %d \n",
2105                            interface->dwDspAck,nOperation);
2106                            }
2107                          */
2108                 }
2109 /* need to handle this differently... */
2110                 else {
2111                         HPI_DEBUG_LOG(ERROR,
2112                                 "interrupt from HIF <data> BAD\n");
2113                         err = HPI_ERROR_DSP_HARDWARE;
2114                 }
2115
2116                 /* reset the interrupt from the DSP */
2117                 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2118 #endif
2119                 if (operation == H620_HIF_GET_DATA)
2120                         memcpy(&p_data[data_transferred],
2121                                 (void *)&interface->u.b_data[0], this_copy);
2122
2123                 data_transferred += this_copy;
2124         }
2125         if (interface->dsp_ack != operation)
2126                 HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
2127                         interface->dsp_ack, operation);
2128         /*                      err=HPI_ERROR_DSP_HARDWARE; */
2129
2130         send_dsp_command(phw, H620_HIF_IDLE);
2131
2132         return err;
2133 }
2134
2135 /* wait for up to timeout_us microseconds for the DSP
2136    to signal state by DMA into dwDspAck
2137 */
2138 static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2139 {
2140         struct bus_master_interface *interface = phw->p_interface_buffer;
2141         int t = timeout_us / 4;
2142
2143         rmb();  /* ensure interface->dsp_ack is up to date */
2144         while ((interface->dsp_ack != state) && --t) {
2145                 hpios_delay_micro_seconds(4);
2146                 rmb();  /* DSP changes dsp_ack by DMA */
2147         }
2148
2149         /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2150         return t * 4;
2151 }
2152
2153 /* set the busmaster interface to cmd, then interrupt the DSP */
2154 static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2155 {
2156         struct bus_master_interface *interface = phw->p_interface_buffer;
2157
2158         u32 r;
2159
2160         interface->host_cmd = cmd;
2161         wmb();  /* DSP gets state by DMA, make sure it is written to memory */
2162         /* before we interrupt the DSP */
2163         r = ioread32(phw->prHDCR);
2164         r |= (u32)C6205_HDCR_DSPINT;
2165         iowrite32(r, phw->prHDCR);
2166         r &= ~(u32)C6205_HDCR_DSPINT;
2167         iowrite32(r, phw->prHDCR);
2168 }
2169
2170 static unsigned int message_count;
2171
2172 static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2173         struct hpi_message *phm, struct hpi_response *phr)
2174 {
2175 #ifndef HPI6205_NO_HSR_POLL
2176         u32 temp2;
2177 #endif
2178         u32 time_out, time_out2;
2179         struct hpi_hw_obj *phw = pao->priv;
2180         struct bus_master_interface *interface = phw->p_interface_buffer;
2181         u16 err = 0;
2182
2183         message_count++;
2184         /* Assume buffer of type struct bus_master_interface
2185            is allocated "noncacheable" */
2186
2187         if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2188                 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2189                 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2190         }
2191         interface->u.message_buffer = *phm;
2192         /* signal we want a response */
2193         send_dsp_command(phw, H620_HIF_GET_RESP);
2194
2195         time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2196
2197         if (time_out2 == 0) {
2198                 HPI_DEBUG_LOG(ERROR,
2199                         "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2200                         message_count, interface->dsp_ack);
2201         } else {
2202                 HPI_DEBUG_LOG(VERBOSE,
2203                         "(%u) transition to GET_RESP after %u\n",
2204                         message_count, HPI6205_TIMEOUT - time_out2);
2205         }
2206         /* spin waiting on HIF interrupt flag (end of msg process) */
2207         time_out = HPI6205_TIMEOUT;
2208
2209 #ifndef HPI6205_NO_HSR_POLL
2210         temp2 = 0;
2211         while ((temp2 == 0) && --time_out) {
2212                 temp2 = ioread32(phw->prHSR);
2213                 temp2 &= C6205_HSR_INTSRC;
2214                 hpios_delay_micro_seconds(1);
2215         }
2216         if (temp2 == C6205_HSR_INTSRC) {
2217                 rmb();  /* ensure we see latest value for dsp_ack */
2218                 if ((interface->dsp_ack != H620_HIF_GET_RESP)) {
2219                         HPI_DEBUG_LOG(DEBUG,
2220                                 "(%u)interface->dsp_ack(0x%x) != "
2221                                 "H620_HIF_GET_RESP, t=%u\n", message_count,
2222                                 interface->dsp_ack,
2223                                 HPI6205_TIMEOUT - time_out);
2224                 } else {
2225                         HPI_DEBUG_LOG(VERBOSE,
2226                                 "(%u)int with GET_RESP after %u\n",
2227                                 message_count, HPI6205_TIMEOUT - time_out);
2228                 }
2229
2230         } else {
2231                 /* can we do anything else in response to the error ? */
2232                 HPI_DEBUG_LOG(ERROR,
2233                         "interrupt from HIF module BAD (function %x)\n",
2234                         phm->function);
2235         }
2236
2237         /* reset the interrupt from the DSP */
2238         iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2239 #endif
2240
2241         /* read the result */
2242         if (time_out != 0)
2243                 *phr = interface->u.response_buffer;
2244
2245         /* set interface back to idle */
2246         send_dsp_command(phw, H620_HIF_IDLE);
2247
2248         if ((time_out == 0) || (time_out2 == 0)) {
2249                 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2250                 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
2251         }
2252         /* special case for adapter close - */
2253         /* wait for the DSP to indicate it is idle */
2254         if (phm->function == HPI_ADAPTER_CLOSE) {
2255                 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2256                         HPI_DEBUG_LOG(DEBUG,
2257                                 "timeout waiting for idle "
2258                                 "(on adapter_close)\n");
2259                         return hpi6205_error(0,
2260                                 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2261                 }
2262         }
2263         err = hpi_validate_response(phm, phr);
2264         return err;
2265 }
2266
2267 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2268         struct hpi_response *phr)
2269 {
2270
2271         u16 err = 0;
2272
2273         hpios_dsplock_lock(pao);
2274
2275         err = message_response_sequence(pao, phm, phr);
2276
2277         /* maybe an error response */
2278         if (err) {
2279                 /* something failed in the HPI/DSP interface */
2280                 phr->error = err;
2281                 pao->dsp_crashed++;
2282
2283                 /* just the header of the response is valid */
2284                 phr->size = sizeof(struct hpi_response_header);
2285                 goto err;
2286         } else
2287                 pao->dsp_crashed = 0;
2288
2289         if (phr->error != 0)    /* something failed in the DSP */
2290                 goto err;
2291
2292         switch (phm->function) {
2293         case HPI_OSTREAM_WRITE:
2294         case HPI_ISTREAM_ANC_WRITE:
2295                 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2296                         phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
2297                 break;
2298
2299         case HPI_ISTREAM_READ:
2300         case HPI_OSTREAM_ANC_READ:
2301                 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2302                         phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2303                 break;
2304
2305         case HPI_CONTROL_SET_STATE:
2306                 if (phm->object == HPI_OBJ_CONTROLEX
2307                         && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2308                         err = hpi6205_transfer_data(pao,
2309                                 phm->u.cx.u.cobranet_bigdata.pb_data,
2310                                 phm->u.cx.u.cobranet_bigdata.byte_count,
2311                                 H620_HIF_SEND_DATA);
2312                 break;
2313
2314         case HPI_CONTROL_GET_STATE:
2315                 if (phm->object == HPI_OBJ_CONTROLEX
2316                         && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2317                         err = hpi6205_transfer_data(pao,
2318                                 phm->u.cx.u.cobranet_bigdata.pb_data,
2319                                 phr->u.cx.u.cobranet_data.byte_count,
2320                                 H620_HIF_GET_DATA);
2321                 break;
2322         }
2323         phr->error = err;
2324
2325 err:
2326         hpios_dsplock_unlock(pao);
2327
2328         return;
2329 }