brintos

brintos / linux-shallow public Read only

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