hpi6000.c 50 KB

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