From 9099095634b7c959954a1d420c277b743e6ee7f6 Mon Sep 17 00:00:00 2001 From: sruffell Date: Wed, 2 Jan 2008 20:30:58 +0000 Subject: VPMADT032 stability changes for wctdm24xxp and wcte12xp: - Remove double reads. - Wait for writes to complete before starting reads. - Optimize reads of multi-word register. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3592 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wctdm24xxp/GpakCust.c | 152 +++++++++++++++++++++++++++++++++--------------- wctdm24xxp/base.c | 3 - wctdm24xxp/wctdm24xxp.h | 2 +- 3 files changed, 106 insertions(+), 51 deletions(-) (limited to 'wctdm24xxp') diff --git a/wctdm24xxp/GpakCust.c b/wctdm24xxp/GpakCust.c index e8e91c4..1291e33 100644 --- a/wctdm24xxp/GpakCust.c +++ b/wctdm24xxp/GpakCust.c @@ -105,51 +105,97 @@ static inline struct vpm150m_cmd * vpm150m_empty_slot(struct wctdm *wc) int x; for (x = 0; x < VPM150M_MAX_COMMANDS; x++) - if (!wc->vpm150m->cmdq[x].desc) + if (!wc->vpm150m->cmdq[x].desc) { return &wc->vpm150m->cmdq[x]; + } return NULL; } +/* Wait for any outstanding commands to be completed. */ +static inline int vpm150m_io_wait(struct wctdm *wc) +{ + int x; + int ret=0; + for (x=0; x < VPM150M_MAX_COMMANDS;) { + if (wc->vpm150m->cmdq[x].desc) { + if ((ret=schluffen(&wc->regq))) { + return ret; + } + x=0; + } + else { + ++x; + } + } + return ret; +} -unsigned short wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf) +int wctdm_vpm150m_getreg_full_async(struct wctdm *wc, int pagechange, unsigned int len, + unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p) { + int ret=0; unsigned long flags; - volatile struct vpm150m_cmd *hit; - unsigned short ret = 0; - int i; + BUG_ON(!hit_p); + spin_lock_irqsave(&wc->reglock, flags); + (*hit_p) = vpm150m_empty_slot(wc); + if (*hit_p) { + (*hit_p)->desc = __VPM150M_RD; + if (pagechange) { + (*hit_p)->desc |= __VPM150M_RWPAGE; + } + (*hit_p)->datalen = len; + (*hit_p)->addr = addr; + memset((*hit_p)->data, 0, len*sizeof(outbuf[0])); + } + else { + ret = -EBUSY; + } + spin_unlock_irqrestore(&wc->reglock, flags); + return ret; +} + +int wctdm_vpm150m_getreg_full_return(struct wctdm *wc, int pagechange, unsigned int len, + unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p) +{ + int ret = 0; + unsigned long flags; + BUG_ON(!hit_p); + spin_lock_irqsave(&wc->reglock, flags); do { - spin_lock_irqsave(&wc->reglock, flags); - hit = vpm150m_empty_slot(wc); - if (hit) { - hit->desc = __VPM150M_RD; - if (pagechange) { - hit->desc |= __VPM150M_RWPAGE; - } - hit->datalen = len; - hit->addr = addr; - for (i = 0; i < hit->datalen; i++) - hit->data[i] = 0x0000; + if ((*hit_p)->desc & __VPM150M_FIN) { + memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0]))); + (*hit_p)->desc = 0; + (*hit_p) = NULL; + ret = 0; } - spin_unlock_irqrestore(&wc->reglock, flags); - if (!hit) { - if ((ret = schluffen(&wc->regq))) + else { + spin_unlock_irqrestore(&wc->reglock, flags); + if ((ret=schluffen(&wc->regq))) { return ret; + } + spin_lock_irqsave(&wc->reglock, flags); + ret = -EBUSY; } - } while (!hit); + } while (-EBUSY == ret); + spin_unlock_irqrestore(&wc->reglock, flags); + return ret; +} + +int wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf) +{ + struct vpm150m_cmd *hit = 0; + int ret = 0; do { - spin_lock_irqsave(&wc->reglock, flags); - if (hit->desc & __VPM150M_FIN) { - for (i = 0; i < hit->datalen; i++) - outbuf[i] = hit->data[i]; - hit->desc = 0; - hit = NULL; - } - spin_unlock_irqrestore(&wc->reglock, flags); - if (hit) { - if ((ret = schluffen(&wc->regq))) - return ret; + ret = wctdm_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit); + if (!hit) { + if ( -EBUSY == ret ) { + if ((ret = schluffen(&wc->regq))) + return ret; + } + BUG_ON(0 != ret); } - } while (hit); + } while (!hit); + ret = wctdm_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit); return ret; } @@ -202,17 +248,10 @@ unsigned char wctdm_vpm150m_getpage(struct wctdm *wc) unsigned short wctdm_vpm150m_getreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data) { unsigned short res; - unsigned short count=0; - unsigned short first_data=0; - do { - wctdm_vpm150m_setpage(wc, addr >> 16); - if ((addr >> 16) != ((addr + len) >> 16)) - printk("getreg: You found it!\n"); - if (count > 0) { - first_data = *data; - } - res = wctdm_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data); - } while(((0==count++) || (first_data != *data)) && (count < 100)); + wctdm_vpm150m_setpage(wc, addr >> 16); + if ((addr >> 16) != ((addr + len) >> 16)) + printk("getreg: You found it!\n"); + res = wctdm_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data); return res; } @@ -247,9 +286,29 @@ void gpakReadDspMemory( struct wctdm *wc = wc_find_iface(DspId); int i; int transcount; - - //printk("Reading %d words from memory\n"); - if (wc && wc->vpm150m) { + int ret; + + vpm150m_io_wait(wc); + if ( NumWords < VPM150M_MAX_COMMANDS ) { + struct vpm150m_cmd* cmds[VPM150M_MAX_COMMANDS] = {0}; + wctdm_vpm150m_setpage(wc, DspAddress >> 16); + DspAddress &= 0xffff; + for (i=0; i < NumWords; ++i) { + ret = wctdm_vpm150m_getreg_full_async(wc,0,1,DspAddress+i,&pWordValues[i], + &cmds[i]); + if (0 != ret) { + return ret; + } + } + for (i=NumWords-1; i >=0; --i) { + ret = wctdm_vpm150m_getreg_full_return(wc,0,1,DspAddress+i,&pWordValues[i], + &cmds[i]); + if (0 != ret) { + return ret; + } + } + } + else { for (i = 0; i < NumWords;) { if ((NumWords - i) > VPM150M_MAX_DATA) transcount = VPM150M_MAX_DATA; @@ -262,7 +321,6 @@ void gpakReadDspMemory( return; } - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * gpakWriteDspMemory - Write DSP memory. * diff --git a/wctdm24xxp/base.c b/wctdm24xxp/base.c index eef087d..323e7af 100644 --- a/wctdm24xxp/base.c +++ b/wctdm24xxp/base.c @@ -3087,8 +3087,6 @@ static enum vpmadt032_init_result wctdm_vpm150m_init(struct wctdm *wc) while (test_bit(VPM150M_HPIRESET, &vpm150m->control)) schluffen(&wc->regq); - msleep(1000); - printk("VPMADT032 Loading firwmare... "); downloadstatus = gpakDownloadDsp(vpm150m->dspid, &fw); @@ -3107,7 +3105,6 @@ static enum vpmadt032_init_result wctdm_vpm150m_init(struct wctdm *wc) while (test_bit(VPM150M_SWRESET, &vpm150m->control)) schluffen(&wc->regq); - msleep(1000); #if 0 } #endif diff --git a/wctdm24xxp/wctdm24xxp.h b/wctdm24xxp/wctdm24xxp.h index 8e41d66..c5d6042 100644 --- a/wctdm24xxp/wctdm24xxp.h +++ b/wctdm24xxp/wctdm24xxp.h @@ -147,7 +147,7 @@ struct vpm150m { unsigned long desiredecstate; unsigned long curdtmfmutestate; unsigned long desireddtmfmutestate; - struct vpm150m_cmd cmdq[MAX_COMMANDS]; + struct vpm150m_cmd cmdq[VPM150M_MAX_COMMANDS]; unsigned char curtone[24]; }; -- cgit v1.2.3