1 /******************************************************************************
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
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;
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.
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
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
26 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
28 (C) Copyright AudioScience Inc. 1998-2010
29 *******************************************************************************/
30 #define SOURCEFILE_NAME "hpi6205.c"
32 #include "hpi_internal.h"
33 #include "hpimsginit.h"
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
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
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
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)
89 /* used to control LED (revA) and reset C6713 (revB) */
90 #define C6205_BAR0_TIMER1_CTL (0x01980000L)
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
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
119 struct consistent_dma_area h_locked_mem
;
120 struct bus_master_interface
*p_interface_buffer
;
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
];
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
;
137 /*****************************************************************************/
138 /* local prototypes */
140 #define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
142 static int wait_dsp_ack(struct hpi_hw_obj
*phw
, int state
, int timeout_us
);
144 static void send_dsp_command(struct hpi_hw_obj
*phw
, int cmd
);
146 static u16
adapter_boot_load_dsp(struct hpi_adapter_obj
*pao
,
147 u32
*pos_error_code
);
149 static u16
message_response_sequence(struct hpi_adapter_obj
*pao
,
150 struct hpi_message
*phm
, struct hpi_response
*phr
);
152 static void hw_message(struct hpi_adapter_obj
*pao
, struct hpi_message
*phm
,
153 struct hpi_response
*phr
);
155 #define HPI6205_TIMEOUT 1000000
157 static void subsys_create_adapter(struct hpi_message
*phm
,
158 struct hpi_response
*phr
);
159 static void subsys_delete_adapter(struct hpi_message
*phm
,
160 struct hpi_response
*phr
);
162 static u16
create_adapter_obj(struct hpi_adapter_obj
*pao
,
163 u32
*pos_error_code
);
165 static void delete_adapter_obj(struct hpi_adapter_obj
*pao
);
167 static void outstream_host_buffer_allocate(struct hpi_adapter_obj
*pao
,
168 struct hpi_message
*phm
, struct hpi_response
*phr
);
170 static void outstream_host_buffer_get_info(struct hpi_adapter_obj
*pao
,
171 struct hpi_message
*phm
, struct hpi_response
*phr
);
173 static void outstream_host_buffer_free(struct hpi_adapter_obj
*pao
,
174 struct hpi_message
*phm
, struct hpi_response
*phr
);
175 static void outstream_write(struct hpi_adapter_obj
*pao
,
176 struct hpi_message
*phm
, struct hpi_response
*phr
);
178 static void outstream_get_info(struct hpi_adapter_obj
*pao
,
179 struct hpi_message
*phm
, struct hpi_response
*phr
);
181 static void outstream_start(struct hpi_adapter_obj
*pao
,
182 struct hpi_message
*phm
, struct hpi_response
*phr
);
184 static void outstream_open(struct hpi_adapter_obj
*pao
,
185 struct hpi_message
*phm
, struct hpi_response
*phr
);
187 static void outstream_reset(struct hpi_adapter_obj
*pao
,
188 struct hpi_message
*phm
, struct hpi_response
*phr
);
190 static void instream_host_buffer_allocate(struct hpi_adapter_obj
*pao
,
191 struct hpi_message
*phm
, struct hpi_response
*phr
);
193 static void instream_host_buffer_get_info(struct hpi_adapter_obj
*pao
,
194 struct hpi_message
*phm
, struct hpi_response
*phr
);
196 static void instream_host_buffer_free(struct hpi_adapter_obj
*pao
,
197 struct hpi_message
*phm
, struct hpi_response
*phr
);
199 static void instream_read(struct hpi_adapter_obj
*pao
,
200 struct hpi_message
*phm
, struct hpi_response
*phr
);
202 static void instream_get_info(struct hpi_adapter_obj
*pao
,
203 struct hpi_message
*phm
, struct hpi_response
*phr
);
205 static void instream_start(struct hpi_adapter_obj
*pao
,
206 struct hpi_message
*phm
, struct hpi_response
*phr
);
208 static u32
boot_loader_read_mem32(struct hpi_adapter_obj
*pao
, int dsp_index
,
211 static u16
boot_loader_write_mem32(struct hpi_adapter_obj
*pao
, int dsp_index
,
212 u32 address
, u32 data
);
214 static u16
boot_loader_config_emif(struct hpi_adapter_obj
*pao
,
217 static u16
boot_loader_test_memory(struct hpi_adapter_obj
*pao
, int dsp_index
,
218 u32 address
, u32 length
);
220 static u16
boot_loader_test_internal_memory(struct hpi_adapter_obj
*pao
,
223 static u16
boot_loader_test_external_memory(struct hpi_adapter_obj
*pao
,
226 static u16
boot_loader_test_pld(struct hpi_adapter_obj
*pao
, int dsp_index
);
228 /*****************************************************************************/
230 static void subsys_message(struct hpi_message
*phm
, struct hpi_response
*phr
)
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
;
243 case HPI_SUBSYS_CREATE_ADAPTER
:
244 subsys_create_adapter(phm
, phr
);
246 case HPI_SUBSYS_DELETE_ADAPTER
:
247 subsys_delete_adapter(phm
, phr
);
250 phr
->error
= HPI_ERROR_INVALID_FUNC
;
255 static void control_message(struct hpi_adapter_obj
*pao
,
256 struct hpi_message
*phm
, struct hpi_response
*phr
)
259 struct hpi_hw_obj
*phw
= pao
->priv
;
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
))
268 hw_message(pao
, phm
, phr
);
270 case HPI_CONTROL_GET_INFO
:
271 hw_message(pao
, phm
, phr
);
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
);
279 phr
->error
= HPI_ERROR_INVALID_FUNC
;
284 static void adapter_message(struct hpi_adapter_obj
*pao
,
285 struct hpi_message
*phm
, struct hpi_response
*phr
)
287 switch (phm
->function
) {
289 hw_message(pao
, phm
, phr
);
294 static void outstream_message(struct hpi_adapter_obj
*pao
,
295 struct hpi_message
*phm
, struct hpi_response
*phr
)
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
,
307 switch (phm
->function
) {
308 case HPI_OSTREAM_WRITE
:
309 outstream_write(pao
, phm
, phr
);
311 case HPI_OSTREAM_GET_INFO
:
312 outstream_get_info(pao
, phm
, phr
);
314 case HPI_OSTREAM_HOSTBUFFER_ALLOC
:
315 outstream_host_buffer_allocate(pao
, phm
, phr
);
317 case HPI_OSTREAM_HOSTBUFFER_GET_INFO
:
318 outstream_host_buffer_get_info(pao
, phm
, phr
);
320 case HPI_OSTREAM_HOSTBUFFER_FREE
:
321 outstream_host_buffer_free(pao
, phm
, phr
);
323 case HPI_OSTREAM_START
:
324 outstream_start(pao
, phm
, phr
);
326 case HPI_OSTREAM_OPEN
:
327 outstream_open(pao
, phm
, phr
);
329 case HPI_OSTREAM_RESET
:
330 outstream_reset(pao
, phm
, phr
);
333 hw_message(pao
, phm
, phr
);
338 static void instream_message(struct hpi_adapter_obj
*pao
,
339 struct hpi_message
*phm
, struct hpi_response
*phr
)
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
,
351 switch (phm
->function
) {
352 case HPI_ISTREAM_READ
:
353 instream_read(pao
, phm
, phr
);
355 case HPI_ISTREAM_GET_INFO
:
356 instream_get_info(pao
, phm
, phr
);
358 case HPI_ISTREAM_HOSTBUFFER_ALLOC
:
359 instream_host_buffer_allocate(pao
, phm
, phr
);
361 case HPI_ISTREAM_HOSTBUFFER_GET_INFO
:
362 instream_host_buffer_get_info(pao
, phm
, phr
);
364 case HPI_ISTREAM_HOSTBUFFER_FREE
:
365 instream_host_buffer_free(pao
, phm
, phr
);
367 case HPI_ISTREAM_START
:
368 instream_start(pao
, phm
, phr
);
371 hw_message(pao
, phm
, phr
);
376 /*****************************************************************************/
377 /** Entry point to this HPI backend
378 * All calls to the HPI start here
380 void HPI_6205(struct hpi_message
*phm
, struct hpi_response
*phr
)
382 struct hpi_adapter_obj
*pao
= NULL
;
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
388 HPI_DEBUG_LOG(DEBUG
, "HPI obj=%d, func=%d\n", phm
->object
,
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
);
396 " %d,%d refused, for another HPI?\n",
397 phm
->object
, phm
->function
);
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
);
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
);
417 HPI_DEBUG_LOG(VERBOSE
, "start of switch\n");
419 case HPI_TYPE_MESSAGE
:
420 switch (phm
->object
) {
421 case HPI_OBJ_SUBSYSTEM
:
422 subsys_message(phm
, phr
);
425 case HPI_OBJ_ADAPTER
:
427 sizeof(struct hpi_response_header
) +
428 sizeof(struct hpi_adapter_res
);
429 adapter_message(pao
, phm
, phr
);
432 case HPI_OBJ_CONTROLEX
:
433 case HPI_OBJ_CONTROL
:
434 control_message(pao
, phm
, phr
);
437 case HPI_OBJ_OSTREAM
:
438 outstream_message(pao
, phm
, phr
);
441 case HPI_OBJ_ISTREAM
:
442 instream_message(pao
, phm
, phr
);
446 hw_message(pao
, phm
, phr
);
452 phr
->error
= HPI_ERROR_INVALID_TYPE
;
457 /*****************************************************************************/
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 ***
465 static void subsys_create_adapter(struct hpi_message
*phm
,
466 struct hpi_response
*phr
)
468 /* create temp adapter obj, because we don't know what index yet */
469 struct hpi_adapter_obj ao
;
473 HPI_DEBUG_LOG(DEBUG
, " subsys_create_adapter\n");
475 memset(&ao
, 0, sizeof(ao
));
477 /* this HPI only creates adapters for TI/PCI devices */
478 if (phm
->u
.s
.resource
.bus_type
!= HPI_BUS_PCI
)
480 if (phm
->u
.s
.resource
.r
.pci
->vendor_id
!= HPI_PCI_VENDOR_ID_TI
)
482 if (phm
->u
.s
.resource
.r
.pci
->device_id
!= HPI_PCI_DEV_ID_DSP6205
)
485 ao
.priv
= kzalloc(sizeof(struct hpi_hw_obj
), GFP_KERNEL
);
487 HPI_DEBUG_LOG(ERROR
, "cant get mem for adapter object\n");
488 phr
->error
= HPI_ERROR_MEMORY_ALLOC
;
492 ao
.pci
= *phm
->u
.s
.resource
.r
.pci
;
493 err
= create_adapter_obj(&ao
, &os_error_code
);
495 err
= hpi_add_adapter(&ao
);
497 phr
->u
.s
.data
= os_error_code
;
498 delete_adapter_obj(&ao
);
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
++;
509 /** delete an adapter - required by WDM driver */
510 static void subsys_delete_adapter(struct hpi_message
*phm
,
511 struct hpi_response
*phr
)
513 struct hpi_adapter_obj
*pao
;
514 struct hpi_hw_obj
*phw
;
516 pao
= hpi_find_adapter(phm
->adapter_index
);
518 phr
->error
= HPI_ERROR_INVALID_OBJ_INDEX
;
521 phw
= (struct hpi_hw_obj
*)pao
->priv
;
522 /* reset adapter h/w */
524 boot_loader_write_mem32(pao
, 0, C6205_BAR0_TIMER1_CTL
, 0);
526 iowrite32(C6205_HDCR_WARMRESET
, phw
->prHDCR
);
528 delete_adapter_obj(pao
);
532 /** Create adapter object
533 allocate buffers, bootload DSPs, initialise control cache
535 static u16
create_adapter_obj(struct hpi_adapter_obj
*pao
,
538 struct hpi_hw_obj
*phw
= pao
->priv
;
539 struct bus_master_interface
*interface
;
541 #ifndef HPI6205_NO_HSR_POLL
542 u32 time_out
= HPI6205_TIMEOUT
;
548 /* init error reporting */
549 pao
->dsp_crashed
= 0;
551 for (i
= 0; i
< HPI_MAX_STREAMS
; i
++)
552 phw
->flag_outstream_just_reset
[i
] = 1;
554 /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
556 pao
->pci
.ap_mem_base
[1] +
557 C6205_BAR1_HSR
/ sizeof(*pao
->pci
.ap_mem_base
[1]);
559 pao
->pci
.ap_mem_base
[1] +
560 C6205_BAR1_HDCR
/ sizeof(*pao
->pci
.ap_mem_base
[1]);
562 pao
->pci
.ap_mem_base
[1] +
563 C6205_BAR1_DSPP
/ sizeof(*pao
->pci
.ap_mem_base
[1]);
565 pao
->has_control_cache
= 0;
567 if (hpios_locked_mem_alloc(&phw
->h_locked_mem
,
568 sizeof(struct bus_master_interface
),
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
;
575 HPI_DEBUG_LOG(DEBUG
, "interface buffer address %p\n",
576 phw
->p_interface_buffer
);
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
;
584 err
= adapter_boot_load_dsp(pao
, pos_error_code
);
586 /* no need to clean up as SubSysCreateAdapter */
587 /* calls DeleteAdapter on error. */
590 HPI_DEBUG_LOG(INFO
, "load DSP code OK\n");
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
);
596 interface
= phw
->p_interface_buffer
;
598 #ifndef HPI6205_NO_HSR_POLL
599 /* wait for first interrupt indicating the DSP init is done */
600 time_out
= HPI6205_TIMEOUT
* 10;
602 while (((temp1
& C6205_HSR_INTSRC
) == 0) && --time_out
)
603 temp1
= ioread32(phw
->prHSR
);
605 if (temp1
& C6205_HSR_INTSRC
)
607 "interrupt confirming DSP code running OK\n");
610 "timed out waiting for interrupt "
611 "confirming DSP code running\n");
612 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ
);
615 /* reset the interrupt */
616 iowrite32(C6205_HSR_INTSRC
, phw
->prHSR
);
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
);
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
628 if (interface
->control_cache
.number_of_controls
) {
629 void *p_control_cache_virtual
;
631 err
= hpios_locked_mem_alloc(&phw
->h_control_cache
,
632 interface
->control_cache
.size_in_bytes
,
635 err
= hpios_locked_mem_get_virt_addr(&phw
->
636 h_control_cache
, &p_control_cache_virtual
);
638 memset(p_control_cache_virtual
, 0,
639 interface
->control_cache
.size_in_bytes
);
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
);
648 err
= HPI_ERROR_MEMORY_ALLOC
;
651 err
= hpios_locked_mem_get_phys_addr(&phw
->
652 h_control_cache
, &phys_addr
);
653 interface
->control_cache
.physical_address32
=
658 pao
->has_control_cache
= 1;
660 if (hpios_locked_mem_valid(&phw
->h_control_cache
))
661 hpios_locked_mem_free(&phw
->h_control_cache
);
662 pao
->has_control_cache
= 0;
665 /* allocate bus mastering async buffer and tell the DSP about it */
666 if (interface
->async_buffer
.b
.size
) {
667 err
= hpios_locked_mem_alloc(&phw
->h_async_event_buffer
,
668 interface
->async_buffer
.b
.size
*
669 sizeof(struct hpi_async_event
), pao
->pci
.p_os_data
);
671 err
= hpios_locked_mem_get_virt_addr
672 (&phw
->h_async_event_buffer
, (void *)
673 &phw
->p_async_event_buffer
);
675 memset((void *)phw
->p_async_event_buffer
, 0,
676 interface
->async_buffer
.b
.size
*
677 sizeof(struct hpi_async_event
));
679 err
= hpios_locked_mem_get_phys_addr
680 (&phw
->h_async_event_buffer
, &phys_addr
);
681 interface
->async_buffer
.physical_address32
=
685 if (hpios_locked_mem_valid(&phw
->
686 h_async_event_buffer
)) {
687 hpios_locked_mem_free
688 (&phw
->h_async_event_buffer
);
689 phw
->p_async_event_buffer
= NULL
;
693 send_dsp_command(phw
, H620_HIF_IDLE
);
696 struct hpi_message hM
;
697 struct hpi_response hR
;
700 HPI_DEBUG_LOG(VERBOSE
, "init ADAPTER_GET_INFO\n");
701 memset(&hM
, 0, sizeof(hM
));
702 hM
.type
= HPI_TYPE_MESSAGE
;
703 hM
.size
= sizeof(hM
);
704 hM
.object
= HPI_OBJ_ADAPTER
;
705 hM
.function
= HPI_ADAPTER_GET_INFO
;
706 hM
.adapter_index
= 0;
707 memset(&hR
, 0, sizeof(hR
));
708 hR
.size
= sizeof(hR
);
710 err
= message_response_sequence(pao
, &hM
, &hR
);
712 HPI_DEBUG_LOG(ERROR
, "message transport error %d\n",
719 pao
->adapter_type
= hR
.u
.a
.adapter_type
;
720 pao
->index
= hR
.u
.a
.adapter_index
;
722 max_streams
= hR
.u
.a
.num_outstreams
+ hR
.u
.a
.num_instreams
;
724 hpios_locked_mem_prepare((max_streams
* 6) / 10, max_streams
,
725 65536, pao
->pci
.p_os_data
);
727 HPI_DEBUG_LOG(VERBOSE
,
728 "got adapter info type %x index %d serial %d\n",
729 hR
.u
.a
.adapter_type
, hR
.u
.a
.adapter_index
,
730 hR
.u
.a
.serial_number
);
733 pao
->open
= 0; /* upon creation the adapter is closed */
735 HPI_DEBUG_LOG(INFO
, "bootload DSP OK\n");
739 /** Free memory areas allocated by adapter
740 * this routine is called from SubSysDeleteAdapter,
741 * and SubSysCreateAdapter if duplicate index
743 static void delete_adapter_obj(struct hpi_adapter_obj
*pao
)
745 struct hpi_hw_obj
*phw
;
750 if (hpios_locked_mem_valid(&phw
->h_async_event_buffer
)) {
751 hpios_locked_mem_free(&phw
->h_async_event_buffer
);
752 phw
->p_async_event_buffer
= NULL
;
755 if (hpios_locked_mem_valid(&phw
->h_control_cache
)) {
756 hpios_locked_mem_free(&phw
->h_control_cache
);
757 hpi_free_control_cache(phw
->p_cache
);
760 if (hpios_locked_mem_valid(&phw
->h_locked_mem
)) {
761 hpios_locked_mem_free(&phw
->h_locked_mem
);
762 phw
->p_interface_buffer
= NULL
;
765 for (i
= 0; i
< HPI_MAX_STREAMS
; i
++)
766 if (hpios_locked_mem_valid(&phw
->instream_host_buffers
[i
])) {
767 hpios_locked_mem_free(&phw
->instream_host_buffers
[i
]);
768 /*?phw->InStreamHostBuffers[i] = NULL; */
769 phw
->instream_host_buffer_size
[i
] = 0;
772 for (i
= 0; i
< HPI_MAX_STREAMS
; i
++)
773 if (hpios_locked_mem_valid(&phw
->outstream_host_buffers
[i
])) {
774 hpios_locked_mem_free(&phw
->outstream_host_buffers
776 phw
->outstream_host_buffer_size
[i
] = 0;
779 hpios_locked_mem_unprepare(pao
->pci
.p_os_data
);
781 hpi_delete_adapter(pao
);
785 /*****************************************************************************/
786 /* OutStream Host buffer functions */
788 /** Allocate or attach buffer for busmastering
790 static void outstream_host_buffer_allocate(struct hpi_adapter_obj
*pao
,
791 struct hpi_message
*phm
, struct hpi_response
*phr
)
794 u32 command
= phm
->u
.d
.u
.buffer
.command
;
795 struct hpi_hw_obj
*phw
= pao
->priv
;
796 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
798 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
800 if (command
== HPI_BUFFER_CMD_EXTERNAL
801 || command
== HPI_BUFFER_CMD_INTERNAL_ALLOC
) {
802 /* ALLOC phase, allocate a buffer with power of 2 size,
803 get its bus address for PCI bus mastering
805 phm
->u
.d
.u
.buffer
.buffer_size
=
806 roundup_pow_of_two(phm
->u
.d
.u
.buffer
.buffer_size
);
807 /* return old size and allocated size,
808 so caller can detect change */
809 phr
->u
.d
.u
.stream_info
.data_available
=
810 phw
->outstream_host_buffer_size
[phm
->obj_index
];
811 phr
->u
.d
.u
.stream_info
.buffer_size
=
812 phm
->u
.d
.u
.buffer
.buffer_size
;
814 if (phw
->outstream_host_buffer_size
[phm
->obj_index
] ==
815 phm
->u
.d
.u
.buffer
.buffer_size
) {
816 /* Same size, no action required */
820 if (hpios_locked_mem_valid(&phw
->outstream_host_buffers
[phm
->
822 hpios_locked_mem_free(&phw
->outstream_host_buffers
825 err
= hpios_locked_mem_alloc(&phw
->outstream_host_buffers
826 [phm
->obj_index
], phm
->u
.d
.u
.buffer
.buffer_size
,
830 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
831 phw
->outstream_host_buffer_size
[phm
->obj_index
] = 0;
835 err
= hpios_locked_mem_get_phys_addr
836 (&phw
->outstream_host_buffers
[phm
->obj_index
],
837 &phm
->u
.d
.u
.buffer
.pci_address
);
838 /* get the phys addr into msg for single call alloc caller
839 * needs to do this for split alloc (or use the same message)
840 * return the phy address for split alloc in the respose too
842 phr
->u
.d
.u
.stream_info
.auxiliary_data_available
=
843 phm
->u
.d
.u
.buffer
.pci_address
;
846 hpios_locked_mem_free(&phw
->outstream_host_buffers
848 phw
->outstream_host_buffer_size
[phm
->obj_index
] = 0;
849 phr
->error
= HPI_ERROR_MEMORY_ALLOC
;
854 if (command
== HPI_BUFFER_CMD_EXTERNAL
855 || command
== HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER
) {
856 /* GRANT phase. Set up the BBM status, tell the DSP about
857 the buffer so it can start using BBM.
859 struct hpi_hostbuffer_status
*status
;
861 if (phm
->u
.d
.u
.buffer
.buffer_size
& (phm
->u
.d
.u
.buffer
.
864 "buffer size must be 2^N not %d\n",
865 phm
->u
.d
.u
.buffer
.buffer_size
);
866 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
869 phw
->outstream_host_buffer_size
[phm
->obj_index
] =
870 phm
->u
.d
.u
.buffer
.buffer_size
;
871 status
= &interface
->outstream_host_buffer_status
[phm
->
873 status
->samples_processed
= 0;
874 status
->stream_state
= HPI_STATE_STOPPED
;
875 status
->dSP_index
= 0;
876 status
->host_index
= status
->dSP_index
;
877 status
->size_in_bytes
= phm
->u
.d
.u
.buffer
.buffer_size
;
879 hw_message(pao
, phm
, phr
);
882 && hpios_locked_mem_valid(&phw
->
883 outstream_host_buffers
[phm
->obj_index
])) {
884 hpios_locked_mem_free(&phw
->outstream_host_buffers
886 phw
->outstream_host_buffer_size
[phm
->obj_index
] = 0;
891 static void outstream_host_buffer_get_info(struct hpi_adapter_obj
*pao
,
892 struct hpi_message
*phm
, struct hpi_response
*phr
)
894 struct hpi_hw_obj
*phw
= pao
->priv
;
895 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
896 struct hpi_hostbuffer_status
*status
;
899 if (hpios_locked_mem_valid(&phw
->outstream_host_buffers
[phm
->
901 if (hpios_locked_mem_get_virt_addr(&phw
->
902 outstream_host_buffers
[phm
->obj_index
],
903 (void *)&p_bbm_data
)) {
904 phr
->error
= HPI_ERROR_INVALID_OPERATION
;
907 status
= &interface
->outstream_host_buffer_status
[phm
->
909 hpi_init_response(phr
, HPI_OBJ_OSTREAM
,
910 HPI_OSTREAM_HOSTBUFFER_GET_INFO
, 0);
911 phr
->u
.d
.u
.hostbuffer_info
.p_buffer
= p_bbm_data
;
912 phr
->u
.d
.u
.hostbuffer_info
.p_status
= status
;
914 hpi_init_response(phr
, HPI_OBJ_OSTREAM
,
915 HPI_OSTREAM_HOSTBUFFER_GET_INFO
,
916 HPI_ERROR_INVALID_OPERATION
);
920 static void outstream_host_buffer_free(struct hpi_adapter_obj
*pao
,
921 struct hpi_message
*phm
, struct hpi_response
*phr
)
923 struct hpi_hw_obj
*phw
= pao
->priv
;
924 u32 command
= phm
->u
.d
.u
.buffer
.command
;
926 if (phw
->outstream_host_buffer_size
[phm
->obj_index
]) {
927 if (command
== HPI_BUFFER_CMD_EXTERNAL
928 || command
== HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER
) {
929 phw
->outstream_host_buffer_size
[phm
->obj_index
] = 0;
930 hw_message(pao
, phm
, phr
);
931 /* Tell adapter to stop using the host buffer. */
933 if (command
== HPI_BUFFER_CMD_EXTERNAL
934 || command
== HPI_BUFFER_CMD_INTERNAL_FREE
)
935 hpios_locked_mem_free(&phw
->outstream_host_buffers
938 /* Should HPI_ERROR_INVALID_OPERATION be returned
939 if no host buffer is allocated? */
941 hpi_init_response(phr
, HPI_OBJ_OSTREAM
,
942 HPI_OSTREAM_HOSTBUFFER_FREE
, 0);
946 static u32
outstream_get_space_available(struct hpi_hostbuffer_status
*status
)
948 return status
->size_in_bytes
- (status
->host_index
-
952 static void outstream_write(struct hpi_adapter_obj
*pao
,
953 struct hpi_message
*phm
, struct hpi_response
*phr
)
955 struct hpi_hw_obj
*phw
= pao
->priv
;
956 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
957 struct hpi_hostbuffer_status
*status
;
960 if (!phw
->outstream_host_buffer_size
[phm
->obj_index
]) {
961 /* there is no BBM buffer, write via message */
962 hw_message(pao
, phm
, phr
);
966 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
967 status
= &interface
->outstream_host_buffer_status
[phm
->obj_index
];
969 if (phw
->flag_outstream_just_reset
[phm
->obj_index
]) {
970 /* First OutStremWrite() call following reset will write data to the
971 adapter's buffers, reducing delay before stream can start. The DSP
972 takes care of setting the stream data format using format information
975 int partial_write
= 0;
976 unsigned int original_size
= 0;
978 phw
->flag_outstream_just_reset
[phm
->obj_index
] = 0;
980 /* Send the first buffer to the DSP the old way. */
981 /* Limit size of first transfer - */
982 /* expect that this will not usually be triggered. */
983 if (phm
->u
.d
.u
.data
.data_size
> HPI6205_SIZEOF_DATA
) {
985 original_size
= phm
->u
.d
.u
.data
.data_size
;
986 phm
->u
.d
.u
.data
.data_size
= HPI6205_SIZEOF_DATA
;
989 phm
->function
= HPI_OSTREAM_WRITE
;
990 hw_message(pao
, phm
, phr
);
995 /* update status information that the DSP would typically
996 * update (and will update next time the DSP
997 * buffer update task reads data from the host BBM buffer)
999 status
->auxiliary_data_available
= phm
->u
.d
.u
.data
.data_size
;
1000 status
->host_index
+= phm
->u
.d
.u
.data
.data_size
;
1001 status
->dSP_index
+= phm
->u
.d
.u
.data
.data_size
;
1003 /* if we did a full write, we can return from here. */
1007 /* tweak buffer parameters and let the rest of the */
1008 /* buffer land in internal BBM buffer */
1009 phm
->u
.d
.u
.data
.data_size
=
1010 original_size
- HPI6205_SIZEOF_DATA
;
1011 phm
->u
.d
.u
.data
.pb_data
+= HPI6205_SIZEOF_DATA
;
1014 space_available
= outstream_get_space_available(status
);
1015 if (space_available
< phm
->u
.d
.u
.data
.data_size
) {
1016 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
1020 /* HostBuffers is used to indicate host buffer is internally allocated.
1021 otherwise, assumed external, data written externally */
1022 if (phm
->u
.d
.u
.data
.pb_data
1023 && hpios_locked_mem_valid(&phw
->outstream_host_buffers
[phm
->
1027 u8
*p_app_data
= (u8
*)phm
->u
.d
.u
.data
.pb_data
;
1029 if (hpios_locked_mem_get_virt_addr(&phw
->
1030 outstream_host_buffers
[phm
->obj_index
],
1031 (void *)&p_bbm_data
)) {
1032 phr
->error
= HPI_ERROR_INVALID_OPERATION
;
1037 or enough to fit from current to end of BBM buffer */
1039 min(phm
->u
.d
.u
.data
.data_size
,
1040 status
->size_in_bytes
-
1041 (status
->host_index
& (status
->size_in_bytes
- 1)));
1044 (status
->host_index
& (status
->size_in_bytes
- 1)),
1045 p_app_data
, l_first_write
);
1046 /* remaining data if any */
1047 memcpy(p_bbm_data
, p_app_data
+ l_first_write
,
1048 phm
->u
.d
.u
.data
.data_size
- l_first_write
);
1050 status
->host_index
+= phm
->u
.d
.u
.data
.data_size
;
1053 static void outstream_get_info(struct hpi_adapter_obj
*pao
,
1054 struct hpi_message
*phm
, struct hpi_response
*phr
)
1056 struct hpi_hw_obj
*phw
= pao
->priv
;
1057 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1058 struct hpi_hostbuffer_status
*status
;
1060 if (!phw
->outstream_host_buffer_size
[phm
->obj_index
]) {
1061 hw_message(pao
, phm
, phr
);
1065 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
1067 status
= &interface
->outstream_host_buffer_status
[phm
->obj_index
];
1069 phr
->u
.d
.u
.stream_info
.state
= (u16
)status
->stream_state
;
1070 phr
->u
.d
.u
.stream_info
.samples_transferred
=
1071 status
->samples_processed
;
1072 phr
->u
.d
.u
.stream_info
.buffer_size
= status
->size_in_bytes
;
1073 phr
->u
.d
.u
.stream_info
.data_available
=
1074 status
->size_in_bytes
- outstream_get_space_available(status
);
1075 phr
->u
.d
.u
.stream_info
.auxiliary_data_available
=
1076 status
->auxiliary_data_available
;
1079 static void outstream_start(struct hpi_adapter_obj
*pao
,
1080 struct hpi_message
*phm
, struct hpi_response
*phr
)
1082 hw_message(pao
, phm
, phr
);
1085 static void outstream_reset(struct hpi_adapter_obj
*pao
,
1086 struct hpi_message
*phm
, struct hpi_response
*phr
)
1088 struct hpi_hw_obj
*phw
= pao
->priv
;
1089 phw
->flag_outstream_just_reset
[phm
->obj_index
] = 1;
1090 hw_message(pao
, phm
, phr
);
1093 static void outstream_open(struct hpi_adapter_obj
*pao
,
1094 struct hpi_message
*phm
, struct hpi_response
*phr
)
1096 outstream_reset(pao
, phm
, phr
);
1099 /*****************************************************************************/
1100 /* InStream Host buffer functions */
1102 static void instream_host_buffer_allocate(struct hpi_adapter_obj
*pao
,
1103 struct hpi_message
*phm
, struct hpi_response
*phr
)
1106 u32 command
= phm
->u
.d
.u
.buffer
.command
;
1107 struct hpi_hw_obj
*phw
= pao
->priv
;
1108 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1110 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
1112 if (command
== HPI_BUFFER_CMD_EXTERNAL
1113 || command
== HPI_BUFFER_CMD_INTERNAL_ALLOC
) {
1115 phm
->u
.d
.u
.buffer
.buffer_size
=
1116 roundup_pow_of_two(phm
->u
.d
.u
.buffer
.buffer_size
);
1117 phr
->u
.d
.u
.stream_info
.data_available
=
1118 phw
->instream_host_buffer_size
[phm
->obj_index
];
1119 phr
->u
.d
.u
.stream_info
.buffer_size
=
1120 phm
->u
.d
.u
.buffer
.buffer_size
;
1122 if (phw
->instream_host_buffer_size
[phm
->obj_index
] ==
1123 phm
->u
.d
.u
.buffer
.buffer_size
) {
1124 /* Same size, no action required */
1128 if (hpios_locked_mem_valid(&phw
->instream_host_buffers
[phm
->
1130 hpios_locked_mem_free(&phw
->instream_host_buffers
1133 err
= hpios_locked_mem_alloc(&phw
->instream_host_buffers
[phm
->
1134 obj_index
], phm
->u
.d
.u
.buffer
.buffer_size
,
1135 pao
->pci
.p_os_data
);
1138 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
1139 phw
->instream_host_buffer_size
[phm
->obj_index
] = 0;
1143 err
= hpios_locked_mem_get_phys_addr
1144 (&phw
->instream_host_buffers
[phm
->obj_index
],
1145 &phm
->u
.d
.u
.buffer
.pci_address
);
1146 /* get the phys addr into msg for single call alloc. Caller
1147 needs to do this for split alloc so return the phy address */
1148 phr
->u
.d
.u
.stream_info
.auxiliary_data_available
=
1149 phm
->u
.d
.u
.buffer
.pci_address
;
1151 hpios_locked_mem_free(&phw
->instream_host_buffers
1153 phw
->instream_host_buffer_size
[phm
->obj_index
] = 0;
1154 phr
->error
= HPI_ERROR_MEMORY_ALLOC
;
1159 if (command
== HPI_BUFFER_CMD_EXTERNAL
1160 || command
== HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER
) {
1161 struct hpi_hostbuffer_status
*status
;
1163 if (phm
->u
.d
.u
.buffer
.buffer_size
& (phm
->u
.d
.u
.buffer
.
1165 HPI_DEBUG_LOG(ERROR
,
1166 "buffer size must be 2^N not %d\n",
1167 phm
->u
.d
.u
.buffer
.buffer_size
);
1168 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
1172 phw
->instream_host_buffer_size
[phm
->obj_index
] =
1173 phm
->u
.d
.u
.buffer
.buffer_size
;
1174 status
= &interface
->instream_host_buffer_status
[phm
->
1176 status
->samples_processed
= 0;
1177 status
->stream_state
= HPI_STATE_STOPPED
;
1178 status
->dSP_index
= 0;
1179 status
->host_index
= status
->dSP_index
;
1180 status
->size_in_bytes
= phm
->u
.d
.u
.buffer
.buffer_size
;
1182 hw_message(pao
, phm
, phr
);
1184 && hpios_locked_mem_valid(&phw
->
1185 instream_host_buffers
[phm
->obj_index
])) {
1186 hpios_locked_mem_free(&phw
->instream_host_buffers
1188 phw
->instream_host_buffer_size
[phm
->obj_index
] = 0;
1193 static void instream_host_buffer_get_info(struct hpi_adapter_obj
*pao
,
1194 struct hpi_message
*phm
, struct hpi_response
*phr
)
1196 struct hpi_hw_obj
*phw
= pao
->priv
;
1197 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1198 struct hpi_hostbuffer_status
*status
;
1201 if (hpios_locked_mem_valid(&phw
->instream_host_buffers
[phm
->
1203 if (hpios_locked_mem_get_virt_addr(&phw
->
1204 instream_host_buffers
[phm
->obj_index
],
1205 (void *)&p_bbm_data
)) {
1206 phr
->error
= HPI_ERROR_INVALID_OPERATION
;
1209 status
= &interface
->instream_host_buffer_status
[phm
->
1211 hpi_init_response(phr
, HPI_OBJ_ISTREAM
,
1212 HPI_ISTREAM_HOSTBUFFER_GET_INFO
, 0);
1213 phr
->u
.d
.u
.hostbuffer_info
.p_buffer
= p_bbm_data
;
1214 phr
->u
.d
.u
.hostbuffer_info
.p_status
= status
;
1216 hpi_init_response(phr
, HPI_OBJ_ISTREAM
,
1217 HPI_ISTREAM_HOSTBUFFER_GET_INFO
,
1218 HPI_ERROR_INVALID_OPERATION
);
1222 static void instream_host_buffer_free(struct hpi_adapter_obj
*pao
,
1223 struct hpi_message
*phm
, struct hpi_response
*phr
)
1225 struct hpi_hw_obj
*phw
= pao
->priv
;
1226 u32 command
= phm
->u
.d
.u
.buffer
.command
;
1228 if (phw
->instream_host_buffer_size
[phm
->obj_index
]) {
1229 if (command
== HPI_BUFFER_CMD_EXTERNAL
1230 || command
== HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER
) {
1231 phw
->instream_host_buffer_size
[phm
->obj_index
] = 0;
1232 hw_message(pao
, phm
, phr
);
1235 if (command
== HPI_BUFFER_CMD_EXTERNAL
1236 || command
== HPI_BUFFER_CMD_INTERNAL_FREE
)
1237 hpios_locked_mem_free(&phw
->instream_host_buffers
1241 /* Should HPI_ERROR_INVALID_OPERATION be returned
1242 if no host buffer is allocated? */
1243 hpi_init_response(phr
, HPI_OBJ_ISTREAM
,
1244 HPI_ISTREAM_HOSTBUFFER_FREE
, 0);
1250 static void instream_start(struct hpi_adapter_obj
*pao
,
1251 struct hpi_message
*phm
, struct hpi_response
*phr
)
1253 hw_message(pao
, phm
, phr
);
1256 static u32
instream_get_bytes_available(struct hpi_hostbuffer_status
*status
)
1258 return status
->dSP_index
- status
->host_index
;
1261 static void instream_read(struct hpi_adapter_obj
*pao
,
1262 struct hpi_message
*phm
, struct hpi_response
*phr
)
1264 struct hpi_hw_obj
*phw
= pao
->priv
;
1265 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1266 struct hpi_hostbuffer_status
*status
;
1270 u8
*p_app_data
= (u8
*)phm
->u
.d
.u
.data
.pb_data
;
1272 if (!phw
->instream_host_buffer_size
[phm
->obj_index
]) {
1273 hw_message(pao
, phm
, phr
);
1276 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
1278 status
= &interface
->instream_host_buffer_status
[phm
->obj_index
];
1279 data_available
= instream_get_bytes_available(status
);
1280 if (data_available
< phm
->u
.d
.u
.data
.data_size
) {
1281 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
1285 if (hpios_locked_mem_valid(&phw
->instream_host_buffers
[phm
->
1287 if (hpios_locked_mem_get_virt_addr(&phw
->
1288 instream_host_buffers
[phm
->obj_index
],
1289 (void *)&p_bbm_data
)) {
1290 phr
->error
= HPI_ERROR_INVALID_OPERATION
;
1295 or enough to fit from current to end of BBM buffer */
1297 min(phm
->u
.d
.u
.data
.data_size
,
1298 status
->size_in_bytes
-
1299 (status
->host_index
& (status
->size_in_bytes
- 1)));
1303 (status
->host_index
& (status
->size_in_bytes
- 1)),
1305 /* remaining data if any */
1306 memcpy(p_app_data
+ l_first_read
, p_bbm_data
,
1307 phm
->u
.d
.u
.data
.data_size
- l_first_read
);
1309 status
->host_index
+= phm
->u
.d
.u
.data
.data_size
;
1312 static void instream_get_info(struct hpi_adapter_obj
*pao
,
1313 struct hpi_message
*phm
, struct hpi_response
*phr
)
1315 struct hpi_hw_obj
*phw
= pao
->priv
;
1316 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1317 struct hpi_hostbuffer_status
*status
;
1318 if (!phw
->instream_host_buffer_size
[phm
->obj_index
]) {
1319 hw_message(pao
, phm
, phr
);
1323 status
= &interface
->instream_host_buffer_status
[phm
->obj_index
];
1325 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
1327 phr
->u
.d
.u
.stream_info
.state
= (u16
)status
->stream_state
;
1328 phr
->u
.d
.u
.stream_info
.samples_transferred
=
1329 status
->samples_processed
;
1330 phr
->u
.d
.u
.stream_info
.buffer_size
= status
->size_in_bytes
;
1331 phr
->u
.d
.u
.stream_info
.data_available
=
1332 instream_get_bytes_available(status
);
1333 phr
->u
.d
.u
.stream_info
.auxiliary_data_available
=
1334 status
->auxiliary_data_available
;
1337 /*****************************************************************************/
1339 #define HPI6205_MAX_FILES_TO_LOAD 2
1341 static u16
adapter_boot_load_dsp(struct hpi_adapter_obj
*pao
,
1342 u32
*pos_error_code
)
1344 struct hpi_hw_obj
*phw
= pao
->priv
;
1345 struct dsp_code dsp_code
;
1346 u16 boot_code_id
[HPI6205_MAX_FILES_TO_LOAD
];
1347 u16 firmware_id
= pao
->pci
.subsys_device_id
;
1352 boot_code_id
[0] = HPI_ADAPTER_ASI(0x6205);
1354 /* special cases where firmware_id != subsys ID */
1355 switch (firmware_id
) {
1356 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1357 boot_code_id
[0] = firmware_id
;
1360 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1361 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1362 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1363 firmware_id
= HPI_ADAPTER_FAMILY_ASI(0x6400);
1365 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1366 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1367 firmware_id
= HPI_ADAPTER_FAMILY_ASI(0x6600);
1369 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1370 firmware_id
= HPI_ADAPTER_FAMILY_ASI(0x8900);
1373 boot_code_id
[1] = firmware_id
;
1375 /* reset DSP by writing a 1 to the WARMRESET bit */
1376 temp
= C6205_HDCR_WARMRESET
;
1377 iowrite32(temp
, phw
->prHDCR
);
1378 hpios_delay_micro_seconds(1000);
1380 /* check that PCI i/f was configured by EEPROM */
1381 temp
= ioread32(phw
->prHSR
);
1382 if ((temp
& (C6205_HSR_CFGERR
| C6205_HSR_EEREAD
)) !=
1384 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM
);
1386 /* disable PINTA interrupt */
1387 iowrite32(temp
, phw
->prHSR
);
1389 /* check control register reports PCI boot mode */
1390 temp
= ioread32(phw
->prHDCR
);
1391 if (!(temp
& C6205_HDCR_PCIBOOT
))
1392 return hpi6205_error(0, HPI6205_ERROR_6205_REG
);
1394 /* try writing a couple of numbers to the DSP page register */
1395 /* and reading them back. */
1397 iowrite32(temp
, phw
->prDSPP
);
1398 if ((temp
| C6205_DSPP_MAP1
) != ioread32(phw
->prDSPP
))
1399 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE
);
1401 iowrite32(temp
, phw
->prDSPP
);
1402 if ((temp
| C6205_DSPP_MAP1
) != ioread32(phw
->prDSPP
))
1403 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE
);
1405 iowrite32(temp
, phw
->prDSPP
);
1406 if ((temp
| C6205_DSPP_MAP1
) != ioread32(phw
->prDSPP
))
1407 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE
);
1408 /* reset DSP page to the correct number */
1410 iowrite32(temp
, phw
->prDSPP
);
1411 if ((temp
| C6205_DSPP_MAP1
) != ioread32(phw
->prDSPP
))
1412 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE
);
1415 /* release 6713 from reset before 6205 is bootloaded.
1416 This ensures that the EMIF is inactive,
1417 and the 6713 HPI gets the correct bootmode etc
1419 if (boot_code_id
[1] != 0) {
1420 /* DSP 1 is a C6713 */
1421 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1422 boot_loader_write_mem32(pao
, 0, (0x018C0024L
), 0x00002202);
1423 hpios_delay_micro_seconds(100);
1424 /* Reset the 6713 #1 - revB */
1425 boot_loader_write_mem32(pao
, 0, C6205_BAR0_TIMER1_CTL
, 0);
1427 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1428 boot_loader_read_mem32(pao
, 0, 0);
1430 hpios_delay_micro_seconds(100);
1431 /* Release C6713 from reset - revB */
1432 boot_loader_write_mem32(pao
, 0, C6205_BAR0_TIMER1_CTL
, 4);
1433 hpios_delay_micro_seconds(100);
1436 for (dsp
= 0; dsp
< HPI6205_MAX_FILES_TO_LOAD
; dsp
++) {
1437 /* is there a DSP to load? */
1438 if (boot_code_id
[dsp
] == 0)
1441 err
= boot_loader_config_emif(pao
, dsp
);
1445 err
= boot_loader_test_internal_memory(pao
, dsp
);
1449 err
= boot_loader_test_external_memory(pao
, dsp
);
1453 err
= boot_loader_test_pld(pao
, dsp
);
1457 /* write the DSP code down into the DSPs memory */
1458 dsp_code
.ps_dev
= pao
->pci
.p_os_data
;
1459 err
= hpi_dsp_code_open(boot_code_id
[dsp
], &dsp_code
,
1470 err
= hpi_dsp_code_read_word(&dsp_code
, &length
);
1473 if (length
== 0xFFFFFFFF)
1474 break; /* end of code */
1476 err
= hpi_dsp_code_read_word(&dsp_code
, &address
);
1479 err
= hpi_dsp_code_read_word(&dsp_code
, &type
);
1482 err
= hpi_dsp_code_read_block(length
, &dsp_code
,
1486 for (i
= 0; i
< (int)length
; i
++) {
1487 err
= boot_loader_write_mem32(pao
, dsp
,
1491 /* dummy read every 4 words */
1492 /* for 6205 advisory 1.4.4 */
1494 boot_loader_read_mem32(pao
, dsp
,
1502 hpi_dsp_code_close(&dsp_code
);
1507 hpi_dsp_code_rewind(&dsp_code
);
1515 hpi_dsp_code_read_word(&dsp_code
, &length
);
1516 if (length
== 0xFFFFFFFF)
1517 break; /* end of code */
1519 hpi_dsp_code_read_word(&dsp_code
, &address
);
1520 hpi_dsp_code_read_word(&dsp_code
, &type
);
1521 hpi_dsp_code_read_block(length
, &dsp_code
, &pcode
);
1523 for (i
= 0; i
< (int)length
; i
++) {
1524 data
= boot_loader_read_mem32(pao
, dsp
,
1526 if (data
!= *pcode
) {
1536 hpi_dsp_code_close(&dsp_code
);
1541 /* After bootloading all DSPs, start DSP0 running
1542 * The DSP0 code will handle starting and synchronizing with its slaves
1544 if (phw
->p_interface_buffer
) {
1545 /* we need to tell the card the physical PCI address */
1546 u32 physicalPC_iaddress
;
1547 struct bus_master_interface
*interface
=
1548 phw
->p_interface_buffer
;
1549 u32 host_mailbox_address_on_dsp
;
1550 u32 physicalPC_iaddress_verify
= 0;
1552 /* set ack so we know when DSP is ready to go */
1553 /* (dwDspAck will be changed to HIF_RESET) */
1554 interface
->dsp_ack
= H620_HIF_UNKNOWN
;
1555 wmb(); /* ensure ack is written before dsp writes back */
1557 err
= hpios_locked_mem_get_phys_addr(&phw
->h_locked_mem
,
1558 &physicalPC_iaddress
);
1560 /* locate the host mailbox on the DSP. */
1561 host_mailbox_address_on_dsp
= 0x80000000;
1562 while ((physicalPC_iaddress
!= physicalPC_iaddress_verify
)
1564 err
= boot_loader_write_mem32(pao
, 0,
1565 host_mailbox_address_on_dsp
,
1566 physicalPC_iaddress
);
1567 physicalPC_iaddress_verify
=
1568 boot_loader_read_mem32(pao
, 0,
1569 host_mailbox_address_on_dsp
);
1572 HPI_DEBUG_LOG(DEBUG
, "starting DS_ps running\n");
1573 /* enable interrupts */
1574 temp
= ioread32(phw
->prHSR
);
1575 temp
&= ~(u32
)C6205_HSR_INTAM
;
1576 iowrite32(temp
, phw
->prHSR
);
1578 /* start code running... */
1579 temp
= ioread32(phw
->prHDCR
);
1580 temp
|= (u32
)C6205_HDCR_DSPINT
;
1581 iowrite32(temp
, phw
->prHDCR
);
1583 /* give the DSP 10ms to start up */
1584 hpios_delay_micro_seconds(10000);
1589 /*****************************************************************************/
1590 /* Bootloader utility functions */
1592 static u32
boot_loader_read_mem32(struct hpi_adapter_obj
*pao
, int dsp_index
,
1595 struct hpi_hw_obj
*phw
= pao
->priv
;
1597 __iomem u32
*p_data
;
1599 if (dsp_index
== 0) {
1600 /* DSP 0 is always C6205 */
1601 if ((address
>= 0x01800000) & (address
< 0x02000000)) {
1602 /* BAR1 register access */
1603 p_data
= pao
->pci
.ap_mem_base
[1] +
1604 (address
& 0x007fffff) /
1605 sizeof(*pao
->pci
.ap_mem_base
[1]);
1606 /* HPI_DEBUG_LOG(WARNING,
1607 "BAR1 access %08x\n", dwAddress); */
1609 u32 dw4M_page
= address
>> 22L;
1610 if (dw4M_page
!= phw
->dsp_page
) {
1611 phw
->dsp_page
= dw4M_page
;
1613 iowrite32(phw
->dsp_page
, phw
->prDSPP
);
1616 address
&= 0x3fffff; /* address within 4M page */
1617 /* BAR0 memory access */
1618 p_data
= pao
->pci
.ap_mem_base
[0] +
1619 address
/ sizeof(u32
);
1621 data
= ioread32(p_data
);
1622 } else if (dsp_index
== 1) {
1623 /* DSP 1 is a C6713 */
1625 boot_loader_write_mem32(pao
, 0, HPIAL_ADDR
, address
);
1626 boot_loader_write_mem32(pao
, 0, HPIAH_ADDR
, address
>> 16);
1627 lsb
= boot_loader_read_mem32(pao
, 0, HPIDL_ADDR
);
1628 data
= boot_loader_read_mem32(pao
, 0, HPIDH_ADDR
);
1629 data
= (data
<< 16) | (lsb
& 0xFFFF);
1634 static u16
boot_loader_write_mem32(struct hpi_adapter_obj
*pao
, int dsp_index
,
1635 u32 address
, u32 data
)
1637 struct hpi_hw_obj
*phw
= pao
->priv
;
1639 __iomem u32
*p_data
;
1640 /* u32 dwVerifyData=0; */
1642 if (dsp_index
== 0) {
1643 /* DSP 0 is always C6205 */
1644 if ((address
>= 0x01800000) & (address
< 0x02000000)) {
1645 /* BAR1 - DSP register access using */
1646 /* Non-prefetchable PCI access */
1647 p_data
= pao
->pci
.ap_mem_base
[1] +
1648 (address
& 0x007fffff) /
1649 sizeof(*pao
->pci
.ap_mem_base
[1]);
1651 /* BAR0 access - all of DSP memory using */
1652 /* pre-fetchable PCI access */
1653 u32 dw4M_page
= address
>> 22L;
1654 if (dw4M_page
!= phw
->dsp_page
) {
1655 phw
->dsp_page
= dw4M_page
;
1657 iowrite32(phw
->dsp_page
, phw
->prDSPP
);
1660 address
&= 0x3fffff; /* address within 4M page */
1661 p_data
= pao
->pci
.ap_mem_base
[0] +
1662 address
/ sizeof(u32
);
1664 iowrite32(data
, p_data
);
1665 } else if (dsp_index
== 1) {
1666 /* DSP 1 is a C6713 */
1667 boot_loader_write_mem32(pao
, 0, HPIAL_ADDR
, address
);
1668 boot_loader_write_mem32(pao
, 0, HPIAH_ADDR
, address
>> 16);
1670 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1671 boot_loader_read_mem32(pao
, 0, 0);
1673 boot_loader_write_mem32(pao
, 0, HPIDL_ADDR
, data
);
1674 boot_loader_write_mem32(pao
, 0, HPIDH_ADDR
, data
>> 16);
1676 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1677 boot_loader_read_mem32(pao
, 0, 0);
1679 err
= hpi6205_error(dsp_index
, HPI6205_ERROR_BAD_DSPINDEX
);
1683 static u16
boot_loader_config_emif(struct hpi_adapter_obj
*pao
, int dsp_index
)
1687 if (dsp_index
== 0) {
1690 /* DSP 0 is always C6205 */
1693 /* memory map of C6205 */
1694 /* 00000000-0000FFFF 16Kx32 internal program */
1695 /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
1699 /* Global EMIF control */
1700 boot_loader_write_mem32(pao
, dsp_index
, 0x01800000, 0x3779);
1709 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1710 setting
= 0x00000030;
1711 boot_loader_write_mem32(pao
, dsp_index
, 0x01800008, setting
);
1712 if (setting
!= boot_loader_read_mem32(pao
, dsp_index
,
1714 return hpi6205_error(dsp_index
,
1715 HPI6205_ERROR_DSP_EMIF
);
1717 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1718 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1719 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1720 /* WST should be 71, but 63 is max possible */
1722 (1L << WS_OFS
) | (63L << WST_OFS
) | (1L << WH_OFS
) |
1723 (1L << RS_OFS
) | (63L << RST_OFS
) | (1L << RH_OFS
) |
1725 boot_loader_write_mem32(pao
, dsp_index
, 0x01800004, setting
);
1726 if (setting
!= boot_loader_read_mem32(pao
, dsp_index
,
1728 return hpi6205_error(dsp_index
,
1729 HPI6205_ERROR_DSP_EMIF
);
1731 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1732 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1733 /* plenty of wait states */
1735 (1L << WS_OFS
) | (28L << WST_OFS
) | (1L << WH_OFS
) |
1736 (1L << RS_OFS
) | (63L << RST_OFS
) | (1L << RH_OFS
) |
1738 boot_loader_write_mem32(pao
, dsp_index
, 0x01800010, setting
);
1739 if (setting
!= boot_loader_read_mem32(pao
, dsp_index
,
1741 return hpi6205_error(dsp_index
,
1742 HPI6205_ERROR_DSP_EMIF
);
1744 /* EMIF CE3 setup - 32 bit async. */
1745 /* This is the PLD on the ASI5000 cards only */
1747 (1L << WS_OFS
) | (10L << WST_OFS
) | (1L << WH_OFS
) |
1748 (1L << RS_OFS
) | (10L << RST_OFS
) | (1L << RH_OFS
) |
1750 boot_loader_write_mem32(pao
, dsp_index
, 0x01800014, setting
);
1751 if (setting
!= boot_loader_read_mem32(pao
, dsp_index
,
1753 return hpi6205_error(dsp_index
,
1754 HPI6205_ERROR_DSP_EMIF
);
1756 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1757 /* need to use this else DSP code crashes? */
1758 boot_loader_write_mem32(pao
, dsp_index
, 0x01800018,
1761 /* EMIF SDRAM Refresh Timing */
1762 /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
1763 boot_loader_write_mem32(pao
, dsp_index
, 0x0180001C,
1766 } else if (dsp_index
== 1) {
1767 /* test access to the C6713s HPI registers */
1768 u32 write_data
= 0, read_data
= 0, i
= 0;
1770 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1772 boot_loader_write_mem32(pao
, 0, HPICL_ADDR
, write_data
);
1773 boot_loader_write_mem32(pao
, 0, HPICH_ADDR
, write_data
);
1774 /* C67 HPI is on lower 16bits of 32bit EMIF */
1776 0xFFF7 & boot_loader_read_mem32(pao
, 0, HPICL_ADDR
);
1777 if (write_data
!= read_data
) {
1778 err
= hpi6205_error(dsp_index
,
1779 HPI6205_ERROR_C6713_HPIC
);
1780 HPI_DEBUG_LOG(ERROR
, "HPICL %x %x\n", write_data
,
1785 /* HPIA - walking ones test */
1787 for (i
= 0; i
< 32; i
++) {
1788 boot_loader_write_mem32(pao
, 0, HPIAL_ADDR
,
1790 boot_loader_write_mem32(pao
, 0, HPIAH_ADDR
,
1791 (write_data
>> 16));
1793 0xFFFF & boot_loader_read_mem32(pao
, 0,
1796 read_data
| ((0xFFFF &
1797 boot_loader_read_mem32(pao
, 0,
1800 if (read_data
!= write_data
) {
1801 err
= hpi6205_error(dsp_index
,
1802 HPI6205_ERROR_C6713_HPIA
);
1803 HPI_DEBUG_LOG(ERROR
, "HPIA %x %x\n",
1804 write_data
, read_data
);
1807 write_data
= write_data
<< 1;
1811 * ** C6713 datasheet says we cannot program PLL from HPI,
1812 * and indeed if we try to set the PLL multiply from the HPI,
1813 * the PLL does not seem to lock, so we enable the PLL and
1814 * use the default multiply of x 7, which for a 27MHz clock
1815 * gives a DSP speed of 189MHz
1818 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C100, 0x0000);
1819 hpios_delay_micro_seconds(1000);
1820 /* EMIF = 189/3=63MHz */
1821 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C120, 0x8002);
1823 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C11C, 0x8001);
1825 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C118, 0x8000);
1826 hpios_delay_micro_seconds(1000);
1827 /* ** SGT test to take GPO3 high when we start the PLL */
1828 /* and low when the delay is completed */
1829 /* FSX0 <- '1' (GPO3) */
1830 boot_loader_write_mem32(pao
, 0, (0x018C0024L
), 0x00002A0A);
1831 /* PLL not bypassed */
1832 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C100, 0x0001);
1833 hpios_delay_micro_seconds(1000);
1834 /* FSX0 <- '0' (GPO3) */
1835 boot_loader_write_mem32(pao
, 0, (0x018C0024L
), 0x00002A02);
1837 /* 6205 EMIF CE1 resetup - 32 bit async. */
1838 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1839 boot_loader_write_mem32(pao
, 0, 0x01800004, /* CE1 */
1840 (1L << WS_OFS
) | (8L << WST_OFS
) | (1L << WH_OFS
) |
1841 (1L << RS_OFS
) | (12L << RST_OFS
) | (1L << RH_OFS
) |
1844 hpios_delay_micro_seconds(1000);
1846 /* check that we can read one of the PLL registers */
1847 /* PLL should not be bypassed! */
1848 if ((boot_loader_read_mem32(pao
, dsp_index
, 0x01B7C100) & 0xF)
1850 err
= hpi6205_error(dsp_index
,
1851 HPI6205_ERROR_C6713_PLL
);
1854 /* setup C67x EMIF (note this is the only use of
1855 BAR1 via BootLoader_WriteMem32) */
1856 boot_loader_write_mem32(pao
, dsp_index
, C6713_EMIF_GCTL
,
1858 boot_loader_write_mem32(pao
, dsp_index
, C6713_EMIF_CE0
,
1860 boot_loader_write_mem32(pao
, dsp_index
, C6713_EMIF_SDRAMEXT
,
1862 boot_loader_write_mem32(pao
, dsp_index
, C6713_EMIF_SDRAMCTL
,
1864 boot_loader_write_mem32(pao
, dsp_index
,
1865 C6713_EMIF_SDRAMTIMING
, 0x00000410);
1867 hpios_delay_micro_seconds(1000);
1868 } else if (dsp_index
== 2) {
1869 /* DSP 2 is a C6713 */
1872 err
= hpi6205_error(dsp_index
, HPI6205_ERROR_BAD_DSPINDEX
);
1876 static u16
boot_loader_test_memory(struct hpi_adapter_obj
*pao
, int dsp_index
,
1877 u32 start_address
, u32 length
)
1881 u32 test_data
= 0, data
= 0;
1885 /* for 1st word, test each bit in the 32bit word, */
1886 /* dwLength specifies number of 32bit words to test */
1887 /*for(i=0; i<dwLength; i++) */
1890 test_addr
= start_address
+ i
* 4;
1891 test_data
= 0x00000001;
1892 for (j
= 0; j
< 32; j
++) {
1893 boot_loader_write_mem32(pao
, dsp_index
, test_addr
,
1895 data
= boot_loader_read_mem32(pao
, dsp_index
,
1897 if (data
!= test_data
) {
1898 HPI_DEBUG_LOG(VERBOSE
,
1899 "memtest error details "
1900 "%08x %08x %08x %i\n", test_addr
,
1901 test_data
, data
, dsp_index
);
1902 return 1; /* error */
1904 test_data
= test_data
<< 1;
1908 /* for the next 100 locations test each location, leaving it as zero */
1909 /* write a zero to the next word in memory before we read */
1910 /* the previous write to make sure every memory location is unique */
1911 for (i
= 0; i
< 100; i
++) {
1912 test_addr
= start_address
+ i
* 4;
1913 test_data
= 0xA5A55A5A;
1914 boot_loader_write_mem32(pao
, dsp_index
, test_addr
, test_data
);
1915 boot_loader_write_mem32(pao
, dsp_index
, test_addr
+ 4, 0);
1916 data
= boot_loader_read_mem32(pao
, dsp_index
, test_addr
);
1917 if (data
!= test_data
) {
1918 HPI_DEBUG_LOG(VERBOSE
,
1919 "memtest error details "
1920 "%08x %08x %08x %i\n", test_addr
, test_data
,
1922 return 1; /* error */
1924 /* leave location as zero */
1925 boot_loader_write_mem32(pao
, dsp_index
, test_addr
, 0x0);
1928 /* zero out entire memory block */
1929 for (i
= 0; i
< length
; i
++) {
1930 test_addr
= start_address
+ i
* 4;
1931 boot_loader_write_mem32(pao
, dsp_index
, test_addr
, 0x0);
1936 static u16
boot_loader_test_internal_memory(struct hpi_adapter_obj
*pao
,
1940 if (dsp_index
== 0) {
1941 /* DSP 0 is a C6205 */
1943 err
= boot_loader_test_memory(pao
, dsp_index
, 0x00000000,
1947 err
= boot_loader_test_memory(pao
, dsp_index
,
1948 0x80000000, 0x10000);
1949 } else if ((dsp_index
== 1) || (dsp_index
== 2)) {
1950 /* DSP 1&2 are a C6713 */
1951 /* 192K internal mem */
1952 err
= boot_loader_test_memory(pao
, dsp_index
, 0x00000000,
1955 /* 64K internal mem / L2 cache */
1956 err
= boot_loader_test_memory(pao
, dsp_index
,
1957 0x00030000, 0x10000);
1959 return hpi6205_error(dsp_index
, HPI6205_ERROR_BAD_DSPINDEX
);
1962 return hpi6205_error(dsp_index
, HPI6205_ERROR_DSP_INTMEM
);
1967 static u16
boot_loader_test_external_memory(struct hpi_adapter_obj
*pao
,
1970 u32 dRAM_start_address
= 0;
1973 if (dsp_index
== 0) {
1974 /* only test for SDRAM if an ASI5000 card */
1975 if (pao
->pci
.subsys_device_id
== 0x5000) {
1976 /* DSP 0 is always C6205 */
1977 dRAM_start_address
= 0x00400000;
1978 dRAM_size
= 0x200000;
1979 /*dwDRAMinc=1024; */
1982 } else if ((dsp_index
== 1) || (dsp_index
== 2)) {
1983 /* DSP 1 is a C6713 */
1984 dRAM_start_address
= 0x80000000;
1985 dRAM_size
= 0x200000;
1986 /*dwDRAMinc=1024; */
1988 return hpi6205_error(dsp_index
, HPI6205_ERROR_BAD_DSPINDEX
);
1990 if (boot_loader_test_memory(pao
, dsp_index
, dRAM_start_address
,
1992 return hpi6205_error(dsp_index
, HPI6205_ERROR_DSP_EXTMEM
);
1996 static u16
boot_loader_test_pld(struct hpi_adapter_obj
*pao
, int dsp_index
)
1999 if (dsp_index
== 0) {
2000 /* only test for DSP0 PLD on ASI5000 card */
2001 if (pao
->pci
.subsys_device_id
== 0x5000) {
2002 /* PLD is located at CE3=0x03000000 */
2003 data
= boot_loader_read_mem32(pao
, dsp_index
,
2005 if ((data
& 0xF) != 0x5)
2006 return hpi6205_error(dsp_index
,
2007 HPI6205_ERROR_DSP_PLD
);
2008 data
= boot_loader_read_mem32(pao
, dsp_index
,
2010 if ((data
& 0xF) != 0xA)
2011 return hpi6205_error(dsp_index
,
2012 HPI6205_ERROR_DSP_PLD
);
2014 } else if (dsp_index
== 1) {
2015 /* DSP 1 is a C6713 */
2016 if (pao
->pci
.subsys_device_id
== 0x8700) {
2017 /* PLD is located at CE1=0x90000000 */
2018 data
= boot_loader_read_mem32(pao
, dsp_index
,
2020 if ((data
& 0xFF) != 0xAA)
2021 return hpi6205_error(dsp_index
,
2022 HPI6205_ERROR_DSP_PLD
);
2024 boot_loader_write_mem32(pao
, dsp_index
, 0x90000000,
2031 /** Transfer data to or from DSP
2032 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2034 static short hpi6205_transfer_data(struct hpi_adapter_obj
*pao
, u8
*p_data
,
2035 u32 data_size
, int operation
)
2037 struct hpi_hw_obj
*phw
= pao
->priv
;
2038 u32 data_transferred
= 0;
2040 #ifndef HPI6205_NO_HSR_POLL
2044 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
2047 return HPI_ERROR_INVALID_DATA_TRANSFER
;
2049 data_size
&= ~3L; /* round data_size down to nearest 4 bytes */
2051 /* make sure state is IDLE */
2052 if (!wait_dsp_ack(phw
, H620_HIF_IDLE
, HPI6205_TIMEOUT
))
2053 return HPI_ERROR_DSP_HARDWARE
;
2055 while (data_transferred
< data_size
) {
2056 u32 this_copy
= data_size
- data_transferred
;
2058 if (this_copy
> HPI6205_SIZEOF_DATA
)
2059 this_copy
= HPI6205_SIZEOF_DATA
;
2061 if (operation
== H620_HIF_SEND_DATA
)
2062 memcpy((void *)&interface
->u
.b_data
[0],
2063 &p_data
[data_transferred
], this_copy
);
2065 interface
->transfer_size_in_bytes
= this_copy
;
2067 #ifdef HPI6205_NO_HSR_POLL
2068 /* DSP must change this back to nOperation */
2069 interface
->dsp_ack
= H620_HIF_IDLE
;
2072 send_dsp_command(phw
, operation
);
2074 #ifdef HPI6205_NO_HSR_POLL
2075 temp2
= wait_dsp_ack(phw
, operation
, HPI6205_TIMEOUT
);
2076 HPI_DEBUG_LOG(DEBUG
, "spun %d times for data xfer of %d\n",
2077 HPI6205_TIMEOUT
- temp2
, this_copy
);
2081 HPI_DEBUG_LOG(ERROR
,
2082 "timed out waiting for " "state %d got %d\n",
2083 operation
, interface
->dsp_ack
);
2088 /* spin waiting on the result */
2089 time_out
= HPI6205_TIMEOUT
;
2091 while ((temp2
== 0) && time_out
--) {
2092 /* give 16k bus mastering transfer time to happen */
2093 /*(16k / 132Mbytes/s = 122usec) */
2094 hpios_delay_micro_seconds(20);
2095 temp2
= ioread32(phw
->prHSR
);
2096 temp2
&= C6205_HSR_INTSRC
;
2098 HPI_DEBUG_LOG(DEBUG
, "spun %d times for data xfer of %d\n",
2099 HPI6205_TIMEOUT
- time_out
, this_copy
);
2100 if (temp2
== C6205_HSR_INTSRC
) {
2101 HPI_DEBUG_LOG(VERBOSE
,
2102 "interrupt from HIF <data> OK\n");
2104 if(interface->dwDspAck != nOperation) {
2105 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2107 interface->dwDspAck,nOperation);
2111 /* need to handle this differently... */
2113 HPI_DEBUG_LOG(ERROR
,
2114 "interrupt from HIF <data> BAD\n");
2115 err
= HPI_ERROR_DSP_HARDWARE
;
2118 /* reset the interrupt from the DSP */
2119 iowrite32(C6205_HSR_INTSRC
, phw
->prHSR
);
2121 if (operation
== H620_HIF_GET_DATA
)
2122 memcpy(&p_data
[data_transferred
],
2123 (void *)&interface
->u
.b_data
[0], this_copy
);
2125 data_transferred
+= this_copy
;
2127 if (interface
->dsp_ack
!= operation
)
2128 HPI_DEBUG_LOG(DEBUG
, "interface->dsp_ack=%d, expected %d\n",
2129 interface
->dsp_ack
, operation
);
2130 /* err=HPI_ERROR_DSP_HARDWARE; */
2132 send_dsp_command(phw
, H620_HIF_IDLE
);
2137 /* wait for up to timeout_us microseconds for the DSP
2138 to signal state by DMA into dwDspAck
2140 static int wait_dsp_ack(struct hpi_hw_obj
*phw
, int state
, int timeout_us
)
2142 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
2143 int t
= timeout_us
/ 4;
2145 rmb(); /* ensure interface->dsp_ack is up to date */
2146 while ((interface
->dsp_ack
!= state
) && --t
) {
2147 hpios_delay_micro_seconds(4);
2148 rmb(); /* DSP changes dsp_ack by DMA */
2151 /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2155 /* set the busmaster interface to cmd, then interrupt the DSP */
2156 static void send_dsp_command(struct hpi_hw_obj
*phw
, int cmd
)
2158 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
2162 interface
->host_cmd
= cmd
;
2163 wmb(); /* DSP gets state by DMA, make sure it is written to memory */
2164 /* before we interrupt the DSP */
2165 r
= ioread32(phw
->prHDCR
);
2166 r
|= (u32
)C6205_HDCR_DSPINT
;
2167 iowrite32(r
, phw
->prHDCR
);
2168 r
&= ~(u32
)C6205_HDCR_DSPINT
;
2169 iowrite32(r
, phw
->prHDCR
);
2172 static unsigned int message_count
;
2174 static u16
message_response_sequence(struct hpi_adapter_obj
*pao
,
2175 struct hpi_message
*phm
, struct hpi_response
*phr
)
2177 #ifndef HPI6205_NO_HSR_POLL
2180 u32 time_out
, time_out2
;
2181 struct hpi_hw_obj
*phw
= pao
->priv
;
2182 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
2186 /* Assume buffer of type struct bus_master_interface
2187 is allocated "noncacheable" */
2189 if (!wait_dsp_ack(phw
, H620_HIF_IDLE
, HPI6205_TIMEOUT
)) {
2190 HPI_DEBUG_LOG(DEBUG
, "timeout waiting for idle\n");
2191 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT
);
2193 interface
->u
.message_buffer
= *phm
;
2194 /* signal we want a response */
2195 send_dsp_command(phw
, H620_HIF_GET_RESP
);
2197 time_out2
= wait_dsp_ack(phw
, H620_HIF_GET_RESP
, HPI6205_TIMEOUT
);
2199 if (time_out2
== 0) {
2200 HPI_DEBUG_LOG(ERROR
,
2201 "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2202 message_count
, interface
->dsp_ack
);
2204 HPI_DEBUG_LOG(VERBOSE
,
2205 "(%u) transition to GET_RESP after %u\n",
2206 message_count
, HPI6205_TIMEOUT
- time_out2
);
2208 /* spin waiting on HIF interrupt flag (end of msg process) */
2209 time_out
= HPI6205_TIMEOUT
;
2211 #ifndef HPI6205_NO_HSR_POLL
2213 while ((temp2
== 0) && --time_out
) {
2214 temp2
= ioread32(phw
->prHSR
);
2215 temp2
&= C6205_HSR_INTSRC
;
2216 hpios_delay_micro_seconds(1);
2218 if (temp2
== C6205_HSR_INTSRC
) {
2219 rmb(); /* ensure we see latest value for dsp_ack */
2220 if ((interface
->dsp_ack
!= H620_HIF_GET_RESP
)) {
2221 HPI_DEBUG_LOG(DEBUG
,
2222 "(%u)interface->dsp_ack(0x%x) != "
2223 "H620_HIF_GET_RESP, t=%u\n", message_count
,
2225 HPI6205_TIMEOUT
- time_out
);
2227 HPI_DEBUG_LOG(VERBOSE
,
2228 "(%u)int with GET_RESP after %u\n",
2229 message_count
, HPI6205_TIMEOUT
- time_out
);
2233 /* can we do anything else in response to the error ? */
2234 HPI_DEBUG_LOG(ERROR
,
2235 "interrupt from HIF module BAD (function %x)\n",
2239 /* reset the interrupt from the DSP */
2240 iowrite32(C6205_HSR_INTSRC
, phw
->prHSR
);
2243 /* read the result */
2245 *phr
= interface
->u
.response_buffer
;
2247 /* set interface back to idle */
2248 send_dsp_command(phw
, H620_HIF_IDLE
);
2250 if ((time_out
== 0) || (time_out2
== 0)) {
2251 HPI_DEBUG_LOG(DEBUG
, "something timed out!\n");
2252 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT
);
2254 /* special case for adapter close - */
2255 /* wait for the DSP to indicate it is idle */
2256 if (phm
->function
== HPI_ADAPTER_CLOSE
) {
2257 if (!wait_dsp_ack(phw
, H620_HIF_IDLE
, HPI6205_TIMEOUT
)) {
2258 HPI_DEBUG_LOG(DEBUG
,
2259 "timeout waiting for idle "
2260 "(on adapter_close)\n");
2261 return hpi6205_error(0,
2262 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT
);
2265 err
= hpi_validate_response(phm
, phr
);
2269 static void hw_message(struct hpi_adapter_obj
*pao
, struct hpi_message
*phm
,
2270 struct hpi_response
*phr
)
2275 hpios_dsplock_lock(pao
);
2277 err
= message_response_sequence(pao
, phm
, phr
);
2279 /* maybe an error response */
2281 /* something failed in the HPI/DSP interface */
2285 /* just the header of the response is valid */
2286 phr
->size
= sizeof(struct hpi_response_header
);
2289 pao
->dsp_crashed
= 0;
2291 if (phr
->error
!= 0) /* something failed in the DSP */
2294 switch (phm
->function
) {
2295 case HPI_OSTREAM_WRITE
:
2296 case HPI_ISTREAM_ANC_WRITE
:
2297 err
= hpi6205_transfer_data(pao
, phm
->u
.d
.u
.data
.pb_data
,
2298 phm
->u
.d
.u
.data
.data_size
, H620_HIF_SEND_DATA
);
2301 case HPI_ISTREAM_READ
:
2302 case HPI_OSTREAM_ANC_READ
:
2303 err
= hpi6205_transfer_data(pao
, phm
->u
.d
.u
.data
.pb_data
,
2304 phm
->u
.d
.u
.data
.data_size
, H620_HIF_GET_DATA
);
2307 case HPI_CONTROL_SET_STATE
:
2308 if (phm
->object
== HPI_OBJ_CONTROLEX
2309 && phm
->u
.cx
.attribute
== HPI_COBRANET_SET_DATA
)
2310 err
= hpi6205_transfer_data(pao
,
2311 phm
->u
.cx
.u
.cobranet_bigdata
.pb_data
,
2312 phm
->u
.cx
.u
.cobranet_bigdata
.byte_count
,
2313 H620_HIF_SEND_DATA
);
2316 case HPI_CONTROL_GET_STATE
:
2317 if (phm
->object
== HPI_OBJ_CONTROLEX
2318 && phm
->u
.cx
.attribute
== HPI_COBRANET_GET_DATA
)
2319 err
= hpi6205_transfer_data(pao
,
2320 phm
->u
.cx
.u
.cobranet_bigdata
.pb_data
,
2321 phr
->u
.cx
.u
.cobranet_data
.byte_count
,
2328 hpios_dsplock_unlock(pao
);