1 /******************************************************************************
3 AudioScience HPI driver
4 Copyright (C) 1997-2014 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 /* not actually used anywhere */
43 /* operational/messaging errors */
44 #define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
45 #define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
47 /* initialization/bootload errors */
48 #define HPI6205_ERROR_6205_NO_IRQ 1002
49 #define HPI6205_ERROR_6205_INIT_FAILED 1003
50 #define HPI6205_ERROR_6205_REG 1006
51 #define HPI6205_ERROR_6205_DSPPAGE 1007
52 #define HPI6205_ERROR_C6713_HPIC 1009
53 #define HPI6205_ERROR_C6713_HPIA 1010
54 #define HPI6205_ERROR_C6713_PLL 1011
55 #define HPI6205_ERROR_DSP_INTMEM 1012
56 #define HPI6205_ERROR_DSP_EXTMEM 1013
57 #define HPI6205_ERROR_DSP_PLD 1014
58 #define HPI6205_ERROR_6205_EEPROM 1017
59 #define HPI6205_ERROR_DSP_EMIF1 1018
60 #define HPI6205_ERROR_DSP_EMIF2 1019
61 #define HPI6205_ERROR_DSP_EMIF3 1020
62 #define HPI6205_ERROR_DSP_EMIF4 1021
64 /*****************************************************************************/
65 /* for C6205 PCI i/f */
66 /* Host Status Register (HSR) bitfields */
67 #define C6205_HSR_INTSRC 0x01
68 #define C6205_HSR_INTAVAL 0x02
69 #define C6205_HSR_INTAM 0x04
70 #define C6205_HSR_CFGERR 0x08
71 #define C6205_HSR_EEREAD 0x10
72 /* Host-to-DSP Control Register (HDCR) bitfields */
73 #define C6205_HDCR_WARMRESET 0x01
74 #define C6205_HDCR_DSPINT 0x02
75 #define C6205_HDCR_PCIBOOT 0x04
76 /* DSP Page Register (DSPP) bitfields, */
77 /* defines 4 Mbyte page that BAR0 points to */
78 #define C6205_DSPP_MAP1 0x400
80 /* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
81 * BAR1 maps to non-prefetchable 8 Mbyte memory block
82 * of DSP memory mapped registers (starting at 0x01800000).
83 * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
84 * needs to be added to the BAR1 base address set in the PCI config reg
86 #define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
87 #define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
88 #define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
89 #define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
91 /* used to control LED (revA) and reset C6713 (revB) */
92 #define C6205_BAR0_TIMER1_CTL (0x01980000L)
94 /* For first 6713 in CE1 space, using DA17,16,2 */
95 #define HPICL_ADDR 0x01400000L
96 #define HPICH_ADDR 0x01400004L
97 #define HPIAL_ADDR 0x01410000L
98 #define HPIAH_ADDR 0x01410004L
99 #define HPIDIL_ADDR 0x01420000L
100 #define HPIDIH_ADDR 0x01420004L
101 #define HPIDL_ADDR 0x01430000L
102 #define HPIDH_ADDR 0x01430004L
104 #define C6713_EMIF_GCTL 0x01800000
105 #define C6713_EMIF_CE1 0x01800004
106 #define C6713_EMIF_CE0 0x01800008
107 #define C6713_EMIF_CE2 0x01800010
108 #define C6713_EMIF_CE3 0x01800014
109 #define C6713_EMIF_SDRAMCTL 0x01800018
110 #define C6713_EMIF_SDRAMTIMING 0x0180001C
111 #define C6713_EMIF_SDRAMEXT 0x01800020
121 struct consistent_dma_area h_locked_mem
;
122 struct bus_master_interface
*p_interface_buffer
;
124 u16 flag_outstream_just_reset
[HPI_MAX_STREAMS
];
125 /* a non-NULL handle means there is an HPI allocated buffer */
126 struct consistent_dma_area instream_host_buffers
[HPI_MAX_STREAMS
];
127 struct consistent_dma_area outstream_host_buffers
[HPI_MAX_STREAMS
];
128 /* non-zero size means a buffer exists, may be external */
129 u32 instream_host_buffer_size
[HPI_MAX_STREAMS
];
130 u32 outstream_host_buffer_size
[HPI_MAX_STREAMS
];
132 struct consistent_dma_area h_control_cache
;
133 struct hpi_control_cache
*p_cache
;
136 /*****************************************************************************/
137 /* local prototypes */
139 #define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
141 static int wait_dsp_ack(struct hpi_hw_obj
*phw
, int state
, int timeout_us
);
143 static void send_dsp_command(struct hpi_hw_obj
*phw
, int cmd
);
145 static u16
adapter_boot_load_dsp(struct hpi_adapter_obj
*pao
,
146 u32
*pos_error_code
);
148 static u16
message_response_sequence(struct hpi_adapter_obj
*pao
,
149 struct hpi_message
*phm
, struct hpi_response
*phr
);
151 static void hw_message(struct hpi_adapter_obj
*pao
, struct hpi_message
*phm
,
152 struct hpi_response
*phr
);
154 #define HPI6205_TIMEOUT 1000000
156 static void subsys_create_adapter(struct hpi_message
*phm
,
157 struct hpi_response
*phr
);
158 static void adapter_delete(struct hpi_adapter_obj
*pao
,
159 struct hpi_message
*phm
, struct hpi_response
*phr
);
161 static u16
create_adapter_obj(struct hpi_adapter_obj
*pao
,
162 u32
*pos_error_code
);
164 static void delete_adapter_obj(struct hpi_adapter_obj
*pao
);
166 static int adapter_irq_query_and_clear(struct hpi_adapter_obj
*pao
,
169 static void outstream_host_buffer_allocate(struct hpi_adapter_obj
*pao
,
170 struct hpi_message
*phm
, struct hpi_response
*phr
);
172 static void outstream_host_buffer_get_info(struct hpi_adapter_obj
*pao
,
173 struct hpi_message
*phm
, struct hpi_response
*phr
);
175 static void outstream_host_buffer_free(struct hpi_adapter_obj
*pao
,
176 struct hpi_message
*phm
, struct hpi_response
*phr
);
177 static void outstream_write(struct hpi_adapter_obj
*pao
,
178 struct hpi_message
*phm
, struct hpi_response
*phr
);
180 static void outstream_get_info(struct hpi_adapter_obj
*pao
,
181 struct hpi_message
*phm
, struct hpi_response
*phr
);
183 static void outstream_start(struct hpi_adapter_obj
*pao
,
184 struct hpi_message
*phm
, struct hpi_response
*phr
);
186 static void outstream_open(struct hpi_adapter_obj
*pao
,
187 struct hpi_message
*phm
, struct hpi_response
*phr
);
189 static void outstream_reset(struct hpi_adapter_obj
*pao
,
190 struct hpi_message
*phm
, struct hpi_response
*phr
);
192 static void instream_host_buffer_allocate(struct hpi_adapter_obj
*pao
,
193 struct hpi_message
*phm
, struct hpi_response
*phr
);
195 static void instream_host_buffer_get_info(struct hpi_adapter_obj
*pao
,
196 struct hpi_message
*phm
, struct hpi_response
*phr
);
198 static void instream_host_buffer_free(struct hpi_adapter_obj
*pao
,
199 struct hpi_message
*phm
, struct hpi_response
*phr
);
201 static void instream_read(struct hpi_adapter_obj
*pao
,
202 struct hpi_message
*phm
, struct hpi_response
*phr
);
204 static void instream_get_info(struct hpi_adapter_obj
*pao
,
205 struct hpi_message
*phm
, struct hpi_response
*phr
);
207 static void instream_start(struct hpi_adapter_obj
*pao
,
208 struct hpi_message
*phm
, struct hpi_response
*phr
);
210 static u32
boot_loader_read_mem32(struct hpi_adapter_obj
*pao
, int dsp_index
,
213 static void boot_loader_write_mem32(struct hpi_adapter_obj
*pao
,
214 int dsp_index
, u32 address
, u32 data
);
216 static u16
boot_loader_config_emif(struct hpi_adapter_obj
*pao
,
219 static u16
boot_loader_test_memory(struct hpi_adapter_obj
*pao
, int dsp_index
,
220 u32 address
, u32 length
);
222 static u16
boot_loader_test_internal_memory(struct hpi_adapter_obj
*pao
,
225 static u16
boot_loader_test_external_memory(struct hpi_adapter_obj
*pao
,
228 static u16
boot_loader_test_pld(struct hpi_adapter_obj
*pao
, int dsp_index
);
230 /*****************************************************************************/
232 static void subsys_message(struct hpi_adapter_obj
*pao
,
233 struct hpi_message
*phm
, struct hpi_response
*phr
)
235 switch (phm
->function
) {
236 case HPI_SUBSYS_CREATE_ADAPTER
:
237 subsys_create_adapter(phm
, phr
);
240 phr
->error
= HPI_ERROR_INVALID_FUNC
;
245 static void control_message(struct hpi_adapter_obj
*pao
,
246 struct hpi_message
*phm
, struct hpi_response
*phr
)
249 struct hpi_hw_obj
*phw
= pao
->priv
;
250 u16 pending_cache_error
= 0;
252 switch (phm
->function
) {
253 case HPI_CONTROL_GET_STATE
:
254 if (pao
->has_control_cache
) {
255 rmb(); /* make sure we see updates DMAed from DSP */
256 if (hpi_check_control_cache(phw
->p_cache
, phm
, phr
)) {
258 } else if (phm
->u
.c
.attribute
== HPI_METER_PEAK
) {
259 pending_cache_error
=
260 HPI_ERROR_CONTROL_CACHING
;
263 hw_message(pao
, phm
, phr
);
264 if (pending_cache_error
&& !phr
->error
)
265 phr
->error
= pending_cache_error
;
267 case HPI_CONTROL_GET_INFO
:
268 hw_message(pao
, phm
, phr
);
270 case HPI_CONTROL_SET_STATE
:
271 hw_message(pao
, phm
, phr
);
272 if (pao
->has_control_cache
)
273 hpi_cmn_control_cache_sync_to_msg(phw
->p_cache
, phm
,
277 phr
->error
= HPI_ERROR_INVALID_FUNC
;
282 static void adapter_message(struct hpi_adapter_obj
*pao
,
283 struct hpi_message
*phm
, struct hpi_response
*phr
)
285 switch (phm
->function
) {
286 case HPI_ADAPTER_DELETE
:
287 adapter_delete(pao
, phm
, phr
);
290 hw_message(pao
, phm
, phr
);
295 static void outstream_message(struct hpi_adapter_obj
*pao
,
296 struct hpi_message
*phm
, struct hpi_response
*phr
)
299 if (phm
->obj_index
>= HPI_MAX_STREAMS
) {
300 phr
->error
= HPI_ERROR_INVALID_OBJ_INDEX
;
301 HPI_DEBUG_LOG(WARNING
,
302 "Message referencing invalid stream %d "
303 "on adapter index %d\n", phm
->obj_index
,
308 switch (phm
->function
) {
309 case HPI_OSTREAM_WRITE
:
310 outstream_write(pao
, phm
, phr
);
312 case HPI_OSTREAM_GET_INFO
:
313 outstream_get_info(pao
, phm
, phr
);
315 case HPI_OSTREAM_HOSTBUFFER_ALLOC
:
316 outstream_host_buffer_allocate(pao
, phm
, phr
);
318 case HPI_OSTREAM_HOSTBUFFER_GET_INFO
:
319 outstream_host_buffer_get_info(pao
, phm
, phr
);
321 case HPI_OSTREAM_HOSTBUFFER_FREE
:
322 outstream_host_buffer_free(pao
, phm
, phr
);
324 case HPI_OSTREAM_START
:
325 outstream_start(pao
, phm
, phr
);
327 case HPI_OSTREAM_OPEN
:
328 outstream_open(pao
, phm
, phr
);
330 case HPI_OSTREAM_RESET
:
331 outstream_reset(pao
, phm
, phr
);
334 hw_message(pao
, phm
, phr
);
339 static void instream_message(struct hpi_adapter_obj
*pao
,
340 struct hpi_message
*phm
, struct hpi_response
*phr
)
343 if (phm
->obj_index
>= HPI_MAX_STREAMS
) {
344 phr
->error
= HPI_ERROR_INVALID_OBJ_INDEX
;
345 HPI_DEBUG_LOG(WARNING
,
346 "Message referencing invalid stream %d "
347 "on adapter index %d\n", phm
->obj_index
,
352 switch (phm
->function
) {
353 case HPI_ISTREAM_READ
:
354 instream_read(pao
, phm
, phr
);
356 case HPI_ISTREAM_GET_INFO
:
357 instream_get_info(pao
, phm
, phr
);
359 case HPI_ISTREAM_HOSTBUFFER_ALLOC
:
360 instream_host_buffer_allocate(pao
, phm
, phr
);
362 case HPI_ISTREAM_HOSTBUFFER_GET_INFO
:
363 instream_host_buffer_get_info(pao
, phm
, phr
);
365 case HPI_ISTREAM_HOSTBUFFER_FREE
:
366 instream_host_buffer_free(pao
, phm
, phr
);
368 case HPI_ISTREAM_START
:
369 instream_start(pao
, phm
, phr
);
372 hw_message(pao
, phm
, phr
);
377 /*****************************************************************************/
378 /** Entry point to this HPI backend
379 * All calls to the HPI start here
382 void _HPI_6205(struct hpi_adapter_obj
*pao
, struct hpi_message
*phm
,
383 struct hpi_response
*phr
)
385 if (pao
&& (pao
->dsp_crashed
>= 10)
386 && (phm
->function
!= HPI_ADAPTER_DEBUG_READ
)) {
387 /* allow last resort debug read even after crash */
388 hpi_init_response(phr
, phm
->object
, phm
->function
,
389 HPI_ERROR_DSP_HARDWARE
);
390 HPI_DEBUG_LOG(WARNING
, " %d,%d dsp crashed.\n", phm
->object
,
395 /* Init default response */
396 if (phm
->function
!= HPI_SUBSYS_CREATE_ADAPTER
)
397 phr
->error
= HPI_ERROR_PROCESSING_MESSAGE
;
399 HPI_DEBUG_LOG(VERBOSE
, "start of switch\n");
401 case HPI_TYPE_REQUEST
:
402 switch (phm
->object
) {
403 case HPI_OBJ_SUBSYSTEM
:
404 subsys_message(pao
, phm
, phr
);
407 case HPI_OBJ_ADAPTER
:
408 adapter_message(pao
, phm
, phr
);
411 case HPI_OBJ_CONTROL
:
412 control_message(pao
, phm
, phr
);
415 case HPI_OBJ_OSTREAM
:
416 outstream_message(pao
, phm
, phr
);
419 case HPI_OBJ_ISTREAM
:
420 instream_message(pao
, phm
, phr
);
424 hw_message(pao
, phm
, phr
);
430 phr
->error
= HPI_ERROR_INVALID_TYPE
;
435 void HPI_6205(struct hpi_message
*phm
, struct hpi_response
*phr
)
437 struct hpi_adapter_obj
*pao
= NULL
;
439 if (phm
->object
!= HPI_OBJ_SUBSYSTEM
) {
440 /* normal messages must have valid adapter index */
441 pao
= hpi_find_adapter(phm
->adapter_index
);
443 /* subsys messages don't address an adapter */
444 _HPI_6205(NULL
, phm
, phr
);
449 _HPI_6205(pao
, phm
, phr
);
451 hpi_init_response(phr
, phm
->object
, phm
->function
,
452 HPI_ERROR_BAD_ADAPTER_NUMBER
);
455 /*****************************************************************************/
458 /** Create an adapter object and initialise it based on resource information
459 * passed in in the message
460 * *** NOTE - you cannot use this function AND the FindAdapters function at the
461 * same time, the application must use only one of them to get the adapters ***
463 static void subsys_create_adapter(struct hpi_message
*phm
,
464 struct hpi_response
*phr
)
466 /* create temp adapter obj, because we don't know what index yet */
467 struct hpi_adapter_obj ao
;
471 HPI_DEBUG_LOG(DEBUG
, " subsys_create_adapter\n");
473 memset(&ao
, 0, sizeof(ao
));
475 ao
.priv
= kzalloc(sizeof(struct hpi_hw_obj
), GFP_KERNEL
);
477 HPI_DEBUG_LOG(ERROR
, "can't get mem for adapter object\n");
478 phr
->error
= HPI_ERROR_MEMORY_ALLOC
;
482 ao
.pci
= *phm
->u
.s
.resource
.r
.pci
;
483 err
= create_adapter_obj(&ao
, &os_error_code
);
485 delete_adapter_obj(&ao
);
486 if (err
>= HPI_ERROR_BACKEND_BASE
) {
487 phr
->error
= HPI_ERROR_DSP_BOOTLOAD
;
488 phr
->specific_error
= err
;
492 phr
->u
.s
.data
= os_error_code
;
496 phr
->u
.s
.adapter_type
= ao
.type
;
497 phr
->u
.s
.adapter_index
= ao
.index
;
501 /** delete an adapter - required by WDM driver */
502 static void adapter_delete(struct hpi_adapter_obj
*pao
,
503 struct hpi_message
*phm
, struct hpi_response
*phr
)
505 struct hpi_hw_obj
*phw
;
508 phr
->error
= HPI_ERROR_INVALID_OBJ_INDEX
;
512 /* reset adapter h/w */
514 boot_loader_write_mem32(pao
, 0, C6205_BAR0_TIMER1_CTL
, 0);
516 iowrite32(C6205_HDCR_WARMRESET
, phw
->prHDCR
);
518 delete_adapter_obj(pao
);
519 hpi_delete_adapter(pao
);
523 /** Create adapter object
524 allocate buffers, bootload DSPs, initialise control cache
526 static u16
create_adapter_obj(struct hpi_adapter_obj
*pao
,
529 struct hpi_hw_obj
*phw
= pao
->priv
;
530 struct bus_master_interface
*interface
;
535 /* init error reporting */
536 pao
->dsp_crashed
= 0;
538 for (i
= 0; i
< HPI_MAX_STREAMS
; i
++)
539 phw
->flag_outstream_just_reset
[i
] = 1;
541 /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
543 pao
->pci
.ap_mem_base
[1] +
544 C6205_BAR1_HSR
/ sizeof(*pao
->pci
.ap_mem_base
[1]);
546 pao
->pci
.ap_mem_base
[1] +
547 C6205_BAR1_HDCR
/ sizeof(*pao
->pci
.ap_mem_base
[1]);
549 pao
->pci
.ap_mem_base
[1] +
550 C6205_BAR1_DSPP
/ sizeof(*pao
->pci
.ap_mem_base
[1]);
552 pao
->has_control_cache
= 0;
554 if (hpios_locked_mem_alloc(&phw
->h_locked_mem
,
555 sizeof(struct bus_master_interface
),
557 phw
->p_interface_buffer
= NULL
;
558 else if (hpios_locked_mem_get_virt_addr(&phw
->h_locked_mem
,
559 (void *)&phw
->p_interface_buffer
))
560 phw
->p_interface_buffer
= NULL
;
562 HPI_DEBUG_LOG(DEBUG
, "interface buffer address %p\n",
563 phw
->p_interface_buffer
);
565 if (phw
->p_interface_buffer
) {
566 memset((void *)phw
->p_interface_buffer
, 0,
567 sizeof(struct bus_master_interface
));
568 phw
->p_interface_buffer
->dsp_ack
= H620_HIF_UNKNOWN
;
571 err
= adapter_boot_load_dsp(pao
, pos_error_code
);
573 HPI_DEBUG_LOG(ERROR
, "DSP code load failed\n");
574 /* no need to clean up as SubSysCreateAdapter */
575 /* calls DeleteAdapter on error. */
578 HPI_DEBUG_LOG(INFO
, "load DSP code OK\n");
580 /* allow boot load even if mem alloc wont work */
581 if (!phw
->p_interface_buffer
)
582 return HPI_ERROR_MEMORY_ALLOC
;
584 interface
= phw
->p_interface_buffer
;
586 /* make sure the DSP has started ok */
587 if (!wait_dsp_ack(phw
, H620_HIF_RESET
, HPI6205_TIMEOUT
* 10)) {
588 HPI_DEBUG_LOG(ERROR
, "timed out waiting reset state \n");
589 return HPI6205_ERROR_6205_INIT_FAILED
;
591 /* Note that *pao, *phw are zeroed after allocation,
592 * so pointers and flags are NULL by default.
593 * Allocate bus mastering control cache buffer and tell the DSP about it
595 if (interface
->control_cache
.number_of_controls
) {
596 u8
*p_control_cache_virtual
;
598 err
= hpios_locked_mem_alloc(&phw
->h_control_cache
,
599 interface
->control_cache
.size_in_bytes
,
602 err
= hpios_locked_mem_get_virt_addr(&phw
->
604 (void *)&p_control_cache_virtual
);
606 memset(p_control_cache_virtual
, 0,
607 interface
->control_cache
.size_in_bytes
);
610 hpi_alloc_control_cache(interface
->
611 control_cache
.number_of_controls
,
612 interface
->control_cache
.size_in_bytes
,
613 p_control_cache_virtual
);
616 err
= HPI_ERROR_MEMORY_ALLOC
;
619 err
= hpios_locked_mem_get_phys_addr(&phw
->
620 h_control_cache
, &phys_addr
);
621 interface
->control_cache
.physical_address32
=
626 pao
->has_control_cache
= 1;
628 if (hpios_locked_mem_valid(&phw
->h_control_cache
))
629 hpios_locked_mem_free(&phw
->h_control_cache
);
630 pao
->has_control_cache
= 0;
633 send_dsp_command(phw
, H620_HIF_IDLE
);
636 struct hpi_message hm
;
637 struct hpi_response hr
;
640 HPI_DEBUG_LOG(VERBOSE
, "init ADAPTER_GET_INFO\n");
641 memset(&hm
, 0, sizeof(hm
));
642 /* wAdapterIndex == version == 0 */
643 hm
.type
= HPI_TYPE_REQUEST
;
644 hm
.size
= sizeof(hm
);
645 hm
.object
= HPI_OBJ_ADAPTER
;
646 hm
.function
= HPI_ADAPTER_GET_INFO
;
648 memset(&hr
, 0, sizeof(hr
));
649 hr
.size
= sizeof(hr
);
651 err
= message_response_sequence(pao
, &hm
, &hr
);
653 HPI_DEBUG_LOG(ERROR
, "message transport error %d\n",
660 pao
->type
= hr
.u
.ax
.info
.adapter_type
;
661 pao
->index
= hr
.u
.ax
.info
.adapter_index
;
664 hr
.u
.ax
.info
.num_outstreams
+
665 hr
.u
.ax
.info
.num_instreams
;
667 HPI_DEBUG_LOG(VERBOSE
,
668 "got adapter info type %x index %d serial %d\n",
669 hr
.u
.ax
.info
.adapter_type
, hr
.u
.ax
.info
.adapter_index
,
670 hr
.u
.ax
.info
.serial_number
);
674 phw
->p_cache
->adap_idx
= pao
->index
;
676 HPI_DEBUG_LOG(INFO
, "bootload DSP OK\n");
678 pao
->irq_query_and_clear
= adapter_irq_query_and_clear
;
679 pao
->instream_host_buffer_status
=
680 phw
->p_interface_buffer
->instream_host_buffer_status
;
681 pao
->outstream_host_buffer_status
=
682 phw
->p_interface_buffer
->outstream_host_buffer_status
;
684 return hpi_add_adapter(pao
);
687 /** Free memory areas allocated by adapter
688 * this routine is called from AdapterDelete,
689 * and SubSysCreateAdapter if duplicate index
691 static void delete_adapter_obj(struct hpi_adapter_obj
*pao
)
693 struct hpi_hw_obj
*phw
= pao
->priv
;
696 if (hpios_locked_mem_valid(&phw
->h_control_cache
)) {
697 hpios_locked_mem_free(&phw
->h_control_cache
);
698 hpi_free_control_cache(phw
->p_cache
);
701 if (hpios_locked_mem_valid(&phw
->h_locked_mem
)) {
702 hpios_locked_mem_free(&phw
->h_locked_mem
);
703 phw
->p_interface_buffer
= NULL
;
706 for (i
= 0; i
< HPI_MAX_STREAMS
; i
++)
707 if (hpios_locked_mem_valid(&phw
->instream_host_buffers
[i
])) {
708 hpios_locked_mem_free(&phw
->instream_host_buffers
[i
]);
709 /*?phw->InStreamHostBuffers[i] = NULL; */
710 phw
->instream_host_buffer_size
[i
] = 0;
713 for (i
= 0; i
< HPI_MAX_STREAMS
; i
++)
714 if (hpios_locked_mem_valid(&phw
->outstream_host_buffers
[i
])) {
715 hpios_locked_mem_free(&phw
->outstream_host_buffers
717 phw
->outstream_host_buffer_size
[i
] = 0;
722 /*****************************************************************************/
723 /* Adapter functions */
724 static int adapter_irq_query_and_clear(struct hpi_adapter_obj
*pao
,
727 struct hpi_hw_obj
*phw
= pao
->priv
;
730 hsr
= ioread32(phw
->prHSR
);
731 if (hsr
& C6205_HSR_INTSRC
) {
732 /* reset the interrupt from the DSP */
733 iowrite32(C6205_HSR_INTSRC
, phw
->prHSR
);
734 return HPI_IRQ_MIXER
;
740 /*****************************************************************************/
741 /* OutStream Host buffer functions */
743 /** Allocate or attach buffer for busmastering
745 static void outstream_host_buffer_allocate(struct hpi_adapter_obj
*pao
,
746 struct hpi_message
*phm
, struct hpi_response
*phr
)
749 u32 command
= phm
->u
.d
.u
.buffer
.command
;
750 struct hpi_hw_obj
*phw
= pao
->priv
;
751 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
753 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
755 if (command
== HPI_BUFFER_CMD_EXTERNAL
756 || command
== HPI_BUFFER_CMD_INTERNAL_ALLOC
) {
757 /* ALLOC phase, allocate a buffer with power of 2 size,
758 get its bus address for PCI bus mastering
760 phm
->u
.d
.u
.buffer
.buffer_size
=
761 roundup_pow_of_two(phm
->u
.d
.u
.buffer
.buffer_size
);
762 /* return old size and allocated size,
763 so caller can detect change */
764 phr
->u
.d
.u
.stream_info
.data_available
=
765 phw
->outstream_host_buffer_size
[phm
->obj_index
];
766 phr
->u
.d
.u
.stream_info
.buffer_size
=
767 phm
->u
.d
.u
.buffer
.buffer_size
;
769 if (phw
->outstream_host_buffer_size
[phm
->obj_index
] ==
770 phm
->u
.d
.u
.buffer
.buffer_size
) {
771 /* Same size, no action required */
775 if (hpios_locked_mem_valid(&phw
->outstream_host_buffers
[phm
->
777 hpios_locked_mem_free(&phw
->outstream_host_buffers
780 err
= hpios_locked_mem_alloc(&phw
->outstream_host_buffers
781 [phm
->obj_index
], phm
->u
.d
.u
.buffer
.buffer_size
,
785 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
786 phw
->outstream_host_buffer_size
[phm
->obj_index
] = 0;
790 err
= hpios_locked_mem_get_phys_addr
791 (&phw
->outstream_host_buffers
[phm
->obj_index
],
792 &phm
->u
.d
.u
.buffer
.pci_address
);
793 /* get the phys addr into msg for single call alloc caller
794 * needs to do this for split alloc (or use the same message)
795 * return the phy address for split alloc in the respose too
797 phr
->u
.d
.u
.stream_info
.auxiliary_data_available
=
798 phm
->u
.d
.u
.buffer
.pci_address
;
801 hpios_locked_mem_free(&phw
->outstream_host_buffers
803 phw
->outstream_host_buffer_size
[phm
->obj_index
] = 0;
804 phr
->error
= HPI_ERROR_MEMORY_ALLOC
;
809 if (command
== HPI_BUFFER_CMD_EXTERNAL
810 || command
== HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER
) {
811 /* GRANT phase. Set up the BBM status, tell the DSP about
812 the buffer so it can start using BBM.
814 struct hpi_hostbuffer_status
*status
;
816 if (phm
->u
.d
.u
.buffer
.buffer_size
& (phm
->u
.d
.u
.buffer
.
819 "Buffer size must be 2^N not %d\n",
820 phm
->u
.d
.u
.buffer
.buffer_size
);
821 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
824 phw
->outstream_host_buffer_size
[phm
->obj_index
] =
825 phm
->u
.d
.u
.buffer
.buffer_size
;
826 status
= &interface
->outstream_host_buffer_status
[phm
->
828 status
->samples_processed
= 0;
829 status
->stream_state
= HPI_STATE_STOPPED
;
830 status
->dsp_index
= 0;
831 status
->host_index
= status
->dsp_index
;
832 status
->size_in_bytes
= phm
->u
.d
.u
.buffer
.buffer_size
;
833 status
->auxiliary_data_available
= 0;
835 hw_message(pao
, phm
, phr
);
838 && hpios_locked_mem_valid(&phw
->
839 outstream_host_buffers
[phm
->obj_index
])) {
840 hpios_locked_mem_free(&phw
->outstream_host_buffers
842 phw
->outstream_host_buffer_size
[phm
->obj_index
] = 0;
847 static void outstream_host_buffer_get_info(struct hpi_adapter_obj
*pao
,
848 struct hpi_message
*phm
, struct hpi_response
*phr
)
850 struct hpi_hw_obj
*phw
= pao
->priv
;
851 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
852 struct hpi_hostbuffer_status
*status
;
855 if (hpios_locked_mem_valid(&phw
->outstream_host_buffers
[phm
->
857 if (hpios_locked_mem_get_virt_addr(&phw
->
858 outstream_host_buffers
[phm
->obj_index
],
859 (void *)&p_bbm_data
)) {
860 phr
->error
= HPI_ERROR_INVALID_OPERATION
;
863 status
= &interface
->outstream_host_buffer_status
[phm
->
865 hpi_init_response(phr
, HPI_OBJ_OSTREAM
,
866 HPI_OSTREAM_HOSTBUFFER_GET_INFO
, 0);
867 phr
->u
.d
.u
.hostbuffer_info
.p_buffer
= p_bbm_data
;
868 phr
->u
.d
.u
.hostbuffer_info
.p_status
= status
;
870 hpi_init_response(phr
, HPI_OBJ_OSTREAM
,
871 HPI_OSTREAM_HOSTBUFFER_GET_INFO
,
872 HPI_ERROR_INVALID_OPERATION
);
876 static void outstream_host_buffer_free(struct hpi_adapter_obj
*pao
,
877 struct hpi_message
*phm
, struct hpi_response
*phr
)
879 struct hpi_hw_obj
*phw
= pao
->priv
;
880 u32 command
= phm
->u
.d
.u
.buffer
.command
;
882 if (phw
->outstream_host_buffer_size
[phm
->obj_index
]) {
883 if (command
== HPI_BUFFER_CMD_EXTERNAL
884 || command
== HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER
) {
885 phw
->outstream_host_buffer_size
[phm
->obj_index
] = 0;
886 hw_message(pao
, phm
, phr
);
887 /* Tell adapter to stop using the host buffer. */
889 if (command
== HPI_BUFFER_CMD_EXTERNAL
890 || command
== HPI_BUFFER_CMD_INTERNAL_FREE
)
891 hpios_locked_mem_free(&phw
->outstream_host_buffers
894 /* Should HPI_ERROR_INVALID_OPERATION be returned
895 if no host buffer is allocated? */
897 hpi_init_response(phr
, HPI_OBJ_OSTREAM
,
898 HPI_OSTREAM_HOSTBUFFER_FREE
, 0);
902 static u32
outstream_get_space_available(struct hpi_hostbuffer_status
*status
)
904 return status
->size_in_bytes
- (status
->host_index
-
908 static void outstream_write(struct hpi_adapter_obj
*pao
,
909 struct hpi_message
*phm
, struct hpi_response
*phr
)
911 struct hpi_hw_obj
*phw
= pao
->priv
;
912 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
913 struct hpi_hostbuffer_status
*status
;
916 if (!phw
->outstream_host_buffer_size
[phm
->obj_index
]) {
917 /* there is no BBM buffer, write via message */
918 hw_message(pao
, phm
, phr
);
922 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
923 status
= &interface
->outstream_host_buffer_status
[phm
->obj_index
];
925 space_available
= outstream_get_space_available(status
);
926 if (space_available
< phm
->u
.d
.u
.data
.data_size
) {
927 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
931 /* HostBuffers is used to indicate host buffer is internally allocated.
932 otherwise, assumed external, data written externally */
933 if (phm
->u
.d
.u
.data
.pb_data
934 && hpios_locked_mem_valid(&phw
->outstream_host_buffers
[phm
->
938 u8
*p_app_data
= (u8
*)phm
->u
.d
.u
.data
.pb_data
;
940 if (hpios_locked_mem_get_virt_addr(&phw
->
941 outstream_host_buffers
[phm
->obj_index
],
942 (void *)&p_bbm_data
)) {
943 phr
->error
= HPI_ERROR_INVALID_OPERATION
;
948 or enough to fit from current to end of BBM buffer */
950 min(phm
->u
.d
.u
.data
.data_size
,
951 status
->size_in_bytes
-
952 (status
->host_index
& (status
->size_in_bytes
- 1)));
955 (status
->host_index
& (status
->size_in_bytes
- 1)),
956 p_app_data
, l_first_write
);
957 /* remaining data if any */
958 memcpy(p_bbm_data
, p_app_data
+ l_first_write
,
959 phm
->u
.d
.u
.data
.data_size
- l_first_write
);
963 * This version relies on the DSP code triggering an OStream buffer
964 * update immediately following a SET_FORMAT call. The host has
965 * already written data into the BBM buffer, but the DSP won't know
966 * about it until dwHostIndex is adjusted.
968 if (phw
->flag_outstream_just_reset
[phm
->obj_index
]) {
969 /* Format can only change after reset. Must tell DSP. */
970 u16 function
= phm
->function
;
971 phw
->flag_outstream_just_reset
[phm
->obj_index
] = 0;
972 phm
->function
= HPI_OSTREAM_SET_FORMAT
;
973 hw_message(pao
, phm
, phr
); /* send the format to the DSP */
974 phm
->function
= function
;
979 status
->host_index
+= phm
->u
.d
.u
.data
.data_size
;
982 static void outstream_get_info(struct hpi_adapter_obj
*pao
,
983 struct hpi_message
*phm
, struct hpi_response
*phr
)
985 struct hpi_hw_obj
*phw
= pao
->priv
;
986 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
987 struct hpi_hostbuffer_status
*status
;
989 if (!phw
->outstream_host_buffer_size
[phm
->obj_index
]) {
990 hw_message(pao
, phm
, phr
);
994 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
996 status
= &interface
->outstream_host_buffer_status
[phm
->obj_index
];
998 phr
->u
.d
.u
.stream_info
.state
= (u16
)status
->stream_state
;
999 phr
->u
.d
.u
.stream_info
.samples_transferred
=
1000 status
->samples_processed
;
1001 phr
->u
.d
.u
.stream_info
.buffer_size
= status
->size_in_bytes
;
1002 phr
->u
.d
.u
.stream_info
.data_available
=
1003 status
->size_in_bytes
- outstream_get_space_available(status
);
1004 phr
->u
.d
.u
.stream_info
.auxiliary_data_available
=
1005 status
->auxiliary_data_available
;
1008 static void outstream_start(struct hpi_adapter_obj
*pao
,
1009 struct hpi_message
*phm
, struct hpi_response
*phr
)
1011 hw_message(pao
, phm
, phr
);
1014 static void outstream_reset(struct hpi_adapter_obj
*pao
,
1015 struct hpi_message
*phm
, struct hpi_response
*phr
)
1017 struct hpi_hw_obj
*phw
= pao
->priv
;
1018 phw
->flag_outstream_just_reset
[phm
->obj_index
] = 1;
1019 hw_message(pao
, phm
, phr
);
1022 static void outstream_open(struct hpi_adapter_obj
*pao
,
1023 struct hpi_message
*phm
, struct hpi_response
*phr
)
1025 outstream_reset(pao
, phm
, phr
);
1028 /*****************************************************************************/
1029 /* InStream Host buffer functions */
1031 static void instream_host_buffer_allocate(struct hpi_adapter_obj
*pao
,
1032 struct hpi_message
*phm
, struct hpi_response
*phr
)
1035 u32 command
= phm
->u
.d
.u
.buffer
.command
;
1036 struct hpi_hw_obj
*phw
= pao
->priv
;
1037 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1039 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
1041 if (command
== HPI_BUFFER_CMD_EXTERNAL
1042 || command
== HPI_BUFFER_CMD_INTERNAL_ALLOC
) {
1044 phm
->u
.d
.u
.buffer
.buffer_size
=
1045 roundup_pow_of_two(phm
->u
.d
.u
.buffer
.buffer_size
);
1046 phr
->u
.d
.u
.stream_info
.data_available
=
1047 phw
->instream_host_buffer_size
[phm
->obj_index
];
1048 phr
->u
.d
.u
.stream_info
.buffer_size
=
1049 phm
->u
.d
.u
.buffer
.buffer_size
;
1051 if (phw
->instream_host_buffer_size
[phm
->obj_index
] ==
1052 phm
->u
.d
.u
.buffer
.buffer_size
) {
1053 /* Same size, no action required */
1057 if (hpios_locked_mem_valid(&phw
->instream_host_buffers
[phm
->
1059 hpios_locked_mem_free(&phw
->instream_host_buffers
1062 err
= hpios_locked_mem_alloc(&phw
->instream_host_buffers
[phm
->
1063 obj_index
], phm
->u
.d
.u
.buffer
.buffer_size
,
1067 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
1068 phw
->instream_host_buffer_size
[phm
->obj_index
] = 0;
1072 err
= hpios_locked_mem_get_phys_addr
1073 (&phw
->instream_host_buffers
[phm
->obj_index
],
1074 &phm
->u
.d
.u
.buffer
.pci_address
);
1075 /* get the phys addr into msg for single call alloc. Caller
1076 needs to do this for split alloc so return the phy address */
1077 phr
->u
.d
.u
.stream_info
.auxiliary_data_available
=
1078 phm
->u
.d
.u
.buffer
.pci_address
;
1080 hpios_locked_mem_free(&phw
->instream_host_buffers
1082 phw
->instream_host_buffer_size
[phm
->obj_index
] = 0;
1083 phr
->error
= HPI_ERROR_MEMORY_ALLOC
;
1088 if (command
== HPI_BUFFER_CMD_EXTERNAL
1089 || command
== HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER
) {
1090 struct hpi_hostbuffer_status
*status
;
1092 if (phm
->u
.d
.u
.buffer
.buffer_size
& (phm
->u
.d
.u
.buffer
.
1094 HPI_DEBUG_LOG(ERROR
,
1095 "Buffer size must be 2^N not %d\n",
1096 phm
->u
.d
.u
.buffer
.buffer_size
);
1097 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
1101 phw
->instream_host_buffer_size
[phm
->obj_index
] =
1102 phm
->u
.d
.u
.buffer
.buffer_size
;
1103 status
= &interface
->instream_host_buffer_status
[phm
->
1105 status
->samples_processed
= 0;
1106 status
->stream_state
= HPI_STATE_STOPPED
;
1107 status
->dsp_index
= 0;
1108 status
->host_index
= status
->dsp_index
;
1109 status
->size_in_bytes
= phm
->u
.d
.u
.buffer
.buffer_size
;
1110 status
->auxiliary_data_available
= 0;
1112 hw_message(pao
, phm
, phr
);
1115 && hpios_locked_mem_valid(&phw
->
1116 instream_host_buffers
[phm
->obj_index
])) {
1117 hpios_locked_mem_free(&phw
->instream_host_buffers
1119 phw
->instream_host_buffer_size
[phm
->obj_index
] = 0;
1124 static void instream_host_buffer_get_info(struct hpi_adapter_obj
*pao
,
1125 struct hpi_message
*phm
, struct hpi_response
*phr
)
1127 struct hpi_hw_obj
*phw
= pao
->priv
;
1128 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1129 struct hpi_hostbuffer_status
*status
;
1132 if (hpios_locked_mem_valid(&phw
->instream_host_buffers
[phm
->
1134 if (hpios_locked_mem_get_virt_addr(&phw
->
1135 instream_host_buffers
[phm
->obj_index
],
1136 (void *)&p_bbm_data
)) {
1137 phr
->error
= HPI_ERROR_INVALID_OPERATION
;
1140 status
= &interface
->instream_host_buffer_status
[phm
->
1142 hpi_init_response(phr
, HPI_OBJ_ISTREAM
,
1143 HPI_ISTREAM_HOSTBUFFER_GET_INFO
, 0);
1144 phr
->u
.d
.u
.hostbuffer_info
.p_buffer
= p_bbm_data
;
1145 phr
->u
.d
.u
.hostbuffer_info
.p_status
= status
;
1147 hpi_init_response(phr
, HPI_OBJ_ISTREAM
,
1148 HPI_ISTREAM_HOSTBUFFER_GET_INFO
,
1149 HPI_ERROR_INVALID_OPERATION
);
1153 static void instream_host_buffer_free(struct hpi_adapter_obj
*pao
,
1154 struct hpi_message
*phm
, struct hpi_response
*phr
)
1156 struct hpi_hw_obj
*phw
= pao
->priv
;
1157 u32 command
= phm
->u
.d
.u
.buffer
.command
;
1159 if (phw
->instream_host_buffer_size
[phm
->obj_index
]) {
1160 if (command
== HPI_BUFFER_CMD_EXTERNAL
1161 || command
== HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER
) {
1162 phw
->instream_host_buffer_size
[phm
->obj_index
] = 0;
1163 hw_message(pao
, phm
, phr
);
1166 if (command
== HPI_BUFFER_CMD_EXTERNAL
1167 || command
== HPI_BUFFER_CMD_INTERNAL_FREE
)
1168 hpios_locked_mem_free(&phw
->instream_host_buffers
1172 /* Should HPI_ERROR_INVALID_OPERATION be returned
1173 if no host buffer is allocated? */
1174 hpi_init_response(phr
, HPI_OBJ_ISTREAM
,
1175 HPI_ISTREAM_HOSTBUFFER_FREE
, 0);
1181 static void instream_start(struct hpi_adapter_obj
*pao
,
1182 struct hpi_message
*phm
, struct hpi_response
*phr
)
1184 hw_message(pao
, phm
, phr
);
1187 static u32
instream_get_bytes_available(struct hpi_hostbuffer_status
*status
)
1189 return status
->dsp_index
- status
->host_index
;
1192 static void instream_read(struct hpi_adapter_obj
*pao
,
1193 struct hpi_message
*phm
, struct hpi_response
*phr
)
1195 struct hpi_hw_obj
*phw
= pao
->priv
;
1196 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1197 struct hpi_hostbuffer_status
*status
;
1201 u8
*p_app_data
= (u8
*)phm
->u
.d
.u
.data
.pb_data
;
1203 if (!phw
->instream_host_buffer_size
[phm
->obj_index
]) {
1204 hw_message(pao
, phm
, phr
);
1207 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
1209 status
= &interface
->instream_host_buffer_status
[phm
->obj_index
];
1210 data_available
= instream_get_bytes_available(status
);
1211 if (data_available
< phm
->u
.d
.u
.data
.data_size
) {
1212 phr
->error
= HPI_ERROR_INVALID_DATASIZE
;
1216 if (hpios_locked_mem_valid(&phw
->instream_host_buffers
[phm
->
1218 if (hpios_locked_mem_get_virt_addr(&phw
->
1219 instream_host_buffers
[phm
->obj_index
],
1220 (void *)&p_bbm_data
)) {
1221 phr
->error
= HPI_ERROR_INVALID_OPERATION
;
1226 or enough to fit from current to end of BBM buffer */
1228 min(phm
->u
.d
.u
.data
.data_size
,
1229 status
->size_in_bytes
-
1230 (status
->host_index
& (status
->size_in_bytes
- 1)));
1234 (status
->host_index
& (status
->size_in_bytes
- 1)),
1236 /* remaining data if any */
1237 memcpy(p_app_data
+ l_first_read
, p_bbm_data
,
1238 phm
->u
.d
.u
.data
.data_size
- l_first_read
);
1240 status
->host_index
+= phm
->u
.d
.u
.data
.data_size
;
1243 static void instream_get_info(struct hpi_adapter_obj
*pao
,
1244 struct hpi_message
*phm
, struct hpi_response
*phr
)
1246 struct hpi_hw_obj
*phw
= pao
->priv
;
1247 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
1248 struct hpi_hostbuffer_status
*status
;
1249 if (!phw
->instream_host_buffer_size
[phm
->obj_index
]) {
1250 hw_message(pao
, phm
, phr
);
1254 status
= &interface
->instream_host_buffer_status
[phm
->obj_index
];
1256 hpi_init_response(phr
, phm
->object
, phm
->function
, 0);
1258 phr
->u
.d
.u
.stream_info
.state
= (u16
)status
->stream_state
;
1259 phr
->u
.d
.u
.stream_info
.samples_transferred
=
1260 status
->samples_processed
;
1261 phr
->u
.d
.u
.stream_info
.buffer_size
= status
->size_in_bytes
;
1262 phr
->u
.d
.u
.stream_info
.data_available
=
1263 instream_get_bytes_available(status
);
1264 phr
->u
.d
.u
.stream_info
.auxiliary_data_available
=
1265 status
->auxiliary_data_available
;
1268 /*****************************************************************************/
1270 #define HPI6205_MAX_FILES_TO_LOAD 2
1272 static u16
adapter_boot_load_dsp(struct hpi_adapter_obj
*pao
,
1273 u32
*pos_error_code
)
1275 struct hpi_hw_obj
*phw
= pao
->priv
;
1276 struct dsp_code dsp_code
;
1277 u16 boot_code_id
[HPI6205_MAX_FILES_TO_LOAD
];
1282 boot_code_id
[0] = HPI_ADAPTER_ASI(0x6205);
1284 boot_code_id
[1] = pao
->pci
.pci_dev
->subsystem_device
;
1285 boot_code_id
[1] = HPI_ADAPTER_FAMILY_ASI(boot_code_id
[1]);
1287 /* fix up cases where bootcode id[1] != subsys id */
1288 switch (boot_code_id
[1]) {
1289 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1290 boot_code_id
[0] = boot_code_id
[1];
1291 boot_code_id
[1] = 0;
1293 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1294 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1295 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1296 boot_code_id
[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
1298 case HPI_ADAPTER_FAMILY_ASI(0x5500):
1299 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1300 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1301 boot_code_id
[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
1303 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1304 boot_code_id
[1] = HPI_ADAPTER_FAMILY_ASI(0x8900);
1310 /* reset DSP by writing a 1 to the WARMRESET bit */
1311 temp
= C6205_HDCR_WARMRESET
;
1312 iowrite32(temp
, phw
->prHDCR
);
1313 hpios_delay_micro_seconds(1000);
1315 /* check that PCI i/f was configured by EEPROM */
1316 temp
= ioread32(phw
->prHSR
);
1317 if ((temp
& (C6205_HSR_CFGERR
| C6205_HSR_EEREAD
)) !=
1319 return HPI6205_ERROR_6205_EEPROM
;
1321 /* disable PINTA interrupt */
1322 iowrite32(temp
, phw
->prHSR
);
1324 /* check control register reports PCI boot mode */
1325 temp
= ioread32(phw
->prHDCR
);
1326 if (!(temp
& C6205_HDCR_PCIBOOT
))
1327 return HPI6205_ERROR_6205_REG
;
1329 /* try writing a few numbers to the DSP page register */
1330 /* and reading them back. */
1332 iowrite32(temp
, phw
->prDSPP
);
1333 if ((temp
| C6205_DSPP_MAP1
) != ioread32(phw
->prDSPP
))
1334 return HPI6205_ERROR_6205_DSPPAGE
;
1336 iowrite32(temp
, phw
->prDSPP
);
1337 if ((temp
| C6205_DSPP_MAP1
) != ioread32(phw
->prDSPP
))
1338 return HPI6205_ERROR_6205_DSPPAGE
;
1340 iowrite32(temp
, phw
->prDSPP
);
1341 if ((temp
| C6205_DSPP_MAP1
) != ioread32(phw
->prDSPP
))
1342 return HPI6205_ERROR_6205_DSPPAGE
;
1343 /* reset DSP page to the correct number */
1345 iowrite32(temp
, phw
->prDSPP
);
1346 if ((temp
| C6205_DSPP_MAP1
) != ioread32(phw
->prDSPP
))
1347 return HPI6205_ERROR_6205_DSPPAGE
;
1350 /* release 6713 from reset before 6205 is bootloaded.
1351 This ensures that the EMIF is inactive,
1352 and the 6713 HPI gets the correct bootmode etc
1354 if (boot_code_id
[1] != 0) {
1355 /* DSP 1 is a C6713 */
1356 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1357 boot_loader_write_mem32(pao
, 0, 0x018C0024, 0x00002202);
1358 hpios_delay_micro_seconds(100);
1359 /* Reset the 6713 #1 - revB */
1360 boot_loader_write_mem32(pao
, 0, C6205_BAR0_TIMER1_CTL
, 0);
1361 /* value of bit 3 is unknown after DSP reset, other bits shoudl be 0 */
1362 if (0 != (boot_loader_read_mem32(pao
, 0,
1363 (C6205_BAR0_TIMER1_CTL
)) & ~8))
1364 return HPI6205_ERROR_6205_REG
;
1365 hpios_delay_micro_seconds(100);
1367 /* Release C6713 from reset - revB */
1368 boot_loader_write_mem32(pao
, 0, C6205_BAR0_TIMER1_CTL
, 4);
1369 if (4 != (boot_loader_read_mem32(pao
, 0,
1370 (C6205_BAR0_TIMER1_CTL
)) & ~8))
1371 return HPI6205_ERROR_6205_REG
;
1372 hpios_delay_micro_seconds(100);
1375 for (dsp
= 0; dsp
< HPI6205_MAX_FILES_TO_LOAD
; dsp
++) {
1376 /* is there a DSP to load? */
1377 if (boot_code_id
[dsp
] == 0)
1380 err
= boot_loader_config_emif(pao
, dsp
);
1384 err
= boot_loader_test_internal_memory(pao
, dsp
);
1388 err
= boot_loader_test_external_memory(pao
, dsp
);
1392 err
= boot_loader_test_pld(pao
, dsp
);
1396 /* write the DSP code down into the DSPs memory */
1397 err
= hpi_dsp_code_open(boot_code_id
[dsp
], pao
->pci
.pci_dev
,
1398 &dsp_code
, pos_error_code
);
1408 err
= hpi_dsp_code_read_word(&dsp_code
, &length
);
1411 if (length
== 0xFFFFFFFF)
1412 break; /* end of code */
1414 err
= hpi_dsp_code_read_word(&dsp_code
, &address
);
1417 err
= hpi_dsp_code_read_word(&dsp_code
, &type
);
1420 err
= hpi_dsp_code_read_block(length
, &dsp_code
,
1424 for (i
= 0; i
< (int)length
; i
++) {
1425 boot_loader_write_mem32(pao
, dsp
, address
,
1427 /* dummy read every 4 words */
1428 /* for 6205 advisory 1.4.4 */
1430 boot_loader_read_mem32(pao
, dsp
,
1438 hpi_dsp_code_close(&dsp_code
);
1443 hpi_dsp_code_rewind(&dsp_code
);
1451 hpi_dsp_code_read_word(&dsp_code
, &length
);
1452 if (length
== 0xFFFFFFFF)
1453 break; /* end of code */
1455 hpi_dsp_code_read_word(&dsp_code
, &address
);
1456 hpi_dsp_code_read_word(&dsp_code
, &type
);
1457 hpi_dsp_code_read_block(length
, &dsp_code
, &pcode
);
1459 for (i
= 0; i
< (int)length
; i
++) {
1460 data
= boot_loader_read_mem32(pao
, dsp
,
1462 if (data
!= *pcode
) {
1472 hpi_dsp_code_close(&dsp_code
);
1477 /* After bootloading all DSPs, start DSP0 running
1478 * The DSP0 code will handle starting and synchronizing with its slaves
1480 if (phw
->p_interface_buffer
) {
1481 /* we need to tell the card the physical PCI address */
1482 u32 physicalPC_iaddress
;
1483 struct bus_master_interface
*interface
=
1484 phw
->p_interface_buffer
;
1485 u32 host_mailbox_address_on_dsp
;
1486 u32 physicalPC_iaddress_verify
= 0;
1488 /* set ack so we know when DSP is ready to go */
1489 /* (dwDspAck will be changed to HIF_RESET) */
1490 interface
->dsp_ack
= H620_HIF_UNKNOWN
;
1491 wmb(); /* ensure ack is written before dsp writes back */
1493 err
= hpios_locked_mem_get_phys_addr(&phw
->h_locked_mem
,
1494 &physicalPC_iaddress
);
1496 /* locate the host mailbox on the DSP. */
1497 host_mailbox_address_on_dsp
= 0x80000000;
1498 while ((physicalPC_iaddress
!= physicalPC_iaddress_verify
)
1500 boot_loader_write_mem32(pao
, 0,
1501 host_mailbox_address_on_dsp
,
1502 physicalPC_iaddress
);
1503 physicalPC_iaddress_verify
=
1504 boot_loader_read_mem32(pao
, 0,
1505 host_mailbox_address_on_dsp
);
1508 HPI_DEBUG_LOG(DEBUG
, "starting DS_ps running\n");
1509 /* enable interrupts */
1510 temp
= ioread32(phw
->prHSR
);
1511 temp
&= ~(u32
)C6205_HSR_INTAM
;
1512 iowrite32(temp
, phw
->prHSR
);
1514 /* start code running... */
1515 temp
= ioread32(phw
->prHDCR
);
1516 temp
|= (u32
)C6205_HDCR_DSPINT
;
1517 iowrite32(temp
, phw
->prHDCR
);
1519 /* give the DSP 10ms to start up */
1520 hpios_delay_micro_seconds(10000);
1525 /*****************************************************************************/
1526 /* Bootloader utility functions */
1528 static u32
boot_loader_read_mem32(struct hpi_adapter_obj
*pao
, int dsp_index
,
1531 struct hpi_hw_obj
*phw
= pao
->priv
;
1533 __iomem u32
*p_data
;
1535 if (dsp_index
== 0) {
1536 /* DSP 0 is always C6205 */
1537 if ((address
>= 0x01800000) & (address
< 0x02000000)) {
1538 /* BAR1 register access */
1539 p_data
= pao
->pci
.ap_mem_base
[1] +
1540 (address
& 0x007fffff) /
1541 sizeof(*pao
->pci
.ap_mem_base
[1]);
1542 /* HPI_DEBUG_LOG(WARNING,
1543 "BAR1 access %08x\n", dwAddress); */
1545 u32 dw4M_page
= address
>> 22L;
1546 if (dw4M_page
!= phw
->dsp_page
) {
1547 phw
->dsp_page
= dw4M_page
;
1549 iowrite32(phw
->dsp_page
, phw
->prDSPP
);
1552 address
&= 0x3fffff; /* address within 4M page */
1553 /* BAR0 memory access */
1554 p_data
= pao
->pci
.ap_mem_base
[0] +
1555 address
/ sizeof(u32
);
1557 data
= ioread32(p_data
);
1558 } else if (dsp_index
== 1) {
1559 /* DSP 1 is a C6713 */
1561 boot_loader_write_mem32(pao
, 0, HPIAL_ADDR
, address
);
1562 boot_loader_write_mem32(pao
, 0, HPIAH_ADDR
, address
>> 16);
1563 lsb
= boot_loader_read_mem32(pao
, 0, HPIDL_ADDR
);
1564 data
= boot_loader_read_mem32(pao
, 0, HPIDH_ADDR
);
1565 data
= (data
<< 16) | (lsb
& 0xFFFF);
1570 static void boot_loader_write_mem32(struct hpi_adapter_obj
*pao
,
1571 int dsp_index
, u32 address
, u32 data
)
1573 struct hpi_hw_obj
*phw
= pao
->priv
;
1574 __iomem u32
*p_data
;
1575 /* u32 dwVerifyData=0; */
1577 if (dsp_index
== 0) {
1578 /* DSP 0 is always C6205 */
1579 if ((address
>= 0x01800000) & (address
< 0x02000000)) {
1580 /* BAR1 - DSP register access using */
1581 /* Non-prefetchable PCI access */
1582 p_data
= pao
->pci
.ap_mem_base
[1] +
1583 (address
& 0x007fffff) /
1584 sizeof(*pao
->pci
.ap_mem_base
[1]);
1586 /* BAR0 access - all of DSP memory using */
1587 /* pre-fetchable PCI access */
1588 u32 dw4M_page
= address
>> 22L;
1589 if (dw4M_page
!= phw
->dsp_page
) {
1590 phw
->dsp_page
= dw4M_page
;
1592 iowrite32(phw
->dsp_page
, phw
->prDSPP
);
1595 address
&= 0x3fffff; /* address within 4M page */
1596 p_data
= pao
->pci
.ap_mem_base
[0] +
1597 address
/ sizeof(u32
);
1599 iowrite32(data
, p_data
);
1600 } else if (dsp_index
== 1) {
1601 /* DSP 1 is a C6713 */
1602 boot_loader_write_mem32(pao
, 0, HPIAL_ADDR
, address
);
1603 boot_loader_write_mem32(pao
, 0, HPIAH_ADDR
, address
>> 16);
1605 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1606 boot_loader_read_mem32(pao
, 0, 0);
1608 boot_loader_write_mem32(pao
, 0, HPIDL_ADDR
, data
);
1609 boot_loader_write_mem32(pao
, 0, HPIDH_ADDR
, data
>> 16);
1611 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1612 boot_loader_read_mem32(pao
, 0, 0);
1616 static u16
boot_loader_config_emif(struct hpi_adapter_obj
*pao
, int dsp_index
)
1618 if (dsp_index
== 0) {
1621 /* DSP 0 is always C6205 */
1624 /* memory map of C6205 */
1625 /* 00000000-0000FFFF 16Kx32 internal program */
1626 /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
1630 /* Global EMIF control */
1631 boot_loader_write_mem32(pao
, dsp_index
, 0x01800000, 0x3779);
1640 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1641 setting
= 0x00000030;
1642 boot_loader_write_mem32(pao
, dsp_index
, 0x01800008, setting
);
1643 if (setting
!= boot_loader_read_mem32(pao
, dsp_index
,
1645 return HPI6205_ERROR_DSP_EMIF1
;
1647 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1648 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1649 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1650 /* WST should be 71, but 63 is max possible */
1652 (1L << WS_OFS
) | (63L << WST_OFS
) | (1L << WH_OFS
) |
1653 (1L << RS_OFS
) | (63L << RST_OFS
) | (1L << RH_OFS
) |
1655 boot_loader_write_mem32(pao
, dsp_index
, 0x01800004, setting
);
1656 if (setting
!= boot_loader_read_mem32(pao
, dsp_index
,
1658 return HPI6205_ERROR_DSP_EMIF2
;
1660 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1661 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1662 /* plenty of wait states */
1664 (1L << WS_OFS
) | (28L << WST_OFS
) | (1L << WH_OFS
) |
1665 (1L << RS_OFS
) | (63L << RST_OFS
) | (1L << RH_OFS
) |
1667 boot_loader_write_mem32(pao
, dsp_index
, 0x01800010, setting
);
1668 if (setting
!= boot_loader_read_mem32(pao
, dsp_index
,
1670 return HPI6205_ERROR_DSP_EMIF3
;
1672 /* EMIF CE3 setup - 32 bit async. */
1673 /* This is the PLD on the ASI5000 cards only */
1675 (1L << WS_OFS
) | (10L << WST_OFS
) | (1L << WH_OFS
) |
1676 (1L << RS_OFS
) | (10L << RST_OFS
) | (1L << RH_OFS
) |
1678 boot_loader_write_mem32(pao
, dsp_index
, 0x01800014, setting
);
1679 if (setting
!= boot_loader_read_mem32(pao
, dsp_index
,
1681 return HPI6205_ERROR_DSP_EMIF4
;
1683 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1684 /* need to use this else DSP code crashes? */
1685 boot_loader_write_mem32(pao
, dsp_index
, 0x01800018,
1688 /* EMIF SDRAM Refresh Timing */
1689 /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
1690 boot_loader_write_mem32(pao
, dsp_index
, 0x0180001C,
1693 } else if (dsp_index
== 1) {
1694 /* test access to the C6713s HPI registers */
1695 u32 write_data
= 0, read_data
= 0, i
= 0;
1697 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1699 boot_loader_write_mem32(pao
, 0, HPICL_ADDR
, write_data
);
1700 boot_loader_write_mem32(pao
, 0, HPICH_ADDR
, write_data
);
1701 /* C67 HPI is on lower 16bits of 32bit EMIF */
1703 0xFFF7 & boot_loader_read_mem32(pao
, 0, HPICL_ADDR
);
1704 if (write_data
!= read_data
) {
1705 HPI_DEBUG_LOG(ERROR
, "HPICL %x %x\n", write_data
,
1707 return HPI6205_ERROR_C6713_HPIC
;
1709 /* HPIA - walking ones test */
1711 for (i
= 0; i
< 32; i
++) {
1712 boot_loader_write_mem32(pao
, 0, HPIAL_ADDR
,
1714 boot_loader_write_mem32(pao
, 0, HPIAH_ADDR
,
1715 (write_data
>> 16));
1717 0xFFFF & boot_loader_read_mem32(pao
, 0,
1720 read_data
| ((0xFFFF &
1721 boot_loader_read_mem32(pao
, 0,
1724 if (read_data
!= write_data
) {
1725 HPI_DEBUG_LOG(ERROR
, "HPIA %x %x\n",
1726 write_data
, read_data
);
1727 return HPI6205_ERROR_C6713_HPIA
;
1729 write_data
= write_data
<< 1;
1733 * ** C6713 datasheet says we cannot program PLL from HPI,
1734 * and indeed if we try to set the PLL multiply from the HPI,
1735 * the PLL does not seem to lock, so we enable the PLL and
1736 * use the default multiply of x 7, which for a 27MHz clock
1737 * gives a DSP speed of 189MHz
1740 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C100, 0x0000);
1741 hpios_delay_micro_seconds(1000);
1742 /* EMIF = 189/3=63MHz */
1743 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C120, 0x8002);
1745 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C11C, 0x8001);
1747 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C118, 0x8000);
1748 hpios_delay_micro_seconds(1000);
1749 /* ** SGT test to take GPO3 high when we start the PLL */
1750 /* and low when the delay is completed */
1751 /* FSX0 <- '1' (GPO3) */
1752 boot_loader_write_mem32(pao
, 0, (0x018C0024L
), 0x00002A0A);
1753 /* PLL not bypassed */
1754 boot_loader_write_mem32(pao
, dsp_index
, 0x01B7C100, 0x0001);
1755 hpios_delay_micro_seconds(1000);
1756 /* FSX0 <- '0' (GPO3) */
1757 boot_loader_write_mem32(pao
, 0, (0x018C0024L
), 0x00002A02);
1759 /* 6205 EMIF CE1 resetup - 32 bit async. */
1760 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1761 boot_loader_write_mem32(pao
, 0, 0x01800004, /* CE1 */
1762 (1L << WS_OFS
) | (8L << WST_OFS
) | (1L << WH_OFS
) |
1763 (1L << RS_OFS
) | (12L << RST_OFS
) | (1L << RH_OFS
) |
1766 hpios_delay_micro_seconds(1000);
1768 /* check that we can read one of the PLL registers */
1769 /* PLL should not be bypassed! */
1770 if ((boot_loader_read_mem32(pao
, dsp_index
, 0x01B7C100) & 0xF)
1772 return HPI6205_ERROR_C6713_PLL
;
1774 /* setup C67x EMIF (note this is the only use of
1775 BAR1 via BootLoader_WriteMem32) */
1776 boot_loader_write_mem32(pao
, dsp_index
, C6713_EMIF_GCTL
,
1779 /* EMIF CE0 setup - 2Mx32 Sync DRAM
1786 7..4 MTYPE 0011 Sync DRAM 32bits
1790 boot_loader_write_mem32(pao
, dsp_index
, C6713_EMIF_CE0
,
1793 /* EMIF SDRAM Extension
1795 31-21 0000b 0000b 000b
1796 20 WR2RD = 2cycles-1 = 1b
1798 19-18 WR2DEAC = 3cycle-1 = 10b
1799 17 WR2WR = 2cycle-1 = 1b
1800 16-15 R2WDQM = 4cycle-1 = 11b
1801 14-12 RD2WR = 6cycles-1 = 101b
1803 11-10 RD2DEAC = 4cycle-1 = 11b
1804 9 RD2RD = 2cycle-1 = 1b
1805 8-7 THZP = 3cycle-1 = 10b
1806 6-5 TWR = 2cycle-1 = 01b (tWR = 17ns)
1807 4 TRRD = 2cycle = 0b (tRRD = 14ns)
1808 3-1 TRAS = 5cycle-1 = 100b (Tras=42ns)
1809 1 CAS latency = 3cyc = 1b
1810 (for Micron 2M32-7 operating at 100MHz)
1812 boot_loader_write_mem32(pao
, dsp_index
, C6713_EMIF_SDRAMEXT
,
1815 /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
1818 29..28 SDRSZ 00b 11 row address pins
1820 27..26 SDCSZ 01b 8 column address pins
1821 25 RFEN 1b refersh enabled
1822 24 INIT 1b init SDRAM!
1824 23..20 TRCD 0001b (Trcd/Tcyc)-1 = (20/10)-1 = 1
1826 19..16 TRP 0001b (Trp/Tcyc)-1 = (20/10)-1 = 1
1828 15..12 TRC 0110b (Trc/Tcyc)-1 = (70/10)-1 = 6
1830 11..0 - 0000b 0000b 0000b
1832 boot_loader_write_mem32(pao
, dsp_index
, C6713_EMIF_SDRAMCTL
,
1835 /* SDRAM refresh timing
1836 Need 4,096 refresh cycles every 64ms = 15.625us = 1562cycles of 100MHz = 0x61A
1838 boot_loader_write_mem32(pao
, dsp_index
,
1839 C6713_EMIF_SDRAMTIMING
, 0x00000410);
1841 hpios_delay_micro_seconds(1000);
1842 } else if (dsp_index
== 2) {
1843 /* DSP 2 is a C6713 */
1849 static u16
boot_loader_test_memory(struct hpi_adapter_obj
*pao
, int dsp_index
,
1850 u32 start_address
, u32 length
)
1854 u32 test_data
= 0, data
= 0;
1858 /* for 1st word, test each bit in the 32bit word, */
1859 /* dwLength specifies number of 32bit words to test */
1860 /*for(i=0; i<dwLength; i++) */
1863 test_addr
= start_address
+ i
* 4;
1864 test_data
= 0x00000001;
1865 for (j
= 0; j
< 32; j
++) {
1866 boot_loader_write_mem32(pao
, dsp_index
, test_addr
,
1868 data
= boot_loader_read_mem32(pao
, dsp_index
,
1870 if (data
!= test_data
) {
1871 HPI_DEBUG_LOG(VERBOSE
,
1872 "Memtest error details "
1873 "%08x %08x %08x %i\n", test_addr
,
1874 test_data
, data
, dsp_index
);
1875 return 1; /* error */
1877 test_data
= test_data
<< 1;
1881 /* for the next 100 locations test each location, leaving it as zero */
1882 /* write a zero to the next word in memory before we read */
1883 /* the previous write to make sure every memory location is unique */
1884 for (i
= 0; i
< 100; i
++) {
1885 test_addr
= start_address
+ i
* 4;
1886 test_data
= 0xA5A55A5A;
1887 boot_loader_write_mem32(pao
, dsp_index
, test_addr
, test_data
);
1888 boot_loader_write_mem32(pao
, dsp_index
, test_addr
+ 4, 0);
1889 data
= boot_loader_read_mem32(pao
, dsp_index
, test_addr
);
1890 if (data
!= test_data
) {
1891 HPI_DEBUG_LOG(VERBOSE
,
1892 "Memtest error details "
1893 "%08x %08x %08x %i\n", test_addr
, test_data
,
1895 return 1; /* error */
1897 /* leave location as zero */
1898 boot_loader_write_mem32(pao
, dsp_index
, test_addr
, 0x0);
1901 /* zero out entire memory block */
1902 for (i
= 0; i
< length
; i
++) {
1903 test_addr
= start_address
+ i
* 4;
1904 boot_loader_write_mem32(pao
, dsp_index
, test_addr
, 0x0);
1909 static u16
boot_loader_test_internal_memory(struct hpi_adapter_obj
*pao
,
1913 if (dsp_index
== 0) {
1914 /* DSP 0 is a C6205 */
1916 err
= boot_loader_test_memory(pao
, dsp_index
, 0x00000000,
1920 err
= boot_loader_test_memory(pao
, dsp_index
,
1921 0x80000000, 0x10000);
1922 } else if (dsp_index
== 1) {
1923 /* DSP 1 is a C6713 */
1924 /* 192K internal mem */
1925 err
= boot_loader_test_memory(pao
, dsp_index
, 0x00000000,
1928 /* 64K internal mem / L2 cache */
1929 err
= boot_loader_test_memory(pao
, dsp_index
,
1930 0x00030000, 0x10000);
1934 return HPI6205_ERROR_DSP_INTMEM
;
1939 static u16
boot_loader_test_external_memory(struct hpi_adapter_obj
*pao
,
1942 u32 dRAM_start_address
= 0;
1945 if (dsp_index
== 0) {
1946 /* only test for SDRAM if an ASI5000 card */
1947 if (pao
->pci
.pci_dev
->subsystem_device
== 0x5000) {
1948 /* DSP 0 is always C6205 */
1949 dRAM_start_address
= 0x00400000;
1950 dRAM_size
= 0x200000;
1951 /*dwDRAMinc=1024; */
1954 } else if (dsp_index
== 1) {
1955 /* DSP 1 is a C6713 */
1956 dRAM_start_address
= 0x80000000;
1957 dRAM_size
= 0x200000;
1958 /*dwDRAMinc=1024; */
1961 if (boot_loader_test_memory(pao
, dsp_index
, dRAM_start_address
,
1963 return HPI6205_ERROR_DSP_EXTMEM
;
1967 static u16
boot_loader_test_pld(struct hpi_adapter_obj
*pao
, int dsp_index
)
1970 if (dsp_index
== 0) {
1971 /* only test for DSP0 PLD on ASI5000 card */
1972 if (pao
->pci
.pci_dev
->subsystem_device
== 0x5000) {
1973 /* PLD is located at CE3=0x03000000 */
1974 data
= boot_loader_read_mem32(pao
, dsp_index
,
1976 if ((data
& 0xF) != 0x5)
1977 return HPI6205_ERROR_DSP_PLD
;
1978 data
= boot_loader_read_mem32(pao
, dsp_index
,
1980 if ((data
& 0xF) != 0xA)
1981 return HPI6205_ERROR_DSP_PLD
;
1983 } else if (dsp_index
== 1) {
1984 /* DSP 1 is a C6713 */
1985 if (pao
->pci
.pci_dev
->subsystem_device
== 0x8700) {
1986 /* PLD is located at CE1=0x90000000 */
1987 data
= boot_loader_read_mem32(pao
, dsp_index
,
1989 if ((data
& 0xFF) != 0xAA)
1990 return HPI6205_ERROR_DSP_PLD
;
1992 boot_loader_write_mem32(pao
, dsp_index
, 0x90000000,
1999 /** Transfer data to or from DSP
2000 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2002 static short hpi6205_transfer_data(struct hpi_adapter_obj
*pao
, u8
*p_data
,
2003 u32 data_size
, int operation
)
2005 struct hpi_hw_obj
*phw
= pao
->priv
;
2006 u32 data_transferred
= 0;
2009 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
2012 return HPI_ERROR_INVALID_DATA_POINTER
;
2014 data_size
&= ~3L; /* round data_size down to nearest 4 bytes */
2016 /* make sure state is IDLE */
2017 if (!wait_dsp_ack(phw
, H620_HIF_IDLE
, HPI6205_TIMEOUT
))
2018 return HPI_ERROR_DSP_HARDWARE
;
2020 while (data_transferred
< data_size
) {
2021 u32 this_copy
= data_size
- data_transferred
;
2023 if (this_copy
> HPI6205_SIZEOF_DATA
)
2024 this_copy
= HPI6205_SIZEOF_DATA
;
2026 if (operation
== H620_HIF_SEND_DATA
)
2027 memcpy((void *)&interface
->u
.b_data
[0],
2028 &p_data
[data_transferred
], this_copy
);
2030 interface
->transfer_size_in_bytes
= this_copy
;
2032 /* DSP must change this back to nOperation */
2033 interface
->dsp_ack
= H620_HIF_IDLE
;
2034 send_dsp_command(phw
, operation
);
2036 temp2
= wait_dsp_ack(phw
, operation
, HPI6205_TIMEOUT
);
2037 HPI_DEBUG_LOG(DEBUG
, "spun %d times for data xfer of %d\n",
2038 HPI6205_TIMEOUT
- temp2
, this_copy
);
2042 HPI_DEBUG_LOG(ERROR
,
2043 "Timed out waiting for " "state %d got %d\n",
2044 operation
, interface
->dsp_ack
);
2048 if (operation
== H620_HIF_GET_DATA
)
2049 memcpy(&p_data
[data_transferred
],
2050 (void *)&interface
->u
.b_data
[0], this_copy
);
2052 data_transferred
+= this_copy
;
2054 if (interface
->dsp_ack
!= operation
)
2055 HPI_DEBUG_LOG(DEBUG
, "interface->dsp_ack=%d, expected %d\n",
2056 interface
->dsp_ack
, operation
);
2057 /* err=HPI_ERROR_DSP_HARDWARE; */
2059 send_dsp_command(phw
, H620_HIF_IDLE
);
2064 /* wait for up to timeout_us microseconds for the DSP
2065 to signal state by DMA into dwDspAck
2067 static int wait_dsp_ack(struct hpi_hw_obj
*phw
, int state
, int timeout_us
)
2069 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
2070 int t
= timeout_us
/ 4;
2072 rmb(); /* ensure interface->dsp_ack is up to date */
2073 while ((interface
->dsp_ack
!= state
) && --t
) {
2074 hpios_delay_micro_seconds(4);
2075 rmb(); /* DSP changes dsp_ack by DMA */
2078 /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2082 /* set the busmaster interface to cmd, then interrupt the DSP */
2083 static void send_dsp_command(struct hpi_hw_obj
*phw
, int cmd
)
2085 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
2088 interface
->host_cmd
= cmd
;
2089 wmb(); /* DSP gets state by DMA, make sure it is written to memory */
2090 /* before we interrupt the DSP */
2091 r
= ioread32(phw
->prHDCR
);
2092 r
|= (u32
)C6205_HDCR_DSPINT
;
2093 iowrite32(r
, phw
->prHDCR
);
2094 r
&= ~(u32
)C6205_HDCR_DSPINT
;
2095 iowrite32(r
, phw
->prHDCR
);
2098 static unsigned int message_count
;
2100 static u16
message_response_sequence(struct hpi_adapter_obj
*pao
,
2101 struct hpi_message
*phm
, struct hpi_response
*phr
)
2103 u32 time_out
, time_out2
;
2104 struct hpi_hw_obj
*phw
= pao
->priv
;
2105 struct bus_master_interface
*interface
= phw
->p_interface_buffer
;
2109 if (phm
->size
> sizeof(interface
->u
.message_buffer
)) {
2110 phr
->error
= HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL
;
2111 phr
->specific_error
= sizeof(interface
->u
.message_buffer
);
2112 phr
->size
= sizeof(struct hpi_response_header
);
2113 HPI_DEBUG_LOG(ERROR
,
2114 "message len %d too big for buffer %zd \n", phm
->size
,
2115 sizeof(interface
->u
.message_buffer
));
2119 /* Assume buffer of type struct bus_master_interface_62
2120 is allocated "noncacheable" */
2122 if (!wait_dsp_ack(phw
, H620_HIF_IDLE
, HPI6205_TIMEOUT
)) {
2123 HPI_DEBUG_LOG(DEBUG
, "timeout waiting for idle\n");
2124 return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT
;
2127 memcpy(&interface
->u
.message_buffer
, phm
, phm
->size
);
2128 /* signal we want a response */
2129 send_dsp_command(phw
, H620_HIF_GET_RESP
);
2131 time_out2
= wait_dsp_ack(phw
, H620_HIF_GET_RESP
, HPI6205_TIMEOUT
);
2134 HPI_DEBUG_LOG(ERROR
,
2135 "(%u) Timed out waiting for " "GET_RESP state [%x]\n",
2136 message_count
, interface
->dsp_ack
);
2138 HPI_DEBUG_LOG(VERBOSE
,
2139 "(%u) transition to GET_RESP after %u\n",
2140 message_count
, HPI6205_TIMEOUT
- time_out2
);
2142 /* spin waiting on HIF interrupt flag (end of msg process) */
2143 time_out
= HPI6205_TIMEOUT
;
2145 /* read the result */
2147 if (interface
->u
.response_buffer
.response
.size
<= phr
->size
)
2148 memcpy(phr
, &interface
->u
.response_buffer
,
2149 interface
->u
.response_buffer
.response
.size
);
2151 HPI_DEBUG_LOG(ERROR
,
2152 "response len %d too big for buffer %d\n",
2153 interface
->u
.response_buffer
.response
.size
,
2155 memcpy(phr
, &interface
->u
.response_buffer
,
2156 sizeof(struct hpi_response_header
));
2157 phr
->error
= HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL
;
2158 phr
->specific_error
=
2159 interface
->u
.response_buffer
.response
.size
;
2160 phr
->size
= sizeof(struct hpi_response_header
);
2163 /* set interface back to idle */
2164 send_dsp_command(phw
, H620_HIF_IDLE
);
2166 if (!time_out
|| !time_out2
) {
2167 HPI_DEBUG_LOG(DEBUG
, "something timed out!\n");
2168 return HPI6205_ERROR_MSG_RESP_TIMEOUT
;
2170 /* special case for adapter close - */
2171 /* wait for the DSP to indicate it is idle */
2172 if (phm
->function
== HPI_ADAPTER_CLOSE
) {
2173 if (!wait_dsp_ack(phw
, H620_HIF_IDLE
, HPI6205_TIMEOUT
)) {
2174 HPI_DEBUG_LOG(DEBUG
,
2175 "Timeout waiting for idle "
2176 "(on adapter_close)\n");
2177 return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT
;
2180 err
= hpi_validate_response(phm
, phr
);
2184 static void hw_message(struct hpi_adapter_obj
*pao
, struct hpi_message
*phm
,
2185 struct hpi_response
*phr
)
2190 hpios_dsplock_lock(pao
);
2192 err
= message_response_sequence(pao
, phm
, phr
);
2194 /* maybe an error response */
2196 /* something failed in the HPI/DSP interface */
2197 if (err
>= HPI_ERROR_BACKEND_BASE
) {
2198 phr
->error
= HPI_ERROR_DSP_COMMUNICATION
;
2199 phr
->specific_error
= err
;
2206 /* just the header of the response is valid */
2207 phr
->size
= sizeof(struct hpi_response_header
);
2210 pao
->dsp_crashed
= 0;
2212 if (phr
->error
!= 0) /* something failed in the DSP */
2215 switch (phm
->function
) {
2216 case HPI_OSTREAM_WRITE
:
2217 case HPI_ISTREAM_ANC_WRITE
:
2218 err
= hpi6205_transfer_data(pao
, phm
->u
.d
.u
.data
.pb_data
,
2219 phm
->u
.d
.u
.data
.data_size
, H620_HIF_SEND_DATA
);
2222 case HPI_ISTREAM_READ
:
2223 case HPI_OSTREAM_ANC_READ
:
2224 err
= hpi6205_transfer_data(pao
, phm
->u
.d
.u
.data
.pb_data
,
2225 phm
->u
.d
.u
.data
.data_size
, H620_HIF_GET_DATA
);
2232 hpios_dsplock_unlock(pao
);