hpi6000.c 49 KB

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