2
* Copyright (c) 2005, Adaptive Digital Technologies, Inc.
4
* File Name: GpakCust.c
7
* This file contains host system dependent functions to support generic
8
* G.PAK API functions. The file is integrated into the host processor
9
* connected to C55x G.PAK DSPs via a Host Port Interface.
11
* Note: This file needs to be modified by the G.PAK system integrator.
16
* 06/15/05 - Initial release.
18
* This program has been released under the terms of the GPL version 2 by
19
* permission of Adaptive Digital Technologies, Inc. The standard
20
* GPL disclaimer is given inline below for your convenience.
22
* This program is free software; you can redistribute it and/or modify
23
* it under the terms of the GNU General Public License as published by
24
* the Free Software Foundation; either version 2 of the License, or
25
* (at your option) any later version.
27
* This program is distributed in the hope that it will be useful,
28
* but WITHOUT ANY WARRANTY; without even the implied warranty of
29
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
* GNU General Public License for more details.
32
* You should have received a copy of the GNU General Public License
33
* along with this program; if not, write to the Free Software
34
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38
#include <linux/version.h>
39
#include <linux/delay.h>
40
#include <asm/semaphore.h>
43
#include "wctdm24xxp.h"
46
char vpm150mtone_to_zaptone(GpakToneCodes_t tone)
88
static inline struct wctdm * wc_find_iface(unsigned short dspid)
91
struct wctdm *ret = NULL;
94
spin_lock_irqsave(&ifacelock, flags);
95
for (i = 0; i < WC_MAX_IFACES; i++)
96
if (ifaces[i] && ifaces[i]->vpm150m && (ifaces[i]->vpm150m->dspid == dspid))
98
spin_unlock_irqrestore(&ifacelock, flags);
103
static inline struct vpm150m_cmd * vpm150m_empty_slot(struct wctdm *wc)
107
for (x = 0; x < VPM150M_MAX_COMMANDS; x++)
108
if (!wc->vpm150m->cmdq[x].desc) {
109
return &wc->vpm150m->cmdq[x];
114
/* Wait for any outstanding commands to be completed. */
115
static inline int vpm150m_io_wait(struct wctdm *wc)
119
for (x=0; x < VPM150M_MAX_COMMANDS;) {
120
if (wc->vpm150m->cmdq[x].desc) {
121
if ((ret=schluffen(&wc->regq))) {
133
int wctdm_vpm150m_getreg_full_async(struct wctdm *wc, int pagechange, unsigned int len,
134
unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
139
spin_lock_irqsave(&wc->reglock, flags);
140
(*hit_p) = vpm150m_empty_slot(wc);
142
(*hit_p)->desc = __VPM150M_RD;
144
(*hit_p)->desc |= __VPM150M_RWPAGE;
146
(*hit_p)->datalen = len;
147
(*hit_p)->addr = addr;
148
memset((*hit_p)->data, 0, len*sizeof(outbuf[0]));
153
spin_unlock_irqrestore(&wc->reglock, flags);
157
int wctdm_vpm150m_getreg_full_return(struct wctdm *wc, int pagechange, unsigned int len,
158
unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
163
spin_lock_irqsave(&wc->reglock, flags);
165
if ((*hit_p)->desc & __VPM150M_FIN) {
166
memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0])));
172
spin_unlock_irqrestore(&wc->reglock, flags);
173
if ((ret=schluffen(&wc->regq))) {
176
spin_lock_irqsave(&wc->reglock, flags);
179
} while (-EBUSY == ret);
180
spin_unlock_irqrestore(&wc->reglock, flags);
184
int wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
186
struct vpm150m_cmd *hit = 0;
189
ret = wctdm_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit);
191
if ( -EBUSY == ret ) {
192
if ((ret = schluffen(&wc->regq)))
198
ret = wctdm_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit);
202
int wctdm_vpm150m_setreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned int addr, unsigned short *data)
205
struct vpm150m_cmd *hit;
208
spin_lock_irqsave(&wc->reglock, flags);
209
hit = vpm150m_empty_slot(wc);
211
hit->desc = __VPM150M_WR;
213
hit->desc |= __VPM150M_RWPAGE;
216
for (i = 0; i < len; i++)
217
hit->data[i] = data[i];
219
spin_unlock_irqrestore(&wc->reglock, flags);
221
if ((ret = schluffen(&wc->regq)))
225
return (hit) ? 0 : -1;
228
int wctdm_vpm150m_setpage(struct wctdm *wc, unsigned short addr)
231
/* Let's optimize this a little bit */
232
if (wc->vpm150m->curpage == addr)
235
wc->vpm150m->curpage = addr;
238
return wctdm_vpm150m_setreg_full(wc, 1, 1, 0, &addr);
241
unsigned char wctdm_vpm150m_getpage(struct wctdm *wc)
244
wctdm_vpm150m_getreg_full(wc, 1, 1, 0, &res);
248
unsigned short wctdm_vpm150m_getreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data)
251
wctdm_vpm150m_setpage(wc, addr >> 16);
252
if ((addr >> 16) != ((addr + len) >> 16))
253
printk("getreg: You found it!\n");
254
res = wctdm_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
258
int wctdm_vpm150m_setreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data)
261
wctdm_vpm150m_setpage(wc, addr >> 16);
262
if ((addr >> 16) != ((addr + len) >> 16))
263
printk("getreg: You found it!\n");
264
res = wctdm_vpm150m_setreg_full(wc, 0, len, addr & 0xffff, data);
268
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
269
* gpakReadDspMemory - Read DSP memory.
272
* This function reads a contiguous block of words from DSP memory starting at
273
* the specified address.
279
void gpakReadDspMemory(
280
unsigned short int DspId, /* DSP Identifier (0 to MAX_DSP_CORES-1) */
281
DSP_ADDRESS DspAddress, /* DSP's memory address of first word */
282
unsigned int NumWords, /* number of contiguous words to read */
283
DSP_WORD *pWordValues /* pointer to array of word values variable */
286
struct wctdm *wc = wc_find_iface(DspId);
292
if ( NumWords < VPM150M_MAX_COMMANDS ) {
293
struct vpm150m_cmd* cmds[VPM150M_MAX_COMMANDS] = {0};
294
wctdm_vpm150m_setpage(wc, DspAddress >> 16);
295
DspAddress &= 0xffff;
296
for (i=0; i < NumWords; ++i) {
297
ret = wctdm_vpm150m_getreg_full_async(wc,0,1,DspAddress+i,&pWordValues[i],
303
for (i=NumWords-1; i >=0; --i) {
304
ret = wctdm_vpm150m_getreg_full_return(wc,0,1,DspAddress+i,&pWordValues[i],
312
for (i = 0; i < NumWords;) {
313
if ((NumWords - i) > VPM150M_MAX_DATA)
314
transcount = VPM150M_MAX_DATA;
316
transcount = NumWords - i;
317
wctdm_vpm150m_getreg(wc, transcount, DspAddress + i, &pWordValues[i]);
324
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
325
* gpakWriteDspMemory - Write DSP memory.
328
* This function writes a contiguous block of words to DSP memory starting at
329
* the specified address.
335
void gpakWriteDspMemory(
336
unsigned short int DspId, /* DSP Identifier (0 to MAX_DSP_CORES-1) */
337
DSP_ADDRESS DspAddress, /* DSP's memory address of first word */
338
unsigned int NumWords, /* number of contiguous words to write */
339
DSP_WORD *pWordValues /* pointer to array of word values to write */
343
struct wctdm *wc = wc_find_iface(DspId);
347
//printk("Writing %d words to memory\n", NumWords);
348
if (wc && wc->vpm150m) {
349
for (i = 0; i < NumWords;) {
350
if ((NumWords - i) > VPM150M_MAX_DATA)
351
transcount = VPM150M_MAX_DATA;
353
transcount = NumWords - i;
355
wctdm_vpm150m_setreg(wc, transcount, DspAddress + i, &pWordValues[i]);
359
for (i = 0; i < NumWords; i++) {
360
if (wctdm_vpm150m_getreg(wc, DspAddress + i) != pWordValues[i]) {
361
printk("Error in write. Address %x is not %x\n", DspAddress + i, pWordValues[i]);
371
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
372
* gpakHostDelay - Delay for a fixed time interval.
375
* This function delays for a fixed time interval before returning. The time
376
* interval is the Host Port Interface sampling period when polling a DSP for
377
* replies to command messages.
383
void gpakHostDelay(void)
388
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
389
* gpakLockAccess - Lock access to the specified DSP.
392
* This function aquires exclusive access to the specified DSP.
398
void gpakLockAccess(unsigned short DspId)
402
wc = wc_find_iface(DspId);
405
struct vpm150m *vpm = wc->vpm150m;
408
down_interruptible(&vpm->sem);
413
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
414
* gpakUnlockAccess - Unlock access to the specified DSP.
417
* This function releases exclusive access to the specified DSP.
423
void gpakUnlockAccess(unsigned short DspId)
427
wc = wc_find_iface(DspId);
430
struct vpm150m *vpm = wc->vpm150m;
438
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
439
* gpakReadFile - Read a block of bytes from a G.PAK Download file.
442
* This function reads a contiguous block of bytes from a G.PAK Download file
443
* starting at the current file position.
446
* The number of bytes read from the file.
447
* -1 indicates an error occurred.
448
* 0 indicates all bytes have been read (end of file)
452
GPAK_FILE_ID FileId, /* G.PAK Download File Identifier */
453
unsigned char *pBuffer, /* pointer to buffer for storing bytes */
454
unsigned int NumBytes /* number of bytes to read */
457
#ifdef VPM150M_SUPPORT
458
struct wctdm_firmware *fw = FileId;
459
unsigned int i, count;
464
if (NumBytes > (fw->fw->size - fw->offset))
465
count = fw->fw->size - fw->offset;
469
for (i = 0; i < count; i++)
470
pBuffer[i] = fw->fw->data[fw->offset + i];