1/******************************************************************************
2
3    AudioScience HPI driver
4    Copyright (C) 1997-2011  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 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#define HPI6000_ERROR_RESP_GET_LEN                      902
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
130struct dsp_obj {
131	__iomem u32 *prHPI_control;
132	__iomem u32 *prHPI_address;
133	__iomem u32 *prHPI_data;
134	__iomem u32 *prHPI_data_auto_inc;
135	char c_dsp_rev;		/*A, B */
136	u32 control_cache_address_on_dsp;
137	u32 control_cache_length_on_dsp;
138	struct hpi_adapter_obj *pa_parent_adapter;
139};
140
141struct hpi_hw_obj {
142	__iomem u32 *dw2040_HPICSR;
143	__iomem u32 *dw2040_HPIDSP;
144
145	u16 num_dsp;
146	struct dsp_obj ado[MAX_DSPS];
147
148	u32 message_buffer_address_on_dsp;
149	u32 response_buffer_address_on_dsp;
150	u32 pCI2040HPI_error_count;
151
152	struct hpi_control_cache_single control_cache[HPI_NMIXER_CONTROLS];
153	struct hpi_control_cache *p_cache;
154};
155
156static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
157	u16 dsp_index, u32 hpi_address, u32 *source, u32 count);
158static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
159	u16 dsp_index, u32 hpi_address, u32 *dest, u32 count);
160
161static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
162	u32 *pos_error_code);
163static 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
168static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
169	struct hpi_message *phm);
170static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
171	u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr);
172
173static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
174	struct hpi_response *phr);
175
176static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
177	u32 ack_value);
178
179static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
180	u16 dsp_index, u32 host_cmd);
181
182static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo);
183
184static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
185	struct hpi_message *phm, struct hpi_response *phr);
186
187static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
188	struct hpi_message *phm, struct hpi_response *phr);
189
190static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data);
191
192static u32 hpi_read_word(struct dsp_obj *pdo, u32 address);
193
194static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
195	u32 length);
196
197static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
198	u32 length);
199
200static void subsys_create_adapter(struct hpi_message *phm,
201	struct hpi_response *phr);
202
203static void adapter_delete(struct hpi_adapter_obj *pao,
204	struct hpi_message *phm, struct hpi_response *phr);
205
206static void adapter_get_asserts(struct hpi_adapter_obj *pao,
207	struct hpi_message *phm, struct hpi_response *phr);
208
209static short create_adapter_obj(struct hpi_adapter_obj *pao,
210	u32 *pos_error_code);
211
212static void delete_adapter_obj(struct hpi_adapter_obj *pao);
213
214/* local globals */
215
216static u16 gw_pci_read_asserts;	/* used to count PCI2040 errors */
217static u16 gw_pci_write_asserts;	/* used to count PCI2040 errors */
218
219static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
220{
221	switch (phm->function) {
222	case HPI_SUBSYS_CREATE_ADAPTER:
223		subsys_create_adapter(phm, phr);
224		break;
225	default:
226		phr->error = HPI_ERROR_INVALID_FUNC;
227		break;
228	}
229}
230
231static 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) {
237	case HPI_CONTROL_GET_STATE:
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 =
245						HPI_ERROR_CONTROL_CACHING;
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;
258	case HPI_CONTROL_SET_STATE:
259		hw_message(pao, phm, phr);
260		hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm, phr);
261		break;
262
263	case HPI_CONTROL_GET_INFO:
264	default:
265		hw_message(pao, phm, phr);
266		break;
267	}
268}
269
270static void adapter_message(struct hpi_adapter_obj *pao,
271	struct hpi_message *phm, struct hpi_response *phr)
272{
273	switch (phm->function) {
274	case HPI_ADAPTER_GET_ASSERT:
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
288static void outstream_message(struct hpi_adapter_obj *pao,
289	struct hpi_message *phm, struct hpi_response *phr)
290{
291	switch (phm->function) {
292	case HPI_OSTREAM_HOSTBUFFER_ALLOC:
293	case HPI_OSTREAM_HOSTBUFFER_FREE:
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		 */
299		phr->error = HPI_ERROR_INVALID_FUNC;
300		break;
301	default:
302		hw_message(pao, phm, phr);
303		return;
304	}
305}
306
307static void instream_message(struct hpi_adapter_obj *pao,
308	struct hpi_message *phm, struct hpi_response *phr)
309{
310
311	switch (phm->function) {
312	case HPI_ISTREAM_HOSTBUFFER_ALLOC:
313	case HPI_ISTREAM_HOSTBUFFER_FREE:
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		 */
319		phr->error = HPI_ERROR_INVALID_FUNC;
320		break;
321	default:
322		hw_message(pao, phm, phr);
323		return;
324	}
325}
326
327/************************************************************************/
328/** HPI_6000()
329 * Entry point from HPIMAN
330 * All calls to the HPI start here
331 */
332void 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,
340				HPI_ERROR_BAD_ADAPTER_NUMBER);
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,
349				HPI_ERROR_DSP_HARDWARE);
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 */
356	if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
357		hpi_init_response(phr, phm->object, phm->function,
358			HPI_ERROR_PROCESSING_MESSAGE);
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:
393		phr->error = HPI_ERROR_INVALID_TYPE;
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 */
406static 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");
423		phr->error = HPI_ERROR_MEMORY_ALLOC;
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) {
434			phr->error = HPI_ERROR_DSP_BOOTLOAD;
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");
448		phr->error = HPI_ERROR_BAD_ADAPTER;
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
462static 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 */
471static 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
527	phw->message_buffer_address_on_dsp = 0L;
528	phw->response_buffer_address_on_dsp = 0L;
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) *
567		HPI_NMIXER_CONTROLS);
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
595static 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)
600		hpi_free_control_cache(phw->p_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
611static 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
637static 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:
669		return HPI6000_ERROR_UNHANDLED_SUBSYS_ID;
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	 */
683	hpios_delay_micro_seconds(1000);
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);
689		return HPI6000_ERROR_INIT_PCI2040;
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 */
718	hpios_delay_micro_seconds(100);
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);
736				return HPI6000_ERROR_INIT_DSPHPI;
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);
757			hpios_delay_micro_seconds(100);
758
759			/*  ** use default of PLL  x7 ** */
760			/* EMIF = 225/3=75MHz */
761			hpi_write_word(pdo, 0x01B7C120, 0x8002);
762			hpios_delay_micro_seconds(100);
763
764			/* peri = 225/2 */
765			hpi_write_word(pdo, 0x01B7C11C, 0x8001);
766			hpios_delay_micro_seconds(100);
767
768			/* cpu  = 225/1 */
769			hpi_write_word(pdo, 0x01B7C118, 0x8000);
770
771			/* ~2ms delay */
772			hpios_delay_micro_seconds(2000);
773
774			/* PLL not bypassed */
775			hpi_write_word(pdo, 0x01B7C100, 0x0001);
776			/* ~2ms delay */
777			hpios_delay_micro_seconds(2000);
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) {
794					HPI_DEBUG_LOG(ERROR,
795						"DSP mem %x %x %x %x\n",
796						test_addr + i, test_data,
797						data, dsp_index);
798
799					return HPI6000_ERROR_INIT_DSPINTMEM;
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" */
901		hpios_delay_micro_seconds(1000);
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) {
912					HPI_DEBUG_LOG(ERROR,
913						"DSP dram %x %x %x %x\n",
914						test_addr, test_data, data,
915						dsp_index);
916
917					return HPI6000_ERROR_INIT_SDRAM1;
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) {
935					HPI_DEBUG_LOG(ERROR,
936						"DSP dram %x %x %x %x\n",
937						test_addr + i, test_data,
938						data, dsp_index);
939					return HPI6000_ERROR_INIT_SDRAM2;
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) {
982			hpi_dsp_code_close(&dsp_code);
983			return error;
984		}
985		/* verify that code was written correctly */
986		/* this time through, assume no errors in DSP code file/array */
987		hpi_dsp_code_rewind(&dsp_code);
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);
999			hpi_dsp_code_read_word(&dsp_code, &type);
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;
1006					HPI_DEBUG_LOG(ERROR,
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		}
1018		hpi_dsp_code_close(&dsp_code);
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);
1042		hpios_delay_micro_seconds(10000);
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,
1055					HPI_HIF_ADDR(host_cmd));
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
1069				hpios_delay_micro_seconds(10000);
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));
1083			if (HPI_ADAPTER_FAMILY_ASI
1084				(HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER
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);
1124				return HPI6000_ERROR_INIT_PLDTEST1;
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);
1133				return HPI6000_ERROR_INIT_PLDTEST2;
1134			}
1135		}
1136	}	/* for numDSP */
1137	return 0;
1138}
1139
1140#define PCI_TIMEOUT 100
1141
1142static 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 */
1159static 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 */
1167static 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 */
1180static 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
1198/** read a block of 32bit words from the DSP HPI port using auto-inc mode
1199 */
1200static 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
1218static 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
1256static 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
1296static 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++;
1311		return HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT;
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));
1322			phw->message_buffer_address_on_dsp = address;
1323		} while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1324			&& --timeout);
1325		if (!timeout)
1326			return HPI6000_ERROR_MSG_GET_ADR;
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))
1336		return HPI6000_ERROR_MSG_RESP_BLOCKWRITE32;
1337
1338	if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_GET_RESP))
1339		return HPI6000_ERROR_MSG_RESP_GETRESPCMD;
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)
1344		return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
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);
1355		phw->response_buffer_address_on_dsp = address;
1356
1357		if (!timeout)
1358			return HPI6000_ERROR_RESP_GET_ADR;
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		return HPI6000_ERROR_RESP_GET_LEN;
1369
1370	if (length > phr->size)
1371		return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
1372
1373	/* get the response */
1374	p_data = (u32 *)phr;
1375	if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
1376			(u16)length / 4))
1377		return HPI6000_ERROR_MSG_RESP_BLOCKREAD32;
1378
1379	/* set i/f back to idle */
1380	if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1381		return HPI6000_ERROR_MSG_RESP_IDLECMD;
1382	hpi6000_send_dsp_interrupt(pdo);
1383
1384	error = hpi_validate_response(phm, phr);
1385	return error;
1386}
1387
1388/* have to set up the below defines to match stuff in the MAP file */
1389
1390#define MSG_ADDRESS (HPI_HIF_BASE+0x18)
1391#define MSG_LENGTH 11
1392#define RESP_ADDRESS (HPI_HIF_BASE+0x44)
1393#define RESP_LENGTH 16
1394#define QUEUE_START  (HPI_HIF_BASE+0x88)
1395#define QUEUE_SIZE 0x8000
1396
1397static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords)
1398{
1399/*#define CHECKING       // comment this line in to enable checking */
1400#ifdef CHECKING
1401	if (address < (u32)MSG_ADDRESS)
1402		return 0;
1403	if (address > (u32)(QUEUE_START + QUEUE_SIZE))
1404		return 0;
1405	if ((address + (length_in_dwords << 2)) >
1406		(u32)(QUEUE_START + QUEUE_SIZE))
1407		return 0;
1408#else
1409	(void)address;
1410	(void)length_in_dwords;
1411	return 1;
1412#endif
1413}
1414
1415static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1416	struct hpi_message *phm, struct hpi_response *phr)
1417{
1418	struct hpi_hw_obj *phw = pao->priv;
1419	struct dsp_obj *pdo = &phw->ado[dsp_index];
1420	u32 data_sent = 0;
1421	u16 ack;
1422	u32 length, address;
1423	u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1424	u16 time_out = 8;
1425
1426	(void)phr;
1427
1428	/* round dwDataSize down to nearest 4 bytes */
1429	while ((data_sent < (phm->u.d.u.data.data_size & ~3L))
1430		&& --time_out) {
1431		ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1432		if (ack & HPI_HIF_ERROR_MASK)
1433			return HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT;
1434
1435		if (hpi6000_send_host_command(pao, dsp_index,
1436				HPI_HIF_SEND_DATA))
1437			return HPI6000_ERROR_SEND_DATA_CMD;
1438
1439		hpi6000_send_dsp_interrupt(pdo);
1440
1441		ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_SEND_DATA);
1442
1443		if (ack & HPI_HIF_ERROR_MASK)
1444			return HPI6000_ERROR_SEND_DATA_ACK;
1445
1446		do {
1447			/* get the address and size */
1448			address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1449			/* DSP returns number of DWORDS */
1450			length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1451		} while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1452
1453		if (!hpi6000_send_data_check_adr(address, length))
1454			return HPI6000_ERROR_SEND_DATA_ADR;
1455
1456		/* send the data. break data into 512 DWORD blocks (2K bytes)
1457		 * and send using block write. 2Kbytes is the max as this is the
1458		 * memory window given to the HPI data register by the PCI2040
1459		 */
1460
1461		{
1462			u32 len = length;
1463			u32 blk_len = 512;
1464			while (len) {
1465				if (len < blk_len)
1466					blk_len = len;
1467				if (hpi6000_dsp_block_write32(pao, dsp_index,
1468						address, p_data, blk_len))
1469					return HPI6000_ERROR_SEND_DATA_WRITE;
1470				address += blk_len * 4;
1471				p_data += blk_len;
1472				len -= blk_len;
1473			}
1474		}
1475
1476		if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1477			return HPI6000_ERROR_SEND_DATA_IDLECMD;
1478
1479		hpi6000_send_dsp_interrupt(pdo);
1480
1481		data_sent += length * 4;
1482	}
1483	if (!time_out)
1484		return HPI6000_ERROR_SEND_DATA_TIMEOUT;
1485	return 0;
1486}
1487
1488static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1489	struct hpi_message *phm, struct hpi_response *phr)
1490{
1491	struct hpi_hw_obj *phw = pao->priv;
1492	struct dsp_obj *pdo = &phw->ado[dsp_index];
1493	u32 data_got = 0;
1494	u16 ack;
1495	u32 length, address;
1496	u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1497
1498	(void)phr;	/* this parameter not used! */
1499
1500	/* round dwDataSize down to nearest 4 bytes */
1501	while (data_got < (phm->u.d.u.data.data_size & ~3L)) {
1502		ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1503		if (ack & HPI_HIF_ERROR_MASK)
1504			return HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT;
1505
1506		if (hpi6000_send_host_command(pao, dsp_index,
1507				HPI_HIF_GET_DATA))
1508			return HPI6000_ERROR_GET_DATA_CMD;
1509		hpi6000_send_dsp_interrupt(pdo);
1510
1511		ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_DATA);
1512
1513		if (ack & HPI_HIF_ERROR_MASK)
1514			return HPI6000_ERROR_GET_DATA_ACK;
1515
1516		/* get the address and size */
1517		do {
1518			address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1519			length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1520		} while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1521
1522		/* read the data */
1523		{
1524			u32 len = length;
1525			u32 blk_len = 512;
1526			while (len) {
1527				if (len < blk_len)
1528					blk_len = len;
1529				if (hpi6000_dsp_block_read32(pao, dsp_index,
1530						address, p_data, blk_len))
1531					return HPI6000_ERROR_GET_DATA_READ;
1532				address += blk_len * 4;
1533				p_data += blk_len;
1534				len -= blk_len;
1535			}
1536		}
1537
1538		if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1539			return HPI6000_ERROR_GET_DATA_IDLECMD;
1540		hpi6000_send_dsp_interrupt(pdo);
1541
1542		data_got += length * 4;
1543	}
1544	return 0;
1545}
1546
1547static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo)
1548{
1549	iowrite32(0x00030003, pdo->prHPI_control);	/* DSPINT */
1550}
1551
1552static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
1553	u16 dsp_index, u32 host_cmd)
1554{
1555	struct hpi_hw_obj *phw = pao->priv;
1556	struct dsp_obj *pdo = &phw->ado[dsp_index];
1557	u32 timeout = TIMEOUT;
1558
1559	/* set command */
1560	do {
1561		hpi_write_word(pdo, HPI_HIF_ADDR(host_cmd), host_cmd);
1562		/* flush the FIFO */
1563		hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1564	} while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) && --timeout);
1565
1566	/* reset the interrupt bit */
1567	iowrite32(0x00040004, pdo->prHPI_control);
1568
1569	if (timeout)
1570		return 0;
1571	else
1572		return 1;
1573}
1574
1575/* if the PCI2040 has recorded an HPI timeout, reset the error and return 1 */
1576static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
1577	u16 read_or_write)
1578{
1579	u32 hPI_error;
1580
1581	struct hpi_hw_obj *phw = pao->priv;
1582
1583	/* read the error bits from the PCI2040 */
1584	hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1585	if (hPI_error) {
1586		/* reset the error flag */
1587		iowrite32(0L, phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1588		phw->pCI2040HPI_error_count++;
1589		if (read_or_write == 1)
1590			gw_pci_read_asserts++;	   /************* inc global */
1591		else
1592			gw_pci_write_asserts++;
1593		return 1;
1594	} else
1595		return 0;
1596}
1597
1598static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
1599	u32 ack_value)
1600{
1601	struct hpi_hw_obj *phw = pao->priv;
1602	struct dsp_obj *pdo = &phw->ado[dsp_index];
1603	u32 ack = 0L;
1604	u32 timeout;
1605	u32 hPIC = 0L;
1606
1607	/* wait for host interrupt to signal ack is ready */
1608	timeout = TIMEOUT;
1609	while (--timeout) {
1610		hPIC = ioread32(pdo->prHPI_control);
1611		if (hPIC & 0x04)	/* 0x04 = HINT from DSP */
1612			break;
1613	}
1614	if (timeout == 0)
1615		return HPI_HIF_ERROR_MASK;
1616
1617	/* wait for dwAckValue */
1618	timeout = TIMEOUT;
1619	while (--timeout) {
1620		/* read the ack mailbox */
1621		ack = hpi_read_word(pdo, HPI_HIF_ADDR(dsp_ack));
1622		if (ack == ack_value)
1623			break;
1624		if ((ack & HPI_HIF_ERROR_MASK)
1625			&& !hpi6000_check_PCI2040_error_flag(pao, H6READ))
1626			break;
1627		/*for (i=0;i<1000;i++) */
1628		/*      dwPause=i+1; */
1629	}
1630	if (ack & HPI_HIF_ERROR_MASK)
1631		/* indicates bad read from DSP -
1632		   typically 0xffffff is read for some reason */
1633		ack = HPI_HIF_ERROR_MASK;
1634
1635	if (timeout == 0)
1636		ack = HPI_HIF_ERROR_MASK;
1637	return (short)ack;
1638}
1639
1640static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
1641	struct hpi_message *phm)
1642{
1643	const u16 dsp_index = 0;
1644	struct hpi_hw_obj *phw = pao->priv;
1645	struct dsp_obj *pdo = &phw->ado[dsp_index];
1646	u32 timeout;
1647	u32 cache_dirty_flag;
1648	u16 err;
1649
1650	hpios_dsplock_lock(pao);
1651
1652	timeout = TIMEOUT;
1653	do {
1654		cache_dirty_flag =
1655			hpi_read_word((struct dsp_obj *)pdo,
1656			HPI_HIF_ADDR(control_cache_is_dirty));
1657	} while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1658	if (!timeout) {
1659		err = HPI6000_ERROR_CONTROL_CACHE_PARAMS;
1660		goto unlock;
1661	}
1662
1663	if (cache_dirty_flag) {
1664		/* read the cached controls */
1665		u32 address;
1666		u32 length;
1667
1668		timeout = TIMEOUT;
1669		if (pdo->control_cache_address_on_dsp == 0) {
1670			do {
1671				address =
1672					hpi_read_word((struct dsp_obj *)pdo,
1673					HPI_HIF_ADDR(control_cache_address));
1674
1675				length = hpi_read_word((struct dsp_obj *)pdo,
1676					HPI_HIF_ADDR
1677					(control_cache_size_in_bytes));
1678			} while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1679				&& --timeout);
1680			if (!timeout) {
1681				err = HPI6000_ERROR_CONTROL_CACHE_ADDRLEN;
1682				goto unlock;
1683			}
1684			pdo->control_cache_address_on_dsp = address;
1685			pdo->control_cache_length_on_dsp = length;
1686		} else {
1687			address = pdo->control_cache_address_on_dsp;
1688			length = pdo->control_cache_length_on_dsp;
1689		}
1690
1691		if (hpi6000_dsp_block_read32(pao, dsp_index, address,
1692				(u32 *)&phw->control_cache[0],
1693				length / sizeof(u32))) {
1694			err = HPI6000_ERROR_CONTROL_CACHE_READ;
1695			goto unlock;
1696		}
1697		do {
1698			hpi_write_word((struct dsp_obj *)pdo,
1699				HPI_HIF_ADDR(control_cache_is_dirty), 0);
1700			/* flush the FIFO */
1701			hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1702		} while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1703			&& --timeout);
1704		if (!timeout) {
1705			err = HPI6000_ERROR_CONTROL_CACHE_FLUSH;
1706			goto unlock;
1707		}
1708
1709	}
1710	err = 0;
1711
1712unlock:
1713	hpios_dsplock_unlock(pao);
1714	return err;
1715}
1716
1717/** Get dsp index for multi DSP adapters only */
1718static u16 get_dsp_index(struct hpi_adapter_obj *pao, struct hpi_message *phm)
1719{
1720	u16 ret = 0;
1721	switch (phm->object) {
1722	case HPI_OBJ_ISTREAM:
1723		if (phm->obj_index < 2)
1724			ret = 1;
1725		break;
1726	case HPI_OBJ_PROFILE:
1727		ret = phm->obj_index;
1728		break;
1729	default:
1730		break;
1731	}
1732	return ret;
1733}
1734
1735/** Complete transaction with DSP
1736
1737Send message, get response, send or get stream data if any.
1738*/
1739static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1740	struct hpi_response *phr)
1741{
1742	u16 error = 0;
1743	u16 dsp_index = 0;
1744	struct hpi_hw_obj *phw = pao->priv;
1745	u16 num_dsp = phw->num_dsp;
1746
1747	if (num_dsp < 2)
1748		dsp_index = 0;
1749	else {
1750		dsp_index = get_dsp_index(pao, phm);
1751
1752		/* is this  checked on the DSP anyway? */
1753		if ((phm->function == HPI_ISTREAM_GROUP_ADD)
1754			|| (phm->function == HPI_OSTREAM_GROUP_ADD)) {
1755			struct hpi_message hm;
1756			u16 add_index;
1757			hm.obj_index = phm->u.d.u.stream.stream_index;
1758			hm.object = phm->u.d.u.stream.object_type;
1759			add_index = get_dsp_index(pao, &hm);
1760			if (add_index != dsp_index) {
1761				phr->error = HPI_ERROR_NO_INTERDSP_GROUPS;
1762				return;
1763			}
1764		}
1765	}
1766
1767	hpios_dsplock_lock(pao);
1768	error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
1769
1770	if (error)	/* something failed in the HPI/DSP interface */
1771		goto err;
1772
1773	if (phr->error)	/* something failed in the DSP */
1774		goto out;
1775
1776	switch (phm->function) {
1777	case HPI_OSTREAM_WRITE:
1778	case HPI_ISTREAM_ANC_WRITE:
1779		error = hpi6000_send_data(pao, dsp_index, phm, phr);
1780		break;
1781	case HPI_ISTREAM_READ:
1782	case HPI_OSTREAM_ANC_READ:
1783		error = hpi6000_get_data(pao, dsp_index, phm, phr);
1784		break;
1785	case HPI_ADAPTER_GET_ASSERT:
1786		phr->u.ax.assert.dsp_index = 0;	/* dsp 0 default */
1787		if (num_dsp == 2) {
1788			if (!phr->u.ax.assert.count) {
1789				/* no assert from dsp 0, check dsp 1 */
1790				error = hpi6000_message_response_sequence(pao,
1791					1, phm, phr);
1792				phr->u.ax.assert.dsp_index = 1;
1793			}
1794		}
1795	}
1796
1797err:
1798	if (error) {
1799		if (error >= HPI_ERROR_BACKEND_BASE) {
1800			phr->error = HPI_ERROR_DSP_COMMUNICATION;
1801			phr->specific_error = error;
1802		} else {
1803			phr->error = error;
1804		}
1805
1806		/* just the header of the response is valid */
1807		phr->size = sizeof(struct hpi_response_header);
1808	}
1809out:
1810	hpios_dsplock_unlock(pao);
1811	return;
1812}
1813