Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hpi6000.c
Go to the documentation of this file.
1 /******************************************************************************
2 
3  AudioScience HPI driver
4  Copyright (C) 1997-2011 AudioScience Inc. <[email protected]>
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 ASI6200 series adapters.
20  These PCI bus adapters are based on the TI C6711 DSP.
21 
22  Exported functions:
23  void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
24 
25  #defines
26  HIDE_PCI_ASSERTS to show the PCI asserts
27  PROFILE_DSP2 get profile data from DSP2 if present (instead of DSP 1)
28 
29 (C) Copyright AudioScience Inc. 1998-2003
30 *******************************************************************************/
31 #define SOURCEFILE_NAME "hpi6000.c"
32 
33 #include "hpi_internal.h"
34 #include "hpimsginit.h"
35 #include "hpidebug.h"
36 #include "hpi6000.h"
37 #include "hpidspcd.h"
38 #include "hpicmn.h"
39 
40 #define HPI_HIF_BASE (0x00000200) /* start of C67xx internal RAM */
41 #define HPI_HIF_ADDR(member) \
42  (HPI_HIF_BASE + offsetof(struct hpi_hif_6000, member))
43 #define HPI_HIF_ERROR_MASK 0x4000
44 
45 /* HPI6000 specific error codes */
46 #define HPI6000_ERROR_BASE 900 /* not actually used anywhere */
47 
48 /* operational/messaging errors */
49 #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
50 
51 #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
52 #define HPI6000_ERROR_MSG_GET_ADR 904
53 #define HPI6000_ERROR_RESP_GET_ADR 905
54 #define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
55 #define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
56 
57 #define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
58 
59 #define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
60 #define HPI6000_ERROR_SEND_DATA_ACK 912
61 #define HPI6000_ERROR_SEND_DATA_ADR 913
62 #define HPI6000_ERROR_SEND_DATA_TIMEOUT 914
63 #define HPI6000_ERROR_SEND_DATA_CMD 915
64 #define HPI6000_ERROR_SEND_DATA_WRITE 916
65 #define HPI6000_ERROR_SEND_DATA_IDLECMD 917
66 
67 #define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
68 #define HPI6000_ERROR_GET_DATA_ACK 922
69 #define HPI6000_ERROR_GET_DATA_CMD 923
70 #define HPI6000_ERROR_GET_DATA_READ 924
71 #define HPI6000_ERROR_GET_DATA_IDLECMD 925
72 
73 #define HPI6000_ERROR_CONTROL_CACHE_ADDRLEN 951
74 #define HPI6000_ERROR_CONTROL_CACHE_READ 952
75 #define HPI6000_ERROR_CONTROL_CACHE_FLUSH 953
76 
77 #define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
78 #define HPI6000_ERROR_MSG_RESP_IDLECMD 962
79 
80 /* Initialisation/bootload errors */
81 #define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
82 
83 /* can't access PCI2040 */
84 #define HPI6000_ERROR_INIT_PCI2040 931
85 /* can't access DSP HPI i/f */
86 #define HPI6000_ERROR_INIT_DSPHPI 932
87 /* can't access internal DSP memory */
88 #define HPI6000_ERROR_INIT_DSPINTMEM 933
89 /* can't access SDRAM - test#1 */
90 #define HPI6000_ERROR_INIT_SDRAM1 934
91 /* can't access SDRAM - test#2 */
92 #define HPI6000_ERROR_INIT_SDRAM2 935
93 
94 #define HPI6000_ERROR_INIT_VERIFY 938
95 
96 #define HPI6000_ERROR_INIT_NOACK 939
97 
98 #define HPI6000_ERROR_INIT_PLDTEST1 941
99 #define HPI6000_ERROR_INIT_PLDTEST2 942
100 
101 /* local defines */
102 
103 #define HIDE_PCI_ASSERTS
104 #define PROFILE_DSP2
105 
106 /* for PCI2040 i/f chip */
107 /* HPI CSR registers */
108 /* word offsets from CSR base */
109 /* use when io addresses defined as u32 * */
110 
111 #define INTERRUPT_EVENT_SET 0
112 #define INTERRUPT_EVENT_CLEAR 1
113 #define INTERRUPT_MASK_SET 2
114 #define INTERRUPT_MASK_CLEAR 3
115 #define HPI_ERROR_REPORT 4
116 #define HPI_RESET 5
117 #define HPI_DATA_WIDTH 6
118 
119 #define MAX_DSPS 2
120 /* HPI registers, spaced 8K bytes = 2K words apart */
121 #define DSP_SPACING 0x800
122 
123 #define CONTROL 0x0000
124 #define ADDRESS 0x0200
125 #define DATA_AUTOINC 0x0400
126 #define DATA 0x0600
127 
128 #define TIMEOUT 500000
129 
130 struct dsp_obj {
135  char c_dsp_rev; /*A, B */
139 };
140 
141 struct hpi_hw_obj {
144 
147 
151 
154 };
155 
156 static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
157  u16 dsp_index, u32 hpi_address, u32 *source, u32 count);
158 static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
159  u16 dsp_index, u32 hpi_address, u32 *dest, u32 count);
160 
161 static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
162  u32 *pos_error_code);
163 static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
164  u16 read_or_write);
165 #define H6READ 1
166 #define H6WRITE 0
167 
168 static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
169  struct hpi_message *phm);
170 static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
171  u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr);
172 
173 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
174  struct hpi_response *phr);
175 
176 static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
177  u32 ack_value);
178 
179 static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
180  u16 dsp_index, u32 host_cmd);
181 
182 static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo);
183 
184 static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
185  struct hpi_message *phm, struct hpi_response *phr);
186 
187 static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
188  struct hpi_message *phm, struct hpi_response *phr);
189 
190 static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data);
191 
192 static u32 hpi_read_word(struct dsp_obj *pdo, u32 address);
193 
194 static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
195  u32 length);
196 
197 static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
198  u32 length);
199 
200 static void subsys_create_adapter(struct hpi_message *phm,
201  struct hpi_response *phr);
202 
203 static void adapter_delete(struct hpi_adapter_obj *pao,
204  struct hpi_message *phm, struct hpi_response *phr);
205 
206 static void adapter_get_asserts(struct hpi_adapter_obj *pao,
207  struct hpi_message *phm, struct hpi_response *phr);
208 
209 static short create_adapter_obj(struct hpi_adapter_obj *pao,
210  u32 *pos_error_code);
211 
212 static void delete_adapter_obj(struct hpi_adapter_obj *pao);
213 
214 /* local globals */
215 
216 static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
217 static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
218 
219 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
220 {
221  switch (phm->function) {
223  subsys_create_adapter(phm, phr);
224  break;
225  default:
227  break;
228  }
229 }
230 
231 static void control_message(struct hpi_adapter_obj *pao,
232  struct hpi_message *phm, struct hpi_response *phr)
233 {
234  struct hpi_hw_obj *phw = pao->priv;
235 
236  switch (phm->function) {
238  if (pao->has_control_cache) {
239  u16 err;
240  err = hpi6000_update_control_cache(pao, phm);
241 
242  if (err) {
243  if (err >= HPI_ERROR_BACKEND_BASE) {
244  phr->error =
246  phr->specific_error = err;
247  } else {
248  phr->error = err;
249  }
250  break;
251  }
252 
253  if (hpi_check_control_cache(phw->p_cache, phm, phr))
254  break;
255  }
256  hw_message(pao, phm, phr);
257  break;
259  hw_message(pao, phm, phr);
261  break;
262 
264  default:
265  hw_message(pao, phm, phr);
266  break;
267  }
268 }
269 
270 static void adapter_message(struct hpi_adapter_obj *pao,
271  struct hpi_message *phm, struct hpi_response *phr)
272 {
273  switch (phm->function) {
275  adapter_get_asserts(pao, phm, phr);
276  break;
277 
278  case HPI_ADAPTER_DELETE:
279  adapter_delete(pao, phm, phr);
280  break;
281 
282  default:
283  hw_message(pao, phm, phr);
284  break;
285  }
286 }
287 
288 static void outstream_message(struct hpi_adapter_obj *pao,
289  struct hpi_message *phm, struct hpi_response *phr)
290 {
291  switch (phm->function) {
294  /* Don't let these messages go to the HW function because
295  * they're called without locking the spinlock.
296  * For the HPI6000 adapters the HW would return
297  * HPI_ERROR_INVALID_FUNC anyway.
298  */
300  break;
301  default:
302  hw_message(pao, phm, phr);
303  return;
304  }
305 }
306 
307 static void instream_message(struct hpi_adapter_obj *pao,
308  struct hpi_message *phm, struct hpi_response *phr)
309 {
310 
311  switch (phm->function) {
314  /* Don't let these messages go to the HW function because
315  * they're called without locking the spinlock.
316  * For the HPI6000 adapters the HW would return
317  * HPI_ERROR_INVALID_FUNC anyway.
318  */
320  break;
321  default:
322  hw_message(pao, phm, phr);
323  return;
324  }
325 }
326 
327 /************************************************************************/
332 void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
333 {
334  struct hpi_adapter_obj *pao = NULL;
335 
336  if (phm->object != HPI_OBJ_SUBSYSTEM) {
337  pao = hpi_find_adapter(phm->adapter_index);
338  if (!pao) {
339  hpi_init_response(phr, phm->object, phm->function,
341  HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
342  phm->adapter_index);
343  return;
344  }
345 
346  /* Don't even try to communicate with crashed DSP */
347  if (pao->dsp_crashed >= 10) {
348  hpi_init_response(phr, phm->object, phm->function,
350  HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
351  phm->adapter_index);
352  return;
353  }
354  }
355  /* Init default response including the size field */
357  hpi_init_response(phr, phm->object, phm->function,
359 
360  switch (phm->type) {
361  case HPI_TYPE_REQUEST:
362  switch (phm->object) {
363  case HPI_OBJ_SUBSYSTEM:
364  subsys_message(phm, phr);
365  break;
366 
367  case HPI_OBJ_ADAPTER:
368  phr->size =
369  sizeof(struct hpi_response_header) +
370  sizeof(struct hpi_adapter_res);
371  adapter_message(pao, phm, phr);
372  break;
373 
374  case HPI_OBJ_CONTROL:
375  control_message(pao, phm, phr);
376  break;
377 
378  case HPI_OBJ_OSTREAM:
379  outstream_message(pao, phm, phr);
380  break;
381 
382  case HPI_OBJ_ISTREAM:
383  instream_message(pao, phm, phr);
384  break;
385 
386  default:
387  hw_message(pao, phm, phr);
388  break;
389  }
390  break;
391 
392  default:
394  break;
395  }
396 }
397 
398 /************************************************************************/
399 /* SUBSYSTEM */
400 
401 /* create an adapter object and initialise it based on resource information
402  * passed in in the message
403  * NOTE - you cannot use this function AND the FindAdapters function at the
404  * same time, the application must use only one of them to get the adapters
405  */
406 static void subsys_create_adapter(struct hpi_message *phm,
407  struct hpi_response *phr)
408 {
409  /* create temp adapter obj, because we don't know what index yet */
410  struct hpi_adapter_obj ao;
411  struct hpi_adapter_obj *pao;
412  u32 os_error_code;
413  u16 err = 0;
414  u32 dsp_index = 0;
415 
416  HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n");
417 
418  memset(&ao, 0, sizeof(ao));
419 
420  ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
421  if (!ao.priv) {
422  HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n");
424  return;
425  }
426 
427  /* create the adapter object based on the resource information */
428  ao.pci = *phm->u.s.resource.r.pci;
429 
430  err = create_adapter_obj(&ao, &os_error_code);
431  if (err) {
432  delete_adapter_obj(&ao);
433  if (err >= HPI_ERROR_BACKEND_BASE) {
435  phr->specific_error = err;
436  } else {
437  phr->error = err;
438  }
439 
440  phr->u.s.data = os_error_code;
441  return;
442  }
443  /* need to update paParentAdapter */
444  pao = hpi_find_adapter(ao.index);
445  if (!pao) {
446  /* We just added this adapter, why can't we find it!? */
447  HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n");
449  return;
450  }
451 
452  for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
453  struct hpi_hw_obj *phw = pao->priv;
454  phw->ado[dsp_index].pa_parent_adapter = pao;
455  }
456 
457  phr->u.s.adapter_type = ao.type;
458  phr->u.s.adapter_index = ao.index;
459  phr->error = 0;
460 }
461 
462 static void adapter_delete(struct hpi_adapter_obj *pao,
463  struct hpi_message *phm, struct hpi_response *phr)
464 {
465  delete_adapter_obj(pao);
466  hpi_delete_adapter(pao);
467  phr->error = 0;
468 }
469 
470 /* this routine is called from SubSysFindAdapter and SubSysCreateAdapter */
471 static short create_adapter_obj(struct hpi_adapter_obj *pao,
472  u32 *pos_error_code)
473 {
474  short boot_error = 0;
475  u32 dsp_index = 0;
476  u32 control_cache_size = 0;
477  u32 control_cache_count = 0;
478  struct hpi_hw_obj *phw = pao->priv;
479 
480  /* The PCI2040 has the following address map */
481  /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
482  /* BAR1 - 32K = HPI registers on DSP */
483  phw->dw2040_HPICSR = pao->pci.ap_mem_base[0];
484  phw->dw2040_HPIDSP = pao->pci.ap_mem_base[1];
485  HPI_DEBUG_LOG(VERBOSE, "csr %p, dsp %p\n", phw->dw2040_HPICSR,
486  phw->dw2040_HPIDSP);
487 
488  /* set addresses for the possible DSP HPI interfaces */
489  for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
490  phw->ado[dsp_index].prHPI_control =
491  phw->dw2040_HPIDSP + (CONTROL +
492  DSP_SPACING * dsp_index);
493 
494  phw->ado[dsp_index].prHPI_address =
495  phw->dw2040_HPIDSP + (ADDRESS +
496  DSP_SPACING * dsp_index);
497  phw->ado[dsp_index].prHPI_data =
498  phw->dw2040_HPIDSP + (DATA + DSP_SPACING * dsp_index);
499 
500  phw->ado[dsp_index].prHPI_data_auto_inc =
501  phw->dw2040_HPIDSP + (DATA_AUTOINC +
502  DSP_SPACING * dsp_index);
503 
504  HPI_DEBUG_LOG(VERBOSE, "ctl %p, adr %p, dat %p, dat++ %p\n",
505  phw->ado[dsp_index].prHPI_control,
506  phw->ado[dsp_index].prHPI_address,
507  phw->ado[dsp_index].prHPI_data,
508  phw->ado[dsp_index].prHPI_data_auto_inc);
509 
510  phw->ado[dsp_index].pa_parent_adapter = pao;
511  }
512 
513  phw->pCI2040HPI_error_count = 0;
514  pao->has_control_cache = 0;
515 
516  /* Set the default number of DSPs on this card */
517  /* This is (conditionally) adjusted after bootloading */
518  /* of the first DSP in the bootload section. */
519  phw->num_dsp = 1;
520 
521  boot_error = hpi6000_adapter_boot_load_dsp(pao, pos_error_code);
522  if (boot_error)
523  return boot_error;
524 
525  HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
526 
529 
530  /* get info about the adapter by asking the adapter */
531  /* send a HPI_ADAPTER_GET_INFO message */
532  {
533  struct hpi_message hm;
534  struct hpi_response hr0; /* response from DSP 0 */
535  struct hpi_response hr1; /* response from DSP 1 */
536  u16 error = 0;
537 
538  HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
539  memset(&hm, 0, sizeof(hm));
540  hm.type = HPI_TYPE_REQUEST;
541  hm.size = sizeof(struct hpi_message);
542  hm.object = HPI_OBJ_ADAPTER;
543  hm.function = HPI_ADAPTER_GET_INFO;
544  hm.adapter_index = 0;
545  memset(&hr0, 0, sizeof(hr0));
546  memset(&hr1, 0, sizeof(hr1));
547  hr0.size = sizeof(hr0);
548  hr1.size = sizeof(hr1);
549 
550  error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0);
551  if (hr0.error) {
552  HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error);
553  return hr0.error;
554  }
555  if (phw->num_dsp == 2) {
556  error = hpi6000_message_response_sequence(pao, 1, &hm,
557  &hr1);
558  if (error)
559  return error;
560  }
561  pao->type = hr0.u.ax.info.adapter_type;
562  pao->index = hr0.u.ax.info.adapter_index;
563  }
564 
565  memset(&phw->control_cache[0], 0,
566  sizeof(struct hpi_control_cache_single) *
568  /* Read the control cache length to figure out if it is turned on */
569  control_cache_size =
570  hpi_read_word(&phw->ado[0],
571  HPI_HIF_ADDR(control_cache_size_in_bytes));
572  if (control_cache_size) {
573  control_cache_count =
574  hpi_read_word(&phw->ado[0],
575  HPI_HIF_ADDR(control_cache_count));
576 
577  phw->p_cache =
578  hpi_alloc_control_cache(control_cache_count,
579  control_cache_size, (unsigned char *)
580  &phw->control_cache[0]
581  );
582  if (phw->p_cache)
583  pao->has_control_cache = 1;
584  }
585 
586  HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", pao->type,
587  pao->index);
588 
589  if (phw->p_cache)
590  phw->p_cache->adap_idx = pao->index;
591 
592  return hpi_add_adapter(pao);
593 }
594 
595 static void delete_adapter_obj(struct hpi_adapter_obj *pao)
596 {
597  struct hpi_hw_obj *phw = pao->priv;
598 
599  if (pao->has_control_cache)
601 
602  /* reset DSPs on adapter */
603  iowrite32(0x0003000F, phw->dw2040_HPICSR + HPI_RESET);
604 
605  kfree(phw);
606 }
607 
608 /************************************************************************/
609 /* ADAPTER */
610 
611 static void adapter_get_asserts(struct hpi_adapter_obj *pao,
612  struct hpi_message *phm, struct hpi_response *phr)
613 {
614 #ifndef HIDE_PCI_ASSERTS
615  /* if we have PCI2040 asserts then collect them */
616  if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
617  phr->u.ax.assert.p1 =
618  gw_pci_read_asserts * 100 + gw_pci_write_asserts;
619  phr->u.ax.assert.p2 = 0;
620  phr->u.ax.assert.count = 1; /* assert count */
621  phr->u.ax.assert.dsp_index = -1; /* "dsp index" */
622  strcpy(phr->u.ax.assert.sz_message, "PCI2040 error");
623  phr->u.ax.assert.dsp_msg_addr = 0;
624  gw_pci_read_asserts = 0;
625  gw_pci_write_asserts = 0;
626  phr->error = 0;
627  } else
628 #endif
629  hw_message(pao, phm, phr); /*get DSP asserts */
630 
631  return;
632 }
633 
634 /************************************************************************/
635 /* LOW-LEVEL */
636 
637 static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
638  u32 *pos_error_code)
639 {
640  struct hpi_hw_obj *phw = pao->priv;
641  short error;
642  u32 timeout;
643  u32 read = 0;
644  u32 i = 0;
645  u32 data = 0;
646  u32 j = 0;
647  u32 test_addr = 0x80000000;
648  u32 test_data = 0x00000001;
649  u32 dw2040_reset = 0;
650  u32 dsp_index = 0;
651  u32 endian = 0;
652  u32 adapter_info = 0;
653  u32 delay = 0;
654 
655  struct dsp_code dsp_code;
656  u16 boot_load_family = 0;
657 
658  /* NOTE don't use wAdapterType in this routine. It is not setup yet */
659 
660  switch (pao->pci.pci_dev->subsystem_device) {
661  case 0x5100:
662  case 0x5110: /* ASI5100 revB or higher with C6711D */
663  case 0x5200: /* ASI5200 PCIe version of ASI5100 */
664  case 0x6100:
665  case 0x6200:
666  boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
667  break;
668  default:
670  }
671 
672  /* reset all DSPs, indicate two DSPs are present
673  * set RST3-=1 to disconnect HAD8 to set DSP in little endian mode
674  */
675  endian = 0;
676  dw2040_reset = 0x0003000F;
677  iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
678 
679  /* read back register to make sure PCI2040 chip is functioning
680  * note that bits 4..15 are read-only and so should always return zero,
681  * even though we wrote 1 to them
682  */
684  delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
685 
686  if (delay != dw2040_reset) {
687  HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
688  delay);
690  }
691 
692  /* Indicate that DSP#0,1 is a C6X */
693  iowrite32(0x00000003, phw->dw2040_HPICSR + HPI_DATA_WIDTH);
694  /* set Bit30 and 29 - which will prevent Target aborts from being
695  * issued upon HPI or GP error
696  */
697  iowrite32(0x60000000, phw->dw2040_HPICSR + INTERRUPT_MASK_SET);
698 
699  /* isolate DSP HAD8 line from PCI2040 so that
700  * Little endian can be set by pullup
701  */
702  dw2040_reset = dw2040_reset & (~(endian << 3));
703  iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
704 
705  phw->ado[0].c_dsp_rev = 'B'; /* revB */
706  phw->ado[1].c_dsp_rev = 'B'; /* revB */
707 
708  /*Take both DSPs out of reset, setting HAD8 to the correct Endian */
709  dw2040_reset = dw2040_reset & (~0x00000001); /* start DSP 0 */
710  iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
711  dw2040_reset = dw2040_reset & (~0x00000002); /* start DSP 1 */
712  iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
713 
714  /* set HAD8 back to PCI2040, now that DSP set to little endian mode */
715  dw2040_reset = dw2040_reset & (~0x00000008);
716  iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
717  /*delay to allow DSP to get going */
719 
720  /* loop through all DSPs, downloading DSP code */
721  for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
722  struct dsp_obj *pdo = &phw->ado[dsp_index];
723 
724  /* configure DSP so that we download code into the SRAM */
725  /* set control reg for little endian, HWOB=1 */
726  iowrite32(0x00010001, pdo->prHPI_control);
727 
728  /* test access to the HPI address register (HPIA) */
729  test_data = 0x00000001;
730  for (j = 0; j < 32; j++) {
731  iowrite32(test_data, pdo->prHPI_address);
732  data = ioread32(pdo->prHPI_address);
733  if (data != test_data) {
734  HPI_DEBUG_LOG(ERROR, "INIT_DSPHPI %x %x %x\n",
735  test_data, data, dsp_index);
737  }
738  test_data = test_data << 1;
739  }
740 
741 /* if C6713 the setup PLL to generate 225MHz from 25MHz.
742 * Since the PLLDIV1 read is sometimes wrong, even on a C6713,
743 * we're going to do this unconditionally
744 */
745 /* PLLDIV1 should have a value of 8000 after reset */
746 /*
747  if (HpiReadWord(pdo,0x01B7C118) == 0x8000)
748 */
749  {
750  /* C6713 datasheet says we cannot program PLL from HPI,
751  * and indeed if we try to set the PLL multiply from the
752  * HPI, the PLL does not seem to lock,
753  * so we enable the PLL and use the default of x 7
754  */
755  /* bypass PLL */
756  hpi_write_word(pdo, 0x01B7C100, 0x0000);
758 
759  /* ** use default of PLL x7 ** */
760  /* EMIF = 225/3=75MHz */
761  hpi_write_word(pdo, 0x01B7C120, 0x8002);
763 
764  /* peri = 225/2 */
765  hpi_write_word(pdo, 0x01B7C11C, 0x8001);
767 
768  /* cpu = 225/1 */
769  hpi_write_word(pdo, 0x01B7C118, 0x8000);
770 
771  /* ~2ms delay */
773 
774  /* PLL not bypassed */
775  hpi_write_word(pdo, 0x01B7C100, 0x0001);
776  /* ~2ms delay */
778  }
779 
780  /* test r/w to internal DSP memory
781  * C6711 has L2 cache mapped to 0x0 when reset
782  *
783  * revB - because of bug 3.0.1 last HPI read
784  * (before HPI address issued) must be non-autoinc
785  */
786  /* test each bit in the 32bit word */
787  for (i = 0; i < 100; i++) {
788  test_addr = 0x00000000;
789  test_data = 0x00000001;
790  for (j = 0; j < 32; j++) {
791  hpi_write_word(pdo, test_addr + i, test_data);
792  data = hpi_read_word(pdo, test_addr + i);
793  if (data != test_data) {
795  "DSP mem %x %x %x %x\n",
796  test_addr + i, test_data,
797  data, dsp_index);
798 
800  }
801  test_data = test_data << 1;
802  }
803  }
804 
805  /* memory map of ASI6200
806  00000000-0000FFFF 16Kx32 internal program
807  01800000-019FFFFF Internal peripheral
808  80000000-807FFFFF CE0 2Mx32 SDRAM running @ 100MHz
809  90000000-9000FFFF CE1 Async peripherals:
810 
811  EMIF config
812  ------------
813  Global EMIF control
814  0 -
815  1 -
816  2 -
817  3 CLK2EN = 1 CLKOUT2 enabled
818  4 CLK1EN = 0 CLKOUT1 disabled
819  5 EKEN = 1 <--!! C6713 specific, enables ECLKOUT
820  6 -
821  7 NOHOLD = 1 external HOLD disabled
822  8 HOLDA = 0 HOLDA output is low
823  9 HOLD = 0 HOLD input is low
824  10 ARDY = 1 ARDY input is high
825  11 BUSREQ = 0 BUSREQ output is low
826  12,13 Reserved = 1
827  */
828  hpi_write_word(pdo, 0x01800000, 0x34A8);
829 
830  /* EMIF CE0 setup - 2Mx32 Sync DRAM
831  31..28 Wr setup
832  27..22 Wr strobe
833  21..20 Wr hold
834  19..16 Rd setup
835  15..14 -
836  13..8 Rd strobe
837  7..4 MTYPE 0011 Sync DRAM 32bits
838  3 Wr hold MSB
839  2..0 Rd hold
840  */
841  hpi_write_word(pdo, 0x01800008, 0x00000030);
842 
843  /* EMIF SDRAM Extension
844  31-21 0
845  20 WR2RD = 0
846  19-18 WR2DEAC = 1
847  17 WR2WR = 0
848  16-15 R2WDQM = 2
849  14-12 RD2WR = 4
850  11-10 RD2DEAC = 1
851  9 RD2RD = 1
852  8-7 THZP = 10b
853  6-5 TWR = 2-1 = 01b (tWR = 10ns)
854  4 TRRD = 0b = 2 ECLK (tRRD = 14ns)
855  3-1 TRAS = 5-1 = 100b (Tras=42ns = 5 ECLK)
856  1 CAS latency = 3 ECLK
857  (for Micron 2M32-7 operating at 100Mhz)
858  */
859 
860  /* need to use this else DSP code crashes */
861  hpi_write_word(pdo, 0x01800020, 0x001BDF29);
862 
863  /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
864  31 - -
865  30 SDBSZ 1 4 bank
866  29..28 SDRSZ 00 11 row address pins
867  27..26 SDCSZ 01 8 column address pins
868  25 RFEN 1 refersh enabled
869  24 INIT 1 init SDRAM
870  23..20 TRCD 0001
871  19..16 TRP 0001
872  15..12 TRC 0110
873  11..0 - -
874  */
875  /* need to use this else DSP code crashes */
876  hpi_write_word(pdo, 0x01800018, 0x47117000);
877 
878  /* EMIF SDRAM Refresh Timing */
879  hpi_write_word(pdo, 0x0180001C, 0x00000410);
880 
881  /*MIF CE1 setup - Async peripherals
882  @100MHz bus speed, each cycle is 10ns,
883  31..28 Wr setup = 1
884  27..22 Wr strobe = 3 30ns
885  21..20 Wr hold = 1
886  19..16 Rd setup =1
887  15..14 Ta = 2
888  13..8 Rd strobe = 3 30ns
889  7..4 MTYPE 0010 Async 32bits
890  3 Wr hold MSB =0
891  2..0 Rd hold = 1
892  */
893  {
894  u32 cE1 =
895  (1L << 28) | (3L << 22) | (1L << 20) | (1L <<
896  16) | (2L << 14) | (3L << 8) | (2L << 4) | 1L;
897  hpi_write_word(pdo, 0x01800004, cE1);
898  }
899 
900  /* delay a little to allow SDRAM and DSP to "get going" */
902 
903  /* test access to SDRAM */
904  {
905  test_addr = 0x80000000;
906  test_data = 0x00000001;
907  /* test each bit in the 32bit word */
908  for (j = 0; j < 32; j++) {
909  hpi_write_word(pdo, test_addr, test_data);
910  data = hpi_read_word(pdo, test_addr);
911  if (data != test_data) {
913  "DSP dram %x %x %x %x\n",
914  test_addr, test_data, data,
915  dsp_index);
916 
918  }
919  test_data = test_data << 1;
920  }
921  /* test every Nth address in the DRAM */
922 #define DRAM_SIZE_WORDS 0x200000 /*2_mx32 */
923 #define DRAM_INC 1024
924  test_addr = 0x80000000;
925  test_data = 0x0;
926  for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
927  hpi_write_word(pdo, test_addr + i, test_data);
928  test_data++;
929  }
930  test_addr = 0x80000000;
931  test_data = 0x0;
932  for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
933  data = hpi_read_word(pdo, test_addr + i);
934  if (data != test_data) {
936  "DSP dram %x %x %x %x\n",
937  test_addr + i, test_data,
938  data, dsp_index);
940  }
941  test_data++;
942  }
943 
944  }
945 
946  /* write the DSP code down into the DSPs memory */
947  error = hpi_dsp_code_open(boot_load_family, pao->pci.pci_dev,
948  &dsp_code, pos_error_code);
949 
950  if (error)
951  return error;
952 
953  while (1) {
954  u32 length;
955  u32 address;
956  u32 type;
957  u32 *pcode;
958 
959  error = hpi_dsp_code_read_word(&dsp_code, &length);
960  if (error)
961  break;
962  if (length == 0xFFFFFFFF)
963  break; /* end of code */
964 
965  error = hpi_dsp_code_read_word(&dsp_code, &address);
966  if (error)
967  break;
968  error = hpi_dsp_code_read_word(&dsp_code, &type);
969  if (error)
970  break;
971  error = hpi_dsp_code_read_block(length, &dsp_code,
972  &pcode);
973  if (error)
974  break;
975  error = hpi6000_dsp_block_write32(pao, (u16)dsp_index,
976  address, pcode, length);
977  if (error)
978  break;
979  }
980 
981  if (error) {
983  return error;
984  }
985  /* verify that code was written correctly */
986  /* this time through, assume no errors in DSP code file/array */
988  while (1) {
989  u32 length;
990  u32 address;
991  u32 type;
992  u32 *pcode;
993 
994  hpi_dsp_code_read_word(&dsp_code, &length);
995  if (length == 0xFFFFFFFF)
996  break; /* end of code */
997 
998  hpi_dsp_code_read_word(&dsp_code, &address);
1000  hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1001 
1002  for (i = 0; i < length; i++) {
1003  data = hpi_read_word(pdo, address);
1004  if (data != *pcode) {
1005  error = HPI6000_ERROR_INIT_VERIFY;
1007  "DSP verify %x %x %x %x\n",
1008  address, *pcode, data,
1009  dsp_index);
1010  break;
1011  }
1012  pcode++;
1013  address += 4;
1014  }
1015  if (error)
1016  break;
1017  }
1019  if (error)
1020  return error;
1021 
1022  /* zero out the hostmailbox */
1023  {
1024  u32 address = HPI_HIF_ADDR(host_cmd);
1025  for (i = 0; i < 4; i++) {
1026  hpi_write_word(pdo, address, 0);
1027  address += 4;
1028  }
1029  }
1030  /* write the DSP number into the hostmailbox */
1031  /* structure before starting the DSP */
1032  hpi_write_word(pdo, HPI_HIF_ADDR(dsp_number), dsp_index);
1033 
1034  /* write the DSP adapter Info into the */
1035  /* hostmailbox before starting the DSP */
1036  if (dsp_index > 0)
1037  hpi_write_word(pdo, HPI_HIF_ADDR(adapter_info),
1038  adapter_info);
1039 
1040  /* step 3. Start code by sending interrupt */
1041  iowrite32(0x00030003, pdo->prHPI_control);
1043 
1044  /* wait for a non-zero value in hostcmd -
1045  * indicating initialization is complete
1046  *
1047  * Init could take a while if DSP checks SDRAM memory
1048  * Was 200000. Increased to 2000000 for ASI8801 so we
1049  * don't get 938 errors.
1050  */
1051  timeout = 2000000;
1052  while (timeout) {
1053  do {
1054  read = hpi_read_word(pdo,
1056  } while (--timeout
1057  && hpi6000_check_PCI2040_error_flag(pao,
1058  H6READ));
1059 
1060  if (read)
1061  break;
1062  /* The following is a workaround for bug #94:
1063  * Bluescreen on install and subsequent boots on a
1064  * DELL PowerEdge 600SC PC with 1.8GHz P4 and
1065  * ServerWorks chipset. Without this delay the system
1066  * locks up with a bluescreen (NOT GPF or pagefault).
1067  */
1068  else
1070  }
1071  if (timeout == 0)
1072  return HPI6000_ERROR_INIT_NOACK;
1073 
1074  /* read the DSP adapter Info from the */
1075  /* hostmailbox structure after starting the DSP */
1076  if (dsp_index == 0) {
1077  /*u32 dwTestData=0; */
1078  u32 mask = 0;
1079 
1080  adapter_info =
1081  hpi_read_word(pdo,
1082  HPI_HIF_ADDR(adapter_info));
1085  (adapter_info)) ==
1086  HPI_ADAPTER_FAMILY_ASI(0x6200))
1087  /* all 6200 cards have this many DSPs */
1088  phw->num_dsp = 2;
1089 
1090  /* test that the PLD is programmed */
1091  /* and we can read/write 24bits */
1092 #define PLD_BASE_ADDRESS 0x90000000L /*for ASI6100/6200/8800 */
1093 
1094  switch (boot_load_family) {
1095  case HPI_ADAPTER_FAMILY_ASI(0x6200):
1096  /* ASI6100/6200 has 24bit path to FPGA */
1097  mask = 0xFFFFFF00L;
1098  /* ASI5100 uses AX6 code, */
1099  /* but has no PLD r/w register to test */
1100  if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
1101  subsystem_device) ==
1102  HPI_ADAPTER_FAMILY_ASI(0x5100))
1103  mask = 0x00000000L;
1104  /* ASI5200 uses AX6 code, */
1105  /* but has no PLD r/w register to test */
1106  if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
1107  subsystem_device) ==
1108  HPI_ADAPTER_FAMILY_ASI(0x5200))
1109  mask = 0x00000000L;
1110  break;
1111  case HPI_ADAPTER_FAMILY_ASI(0x8800):
1112  /* ASI8800 has 16bit path to FPGA */
1113  mask = 0xFFFF0000L;
1114  break;
1115  }
1116  test_data = 0xAAAAAA00L & mask;
1117  /* write to 24 bit Debug register (D31-D8) */
1118  hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
1119  read = hpi_read_word(pdo,
1120  PLD_BASE_ADDRESS + 4L) & mask;
1121  if (read != test_data) {
1122  HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
1123  read);
1125  }
1126  test_data = 0x55555500L & mask;
1127  hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
1128  read = hpi_read_word(pdo,
1129  PLD_BASE_ADDRESS + 4L) & mask;
1130  if (read != test_data) {
1131  HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
1132  read);
1134  }
1135  }
1136  } /* for numDSP */
1137  return 0;
1138 }
1139 
1140 #define PCI_TIMEOUT 100
1141 
1142 static int hpi_set_address(struct dsp_obj *pdo, u32 address)
1143 {
1144  u32 timeout = PCI_TIMEOUT;
1145 
1146  do {
1147  iowrite32(address, pdo->prHPI_address);
1148  } while (hpi6000_check_PCI2040_error_flag(pdo->pa_parent_adapter,
1149  H6WRITE)
1150  && --timeout);
1151 
1152  if (timeout)
1153  return 0;
1154 
1155  return 1;
1156 }
1157 
1158 /* write one word to the HPI port */
1159 static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data)
1160 {
1161  if (hpi_set_address(pdo, address))
1162  return;
1163  iowrite32(data, pdo->prHPI_data);
1164 }
1165 
1166 /* read one word from the HPI port */
1167 static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
1168 {
1169  u32 data = 0;
1170 
1171  if (hpi_set_address(pdo, address))
1172  return 0; /*? No way to return error */
1173 
1174  /* take care of errata in revB DSP (2.0.1) */
1175  data = ioread32(pdo->prHPI_data);
1176  return data;
1177 }
1178 
1179 /* write a block of 32bit words to the DSP HPI port using auto-inc mode */
1180 static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1181  u32 length)
1182 {
1183  u16 length16 = length - 1;
1184 
1185  if (length == 0)
1186  return;
1187 
1188  if (hpi_set_address(pdo, address))
1189  return;
1190 
1191  iowrite32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
1192 
1193  /* take care of errata in revB DSP (2.0.1) */
1194  /* must end with non auto-inc */
1195  iowrite32(*(pdata + length - 1), pdo->prHPI_data);
1196 }
1197 
1200 static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1201  u32 length)
1202 {
1203  u16 length16 = length - 1;
1204 
1205  if (length == 0)
1206  return;
1207 
1208  if (hpi_set_address(pdo, address))
1209  return;
1210 
1211  ioread32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
1212 
1213  /* take care of errata in revB DSP (2.0.1) */
1214  /* must end with non auto-inc */
1215  *(pdata + length - 1) = ioread32(pdo->prHPI_data);
1216 }
1217 
1218 static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
1219  u16 dsp_index, u32 hpi_address, u32 *source, u32 count)
1220 {
1221  struct hpi_hw_obj *phw = pao->priv;
1222  struct dsp_obj *pdo = &phw->ado[dsp_index];
1223  u32 time_out = PCI_TIMEOUT;
1224  int c6711_burst_size = 128;
1225  u32 local_hpi_address = hpi_address;
1226  int local_count = count;
1227  int xfer_size;
1228  u32 *pdata = source;
1229 
1230  while (local_count) {
1231  if (local_count > c6711_burst_size)
1232  xfer_size = c6711_burst_size;
1233  else
1234  xfer_size = local_count;
1235 
1236  time_out = PCI_TIMEOUT;
1237  do {
1238  hpi_write_block(pdo, local_hpi_address, pdata,
1239  xfer_size);
1240  } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1241  && --time_out);
1242 
1243  if (!time_out)
1244  break;
1245  pdata += xfer_size;
1246  local_hpi_address += sizeof(u32) * xfer_size;
1247  local_count -= xfer_size;
1248  }
1249 
1250  if (time_out)
1251  return 0;
1252  else
1253  return 1;
1254 }
1255 
1256 static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
1257  u16 dsp_index, u32 hpi_address, u32 *dest, u32 count)
1258 {
1259  struct hpi_hw_obj *phw = pao->priv;
1260  struct dsp_obj *pdo = &phw->ado[dsp_index];
1261  u32 time_out = PCI_TIMEOUT;
1262  int c6711_burst_size = 16;
1263  u32 local_hpi_address = hpi_address;
1264  int local_count = count;
1265  int xfer_size;
1266  u32 *pdata = dest;
1267  u32 loop_count = 0;
1268 
1269  while (local_count) {
1270  if (local_count > c6711_burst_size)
1271  xfer_size = c6711_burst_size;
1272  else
1273  xfer_size = local_count;
1274 
1275  time_out = PCI_TIMEOUT;
1276  do {
1277  hpi_read_block(pdo, local_hpi_address, pdata,
1278  xfer_size);
1279  } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1280  && --time_out);
1281  if (!time_out)
1282  break;
1283 
1284  pdata += xfer_size;
1285  local_hpi_address += sizeof(u32) * xfer_size;
1286  local_count -= xfer_size;
1287  loop_count++;
1288  }
1289 
1290  if (time_out)
1291  return 0;
1292  else
1293  return 1;
1294 }
1295 
1296 static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1297  u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr)
1298 {
1299  struct hpi_hw_obj *phw = pao->priv;
1300  struct dsp_obj *pdo = &phw->ado[dsp_index];
1301  u32 timeout;
1302  u16 ack;
1303  u32 address;
1304  u32 length;
1305  u32 *p_data;
1306  u16 error = 0;
1307 
1308  ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1309  if (ack & HPI_HIF_ERROR_MASK) {
1310  pao->dsp_crashed++;
1312  }
1313  pao->dsp_crashed = 0;
1314 
1315  /* get the message address and size */
1316  if (phw->message_buffer_address_on_dsp == 0) {
1317  timeout = TIMEOUT;
1318  do {
1319  address =
1320  hpi_read_word(pdo,
1321  HPI_HIF_ADDR(message_buffer_address));
1323  } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1324  && --timeout);
1325  if (!timeout)
1327  } else
1328  address = phw->message_buffer_address_on_dsp;
1329 
1330  length = phm->size;
1331 
1332  /* send the message */
1333  p_data = (u32 *)phm;
1334  if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
1335  (u16)length / 4))
1337 
1338  if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_GET_RESP))
1340  hpi6000_send_dsp_interrupt(pdo);
1341 
1342  ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_RESP);
1343  if (ack & HPI_HIF_ERROR_MASK)
1345 
1346  /* get the response address */
1347  if (phw->response_buffer_address_on_dsp == 0) {
1348  timeout = TIMEOUT;
1349  do {
1350  address =
1351  hpi_read_word(pdo,
1352  HPI_HIF_ADDR(response_buffer_address));
1353  } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1354  && --timeout);
1356 
1357  if (!timeout)
1359  } else
1360  address = phw->response_buffer_address_on_dsp;
1361 
1362  /* read the length of the response back from the DSP */
1363  timeout = TIMEOUT;
1364  do {
1365  length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1366  } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1367  if (!timeout)
1368  length = sizeof(struct hpi_response);
1369 
1370  /* get the response */
1371  p_data = (u32 *)phr;
1372  if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
1373  (u16)length / 4))
1375 
1376  /* set i/f back to idle */
1377  if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1379  hpi6000_send_dsp_interrupt(pdo);
1380 
1381  error = hpi_validate_response(phm, phr);
1382  return error;
1383 }
1384 
1385 /* have to set up the below defines to match stuff in the MAP file */
1386 
1387 #define MSG_ADDRESS (HPI_HIF_BASE+0x18)
1388 #define MSG_LENGTH 11
1389 #define RESP_ADDRESS (HPI_HIF_BASE+0x44)
1390 #define RESP_LENGTH 16
1391 #define QUEUE_START (HPI_HIF_BASE+0x88)
1392 #define QUEUE_SIZE 0x8000
1393 
1394 static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords)
1395 {
1396 /*#define CHECKING // comment this line in to enable checking */
1397 #ifdef CHECKING
1398  if (address < (u32)MSG_ADDRESS)
1399  return 0;
1400  if (address > (u32)(QUEUE_START + QUEUE_SIZE))
1401  return 0;
1402  if ((address + (length_in_dwords << 2)) >
1403  (u32)(QUEUE_START + QUEUE_SIZE))
1404  return 0;
1405 #else
1406  (void)address;
1407  (void)length_in_dwords;
1408  return 1;
1409 #endif
1410 }
1411 
1412 static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1413  struct hpi_message *phm, struct hpi_response *phr)
1414 {
1415  struct hpi_hw_obj *phw = pao->priv;
1416  struct dsp_obj *pdo = &phw->ado[dsp_index];
1417  u32 data_sent = 0;
1418  u16 ack;
1419  u32 length, address;
1420  u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1421  u16 time_out = 8;
1422 
1423  (void)phr;
1424 
1425  /* round dwDataSize down to nearest 4 bytes */
1426  while ((data_sent < (phm->u.d.u.data.data_size & ~3L))
1427  && --time_out) {
1428  ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1429  if (ack & HPI_HIF_ERROR_MASK)
1431 
1432  if (hpi6000_send_host_command(pao, dsp_index,
1435 
1436  hpi6000_send_dsp_interrupt(pdo);
1437 
1438  ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_SEND_DATA);
1439 
1440  if (ack & HPI_HIF_ERROR_MASK)
1442 
1443  do {
1444  /* get the address and size */
1445  address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1446  /* DSP returns number of DWORDS */
1447  length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1448  } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1449 
1450  if (!hpi6000_send_data_check_adr(address, length))
1452 
1453  /* send the data. break data into 512 DWORD blocks (2K bytes)
1454  * and send using block write. 2Kbytes is the max as this is the
1455  * memory window given to the HPI data register by the PCI2040
1456  */
1457 
1458  {
1459  u32 len = length;
1460  u32 blk_len = 512;
1461  while (len) {
1462  if (len < blk_len)
1463  blk_len = len;
1464  if (hpi6000_dsp_block_write32(pao, dsp_index,
1465  address, p_data, blk_len))
1467  address += blk_len * 4;
1468  p_data += blk_len;
1469  len -= blk_len;
1470  }
1471  }
1472 
1473  if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1475 
1476  hpi6000_send_dsp_interrupt(pdo);
1477 
1478  data_sent += length * 4;
1479  }
1480  if (!time_out)
1482  return 0;
1483 }
1484 
1485 static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1486  struct hpi_message *phm, struct hpi_response *phr)
1487 {
1488  struct hpi_hw_obj *phw = pao->priv;
1489  struct dsp_obj *pdo = &phw->ado[dsp_index];
1490  u32 data_got = 0;
1491  u16 ack;
1492  u32 length, address;
1493  u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1494 
1495  (void)phr; /* this parameter not used! */
1496 
1497  /* round dwDataSize down to nearest 4 bytes */
1498  while (data_got < (phm->u.d.u.data.data_size & ~3L)) {
1499  ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1500  if (ack & HPI_HIF_ERROR_MASK)
1502 
1503  if (hpi6000_send_host_command(pao, dsp_index,
1506  hpi6000_send_dsp_interrupt(pdo);
1507 
1508  ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_DATA);
1509 
1510  if (ack & HPI_HIF_ERROR_MASK)
1512 
1513  /* get the address and size */
1514  do {
1515  address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1516  length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1517  } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1518 
1519  /* read the data */
1520  {
1521  u32 len = length;
1522  u32 blk_len = 512;
1523  while (len) {
1524  if (len < blk_len)
1525  blk_len = len;
1526  if (hpi6000_dsp_block_read32(pao, dsp_index,
1527  address, p_data, blk_len))
1529  address += blk_len * 4;
1530  p_data += blk_len;
1531  len -= blk_len;
1532  }
1533  }
1534 
1535  if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1537  hpi6000_send_dsp_interrupt(pdo);
1538 
1539  data_got += length * 4;
1540  }
1541  return 0;
1542 }
1543 
1544 static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo)
1545 {
1546  iowrite32(0x00030003, pdo->prHPI_control); /* DSPINT */
1547 }
1548 
1549 static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
1550  u16 dsp_index, u32 host_cmd)
1551 {
1552  struct hpi_hw_obj *phw = pao->priv;
1553  struct dsp_obj *pdo = &phw->ado[dsp_index];
1554  u32 timeout = TIMEOUT;
1555 
1556  /* set command */
1557  do {
1558  hpi_write_word(pdo, HPI_HIF_ADDR(host_cmd), host_cmd);
1559  /* flush the FIFO */
1560  hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1561  } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) && --timeout);
1562 
1563  /* reset the interrupt bit */
1564  iowrite32(0x00040004, pdo->prHPI_control);
1565 
1566  if (timeout)
1567  return 0;
1568  else
1569  return 1;
1570 }
1571 
1572 /* if the PCI2040 has recorded an HPI timeout, reset the error and return 1 */
1573 static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
1574  u16 read_or_write)
1575 {
1576  u32 hPI_error;
1577 
1578  struct hpi_hw_obj *phw = pao->priv;
1579 
1580  /* read the error bits from the PCI2040 */
1581  hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1582  if (hPI_error) {
1583  /* reset the error flag */
1585  phw->pCI2040HPI_error_count++;
1586  if (read_or_write == 1)
1587  gw_pci_read_asserts++; /************* inc global */
1588  else
1589  gw_pci_write_asserts++;
1590  return 1;
1591  } else
1592  return 0;
1593 }
1594 
1595 static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
1596  u32 ack_value)
1597 {
1598  struct hpi_hw_obj *phw = pao->priv;
1599  struct dsp_obj *pdo = &phw->ado[dsp_index];
1600  u32 ack = 0L;
1601  u32 timeout;
1602  u32 hPIC = 0L;
1603 
1604  /* wait for host interrupt to signal ack is ready */
1605  timeout = TIMEOUT;
1606  while (--timeout) {
1607  hPIC = ioread32(pdo->prHPI_control);
1608  if (hPIC & 0x04) /* 0x04 = HINT from DSP */
1609  break;
1610  }
1611  if (timeout == 0)
1612  return HPI_HIF_ERROR_MASK;
1613 
1614  /* wait for dwAckValue */
1615  timeout = TIMEOUT;
1616  while (--timeout) {
1617  /* read the ack mailbox */
1618  ack = hpi_read_word(pdo, HPI_HIF_ADDR(dsp_ack));
1619  if (ack == ack_value)
1620  break;
1621  if ((ack & HPI_HIF_ERROR_MASK)
1622  && !hpi6000_check_PCI2040_error_flag(pao, H6READ))
1623  break;
1624  /*for (i=0;i<1000;i++) */
1625  /* dwPause=i+1; */
1626  }
1627  if (ack & HPI_HIF_ERROR_MASK)
1628  /* indicates bad read from DSP -
1629  typically 0xffffff is read for some reason */
1630  ack = HPI_HIF_ERROR_MASK;
1631 
1632  if (timeout == 0)
1633  ack = HPI_HIF_ERROR_MASK;
1634  return (short)ack;
1635 }
1636 
1637 static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
1638  struct hpi_message *phm)
1639 {
1640  const u16 dsp_index = 0;
1641  struct hpi_hw_obj *phw = pao->priv;
1642  struct dsp_obj *pdo = &phw->ado[dsp_index];
1643  u32 timeout;
1644  u32 cache_dirty_flag;
1645  u16 err;
1646 
1647  hpios_dsplock_lock(pao);
1648 
1649  timeout = TIMEOUT;
1650  do {
1651  cache_dirty_flag =
1652  hpi_read_word((struct dsp_obj *)pdo,
1653  HPI_HIF_ADDR(control_cache_is_dirty));
1654  } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1655  if (!timeout) {
1657  goto unlock;
1658  }
1659 
1660  if (cache_dirty_flag) {
1661  /* read the cached controls */
1662  u32 address;
1663  u32 length;
1664 
1665  timeout = TIMEOUT;
1666  if (pdo->control_cache_address_on_dsp == 0) {
1667  do {
1668  address =
1669  hpi_read_word((struct dsp_obj *)pdo,
1670  HPI_HIF_ADDR(control_cache_address));
1671 
1672  length = hpi_read_word((struct dsp_obj *)pdo,
1673  HPI_HIF_ADDR
1674  (control_cache_size_in_bytes));
1675  } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1676  && --timeout);
1677  if (!timeout) {
1679  goto unlock;
1680  }
1683  } else {
1684  address = pdo->control_cache_address_on_dsp;
1685  length = pdo->control_cache_length_on_dsp;
1686  }
1687 
1688  if (hpi6000_dsp_block_read32(pao, dsp_index, address,
1689  (u32 *)&phw->control_cache[0],
1690  length / sizeof(u32))) {
1692  goto unlock;
1693  }
1694  do {
1695  hpi_write_word((struct dsp_obj *)pdo,
1696  HPI_HIF_ADDR(control_cache_is_dirty), 0);
1697  /* flush the FIFO */
1698  hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1699  } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1700  && --timeout);
1701  if (!timeout) {
1703  goto unlock;
1704  }
1705 
1706  }
1707  err = 0;
1708 
1709 unlock:
1710  hpios_dsplock_unlock(pao);
1711  return err;
1712 }
1713 
1715 static u16 get_dsp_index(struct hpi_adapter_obj *pao, struct hpi_message *phm)
1716 {
1717  u16 ret = 0;
1718  switch (phm->object) {
1719  case HPI_OBJ_ISTREAM:
1720  if (phm->obj_index < 2)
1721  ret = 1;
1722  break;
1723  case HPI_OBJ_PROFILE:
1724  ret = phm->obj_index;
1725  break;
1726  default:
1727  break;
1728  }
1729  return ret;
1730 }
1731 
1736 static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1737  struct hpi_response *phr)
1738 {
1739  u16 error = 0;
1740  u16 dsp_index = 0;
1741  struct hpi_hw_obj *phw = pao->priv;
1742  u16 num_dsp = phw->num_dsp;
1743 
1744  if (num_dsp < 2)
1745  dsp_index = 0;
1746  else {
1747  dsp_index = get_dsp_index(pao, phm);
1748 
1749  /* is this checked on the DSP anyway? */
1750  if ((phm->function == HPI_ISTREAM_GROUP_ADD)
1751  || (phm->function == HPI_OSTREAM_GROUP_ADD)) {
1752  struct hpi_message hm;
1753  u16 add_index;
1754  hm.obj_index = phm->u.d.u.stream.stream_index;
1755  hm.object = phm->u.d.u.stream.object_type;
1756  add_index = get_dsp_index(pao, &hm);
1757  if (add_index != dsp_index) {
1759  return;
1760  }
1761  }
1762  }
1763 
1764  hpios_dsplock_lock(pao);
1765  error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
1766 
1767  if (error) /* something failed in the HPI/DSP interface */
1768  goto err;
1769 
1770  if (phr->error) /* something failed in the DSP */
1771  goto out;
1772 
1773  switch (phm->function) {
1774  case HPI_OSTREAM_WRITE:
1775  case HPI_ISTREAM_ANC_WRITE:
1776  error = hpi6000_send_data(pao, dsp_index, phm, phr);
1777  break;
1778  case HPI_ISTREAM_READ:
1779  case HPI_OSTREAM_ANC_READ:
1780  error = hpi6000_get_data(pao, dsp_index, phm, phr);
1781  break;
1783  phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */
1784  if (num_dsp == 2) {
1785  if (!phr->u.ax.assert.count) {
1786  /* no assert from dsp 0, check dsp 1 */
1787  error = hpi6000_message_response_sequence(pao,
1788  1, phm, phr);
1789  phr->u.ax.assert.dsp_index = 1;
1790  }
1791  }
1792  }
1793 
1794 err:
1795  if (error) {
1796  if (error >= HPI_ERROR_BACKEND_BASE) {
1798  phr->specific_error = error;
1799  } else {
1800  phr->error = error;
1801  }
1802 
1803  /* just the header of the response is valid */
1804  phr->size = sizeof(struct hpi_response_header);
1805  }
1806 out:
1807  hpios_dsplock_unlock(pao);
1808  return;
1809 }