~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to sound/pci/asihpi/hpi6000.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

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