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