]> bbs.cooldavid.org Git - net-next-2.6.git/blame - sound/pci/asihpi/hpi6205.c
Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[net-next-2.6.git] / sound / pci / asihpi / hpi6205.c
CommitLineData
719f82d3
EB
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) for AudioScience
20 ASI50xx, AS51xx, ASI6xxx, ASI87xx ASI89xx series adapters.
21 These PCI and PCIe bus adapters are based on a
22 TMS320C6205 PCI bus mastering DSP,
23 and (except ASI50xx) TI TMS320C6xxx floating point DSP
24
25 Exported function:
26 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
27
28(C) Copyright AudioScience Inc. 1998-2010
29*******************************************************************************/
30#define SOURCEFILE_NAME "hpi6205.c"
31
32#include "hpi_internal.h"
33#include "hpimsginit.h"
34#include "hpidebug.h"
35#include "hpi6205.h"
36#include "hpidspcd.h"
37#include "hpicmn.h"
38
39/*****************************************************************************/
40/* HPI6205 specific error codes */
41#define HPI6205_ERROR_BASE 1000
42/*#define HPI6205_ERROR_MEM_ALLOC 1001 */
43#define HPI6205_ERROR_6205_NO_IRQ 1002
44#define HPI6205_ERROR_6205_INIT_FAILED 1003
45/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
46#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
47#define HPI6205_ERROR_6205_REG 1006
48#define HPI6205_ERROR_6205_DSPPAGE 1007
49#define HPI6205_ERROR_BAD_DSPINDEX 1008
50#define HPI6205_ERROR_C6713_HPIC 1009
51#define HPI6205_ERROR_C6713_HPIA 1010
52#define HPI6205_ERROR_C6713_PLL 1011
53#define HPI6205_ERROR_DSP_INTMEM 1012
54#define HPI6205_ERROR_DSP_EXTMEM 1013
55#define HPI6205_ERROR_DSP_PLD 1014
56#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
57#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
58#define HPI6205_ERROR_6205_EEPROM 1017
59#define HPI6205_ERROR_DSP_EMIF 1018
60
61#define hpi6205_error(dsp_index, err) (err)
62/*****************************************************************************/
63/* for C6205 PCI i/f */
64/* Host Status Register (HSR) bitfields */
65#define C6205_HSR_INTSRC 0x01
66#define C6205_HSR_INTAVAL 0x02
67#define C6205_HSR_INTAM 0x04
68#define C6205_HSR_CFGERR 0x08
69#define C6205_HSR_EEREAD 0x10
70/* Host-to-DSP Control Register (HDCR) bitfields */
71#define C6205_HDCR_WARMRESET 0x01
72#define C6205_HDCR_DSPINT 0x02
73#define C6205_HDCR_PCIBOOT 0x04
74/* DSP Page Register (DSPP) bitfields, */
75/* defines 4 Mbyte page that BAR0 points to */
76#define C6205_DSPP_MAP1 0x400
77
78/* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
79 * BAR1 maps to non-prefetchable 8 Mbyte memory block
80 * of DSP memory mapped registers (starting at 0x01800000).
81 * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
82 * needs to be added to the BAR1 base address set in the PCI config reg
83 */
84#define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
85#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
86#define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
87#define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
88
89/* used to control LED (revA) and reset C6713 (revB) */
90#define C6205_BAR0_TIMER1_CTL (0x01980000L)
91
92/* For first 6713 in CE1 space, using DA17,16,2 */
93#define HPICL_ADDR 0x01400000L
94#define HPICH_ADDR 0x01400004L
95#define HPIAL_ADDR 0x01410000L
96#define HPIAH_ADDR 0x01410004L
97#define HPIDIL_ADDR 0x01420000L
98#define HPIDIH_ADDR 0x01420004L
99#define HPIDL_ADDR 0x01430000L
100#define HPIDH_ADDR 0x01430004L
101
102#define C6713_EMIF_GCTL 0x01800000
103#define C6713_EMIF_CE1 0x01800004
104#define C6713_EMIF_CE0 0x01800008
105#define C6713_EMIF_CE2 0x01800010
106#define C6713_EMIF_CE3 0x01800014
107#define C6713_EMIF_SDRAMCTL 0x01800018
108#define C6713_EMIF_SDRAMTIMING 0x0180001C
109#define C6713_EMIF_SDRAMEXT 0x01800020
110
111struct hpi_hw_obj {
112 /* PCI registers */
113 __iomem u32 *prHSR;
114 __iomem u32 *prHDCR;
115 __iomem u32 *prDSPP;
116
117 u32 dsp_page;
118
119 struct consistent_dma_area h_locked_mem;
120 struct bus_master_interface *p_interface_buffer;
121
122 u16 flag_outstream_just_reset[HPI_MAX_STREAMS];
123 /* a non-NULL handle means there is an HPI allocated buffer */
124 struct consistent_dma_area instream_host_buffers[HPI_MAX_STREAMS];
125 struct consistent_dma_area outstream_host_buffers[HPI_MAX_STREAMS];
126 /* non-zero size means a buffer exists, may be external */
127 u32 instream_host_buffer_size[HPI_MAX_STREAMS];
128 u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
129
130 struct consistent_dma_area h_control_cache;
131 struct consistent_dma_area h_async_event_buffer;
132/* struct hpi_control_cache_single *pControlCache; */
133 struct hpi_async_event *p_async_event_buffer;
134 struct hpi_control_cache *p_cache;
135};
136
137/*****************************************************************************/
138/* local prototypes */
139
140#define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
141
142static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
143
144static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
145
146static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
147 u32 *pos_error_code);
148
149static u16 message_response_sequence(struct hpi_adapter_obj *pao,
150 struct hpi_message *phm, struct hpi_response *phr);
151
152static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
153 struct hpi_response *phr);
154
155#define HPI6205_TIMEOUT 1000000
156
157static void subsys_create_adapter(struct hpi_message *phm,
158 struct hpi_response *phr);
159static void subsys_delete_adapter(struct hpi_message *phm,
160 struct hpi_response *phr);
161
162static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code);
164
165static void delete_adapter_obj(struct hpi_adapter_obj *pao);
166
167static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
168 struct hpi_message *phm, struct hpi_response *phr);
169
170static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
171 struct hpi_message *phm, struct hpi_response *phr);
172
173static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
174 struct hpi_message *phm, struct hpi_response *phr);
175static void outstream_write(struct hpi_adapter_obj *pao,
176 struct hpi_message *phm, struct hpi_response *phr);
177
178static void outstream_get_info(struct hpi_adapter_obj *pao,
179 struct hpi_message *phm, struct hpi_response *phr);
180
181static void outstream_start(struct hpi_adapter_obj *pao,
182 struct hpi_message *phm, struct hpi_response *phr);
183
184static void outstream_open(struct hpi_adapter_obj *pao,
185 struct hpi_message *phm, struct hpi_response *phr);
186
187static void outstream_reset(struct hpi_adapter_obj *pao,
188 struct hpi_message *phm, struct hpi_response *phr);
189
190static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
191 struct hpi_message *phm, struct hpi_response *phr);
192
193static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
194 struct hpi_message *phm, struct hpi_response *phr);
195
196static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
197 struct hpi_message *phm, struct hpi_response *phr);
198
199static void instream_read(struct hpi_adapter_obj *pao,
200 struct hpi_message *phm, struct hpi_response *phr);
201
202static void instream_get_info(struct hpi_adapter_obj *pao,
203 struct hpi_message *phm, struct hpi_response *phr);
204
205static void instream_start(struct hpi_adapter_obj *pao,
206 struct hpi_message *phm, struct hpi_response *phr);
207
208static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209 u32 address);
210
211static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
212 u32 address, u32 data);
213
214static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215 int dsp_index);
216
217static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
218 u32 address, u32 length);
219
220static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
221 int dsp_index);
222
223static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
224 int dsp_index);
225
226static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
227
228/*****************************************************************************/
229
230static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
231{
232
233 switch (phm->function) {
234 case HPI_SUBSYS_OPEN:
235 case HPI_SUBSYS_CLOSE:
236 case HPI_SUBSYS_GET_INFO:
237 case HPI_SUBSYS_DRIVER_UNLOAD:
238 case HPI_SUBSYS_DRIVER_LOAD:
239 case HPI_SUBSYS_FIND_ADAPTERS:
240 /* messages that should not get here */
241 phr->error = HPI_ERROR_UNIMPLEMENTED;
242 break;
243 case HPI_SUBSYS_CREATE_ADAPTER:
244 subsys_create_adapter(phm, phr);
245 break;
246 case HPI_SUBSYS_DELETE_ADAPTER:
247 subsys_delete_adapter(phm, phr);
248 break;
249 default:
250 phr->error = HPI_ERROR_INVALID_FUNC;
251 break;
252 }
253}
254
255static void control_message(struct hpi_adapter_obj *pao,
256 struct hpi_message *phm, struct hpi_response *phr)
257{
258
259 struct hpi_hw_obj *phw = pao->priv;
260
261 switch (phm->function) {
262 case HPI_CONTROL_GET_STATE:
263 if (pao->has_control_cache) {
264 rmb(); /* make sure we see updates DM_aed from DSP */
265 if (hpi_check_control_cache(phw->p_cache, phm, phr))
266 break;
267 }
268 hw_message(pao, phm, phr);
269 break;
270 case HPI_CONTROL_GET_INFO:
271 hw_message(pao, phm, phr);
272 break;
273 case HPI_CONTROL_SET_STATE:
274 hw_message(pao, phm, phr);
275 if (pao->has_control_cache)
276 hpi_sync_control_cache(phw->p_cache, phm, phr);
277 break;
278 default:
279 phr->error = HPI_ERROR_INVALID_FUNC;
280 break;
281 }
282}
283
284static void adapter_message(struct hpi_adapter_obj *pao,
285 struct hpi_message *phm, struct hpi_response *phr)
286{
287 switch (phm->function) {
288 default:
289 hw_message(pao, phm, phr);
290 break;
291 }
292}
293
294static void outstream_message(struct hpi_adapter_obj *pao,
295 struct hpi_message *phm, struct hpi_response *phr)
296{
297
298 if (phm->obj_index >= HPI_MAX_STREAMS) {
299 phr->error = HPI_ERROR_INVALID_STREAM;
300 HPI_DEBUG_LOG(WARNING,
301 "message referencing invalid stream %d "
302 "on adapter index %d\n", phm->obj_index,
303 phm->adapter_index);
304 return;
305 }
306
307 switch (phm->function) {
308 case HPI_OSTREAM_WRITE:
309 outstream_write(pao, phm, phr);
310 break;
311 case HPI_OSTREAM_GET_INFO:
312 outstream_get_info(pao, phm, phr);
313 break;
314 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
315 outstream_host_buffer_allocate(pao, phm, phr);
316 break;
317 case HPI_OSTREAM_HOSTBUFFER_GET_INFO:
318 outstream_host_buffer_get_info(pao, phm, phr);
319 break;
320 case HPI_OSTREAM_HOSTBUFFER_FREE:
321 outstream_host_buffer_free(pao, phm, phr);
322 break;
323 case HPI_OSTREAM_START:
324 outstream_start(pao, phm, phr);
325 break;
326 case HPI_OSTREAM_OPEN:
327 outstream_open(pao, phm, phr);
328 break;
329 case HPI_OSTREAM_RESET:
330 outstream_reset(pao, phm, phr);
331 break;
332 default:
333 hw_message(pao, phm, phr);
334 break;
335 }
336}
337
338static void instream_message(struct hpi_adapter_obj *pao,
339 struct hpi_message *phm, struct hpi_response *phr)
340{
341
342 if (phm->obj_index >= HPI_MAX_STREAMS) {
343 phr->error = HPI_ERROR_INVALID_STREAM;
344 HPI_DEBUG_LOG(WARNING,
345 "message referencing invalid stream %d "
346 "on adapter index %d\n", phm->obj_index,
347 phm->adapter_index);
348 return;
349 }
350
351 switch (phm->function) {
352 case HPI_ISTREAM_READ:
353 instream_read(pao, phm, phr);
354 break;
355 case HPI_ISTREAM_GET_INFO:
356 instream_get_info(pao, phm, phr);
357 break;
358 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
359 instream_host_buffer_allocate(pao, phm, phr);
360 break;
361 case HPI_ISTREAM_HOSTBUFFER_GET_INFO:
362 instream_host_buffer_get_info(pao, phm, phr);
363 break;
364 case HPI_ISTREAM_HOSTBUFFER_FREE:
365 instream_host_buffer_free(pao, phm, phr);
366 break;
367 case HPI_ISTREAM_START:
368 instream_start(pao, phm, phr);
369 break;
370 default:
371 hw_message(pao, phm, phr);
372 break;
373 }
374}
375
376/*****************************************************************************/
377/** Entry point to this HPI backend
378 * All calls to the HPI start here
379 */
380void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
381{
382 struct hpi_adapter_obj *pao = NULL;
383
384 /* subsytem messages are processed by every HPI.
385 * All other messages are ignored unless the adapter index matches
386 * an adapter in the HPI
387 */
388 HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
389 phm->function);
390
391 /* if Dsp has crashed then do not communicate with it any more */
392 if (phm->object != HPI_OBJ_SUBSYSTEM) {
393 pao = hpi_find_adapter(phm->adapter_index);
394 if (!pao) {
395 HPI_DEBUG_LOG(DEBUG,
396 " %d,%d refused, for another HPI?\n",
397 phm->object, phm->function);
398 return;
399 }
400
401 if ((pao->dsp_crashed >= 10)
402 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
403 /* allow last resort debug read even after crash */
404 hpi_init_response(phr, phm->object, phm->function,
405 HPI_ERROR_DSP_HARDWARE);
406 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
407 phm->object, phm->function);
408 return;
409 }
410 }
411
412 /* Init default response */
413 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
414 hpi_init_response(phr, phm->object, phm->function,
415 HPI_ERROR_PROCESSING_MESSAGE);
416
417 HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
418 switch (phm->type) {
419 case HPI_TYPE_MESSAGE:
420 switch (phm->object) {
421 case HPI_OBJ_SUBSYSTEM:
422 subsys_message(phm, phr);
423 break;
424
425 case HPI_OBJ_ADAPTER:
426 phr->size =
427 sizeof(struct hpi_response_header) +
428 sizeof(struct hpi_adapter_res);
429 adapter_message(pao, phm, phr);
430 break;
431
432 case HPI_OBJ_CONTROLEX:
433 case HPI_OBJ_CONTROL:
434 control_message(pao, phm, phr);
435 break;
436
437 case HPI_OBJ_OSTREAM:
438 outstream_message(pao, phm, phr);
439 break;
440
441 case HPI_OBJ_ISTREAM:
442 instream_message(pao, phm, phr);
443 break;
444
445 default:
446 hw_message(pao, phm, phr);
447 break;
448 }
449 break;
450
451 default:
452 phr->error = HPI_ERROR_INVALID_TYPE;
453 break;
454 }
455}
456
457/*****************************************************************************/
458/* SUBSYSTEM */
459
460/** Create an adapter object and initialise it based on resource information
461 * passed in in the message
462 * *** NOTE - you cannot use this function AND the FindAdapters function at the
463 * same time, the application must use only one of them to get the adapters ***
464 */
465static void subsys_create_adapter(struct hpi_message *phm,
466 struct hpi_response *phr)
467{
468 /* create temp adapter obj, because we don't know what index yet */
469 struct hpi_adapter_obj ao;
470 u32 os_error_code;
471 u16 err;
472
473 HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
474
475 memset(&ao, 0, sizeof(ao));
476
477 /* this HPI only creates adapters for TI/PCI devices */
478 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
479 return;
480 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
481 return;
482 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
483 return;
484
550a8b69 485 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
719f82d3
EB
486 if (!ao.priv) {
487 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
488 phr->error = HPI_ERROR_MEMORY_ALLOC;
489 return;
490 }
719f82d3
EB
491
492 ao.pci = *phm->u.s.resource.r.pci;
493 err = create_adapter_obj(&ao, &os_error_code);
494 if (!err)
495 err = hpi_add_adapter(&ao);
496 if (err) {
497 phr->u.s.data = os_error_code;
498 delete_adapter_obj(&ao);
499 phr->error = err;
500 return;
501 }
502
503 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
504 phr->u.s.adapter_index = ao.index;
505 phr->u.s.num_adapters++;
506 phr->error = 0;
507}
508
509/** delete an adapter - required by WDM driver */
510static void subsys_delete_adapter(struct hpi_message *phm,
511 struct hpi_response *phr)
512{
513 struct hpi_adapter_obj *pao;
514 struct hpi_hw_obj *phw;
515
516 pao = hpi_find_adapter(phm->adapter_index);
517 if (!pao) {
518 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519 return;
520 }
521 phw = (struct hpi_hw_obj *)pao->priv;
522 /* reset adapter h/w */
523 /* Reset C6713 #1 */
524 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
525 /* reset C6205 */
526 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
527
528 delete_adapter_obj(pao);
529 phr->error = 0;
530}
531
532/** Create adapter object
533 allocate buffers, bootload DSPs, initialise control cache
534*/
535static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
536 u32 *pos_error_code)
537{
538 struct hpi_hw_obj *phw = pao->priv;
539 struct bus_master_interface *interface;
540 u32 phys_addr;
541#ifndef HPI6205_NO_HSR_POLL
542 u32 time_out = HPI6205_TIMEOUT;
543 u32 temp1;
544#endif
545 int i;
546 u16 err;
547
548 /* init error reporting */
549 pao->dsp_crashed = 0;
550
551 for (i = 0; i < HPI_MAX_STREAMS; i++)
552 phw->flag_outstream_just_reset[i] = 1;
553
554 /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
555 phw->prHSR =
556 pao->pci.ap_mem_base[1] +
557 C6205_BAR1_HSR / sizeof(*pao->pci.ap_mem_base[1]);
558 phw->prHDCR =
559 pao->pci.ap_mem_base[1] +
560 C6205_BAR1_HDCR / sizeof(*pao->pci.ap_mem_base[1]);
561 phw->prDSPP =
562 pao->pci.ap_mem_base[1] +
563 C6205_BAR1_DSPP / sizeof(*pao->pci.ap_mem_base[1]);
564
565 pao->has_control_cache = 0;
566
567 if (hpios_locked_mem_alloc(&phw->h_locked_mem,
568 sizeof(struct bus_master_interface),
569 pao->pci.p_os_data))
570 phw->p_interface_buffer = NULL;
571 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
572 (void *)&phw->p_interface_buffer))
573 phw->p_interface_buffer = NULL;
574
575 HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
576 phw->p_interface_buffer);
577
578 if (phw->p_interface_buffer) {
579 memset((void *)phw->p_interface_buffer, 0,
580 sizeof(struct bus_master_interface));
581 phw->p_interface_buffer->dsp_ack = H620_HIF_UNKNOWN;
582 }
583
584 err = adapter_boot_load_dsp(pao, pos_error_code);
585 if (err)
586 /* no need to clean up as SubSysCreateAdapter */
587 /* calls DeleteAdapter on error. */
588 return err;
589
590 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
591
592 /* allow boot load even if mem alloc wont work */
593 if (!phw->p_interface_buffer)
594 return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC);
595
596 interface = phw->p_interface_buffer;
597
598#ifndef HPI6205_NO_HSR_POLL
599 /* wait for first interrupt indicating the DSP init is done */
600 time_out = HPI6205_TIMEOUT * 10;
601 temp1 = 0;
602 while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
603 temp1 = ioread32(phw->prHSR);
604
605 if (temp1 & C6205_HSR_INTSRC)
606 HPI_DEBUG_LOG(INFO,
607 "interrupt confirming DSP code running OK\n");
608 else {
609 HPI_DEBUG_LOG(ERROR,
610 "timed out waiting for interrupt "
611 "confirming DSP code running\n");
612 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
613 }
614
615 /* reset the interrupt */
616 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617#endif
618
619 /* make sure the DSP has started ok */
620 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
621 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
622 return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED);
623 }
624 /* Note that *pao, *phw are zeroed after allocation,
625 * so pointers and flags are NULL by default.
626 * Allocate bus mastering control cache buffer and tell the DSP about it
627 */
628 if (interface->control_cache.number_of_controls) {
629 void *p_control_cache_virtual;
630
631 err = hpios_locked_mem_alloc(&phw->h_control_cache,
632 interface->control_cache.size_in_bytes,
633 pao->pci.p_os_data);
634 if (!err)
635 err = hpios_locked_mem_get_virt_addr(&phw->
636 h_control_cache, &p_control_cache_virtual);
637 if (!err) {
638 memset(p_control_cache_virtual, 0,
639 interface->control_cache.size_in_bytes);
640
641 phw->p_cache =
642 hpi_alloc_control_cache(interface->
643 control_cache.number_of_controls,
644 interface->control_cache.size_in_bytes,
645 (struct hpi_control_cache_info *)
646 p_control_cache_virtual);
647 }
648 if (!err) {
649 err = hpios_locked_mem_get_phys_addr(&phw->
650 h_control_cache, &phys_addr);
651 interface->control_cache.physical_address32 =
652 phys_addr;
653 }
654
655 if (!err)
656 pao->has_control_cache = 1;
657 else {
658 if (hpios_locked_mem_valid(&phw->h_control_cache))
659 hpios_locked_mem_free(&phw->h_control_cache);
660 pao->has_control_cache = 0;
661 }
662 }
663 /* allocate bus mastering async buffer and tell the DSP about it */
664 if (interface->async_buffer.b.size) {
665 err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
666 interface->async_buffer.b.size *
667 sizeof(struct hpi_async_event), pao->pci.p_os_data);
668 if (!err)
669 err = hpios_locked_mem_get_virt_addr
670 (&phw->h_async_event_buffer, (void *)
671 &phw->p_async_event_buffer);
672 if (!err)
673 memset((void *)phw->p_async_event_buffer, 0,
674 interface->async_buffer.b.size *
675 sizeof(struct hpi_async_event));
676 if (!err) {
677 err = hpios_locked_mem_get_phys_addr
678 (&phw->h_async_event_buffer, &phys_addr);
679 interface->async_buffer.physical_address32 =
680 phys_addr;
681 }
682 if (err) {
683 if (hpios_locked_mem_valid(&phw->
684 h_async_event_buffer)) {
685 hpios_locked_mem_free
686 (&phw->h_async_event_buffer);
687 phw->p_async_event_buffer = NULL;
688 }
689 }
690 }
691 send_dsp_command(phw, H620_HIF_IDLE);
692
693 {
694 struct hpi_message hM;
695 struct hpi_response hR;
696 u32 max_streams;
697
698 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
699 memset(&hM, 0, sizeof(hM));
700 hM.type = HPI_TYPE_MESSAGE;
701 hM.size = sizeof(hM);
702 hM.object = HPI_OBJ_ADAPTER;
703 hM.function = HPI_ADAPTER_GET_INFO;
704 hM.adapter_index = 0;
705 memset(&hR, 0, sizeof(hR));
706 hR.size = sizeof(hR);
707
708 err = message_response_sequence(pao, &hM, &hR);
709 if (err) {
710 HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
711 err);
712 return err;
713 }
714 if (hR.error)
715 return hR.error;
716
717 pao->adapter_type = hR.u.a.adapter_type;
718 pao->index = hR.u.a.adapter_index;
719
720 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
721
722 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
723 65536, pao->pci.p_os_data);
724
725 HPI_DEBUG_LOG(VERBOSE,
726 "got adapter info type %x index %d serial %d\n",
727 hR.u.a.adapter_type, hR.u.a.adapter_index,
728 hR.u.a.serial_number);
729 }
730
731 pao->open = 0; /* upon creation the adapter is closed */
732
733 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
734 return 0;
735}
736
737/** Free memory areas allocated by adapter
738 * this routine is called from SubSysDeleteAdapter,
739 * and SubSysCreateAdapter if duplicate index
740*/
741static void delete_adapter_obj(struct hpi_adapter_obj *pao)
742{
743 struct hpi_hw_obj *phw;
744 int i;
745
746 phw = pao->priv;
747
748 if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
749 hpios_locked_mem_free(&phw->h_async_event_buffer);
750 phw->p_async_event_buffer = NULL;
751 }
752
753 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
754 hpios_locked_mem_free(&phw->h_control_cache);
755 hpi_free_control_cache(phw->p_cache);
756 }
757
758 if (hpios_locked_mem_valid(&phw->h_locked_mem)) {
759 hpios_locked_mem_free(&phw->h_locked_mem);
760 phw->p_interface_buffer = NULL;
761 }
762
763 for (i = 0; i < HPI_MAX_STREAMS; i++)
764 if (hpios_locked_mem_valid(&phw->instream_host_buffers[i])) {
765 hpios_locked_mem_free(&phw->instream_host_buffers[i]);
766 /*?phw->InStreamHostBuffers[i] = NULL; */
767 phw->instream_host_buffer_size[i] = 0;
768 }
769
770 for (i = 0; i < HPI_MAX_STREAMS; i++)
771 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[i])) {
772 hpios_locked_mem_free(&phw->outstream_host_buffers
773 [i]);
774 phw->outstream_host_buffer_size[i] = 0;
775 }
776
777 hpios_locked_mem_unprepare(pao->pci.p_os_data);
778
779 hpi_delete_adapter(pao);
780 kfree(phw);
781}
782
783/*****************************************************************************/
784/* OutStream Host buffer functions */
785
786/** Allocate or attach buffer for busmastering
787*/
788static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
789 struct hpi_message *phm, struct hpi_response *phr)
790{
791 u16 err = 0;
792 u32 command = phm->u.d.u.buffer.command;
793 struct hpi_hw_obj *phw = pao->priv;
794 struct bus_master_interface *interface = phw->p_interface_buffer;
795
796 hpi_init_response(phr, phm->object, phm->function, 0);
797
798 if (command == HPI_BUFFER_CMD_EXTERNAL
799 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
800 /* ALLOC phase, allocate a buffer with power of 2 size,
801 get its bus address for PCI bus mastering
802 */
803 phm->u.d.u.buffer.buffer_size =
804 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
805 /* return old size and allocated size,
806 so caller can detect change */
807 phr->u.d.u.stream_info.data_available =
808 phw->outstream_host_buffer_size[phm->obj_index];
809 phr->u.d.u.stream_info.buffer_size =
810 phm->u.d.u.buffer.buffer_size;
811
812 if (phw->outstream_host_buffer_size[phm->obj_index] ==
813 phm->u.d.u.buffer.buffer_size) {
814 /* Same size, no action required */
815 return;
816 }
817
818 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
819 obj_index]))
820 hpios_locked_mem_free(&phw->outstream_host_buffers
821 [phm->obj_index]);
822
823 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
824 [phm->obj_index], phm->u.d.u.buffer.buffer_size,
825 pao->pci.p_os_data);
826
827 if (err) {
828 phr->error = HPI_ERROR_INVALID_DATASIZE;
829 phw->outstream_host_buffer_size[phm->obj_index] = 0;
830 return;
831 }
832
833 err = hpios_locked_mem_get_phys_addr
834 (&phw->outstream_host_buffers[phm->obj_index],
835 &phm->u.d.u.buffer.pci_address);
836 /* get the phys addr into msg for single call alloc caller
837 * needs to do this for split alloc (or use the same message)
838 * return the phy address for split alloc in the respose too
839 */
840 phr->u.d.u.stream_info.auxiliary_data_available =
841 phm->u.d.u.buffer.pci_address;
842
843 if (err) {
844 hpios_locked_mem_free(&phw->outstream_host_buffers
845 [phm->obj_index]);
846 phw->outstream_host_buffer_size[phm->obj_index] = 0;
847 phr->error = HPI_ERROR_MEMORY_ALLOC;
848 return;
849 }
850 }
851
852 if (command == HPI_BUFFER_CMD_EXTERNAL
853 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
854 /* GRANT phase. Set up the BBM status, tell the DSP about
855 the buffer so it can start using BBM.
856 */
857 struct hpi_hostbuffer_status *status;
858
859 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
860 buffer_size - 1)) {
861 HPI_DEBUG_LOG(ERROR,
862 "buffer size must be 2^N not %d\n",
863 phm->u.d.u.buffer.buffer_size);
864 phr->error = HPI_ERROR_INVALID_DATASIZE;
865 return;
866 }
867 phw->outstream_host_buffer_size[phm->obj_index] =
868 phm->u.d.u.buffer.buffer_size;
869 status = &interface->outstream_host_buffer_status[phm->
870 obj_index];
871 status->samples_processed = 0;
872 status->stream_state = HPI_STATE_STOPPED;
873 status->dSP_index = 0;
874 status->host_index = status->dSP_index;
875 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
876
877 hw_message(pao, phm, phr);
878
879 if (phr->error
880 && hpios_locked_mem_valid(&phw->
881 outstream_host_buffers[phm->obj_index])) {
882 hpios_locked_mem_free(&phw->outstream_host_buffers
883 [phm->obj_index]);
884 phw->outstream_host_buffer_size[phm->obj_index] = 0;
885 }
886 }
887}
888
889static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
890 struct hpi_message *phm, struct hpi_response *phr)
891{
892 struct hpi_hw_obj *phw = pao->priv;
893 struct bus_master_interface *interface = phw->p_interface_buffer;
894 struct hpi_hostbuffer_status *status;
895 u8 *p_bbm_data;
896
897 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
898 obj_index])) {
899 if (hpios_locked_mem_get_virt_addr(&phw->
900 outstream_host_buffers[phm->obj_index],
901 (void *)&p_bbm_data)) {
902 phr->error = HPI_ERROR_INVALID_OPERATION;
903 return;
904 }
905 status = &interface->outstream_host_buffer_status[phm->
906 obj_index];
907 hpi_init_response(phr, HPI_OBJ_OSTREAM,
908 HPI_OSTREAM_HOSTBUFFER_GET_INFO, 0);
909 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
910 phr->u.d.u.hostbuffer_info.p_status = status;
911 } else {
912 hpi_init_response(phr, HPI_OBJ_OSTREAM,
913 HPI_OSTREAM_HOSTBUFFER_GET_INFO,
914 HPI_ERROR_INVALID_OPERATION);
915 }
916}
917
918static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
919 struct hpi_message *phm, struct hpi_response *phr)
920{
921 struct hpi_hw_obj *phw = pao->priv;
922 u32 command = phm->u.d.u.buffer.command;
923
924 if (phw->outstream_host_buffer_size[phm->obj_index]) {
925 if (command == HPI_BUFFER_CMD_EXTERNAL
926 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
927 phw->outstream_host_buffer_size[phm->obj_index] = 0;
928 hw_message(pao, phm, phr);
929 /* Tell adapter to stop using the host buffer. */
930 }
931 if (command == HPI_BUFFER_CMD_EXTERNAL
932 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
933 hpios_locked_mem_free(&phw->outstream_host_buffers
934 [phm->obj_index]);
935 }
936 /* Should HPI_ERROR_INVALID_OPERATION be returned
937 if no host buffer is allocated? */
938 else
939 hpi_init_response(phr, HPI_OBJ_OSTREAM,
940 HPI_OSTREAM_HOSTBUFFER_FREE, 0);
941
942}
943
2a383cb3 944static u32 outstream_get_space_available(struct hpi_hostbuffer_status
719f82d3
EB
945 *status)
946{
2a383cb3
EB
947 return status->size_in_bytes - (status->host_index -
948 status->dSP_index);
719f82d3
EB
949}
950
951static void outstream_write(struct hpi_adapter_obj *pao,
952 struct hpi_message *phm, struct hpi_response *phr)
953{
954 struct hpi_hw_obj *phw = pao->priv;
955 struct bus_master_interface *interface = phw->p_interface_buffer;
956 struct hpi_hostbuffer_status *status;
2a383cb3 957 u32 space_available;
719f82d3
EB
958
959 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
960 /* there is no BBM buffer, write via message */
961 hw_message(pao, phm, phr);
962 return;
963 }
964
965 hpi_init_response(phr, phm->object, phm->function, 0);
966 status = &interface->outstream_host_buffer_status[phm->obj_index];
967
719f82d3
EB
968 if (phw->flag_outstream_just_reset[phm->obj_index]) {
969 /* First OutStremWrite() call following reset will write data to the
1a59fa7c
EB
970 adapter's buffers, reducing delay before stream can start. The DSP
971 takes care of setting the stream data format using format information
972 embedded in phm.
719f82d3
EB
973 */
974 int partial_write = 0;
975 unsigned int original_size = 0;
976
1a59fa7c
EB
977 phw->flag_outstream_just_reset[phm->obj_index] = 0;
978
719f82d3
EB
979 /* Send the first buffer to the DSP the old way. */
980 /* Limit size of first transfer - */
981 /* expect that this will not usually be triggered. */
982 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
983 partial_write = 1;
984 original_size = phm->u.d.u.data.data_size;
985 phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
986 }
987 /* write it */
988 phm->function = HPI_OSTREAM_WRITE;
989 hw_message(pao, phm, phr);
990 /* update status information that the DSP would typically
991 * update (and will update next time the DSP
992 * buffer update task reads data from the host BBM buffer)
993 */
994 status->auxiliary_data_available = phm->u.d.u.data.data_size;
995 status->host_index += phm->u.d.u.data.data_size;
996 status->dSP_index += phm->u.d.u.data.data_size;
997
998 /* if we did a full write, we can return from here. */
999 if (!partial_write)
1000 return;
1001
1002 /* tweak buffer parameters and let the rest of the */
1003 /* buffer land in internal BBM buffer */
1004 phm->u.d.u.data.data_size =
1005 original_size - HPI6205_SIZEOF_DATA;
1006 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1007 }
719f82d3
EB
1008
1009 space_available = outstream_get_space_available(status);
2a383cb3 1010 if (space_available < phm->u.d.u.data.data_size) {
719f82d3
EB
1011 phr->error = HPI_ERROR_INVALID_DATASIZE;
1012 return;
1013 }
1014
1015 /* HostBuffers is used to indicate host buffer is internally allocated.
1016 otherwise, assumed external, data written externally */
1017 if (phm->u.d.u.data.pb_data
1018 && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
1019 obj_index])) {
1020 u8 *p_bbm_data;
2a383cb3 1021 u32 l_first_write;
719f82d3
EB
1022 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1023
1024 if (hpios_locked_mem_get_virt_addr(&phw->
1025 outstream_host_buffers[phm->obj_index],
1026 (void *)&p_bbm_data)) {
1027 phr->error = HPI_ERROR_INVALID_OPERATION;
1028 return;
1029 }
1030
1031 /* either all data,
1032 or enough to fit from current to end of BBM buffer */
1033 l_first_write =
1034 min(phm->u.d.u.data.data_size,
1035 status->size_in_bytes -
1036 (status->host_index & (status->size_in_bytes - 1)));
1037
1038 memcpy(p_bbm_data +
1039 (status->host_index & (status->size_in_bytes - 1)),
1040 p_app_data, l_first_write);
1041 /* remaining data if any */
1042 memcpy(p_bbm_data, p_app_data + l_first_write,
1043 phm->u.d.u.data.data_size - l_first_write);
1044 }
1045 status->host_index += phm->u.d.u.data.data_size;
1046}
1047
1048static void outstream_get_info(struct hpi_adapter_obj *pao,
1049 struct hpi_message *phm, struct hpi_response *phr)
1050{
1051 struct hpi_hw_obj *phw = pao->priv;
1052 struct bus_master_interface *interface = phw->p_interface_buffer;
1053 struct hpi_hostbuffer_status *status;
1054
1055 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1056 hw_message(pao, phm, phr);
1057 return;
1058 }
1059
1060 hpi_init_response(phr, phm->object, phm->function, 0);
1061
1062 status = &interface->outstream_host_buffer_status[phm->obj_index];
1063
1064 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1065 phr->u.d.u.stream_info.samples_transferred =
1066 status->samples_processed;
1067 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1068 phr->u.d.u.stream_info.data_available =
1069 status->size_in_bytes - outstream_get_space_available(status);
1070 phr->u.d.u.stream_info.auxiliary_data_available =
1071 status->auxiliary_data_available;
1072}
1073
1074static void outstream_start(struct hpi_adapter_obj *pao,
1075 struct hpi_message *phm, struct hpi_response *phr)
1076{
1077 hw_message(pao, phm, phr);
1078}
1079
1080static void outstream_reset(struct hpi_adapter_obj *pao,
1081 struct hpi_message *phm, struct hpi_response *phr)
1082{
1083 struct hpi_hw_obj *phw = pao->priv;
1084 phw->flag_outstream_just_reset[phm->obj_index] = 1;
1085 hw_message(pao, phm, phr);
1086}
1087
1088static void outstream_open(struct hpi_adapter_obj *pao,
1089 struct hpi_message *phm, struct hpi_response *phr)
1090{
1091 outstream_reset(pao, phm, phr);
1092}
1093
1094/*****************************************************************************/
1095/* InStream Host buffer functions */
1096
1097static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1098 struct hpi_message *phm, struct hpi_response *phr)
1099{
1100 u16 err = 0;
1101 u32 command = phm->u.d.u.buffer.command;
1102 struct hpi_hw_obj *phw = pao->priv;
1103 struct bus_master_interface *interface = phw->p_interface_buffer;
1104
1105 hpi_init_response(phr, phm->object, phm->function, 0);
1106
1107 if (command == HPI_BUFFER_CMD_EXTERNAL
1108 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1109
1110 phm->u.d.u.buffer.buffer_size =
1111 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
1112 phr->u.d.u.stream_info.data_available =
1113 phw->instream_host_buffer_size[phm->obj_index];
1114 phr->u.d.u.stream_info.buffer_size =
1115 phm->u.d.u.buffer.buffer_size;
1116
1117 if (phw->instream_host_buffer_size[phm->obj_index] ==
1118 phm->u.d.u.buffer.buffer_size) {
1119 /* Same size, no action required */
1120 return;
1121 }
1122
1123 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1124 obj_index]))
1125 hpios_locked_mem_free(&phw->instream_host_buffers
1126 [phm->obj_index]);
1127
1128 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1129 obj_index], phm->u.d.u.buffer.buffer_size,
1130 pao->pci.p_os_data);
1131
1132 if (err) {
1133 phr->error = HPI_ERROR_INVALID_DATASIZE;
1134 phw->instream_host_buffer_size[phm->obj_index] = 0;
1135 return;
1136 }
1137
1138 err = hpios_locked_mem_get_phys_addr
1139 (&phw->instream_host_buffers[phm->obj_index],
1140 &phm->u.d.u.buffer.pci_address);
1141 /* get the phys addr into msg for single call alloc. Caller
1142 needs to do this for split alloc so return the phy address */
1143 phr->u.d.u.stream_info.auxiliary_data_available =
1144 phm->u.d.u.buffer.pci_address;
1145 if (err) {
1146 hpios_locked_mem_free(&phw->instream_host_buffers
1147 [phm->obj_index]);
1148 phw->instream_host_buffer_size[phm->obj_index] = 0;
1149 phr->error = HPI_ERROR_MEMORY_ALLOC;
1150 return;
1151 }
1152 }
1153
1154 if (command == HPI_BUFFER_CMD_EXTERNAL
1155 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1156 struct hpi_hostbuffer_status *status;
1157
1158 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1159 buffer_size - 1)) {
1160 HPI_DEBUG_LOG(ERROR,
1161 "buffer size must be 2^N not %d\n",
1162 phm->u.d.u.buffer.buffer_size);
1163 phr->error = HPI_ERROR_INVALID_DATASIZE;
1164 return;
1165 }
1166
1167 phw->instream_host_buffer_size[phm->obj_index] =
1168 phm->u.d.u.buffer.buffer_size;
1169 status = &interface->instream_host_buffer_status[phm->
1170 obj_index];
1171 status->samples_processed = 0;
1172 status->stream_state = HPI_STATE_STOPPED;
1173 status->dSP_index = 0;
1174 status->host_index = status->dSP_index;
1175 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1176
1177 hw_message(pao, phm, phr);
1178 if (phr->error
1179 && hpios_locked_mem_valid(&phw->
1180 instream_host_buffers[phm->obj_index])) {
1181 hpios_locked_mem_free(&phw->instream_host_buffers
1182 [phm->obj_index]);
1183 phw->instream_host_buffer_size[phm->obj_index] = 0;
1184 }
1185 }
1186}
1187
1188static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1189 struct hpi_message *phm, struct hpi_response *phr)
1190{
1191 struct hpi_hw_obj *phw = pao->priv;
1192 struct bus_master_interface *interface = phw->p_interface_buffer;
1193 struct hpi_hostbuffer_status *status;
1194 u8 *p_bbm_data;
1195
1196 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1197 obj_index])) {
1198 if (hpios_locked_mem_get_virt_addr(&phw->
1199 instream_host_buffers[phm->obj_index],
1200 (void *)&p_bbm_data)) {
1201 phr->error = HPI_ERROR_INVALID_OPERATION;
1202 return;
1203 }
1204 status = &interface->instream_host_buffer_status[phm->
1205 obj_index];
1206 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1207 HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
1208 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
1209 phr->u.d.u.hostbuffer_info.p_status = status;
1210 } else {
1211 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1212 HPI_ISTREAM_HOSTBUFFER_GET_INFO,
1213 HPI_ERROR_INVALID_OPERATION);
1214 }
1215}
1216
1217static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1218 struct hpi_message *phm, struct hpi_response *phr)
1219{
1220 struct hpi_hw_obj *phw = pao->priv;
1221 u32 command = phm->u.d.u.buffer.command;
1222
1223 if (phw->instream_host_buffer_size[phm->obj_index]) {
1224 if (command == HPI_BUFFER_CMD_EXTERNAL
1225 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
1226 phw->instream_host_buffer_size[phm->obj_index] = 0;
1227 hw_message(pao, phm, phr);
1228 }
1229
1230 if (command == HPI_BUFFER_CMD_EXTERNAL
1231 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
1232 hpios_locked_mem_free(&phw->instream_host_buffers
1233 [phm->obj_index]);
1234
1235 } else {
1236 /* Should HPI_ERROR_INVALID_OPERATION be returned
1237 if no host buffer is allocated? */
1238 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1239 HPI_ISTREAM_HOSTBUFFER_FREE, 0);
1240
1241 }
1242
1243}
1244
1245static void instream_start(struct hpi_adapter_obj *pao,
1246 struct hpi_message *phm, struct hpi_response *phr)
1247{
1248 hw_message(pao, phm, phr);
1249}
1250
2a383cb3 1251static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
719f82d3 1252{
2a383cb3 1253 return status->dSP_index - status->host_index;
719f82d3
EB
1254}
1255
1256static void instream_read(struct hpi_adapter_obj *pao,
1257 struct hpi_message *phm, struct hpi_response *phr)
1258{
1259 struct hpi_hw_obj *phw = pao->priv;
1260 struct bus_master_interface *interface = phw->p_interface_buffer;
1261 struct hpi_hostbuffer_status *status;
2a383cb3 1262 u32 data_available;
719f82d3 1263 u8 *p_bbm_data;
2a383cb3 1264 u32 l_first_read;
719f82d3
EB
1265 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1266
1267 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1268 hw_message(pao, phm, phr);
1269 return;
1270 }
1271 hpi_init_response(phr, phm->object, phm->function, 0);
1272
1273 status = &interface->instream_host_buffer_status[phm->obj_index];
1274 data_available = instream_get_bytes_available(status);
2a383cb3 1275 if (data_available < phm->u.d.u.data.data_size) {
719f82d3
EB
1276 phr->error = HPI_ERROR_INVALID_DATASIZE;
1277 return;
1278 }
1279
1280 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1281 obj_index])) {
1282 if (hpios_locked_mem_get_virt_addr(&phw->
1283 instream_host_buffers[phm->obj_index],
1284 (void *)&p_bbm_data)) {
1285 phr->error = HPI_ERROR_INVALID_OPERATION;
1286 return;
1287 }
1288
1289 /* either all data,
1290 or enough to fit from current to end of BBM buffer */
1291 l_first_read =
1292 min(phm->u.d.u.data.data_size,
1293 status->size_in_bytes -
1294 (status->host_index & (status->size_in_bytes - 1)));
1295
1296 memcpy(p_app_data,
1297 p_bbm_data +
1298 (status->host_index & (status->size_in_bytes - 1)),
1299 l_first_read);
1300 /* remaining data if any */
1301 memcpy(p_app_data + l_first_read, p_bbm_data,
1302 phm->u.d.u.data.data_size - l_first_read);
1303 }
1304 status->host_index += phm->u.d.u.data.data_size;
1305}
1306
1307static void instream_get_info(struct hpi_adapter_obj *pao,
1308 struct hpi_message *phm, struct hpi_response *phr)
1309{
1310 struct hpi_hw_obj *phw = pao->priv;
1311 struct bus_master_interface *interface = phw->p_interface_buffer;
1312 struct hpi_hostbuffer_status *status;
1313 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1314 hw_message(pao, phm, phr);
1315 return;
1316 }
1317
1318 status = &interface->instream_host_buffer_status[phm->obj_index];
1319
1320 hpi_init_response(phr, phm->object, phm->function, 0);
1321
1322 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1323 phr->u.d.u.stream_info.samples_transferred =
1324 status->samples_processed;
1325 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1326 phr->u.d.u.stream_info.data_available =
1327 instream_get_bytes_available(status);
1328 phr->u.d.u.stream_info.auxiliary_data_available =
1329 status->auxiliary_data_available;
1330}
1331
1332/*****************************************************************************/
1333/* LOW-LEVEL */
1334#define HPI6205_MAX_FILES_TO_LOAD 2
1335
1336static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1337 u32 *pos_error_code)
1338{
1339 struct hpi_hw_obj *phw = pao->priv;
1340 struct dsp_code dsp_code;
1341 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1342 u16 firmware_id = pao->pci.subsys_device_id;
1343 u32 temp;
1344 int dsp = 0, i = 0;
1345 u16 err = 0;
1346
1347 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1348
1349 /* special cases where firmware_id != subsys ID */
1350 switch (firmware_id) {
1351 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1352 boot_code_id[0] = firmware_id;
1353 firmware_id = 0;
1354 break;
1355 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1356 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1357 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1358 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400);
1359 break;
1360 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1361 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1362 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600);
1363 break;
cadae428
EB
1364 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1365 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900);
1366 break;
719f82d3
EB
1367 }
1368 boot_code_id[1] = firmware_id;
1369
1370 /* reset DSP by writing a 1 to the WARMRESET bit */
1371 temp = C6205_HDCR_WARMRESET;
1372 iowrite32(temp, phw->prHDCR);
1373 hpios_delay_micro_seconds(1000);
1374
1375 /* check that PCI i/f was configured by EEPROM */
1376 temp = ioread32(phw->prHSR);
1377 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1378 C6205_HSR_EEREAD)
1379 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
1380 temp |= 0x04;
1381 /* disable PINTA interrupt */
1382 iowrite32(temp, phw->prHSR);
1383
1384 /* check control register reports PCI boot mode */
1385 temp = ioread32(phw->prHDCR);
1386 if (!(temp & C6205_HDCR_PCIBOOT))
1387 return hpi6205_error(0, HPI6205_ERROR_6205_REG);
1388
1389 /* try writing a couple of numbers to the DSP page register */
1390 /* and reading them back. */
1391 temp = 1;
1392 iowrite32(temp, phw->prDSPP);
1393 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1394 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1395 temp = 2;
1396 iowrite32(temp, phw->prDSPP);
1397 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1398 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1399 temp = 3;
1400 iowrite32(temp, phw->prDSPP);
1401 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1402 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1403 /* reset DSP page to the correct number */
1404 temp = 0;
1405 iowrite32(temp, phw->prDSPP);
1406 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1407 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1408 phw->dsp_page = 0;
1409
1410 /* release 6713 from reset before 6205 is bootloaded.
1411 This ensures that the EMIF is inactive,
1412 and the 6713 HPI gets the correct bootmode etc
1413 */
1414 if (boot_code_id[1] != 0) {
1415 /* DSP 1 is a C6713 */
1416 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1417 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
1418 hpios_delay_micro_seconds(100);
1419 /* Reset the 6713 #1 - revB */
1420 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
1421
1422 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1423 boot_loader_read_mem32(pao, 0, 0);
1424
1425 hpios_delay_micro_seconds(100);
1426 /* Release C6713 from reset - revB */
1427 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
1428 hpios_delay_micro_seconds(100);
1429 }
1430
1431 for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
1432 /* is there a DSP to load? */
1433 if (boot_code_id[dsp] == 0)
1434 continue;
1435
1436 err = boot_loader_config_emif(pao, dsp);
1437 if (err)
1438 return err;
1439
1440 err = boot_loader_test_internal_memory(pao, dsp);
1441 if (err)
1442 return err;
1443
1444 err = boot_loader_test_external_memory(pao, dsp);
1445 if (err)
1446 return err;
1447
1448 err = boot_loader_test_pld(pao, dsp);
1449 if (err)
1450 return err;
1451
1452 /* write the DSP code down into the DSPs memory */
1453 dsp_code.ps_dev = pao->pci.p_os_data;
1454 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1455 pos_error_code);
1456 if (err)
1457 return err;
1458
1459 while (1) {
1460 u32 length;
1461 u32 address;
1462 u32 type;
1463 u32 *pcode;
1464
1465 err = hpi_dsp_code_read_word(&dsp_code, &length);
1466 if (err)
1467 break;
1468 if (length == 0xFFFFFFFF)
1469 break; /* end of code */
1470
1471 err = hpi_dsp_code_read_word(&dsp_code, &address);
1472 if (err)
1473 break;
1474 err = hpi_dsp_code_read_word(&dsp_code, &type);
1475 if (err)
1476 break;
1477 err = hpi_dsp_code_read_block(length, &dsp_code,
1478 &pcode);
1479 if (err)
1480 break;
1481 for (i = 0; i < (int)length; i++) {
1482 err = boot_loader_write_mem32(pao, dsp,
1483 address, *pcode);
1484 if (err)
1485 break;
1486 /* dummy read every 4 words */
1487 /* for 6205 advisory 1.4.4 */
1488 if (i % 4 == 0)
1489 boot_loader_read_mem32(pao, dsp,
1490 address);
1491 pcode++;
1492 address += 4;
1493 }
1494
1495 }
1496 if (err) {
1497 hpi_dsp_code_close(&dsp_code);
1498 return err;
1499 }
1500
1501 /* verify code */
1502 hpi_dsp_code_rewind(&dsp_code);
1503 while (1) {
1504 u32 length = 0;
1505 u32 address = 0;
1506 u32 type = 0;
1507 u32 *pcode = NULL;
1508 u32 data = 0;
1509
1510 hpi_dsp_code_read_word(&dsp_code, &length);
1511 if (length == 0xFFFFFFFF)
1512 break; /* end of code */
1513
1514 hpi_dsp_code_read_word(&dsp_code, &address);
1515 hpi_dsp_code_read_word(&dsp_code, &type);
1516 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1517
1518 for (i = 0; i < (int)length; i++) {
1519 data = boot_loader_read_mem32(pao, dsp,
1520 address);
1521 if (data != *pcode) {
1522 err = 0;
1523 break;
1524 }
1525 pcode++;
1526 address += 4;
1527 }
1528 if (err)
1529 break;
1530 }
1531 hpi_dsp_code_close(&dsp_code);
1532 if (err)
1533 return err;
1534 }
1535
1536 /* After bootloading all DSPs, start DSP0 running
1537 * The DSP0 code will handle starting and synchronizing with its slaves
1538 */
1539 if (phw->p_interface_buffer) {
1540 /* we need to tell the card the physical PCI address */
1541 u32 physicalPC_iaddress;
1542 struct bus_master_interface *interface =
1543 phw->p_interface_buffer;
1544 u32 host_mailbox_address_on_dsp;
1545 u32 physicalPC_iaddress_verify = 0;
1546 int time_out = 10;
1547 /* set ack so we know when DSP is ready to go */
1548 /* (dwDspAck will be changed to HIF_RESET) */
1549 interface->dsp_ack = H620_HIF_UNKNOWN;
1550 wmb(); /* ensure ack is written before dsp writes back */
1551
1552 err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1553 &physicalPC_iaddress);
1554
1555 /* locate the host mailbox on the DSP. */
1556 host_mailbox_address_on_dsp = 0x80000000;
1557 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1558 && time_out--) {
1559 err = boot_loader_write_mem32(pao, 0,
1560 host_mailbox_address_on_dsp,
1561 physicalPC_iaddress);
1562 physicalPC_iaddress_verify =
1563 boot_loader_read_mem32(pao, 0,
1564 host_mailbox_address_on_dsp);
1565 }
1566 }
1567 HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
1568 /* enable interrupts */
1569 temp = ioread32(phw->prHSR);
1570 temp &= ~(u32)C6205_HSR_INTAM;
1571 iowrite32(temp, phw->prHSR);
1572
1573 /* start code running... */
1574 temp = ioread32(phw->prHDCR);
1575 temp |= (u32)C6205_HDCR_DSPINT;
1576 iowrite32(temp, phw->prHDCR);
1577
1578 /* give the DSP 10ms to start up */
1579 hpios_delay_micro_seconds(10000);
1580 return err;
1581
1582}
1583
1584/*****************************************************************************/
1585/* Bootloader utility functions */
1586
1587static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1588 u32 address)
1589{
1590 struct hpi_hw_obj *phw = pao->priv;
1591 u32 data = 0;
1592 __iomem u32 *p_data;
1593
1594 if (dsp_index == 0) {
1595 /* DSP 0 is always C6205 */
1596 if ((address >= 0x01800000) & (address < 0x02000000)) {
1597 /* BAR1 register access */
1598 p_data = pao->pci.ap_mem_base[1] +
1599 (address & 0x007fffff) /
1600 sizeof(*pao->pci.ap_mem_base[1]);
1601 /* HPI_DEBUG_LOG(WARNING,
1602 "BAR1 access %08x\n", dwAddress); */
1603 } else {
1604 u32 dw4M_page = address >> 22L;
1605 if (dw4M_page != phw->dsp_page) {
1606 phw->dsp_page = dw4M_page;
1607 /* *INDENT OFF* */
1608 iowrite32(phw->dsp_page, phw->prDSPP);
1609 /* *INDENT-ON* */
1610 }
1611 address &= 0x3fffff; /* address within 4M page */
1612 /* BAR0 memory access */
1613 p_data = pao->pci.ap_mem_base[0] +
1614 address / sizeof(u32);
1615 }
1616 data = ioread32(p_data);
1617 } else if (dsp_index == 1) {
1618 /* DSP 1 is a C6713 */
1619 u32 lsb;
1620 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1621 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1622 lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
1623 data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
1624 data = (data << 16) | (lsb & 0xFFFF);
1625 }
1626 return data;
1627}
1628
1629static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1630 u32 address, u32 data)
1631{
1632 struct hpi_hw_obj *phw = pao->priv;
1633 u16 err = 0;
1634 __iomem u32 *p_data;
1635 /* u32 dwVerifyData=0; */
1636
1637 if (dsp_index == 0) {
1638 /* DSP 0 is always C6205 */
1639 if ((address >= 0x01800000) & (address < 0x02000000)) {
1640 /* BAR1 - DSP register access using */
1641 /* Non-prefetchable PCI access */
1642 p_data = pao->pci.ap_mem_base[1] +
1643 (address & 0x007fffff) /
1644 sizeof(*pao->pci.ap_mem_base[1]);
1645 } else {
1646 /* BAR0 access - all of DSP memory using */
1647 /* pre-fetchable PCI access */
1648 u32 dw4M_page = address >> 22L;
1649 if (dw4M_page != phw->dsp_page) {
1650 phw->dsp_page = dw4M_page;
1651 /* *INDENT-OFF* */
1652 iowrite32(phw->dsp_page, phw->prDSPP);
1653 /* *INDENT-ON* */
1654 }
1655 address &= 0x3fffff; /* address within 4M page */
1656 p_data = pao->pci.ap_mem_base[0] +
1657 address / sizeof(u32);
1658 }
1659 iowrite32(data, p_data);
1660 } else if (dsp_index == 1) {
1661 /* DSP 1 is a C6713 */
1662 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1663 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1664
1665 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1666 boot_loader_read_mem32(pao, 0, 0);
1667
1668 boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1669 boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1670
1671 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1672 boot_loader_read_mem32(pao, 0, 0);
1673 } else
1674 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1675 return err;
1676}
1677
1678static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1679{
1680 u16 err = 0;
1681
1682 if (dsp_index == 0) {
1683 u32 setting;
1684
1685 /* DSP 0 is always C6205 */
1686
1687 /* Set the EMIF */
1688 /* memory map of C6205 */
1689 /* 00000000-0000FFFF 16Kx32 internal program */
1690 /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
1691
1692 /* EMIF config */
1693 /*------------ */
1694 /* Global EMIF control */
1695 boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
1696#define WS_OFS 28
1697#define WST_OFS 22
1698#define WH_OFS 20
1699#define RS_OFS 16
1700#define RST_OFS 8
1701#define MTYPE_OFS 4
1702#define RH_OFS 0
1703
1704 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1705 setting = 0x00000030;
1706 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1707 if (setting != boot_loader_read_mem32(pao, dsp_index,
1708 0x01800008))
1709 return hpi6205_error(dsp_index,
1710 HPI6205_ERROR_DSP_EMIF);
1711
1712 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1713 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1714 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1715 /* WST should be 71, but 63 is max possible */
1716 setting =
1717 (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
1718 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1719 (2L << MTYPE_OFS);
1720 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1721 if (setting != boot_loader_read_mem32(pao, dsp_index,
1722 0x01800004))
1723 return hpi6205_error(dsp_index,
1724 HPI6205_ERROR_DSP_EMIF);
1725
1726 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1727 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1728 /* plenty of wait states */
1729 setting =
1730 (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
1731 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1732 (2L << MTYPE_OFS);
1733 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1734 if (setting != boot_loader_read_mem32(pao, dsp_index,
1735 0x01800010))
1736 return hpi6205_error(dsp_index,
1737 HPI6205_ERROR_DSP_EMIF);
1738
1739 /* EMIF CE3 setup - 32 bit async. */
1740 /* This is the PLD on the ASI5000 cards only */
1741 setting =
1742 (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
1743 (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
1744 (2L << MTYPE_OFS);
1745 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1746 if (setting != boot_loader_read_mem32(pao, dsp_index,
1747 0x01800014))
1748 return hpi6205_error(dsp_index,
1749 HPI6205_ERROR_DSP_EMIF);
1750
1751 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1752 /* need to use this else DSP code crashes? */
1753 boot_loader_write_mem32(pao, dsp_index, 0x01800018,
1754 0x07117000);
1755
1756 /* EMIF SDRAM Refresh Timing */
1757 /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
1758 boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1759 0x00000410);
1760
1761 } else if (dsp_index == 1) {
1762 /* test access to the C6713s HPI registers */
1763 u32 write_data = 0, read_data = 0, i = 0;
1764
1765 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1766 write_data = 1;
1767 boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
1768 boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
1769 /* C67 HPI is on lower 16bits of 32bit EMIF */
1770 read_data =
1771 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1772 if (write_data != read_data) {
1773 err = hpi6205_error(dsp_index,
1774 HPI6205_ERROR_C6713_HPIC);
1775 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1776 read_data);
1777
1778 return err;
1779 }
1780 /* HPIA - walking ones test */
1781 write_data = 1;
1782 for (i = 0; i < 32; i++) {
1783 boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
1784 write_data);
1785 boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
1786 (write_data >> 16));
1787 read_data =
1788 0xFFFF & boot_loader_read_mem32(pao, 0,
1789 HPIAL_ADDR);
1790 read_data =
1791 read_data | ((0xFFFF &
1792 boot_loader_read_mem32(pao, 0,
1793 HPIAH_ADDR))
1794 << 16);
1795 if (read_data != write_data) {
1796 err = hpi6205_error(dsp_index,
1797 HPI6205_ERROR_C6713_HPIA);
1798 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1799 write_data, read_data);
1800 return err;
1801 }
1802 write_data = write_data << 1;
1803 }
1804
1805 /* setup C67x PLL
1806 * ** C6713 datasheet says we cannot program PLL from HPI,
1807 * and indeed if we try to set the PLL multiply from the HPI,
1808 * the PLL does not seem to lock, so we enable the PLL and
1809 * use the default multiply of x 7, which for a 27MHz clock
1810 * gives a DSP speed of 189MHz
1811 */
1812 /* bypass PLL */
1813 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
1814 hpios_delay_micro_seconds(1000);
1815 /* EMIF = 189/3=63MHz */
1816 boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
1817 /* peri = 189/2 */
1818 boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
1819 /* cpu = 189/1 */
1820 boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
1821 hpios_delay_micro_seconds(1000);
1822 /* ** SGT test to take GPO3 high when we start the PLL */
1823 /* and low when the delay is completed */
1824 /* FSX0 <- '1' (GPO3) */
1825 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
1826 /* PLL not bypassed */
1827 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
1828 hpios_delay_micro_seconds(1000);
1829 /* FSX0 <- '0' (GPO3) */
1830 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
1831
1832 /* 6205 EMIF CE1 resetup - 32 bit async. */
1833 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1834 boot_loader_write_mem32(pao, 0, 0x01800004, /* CE1 */
1835 (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
1836 (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
1837 (2L << MTYPE_OFS));
1838
1839 hpios_delay_micro_seconds(1000);
1840
1841 /* check that we can read one of the PLL registers */
1842 /* PLL should not be bypassed! */
1843 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1844 != 0x0001) {
1845 err = hpi6205_error(dsp_index,
1846 HPI6205_ERROR_C6713_PLL);
1847 return err;
1848 }
1849 /* setup C67x EMIF (note this is the only use of
1850 BAR1 via BootLoader_WriteMem32) */
1851 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1852 0x000034A8);
1853 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1854 0x00000030);
1855 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1856 0x001BDF29);
1857 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1858 0x47117000);
1859 boot_loader_write_mem32(pao, dsp_index,
1860 C6713_EMIF_SDRAMTIMING, 0x00000410);
1861
1862 hpios_delay_micro_seconds(1000);
1863 } else if (dsp_index == 2) {
1864 /* DSP 2 is a C6713 */
1865
1866 } else
1867 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1868 return err;
1869}
1870
1871static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1872 u32 start_address, u32 length)
1873{
1874 u32 i = 0, j = 0;
1875 u32 test_addr = 0;
1876 u32 test_data = 0, data = 0;
1877
1878 length = 1000;
1879
1880 /* for 1st word, test each bit in the 32bit word, */
1881 /* dwLength specifies number of 32bit words to test */
1882 /*for(i=0; i<dwLength; i++) */
1883 i = 0;
1884 {
1885 test_addr = start_address + i * 4;
1886 test_data = 0x00000001;
1887 for (j = 0; j < 32; j++) {
1888 boot_loader_write_mem32(pao, dsp_index, test_addr,
1889 test_data);
1890 data = boot_loader_read_mem32(pao, dsp_index,
1891 test_addr);
1892 if (data != test_data) {
1893 HPI_DEBUG_LOG(VERBOSE,
1894 "memtest error details "
1895 "%08x %08x %08x %i\n", test_addr,
1896 test_data, data, dsp_index);
1897 return 1; /* error */
1898 }
1899 test_data = test_data << 1;
1900 } /* for(j) */
1901 } /* for(i) */
1902
1903 /* for the next 100 locations test each location, leaving it as zero */
1904 /* write a zero to the next word in memory before we read */
1905 /* the previous write to make sure every memory location is unique */
1906 for (i = 0; i < 100; i++) {
1907 test_addr = start_address + i * 4;
1908 test_data = 0xA5A55A5A;
1909 boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
1910 boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
1911 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1912 if (data != test_data) {
1913 HPI_DEBUG_LOG(VERBOSE,
1914 "memtest error details "
1915 "%08x %08x %08x %i\n", test_addr, test_data,
1916 data, dsp_index);
1917 return 1; /* error */
1918 }
1919 /* leave location as zero */
1920 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1921 }
1922
1923 /* zero out entire memory block */
1924 for (i = 0; i < length; i++) {
1925 test_addr = start_address + i * 4;
1926 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1927 }
1928 return 0;
1929}
1930
1931static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1932 int dsp_index)
1933{
1934 int err = 0;
1935 if (dsp_index == 0) {
1936 /* DSP 0 is a C6205 */
1937 /* 64K prog mem */
1938 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1939 0x10000);
1940 if (!err)
1941 /* 64K data mem */
1942 err = boot_loader_test_memory(pao, dsp_index,
1943 0x80000000, 0x10000);
1944 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1945 /* DSP 1&2 are a C6713 */
1946 /* 192K internal mem */
1947 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1948 0x30000);
1949 if (!err)
1950 /* 64K internal mem / L2 cache */
1951 err = boot_loader_test_memory(pao, dsp_index,
1952 0x00030000, 0x10000);
1953 } else
1954 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1955
1956 if (err)
1957 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1958 else
1959 return 0;
1960}
1961
1962static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1963 int dsp_index)
1964{
1965 u32 dRAM_start_address = 0;
1966 u32 dRAM_size = 0;
1967
1968 if (dsp_index == 0) {
1969 /* only test for SDRAM if an ASI5000 card */
1970 if (pao->pci.subsys_device_id == 0x5000) {
1971 /* DSP 0 is always C6205 */
1972 dRAM_start_address = 0x00400000;
1973 dRAM_size = 0x200000;
1974 /*dwDRAMinc=1024; */
1975 } else
1976 return 0;
1977 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1978 /* DSP 1 is a C6713 */
1979 dRAM_start_address = 0x80000000;
1980 dRAM_size = 0x200000;
1981 /*dwDRAMinc=1024; */
1982 } else
1983 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1984
1985 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1986 dRAM_size))
1987 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
1988 return 0;
1989}
1990
1991static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1992{
1993 u32 data = 0;
1994 if (dsp_index == 0) {
1995 /* only test for DSP0 PLD on ASI5000 card */
1996 if (pao->pci.subsys_device_id == 0x5000) {
1997 /* PLD is located at CE3=0x03000000 */
1998 data = boot_loader_read_mem32(pao, dsp_index,
1999 0x03000008);
2000 if ((data & 0xF) != 0x5)
2001 return hpi6205_error(dsp_index,
2002 HPI6205_ERROR_DSP_PLD);
2003 data = boot_loader_read_mem32(pao, dsp_index,
2004 0x0300000C);
2005 if ((data & 0xF) != 0xA)
2006 return hpi6205_error(dsp_index,
2007 HPI6205_ERROR_DSP_PLD);
2008 }
2009 } else if (dsp_index == 1) {
2010 /* DSP 1 is a C6713 */
2011 if (pao->pci.subsys_device_id == 0x8700) {
2012 /* PLD is located at CE1=0x90000000 */
2013 data = boot_loader_read_mem32(pao, dsp_index,
2014 0x90000010);
2015 if ((data & 0xFF) != 0xAA)
2016 return hpi6205_error(dsp_index,
2017 HPI6205_ERROR_DSP_PLD);
2018 /* 8713 - LED on */
2019 boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2020 0x02);
2021 }
2022 }
2023 return 0;
2024}
2025
2026/** Transfer data to or from DSP
2027 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2028*/
2029static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2030 u32 data_size, int operation)
2031{
2032 struct hpi_hw_obj *phw = pao->priv;
2033 u32 data_transferred = 0;
2034 u16 err = 0;
2035#ifndef HPI6205_NO_HSR_POLL
2036 u32 time_out;
2037#endif
2038 u32 temp2;
2039 struct bus_master_interface *interface = phw->p_interface_buffer;
2040
2041 if (!p_data)
2042 return HPI_ERROR_INVALID_DATA_TRANSFER;
2043
2044 data_size &= ~3L; /* round data_size down to nearest 4 bytes */
2045
2046 /* make sure state is IDLE */
2047 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2048 return HPI_ERROR_DSP_HARDWARE;
2049
2050 while (data_transferred < data_size) {
2051 u32 this_copy = data_size - data_transferred;
2052
2053 if (this_copy > HPI6205_SIZEOF_DATA)
2054 this_copy = HPI6205_SIZEOF_DATA;
2055
2056 if (operation == H620_HIF_SEND_DATA)
2057 memcpy((void *)&interface->u.b_data[0],
2058 &p_data[data_transferred], this_copy);
2059
2060 interface->transfer_size_in_bytes = this_copy;
2061
2062#ifdef HPI6205_NO_HSR_POLL
2063 /* DSP must change this back to nOperation */
2064 interface->dsp_ack = H620_HIF_IDLE;
2065#endif
2066
2067 send_dsp_command(phw, operation);
2068
2069#ifdef HPI6205_NO_HSR_POLL
2070 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2071 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2072 HPI6205_TIMEOUT - temp2, this_copy);
2073
2074 if (!temp2) {
2075 /* timed out */
2076 HPI_DEBUG_LOG(ERROR,
2077 "timed out waiting for " "state %d got %d\n",
2078 operation, interface->dsp_ack);
2079
2080 break;
2081 }
2082#else
2083 /* spin waiting on the result */
2084 time_out = HPI6205_TIMEOUT;
2085 temp2 = 0;
2086 while ((temp2 == 0) && time_out--) {
2087 /* give 16k bus mastering transfer time to happen */
2088 /*(16k / 132Mbytes/s = 122usec) */
2089 hpios_delay_micro_seconds(20);
2090 temp2 = ioread32(phw->prHSR);
2091 temp2 &= C6205_HSR_INTSRC;
2092 }
2093 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2094 HPI6205_TIMEOUT - time_out, this_copy);
2095 if (temp2 == C6205_HSR_INTSRC) {
2096 HPI_DEBUG_LOG(VERBOSE,
2097 "interrupt from HIF <data> OK\n");
2098 /*
2099 if(interface->dwDspAck != nOperation) {
2100 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2101 expected %d \n",
2102 interface->dwDspAck,nOperation);
2103 }
2104 */
2105 }
2106/* need to handle this differently... */
2107 else {
2108 HPI_DEBUG_LOG(ERROR,
2109 "interrupt from HIF <data> BAD\n");
2110 err = HPI_ERROR_DSP_HARDWARE;
2111 }
2112
2113 /* reset the interrupt from the DSP */
2114 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2115#endif
2116 if (operation == H620_HIF_GET_DATA)
2117 memcpy(&p_data[data_transferred],
2118 (void *)&interface->u.b_data[0], this_copy);
2119
2120 data_transferred += this_copy;
2121 }
2122 if (interface->dsp_ack != operation)
2123 HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
2124 interface->dsp_ack, operation);
2125 /* err=HPI_ERROR_DSP_HARDWARE; */
2126
2127 send_dsp_command(phw, H620_HIF_IDLE);
2128
2129 return err;
2130}
2131
2132/* wait for up to timeout_us microseconds for the DSP
2133 to signal state by DMA into dwDspAck
2134*/
2135static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2136{
2137 struct bus_master_interface *interface = phw->p_interface_buffer;
2138 int t = timeout_us / 4;
2139
2140 rmb(); /* ensure interface->dsp_ack is up to date */
2141 while ((interface->dsp_ack != state) && --t) {
2142 hpios_delay_micro_seconds(4);
2143 rmb(); /* DSP changes dsp_ack by DMA */
2144 }
2145
2146 /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2147 return t * 4;
2148}
2149
2150/* set the busmaster interface to cmd, then interrupt the DSP */
2151static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2152{
2153 struct bus_master_interface *interface = phw->p_interface_buffer;
2154
2155 u32 r;
2156
2157 interface->host_cmd = cmd;
2158 wmb(); /* DSP gets state by DMA, make sure it is written to memory */
2159 /* before we interrupt the DSP */
2160 r = ioread32(phw->prHDCR);
2161 r |= (u32)C6205_HDCR_DSPINT;
2162 iowrite32(r, phw->prHDCR);
2163 r &= ~(u32)C6205_HDCR_DSPINT;
2164 iowrite32(r, phw->prHDCR);
2165}
2166
2167static unsigned int message_count;
2168
2169static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2170 struct hpi_message *phm, struct hpi_response *phr)
2171{
2172#ifndef HPI6205_NO_HSR_POLL
2173 u32 temp2;
2174#endif
2175 u32 time_out, time_out2;
2176 struct hpi_hw_obj *phw = pao->priv;
2177 struct bus_master_interface *interface = phw->p_interface_buffer;
2178 u16 err = 0;
2179
2180 message_count++;
2181 /* Assume buffer of type struct bus_master_interface
2182 is allocated "noncacheable" */
2183
2184 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2185 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2186 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2187 }
2188 interface->u.message_buffer = *phm;
2189 /* signal we want a response */
2190 send_dsp_command(phw, H620_HIF_GET_RESP);
2191
2192 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2193
2194 if (time_out2 == 0) {
2195 HPI_DEBUG_LOG(ERROR,
2196 "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2197 message_count, interface->dsp_ack);
2198 } else {
2199 HPI_DEBUG_LOG(VERBOSE,
2200 "(%u) transition to GET_RESP after %u\n",
2201 message_count, HPI6205_TIMEOUT - time_out2);
2202 }
2203 /* spin waiting on HIF interrupt flag (end of msg process) */
2204 time_out = HPI6205_TIMEOUT;
2205
2206#ifndef HPI6205_NO_HSR_POLL
2207 temp2 = 0;
2208 while ((temp2 == 0) && --time_out) {
2209 temp2 = ioread32(phw->prHSR);
2210 temp2 &= C6205_HSR_INTSRC;
2211 hpios_delay_micro_seconds(1);
2212 }
2213 if (temp2 == C6205_HSR_INTSRC) {
2214 rmb(); /* ensure we see latest value for dsp_ack */
2215 if ((interface->dsp_ack != H620_HIF_GET_RESP)) {
2216 HPI_DEBUG_LOG(DEBUG,
2217 "(%u)interface->dsp_ack(0x%x) != "
2218 "H620_HIF_GET_RESP, t=%u\n", message_count,
2219 interface->dsp_ack,
2220 HPI6205_TIMEOUT - time_out);
2221 } else {
2222 HPI_DEBUG_LOG(VERBOSE,
2223 "(%u)int with GET_RESP after %u\n",
2224 message_count, HPI6205_TIMEOUT - time_out);
2225 }
2226
2227 } else {
2228 /* can we do anything else in response to the error ? */
2229 HPI_DEBUG_LOG(ERROR,
2230 "interrupt from HIF module BAD (function %x)\n",
2231 phm->function);
2232 }
2233
2234 /* reset the interrupt from the DSP */
2235 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2236#endif
2237
2238 /* read the result */
2239 if (time_out != 0)
2240 *phr = interface->u.response_buffer;
2241
2242 /* set interface back to idle */
2243 send_dsp_command(phw, H620_HIF_IDLE);
2244
2245 if ((time_out == 0) || (time_out2 == 0)) {
2246 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2247 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
2248 }
2249 /* special case for adapter close - */
2250 /* wait for the DSP to indicate it is idle */
2251 if (phm->function == HPI_ADAPTER_CLOSE) {
2252 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2253 HPI_DEBUG_LOG(DEBUG,
2254 "timeout waiting for idle "
2255 "(on adapter_close)\n");
2256 return hpi6205_error(0,
2257 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2258 }
2259 }
2260 err = hpi_validate_response(phm, phr);
2261 return err;
2262}
2263
2264static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2265 struct hpi_response *phr)
2266{
2267
2268 u16 err = 0;
2269
2270 hpios_dsplock_lock(pao);
2271
2272 err = message_response_sequence(pao, phm, phr);
2273
2274 /* maybe an error response */
2275 if (err) {
2276 /* something failed in the HPI/DSP interface */
2277 phr->error = err;
2278 pao->dsp_crashed++;
2279
2280 /* just the header of the response is valid */
2281 phr->size = sizeof(struct hpi_response_header);
2282 goto err;
2283 } else
2284 pao->dsp_crashed = 0;
2285
2286 if (phr->error != 0) /* something failed in the DSP */
2287 goto err;
2288
2289 switch (phm->function) {
2290 case HPI_OSTREAM_WRITE:
2291 case HPI_ISTREAM_ANC_WRITE:
2292 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2293 phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
2294 break;
2295
2296 case HPI_ISTREAM_READ:
2297 case HPI_OSTREAM_ANC_READ:
2298 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2299 phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2300 break;
2301
2302 case HPI_CONTROL_SET_STATE:
2303 if (phm->object == HPI_OBJ_CONTROLEX
2304 && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2305 err = hpi6205_transfer_data(pao,
2306 phm->u.cx.u.cobranet_bigdata.pb_data,
2307 phm->u.cx.u.cobranet_bigdata.byte_count,
2308 H620_HIF_SEND_DATA);
2309 break;
2310
2311 case HPI_CONTROL_GET_STATE:
2312 if (phm->object == HPI_OBJ_CONTROLEX
2313 && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2314 err = hpi6205_transfer_data(pao,
2315 phm->u.cx.u.cobranet_bigdata.pb_data,
2316 phr->u.cx.u.cobranet_data.byte_count,
2317 H620_HIF_GET_DATA);
2318 break;
2319 }
2320 phr->error = err;
2321
2322err:
2323 hpios_dsplock_unlock(pao);
2324
2325 return;
2326}