linux/drivers/char/mwave/3780i.c
<<
>>
Prefs
   1/*
   2*
   3* 3780i.c -- helper routines for the 3780i DSP
   4*
   5*
   6* Written By: Mike Sullivan IBM Corporation
   7*
   8* Copyright (C) 1999 IBM Corporation
   9*
  10* This program is free software; you can redistribute it and/or modify
  11* it under the terms of the GNU General Public License as published by
  12* the Free Software Foundation; either version 2 of the License, or
  13* (at your option) any later version.
  14*
  15* This program is distributed in the hope that it will be useful,
  16* but WITHOUT ANY WARRANTY; without even the implied warranty of
  17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18* GNU General Public License for more details.
  19*
  20* NO WARRANTY
  21* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  22* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  23* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  24* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  25* solely responsible for determining the appropriateness of using and
  26* distributing the Program and assumes all risks associated with its
  27* exercise of rights under this Agreement, including but not limited to
  28* the risks and costs of program errors, damage to or loss of data,
  29* programs or equipment, and unavailability or interruption of operations.
  30*
  31* DISCLAIMER OF LIABILITY
  32* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  33* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  34* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  35* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  36* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  37* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  38* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  39*
  40* You should have received a copy of the GNU General Public License
  41* along with this program; if not, write to the Free Software
  42* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  43*
  44*
  45* 10/23/2000 - Alpha Release
  46*       First release to the public
  47*/
  48
  49#include <linux/kernel.h>
  50#include <linux/unistd.h>
  51#include <linux/delay.h>
  52#include <linux/ioport.h>
  53#include <linux/bitops.h>
  54#include <linux/sched.h>        /* cond_resched() */
  55
  56#include <asm/io.h>
  57#include <asm/uaccess.h>
  58#include <asm/irq.h>
  59#include "smapi.h"
  60#include "mwavedd.h"
  61#include "3780i.h"
  62
  63static DEFINE_SPINLOCK(dsp_lock);
  64
  65static void PaceMsaAccess(unsigned short usDspBaseIO)
  66{
  67        cond_resched();
  68        udelay(100);
  69        cond_resched();
  70}
  71
  72unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
  73                                   unsigned long ulMsaAddr)
  74{
  75        unsigned long flags;
  76        unsigned short val;
  77
  78        PRINTK_3(TRACE_3780I,
  79                "3780i::dsp3780I_ReadMsaCfg entry usDspBaseIO %x ulMsaAddr %lx\n",
  80                usDspBaseIO, ulMsaAddr);
  81
  82        spin_lock_irqsave(&dsp_lock, flags);
  83        OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr);
  84        OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16));
  85        val = InWordDsp(DSP_MsaDataDSISHigh);
  86        spin_unlock_irqrestore(&dsp_lock, flags);
  87
  88        PRINTK_2(TRACE_3780I, "3780i::dsp3780I_ReadMsaCfg exit val %x\n", val);
  89
  90        return val;
  91}
  92
  93void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
  94                          unsigned long ulMsaAddr, unsigned short usValue)
  95{
  96        unsigned long flags;
  97
  98        PRINTK_4(TRACE_3780I,
  99                "3780i::dsp3780i_WriteMsaCfg entry usDspBaseIO %x ulMsaAddr %lx usValue %x\n",
 100                usDspBaseIO, ulMsaAddr, usValue);
 101
 102        spin_lock_irqsave(&dsp_lock, flags);
 103        OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr);
 104        OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16));
 105        OutWordDsp(DSP_MsaDataDSISHigh, usValue);
 106        spin_unlock_irqrestore(&dsp_lock, flags);
 107}
 108
 109static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
 110                                 unsigned char ucValue)
 111{
 112        DSP_ISA_SLAVE_CONTROL rSlaveControl;
 113        DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
 114
 115
 116        PRINTK_4(TRACE_3780I,
 117                "3780i::dsp3780i_WriteGenCfg entry usDspBaseIO %x uIndex %x ucValue %x\n",
 118                usDspBaseIO, uIndex, ucValue);
 119
 120        MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl);
 121
 122        PRINTK_2(TRACE_3780I,
 123                "3780i::dsp3780i_WriteGenCfg rSlaveControl %x\n",
 124                MKBYTE(rSlaveControl));
 125
 126        rSlaveControl_Save = rSlaveControl;
 127        rSlaveControl.ConfigMode = true;
 128
 129        PRINTK_2(TRACE_3780I,
 130                "3780i::dsp3780i_WriteGenCfg entry rSlaveControl+ConfigMode %x\n",
 131                MKBYTE(rSlaveControl));
 132
 133        OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl));
 134        OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex);
 135        OutByteDsp(DSP_ConfigData, ucValue);
 136        OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save));
 137
 138        PRINTK_1(TRACE_3780I, "3780i::dsp3780i_WriteGenCfg exit\n");
 139
 140
 141}
 142
 143#if 0
 144unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
 145                                  unsigned uIndex)
 146{
 147        DSP_ISA_SLAVE_CONTROL rSlaveControl;
 148        DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
 149        unsigned char ucValue;
 150
 151
 152        PRINTK_3(TRACE_3780I,
 153                "3780i::dsp3780i_ReadGenCfg entry usDspBaseIO %x uIndex %x\n",
 154                usDspBaseIO, uIndex);
 155
 156        MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl);
 157        rSlaveControl_Save = rSlaveControl;
 158        rSlaveControl.ConfigMode = true;
 159        OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl));
 160        OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex);
 161        ucValue = InByteDsp(DSP_ConfigData);
 162        OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save));
 163
 164        PRINTK_2(TRACE_3780I,
 165                "3780i::dsp3780i_ReadGenCfg exit ucValue %x\n", ucValue);
 166
 167
 168        return ucValue;
 169}
 170#endif  /*  0  */
 171
 172int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
 173                       unsigned short *pIrqMap,
 174                       unsigned short *pDmaMap)
 175{
 176        unsigned long flags;
 177        unsigned short usDspBaseIO = pSettings->usDspBaseIO;
 178        int i;
 179        DSP_UART_CFG_1 rUartCfg1;
 180        DSP_UART_CFG_2 rUartCfg2;
 181        DSP_HBRIDGE_CFG_1 rHBridgeCfg1;
 182        DSP_HBRIDGE_CFG_2 rHBridgeCfg2;
 183        DSP_BUSMASTER_CFG_1 rBusmasterCfg1;
 184        DSP_BUSMASTER_CFG_2 rBusmasterCfg2;
 185        DSP_ISA_PROT_CFG rIsaProtCfg;
 186        DSP_POWER_MGMT_CFG rPowerMgmtCfg;
 187        DSP_HBUS_TIMER_CFG rHBusTimerCfg;
 188        DSP_LBUS_TIMEOUT_DISABLE rLBusTimeoutDisable;
 189        DSP_CHIP_RESET rChipReset;
 190        DSP_CLOCK_CONTROL_1 rClockControl1;
 191        DSP_CLOCK_CONTROL_2 rClockControl2;
 192        DSP_ISA_SLAVE_CONTROL rSlaveControl;
 193        DSP_HBRIDGE_CONTROL rHBridgeControl;
 194        unsigned short ChipID = 0;
 195        unsigned short tval;
 196
 197
 198        PRINTK_2(TRACE_3780I,
 199                "3780i::dsp3780I_EnableDSP entry pSettings->bDSPEnabled %x\n",
 200                pSettings->bDSPEnabled);
 201
 202
 203        if (!pSettings->bDSPEnabled) {
 204                PRINTK_ERROR( KERN_ERR "3780i::dsp3780I_EnableDSP: Error: DSP not enabled. Aborting.\n" );
 205                return -EIO;
 206        }
 207
 208
 209        PRINTK_2(TRACE_3780I,
 210                "3780i::dsp3780i_EnableDSP entry pSettings->bModemEnabled %x\n",
 211                pSettings->bModemEnabled);
 212
 213        if (pSettings->bModemEnabled) {
 214                rUartCfg1.Reserved = rUartCfg2.Reserved = 0;
 215                rUartCfg1.IrqActiveLow = pSettings->bUartIrqActiveLow;
 216                rUartCfg1.IrqPulse = pSettings->bUartIrqPulse;
 217                rUartCfg1.Irq =
 218                        (unsigned char) pIrqMap[pSettings->usUartIrq];
 219                switch (pSettings->usUartBaseIO) {
 220                case 0x03F8:
 221                        rUartCfg1.BaseIO = 0;
 222                        break;
 223                case 0x02F8:
 224                        rUartCfg1.BaseIO = 1;
 225                        break;
 226                case 0x03E8:
 227                        rUartCfg1.BaseIO = 2;
 228                        break;
 229                case 0x02E8:
 230                        rUartCfg1.BaseIO = 3;
 231                        break;
 232                }
 233                rUartCfg2.Enable = true;
 234        }
 235
 236        rHBridgeCfg1.Reserved = rHBridgeCfg2.Reserved = 0;
 237        rHBridgeCfg1.IrqActiveLow = pSettings->bDspIrqActiveLow;
 238        rHBridgeCfg1.IrqPulse = pSettings->bDspIrqPulse;
 239        rHBridgeCfg1.Irq = (unsigned char) pIrqMap[pSettings->usDspIrq];
 240        rHBridgeCfg1.AccessMode = 1;
 241        rHBridgeCfg2.Enable = true;
 242
 243
 244        rBusmasterCfg2.Reserved = 0;
 245        rBusmasterCfg1.Dma = (unsigned char) pDmaMap[pSettings->usDspDma];
 246        rBusmasterCfg1.NumTransfers =
 247                (unsigned char) pSettings->usNumTransfers;
 248        rBusmasterCfg1.ReRequest = (unsigned char) pSettings->usReRequest;
 249        rBusmasterCfg1.MEMCS16 = pSettings->bEnableMEMCS16;
 250        rBusmasterCfg2.IsaMemCmdWidth =
 251                (unsigned char) pSettings->usIsaMemCmdWidth;
 252
 253
 254        rIsaProtCfg.Reserved = 0;
 255        rIsaProtCfg.GateIOCHRDY = pSettings->bGateIOCHRDY;
 256
 257        rPowerMgmtCfg.Reserved = 0;
 258        rPowerMgmtCfg.Enable = pSettings->bEnablePwrMgmt;
 259
 260        rHBusTimerCfg.LoadValue =
 261                (unsigned char) pSettings->usHBusTimerLoadValue;
 262
 263        rLBusTimeoutDisable.Reserved = 0;
 264        rLBusTimeoutDisable.DisableTimeout =
 265                pSettings->bDisableLBusTimeout;
 266
 267        MKWORD(rChipReset) = ~pSettings->usChipletEnable;
 268
 269        rClockControl1.Reserved1 = rClockControl1.Reserved2 = 0;
 270        rClockControl1.N_Divisor = pSettings->usN_Divisor;
 271        rClockControl1.M_Multiplier = pSettings->usM_Multiplier;
 272
 273        rClockControl2.Reserved = 0;
 274        rClockControl2.PllBypass = pSettings->bPllBypass;
 275
 276        /* Issue a soft reset to the chip */
 277        /* Note: Since we may be coming in with 3780i clocks suspended, we must keep
 278        * soft-reset active for 10ms.
 279        */
 280        rSlaveControl.ClockControl = 0;
 281        rSlaveControl.SoftReset = true;
 282        rSlaveControl.ConfigMode = false;
 283        rSlaveControl.Reserved = 0;
 284
 285        PRINTK_4(TRACE_3780I,
 286                "3780i::dsp3780i_EnableDSP usDspBaseIO %x index %x taddr %x\n",
 287                usDspBaseIO, DSP_IsaSlaveControl,
 288                usDspBaseIO + DSP_IsaSlaveControl);
 289
 290        PRINTK_2(TRACE_3780I,
 291                "3780i::dsp3780i_EnableDSP rSlaveContrl %x\n",
 292                MKWORD(rSlaveControl));
 293
 294        spin_lock_irqsave(&dsp_lock, flags);
 295        OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
 296        MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl);
 297
 298        PRINTK_2(TRACE_3780I,
 299                "3780i::dsp3780i_EnableDSP rSlaveControl 2 %x\n", tval);
 300
 301
 302        for (i = 0; i < 11; i++)
 303                udelay(2000);
 304
 305        rSlaveControl.SoftReset = false;
 306        OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
 307
 308        MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl);
 309
 310        PRINTK_2(TRACE_3780I,
 311                "3780i::dsp3780i_EnableDSP rSlaveControl 3 %x\n", tval);
 312
 313
 314        /* Program our general configuration registers */
 315        WriteGenCfg(DSP_HBridgeCfg1Index, MKBYTE(rHBridgeCfg1));
 316        WriteGenCfg(DSP_HBridgeCfg2Index, MKBYTE(rHBridgeCfg2));
 317        WriteGenCfg(DSP_BusMasterCfg1Index, MKBYTE(rBusmasterCfg1));
 318        WriteGenCfg(DSP_BusMasterCfg2Index, MKBYTE(rBusmasterCfg2));
 319        WriteGenCfg(DSP_IsaProtCfgIndex, MKBYTE(rIsaProtCfg));
 320        WriteGenCfg(DSP_PowerMgCfgIndex, MKBYTE(rPowerMgmtCfg));
 321        WriteGenCfg(DSP_HBusTimerCfgIndex, MKBYTE(rHBusTimerCfg));
 322
 323        if (pSettings->bModemEnabled) {
 324                WriteGenCfg(DSP_UartCfg1Index, MKBYTE(rUartCfg1));
 325                WriteGenCfg(DSP_UartCfg2Index, MKBYTE(rUartCfg2));
 326        }
 327
 328
 329        rHBridgeControl.EnableDspInt = false;
 330        rHBridgeControl.MemAutoInc = true;
 331        rHBridgeControl.IoAutoInc = false;
 332        rHBridgeControl.DiagnosticMode = false;
 333
 334        PRINTK_3(TRACE_3780I,
 335                "3780i::dsp3780i_EnableDSP DSP_HBridgeControl %x rHBridgeControl %x\n",
 336                DSP_HBridgeControl, MKWORD(rHBridgeControl));
 337
 338        OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
 339        spin_unlock_irqrestore(&dsp_lock, flags);
 340        WriteMsaCfg(DSP_LBusTimeoutDisable, MKWORD(rLBusTimeoutDisable));
 341        WriteMsaCfg(DSP_ClockControl_1, MKWORD(rClockControl1));
 342        WriteMsaCfg(DSP_ClockControl_2, MKWORD(rClockControl2));
 343        WriteMsaCfg(DSP_ChipReset, MKWORD(rChipReset));
 344
 345        ChipID = ReadMsaCfg(DSP_ChipID);
 346
 347        PRINTK_2(TRACE_3780I,
 348                "3780i::dsp3780I_EnableDSP exiting bRC=true, ChipID %x\n",
 349                ChipID);
 350
 351        return 0;
 352}
 353
 354int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings)
 355{
 356        unsigned long flags;
 357        unsigned short usDspBaseIO = pSettings->usDspBaseIO;
 358        DSP_ISA_SLAVE_CONTROL rSlaveControl;
 359
 360
 361        PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP entry\n");
 362
 363        rSlaveControl.ClockControl = 0;
 364        rSlaveControl.SoftReset = true;
 365        rSlaveControl.ConfigMode = false;
 366        rSlaveControl.Reserved = 0;
 367        spin_lock_irqsave(&dsp_lock, flags);
 368        OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
 369
 370        udelay(5);
 371
 372        rSlaveControl.ClockControl = 1;
 373        OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
 374        spin_unlock_irqrestore(&dsp_lock, flags);
 375
 376        udelay(5);
 377
 378
 379        PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP exit\n");
 380
 381        return 0;
 382}
 383
 384int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings)
 385{
 386        unsigned long flags;
 387        unsigned short usDspBaseIO = pSettings->usDspBaseIO;
 388        DSP_BOOT_DOMAIN rBootDomain;
 389        DSP_HBRIDGE_CONTROL rHBridgeControl;
 390
 391
 392        PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset entry\n");
 393
 394        spin_lock_irqsave(&dsp_lock, flags);
 395        /* Mask DSP to PC interrupt */
 396        MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
 397
 398        PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rHBridgeControl %x\n",
 399                MKWORD(rHBridgeControl));
 400
 401        rHBridgeControl.EnableDspInt = false;
 402        OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
 403        spin_unlock_irqrestore(&dsp_lock, flags);
 404
 405        /* Reset the core via the boot domain register */
 406        rBootDomain.ResetCore = true;
 407        rBootDomain.Halt = true;
 408        rBootDomain.NMI = true;
 409        rBootDomain.Reserved = 0;
 410
 411        PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rBootDomain %x\n",
 412                MKWORD(rBootDomain));
 413
 414        WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
 415
 416        /* Reset all the chiplets and then reactivate them */
 417        WriteMsaCfg(DSP_ChipReset, 0xFFFF);
 418        udelay(5);
 419        WriteMsaCfg(DSP_ChipReset,
 420                        (unsigned short) (~pSettings->usChipletEnable));
 421
 422
 423        PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset exit bRC=0\n");
 424
 425        return 0;
 426}
 427
 428
 429int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings)
 430{
 431        unsigned long flags;
 432        unsigned short usDspBaseIO = pSettings->usDspBaseIO;
 433        DSP_BOOT_DOMAIN rBootDomain;
 434        DSP_HBRIDGE_CONTROL rHBridgeControl;
 435
 436
 437        PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run entry\n");
 438
 439
 440        /* Transition the core to a running state */
 441        rBootDomain.ResetCore = true;
 442        rBootDomain.Halt = false;
 443        rBootDomain.NMI = true;
 444        rBootDomain.Reserved = 0;
 445        WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
 446
 447        udelay(5);
 448
 449        rBootDomain.ResetCore = false;
 450        WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
 451        udelay(5);
 452
 453        rBootDomain.NMI = false;
 454        WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
 455        udelay(5);
 456
 457        /* Enable DSP to PC interrupt */
 458        spin_lock_irqsave(&dsp_lock, flags);
 459        MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
 460        rHBridgeControl.EnableDspInt = true;
 461
 462        PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Run rHBridgeControl %x\n",
 463                MKWORD(rHBridgeControl));
 464
 465        OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
 466        spin_unlock_irqrestore(&dsp_lock, flags);
 467
 468
 469        PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run exit bRC=true\n");
 470
 471        return 0;
 472}
 473
 474
 475int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
 476                        unsigned uCount, unsigned long ulDSPAddr)
 477{
 478        unsigned long flags;
 479        unsigned short __user *pusBuffer = pvBuffer;
 480        unsigned short val;
 481
 482
 483        PRINTK_5(TRACE_3780I,
 484                "3780i::dsp3780I_ReadDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
 485                usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
 486
 487
 488        /* Set the initial MSA address. No adjustments need to be made to data store addresses */
 489        spin_lock_irqsave(&dsp_lock, flags);
 490        OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
 491        OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
 492        spin_unlock_irqrestore(&dsp_lock, flags);
 493
 494        /* Transfer the memory block */
 495        while (uCount-- != 0) {
 496                spin_lock_irqsave(&dsp_lock, flags);
 497                val = InWordDsp(DSP_MsaDataDSISHigh);
 498                spin_unlock_irqrestore(&dsp_lock, flags);
 499                if(put_user(val, pusBuffer++))
 500                        return -EFAULT;
 501
 502                PRINTK_3(TRACE_3780I,
 503                        "3780I::dsp3780I_ReadDStore uCount %x val %x\n",
 504                        uCount, val);
 505
 506                PaceMsaAccess(usDspBaseIO);
 507        }
 508
 509
 510        PRINTK_1(TRACE_3780I,
 511                "3780I::dsp3780I_ReadDStore exit bRC=true\n");
 512
 513        return 0;
 514}
 515
 516int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
 517                                void __user *pvBuffer, unsigned uCount,
 518                                unsigned long ulDSPAddr)
 519{
 520        unsigned long flags;
 521        unsigned short __user *pusBuffer = pvBuffer;
 522        unsigned short val;
 523
 524
 525        PRINTK_5(TRACE_3780I,
 526                "3780i::dsp3780I_ReadAndDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
 527                usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
 528
 529
 530        /* Set the initial MSA address. No adjustments need to be made to data store addresses */
 531        spin_lock_irqsave(&dsp_lock, flags);
 532        OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
 533        OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
 534        spin_unlock_irqrestore(&dsp_lock, flags);
 535
 536        /* Transfer the memory block */
 537        while (uCount-- != 0) {
 538                spin_lock_irqsave(&dsp_lock, flags);
 539                val = InWordDsp(DSP_ReadAndClear);
 540                spin_unlock_irqrestore(&dsp_lock, flags);
 541                if(put_user(val, pusBuffer++))
 542                        return -EFAULT;
 543
 544                PRINTK_3(TRACE_3780I,
 545                        "3780I::dsp3780I_ReadAndCleanDStore uCount %x val %x\n",
 546                        uCount, val);
 547
 548                PaceMsaAccess(usDspBaseIO);
 549        }
 550
 551
 552        PRINTK_1(TRACE_3780I,
 553                "3780I::dsp3780I_ReadAndClearDStore exit bRC=true\n");
 554
 555        return 0;
 556}
 557
 558
 559int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
 560                         unsigned uCount, unsigned long ulDSPAddr)
 561{
 562        unsigned long flags;
 563        unsigned short __user *pusBuffer = pvBuffer;
 564
 565
 566        PRINTK_5(TRACE_3780I,
 567                "3780i::dsp3780D_WriteDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
 568                usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
 569
 570
 571        /* Set the initial MSA address. No adjustments need to be made to data store addresses */
 572        spin_lock_irqsave(&dsp_lock, flags);
 573        OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
 574        OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
 575        spin_unlock_irqrestore(&dsp_lock, flags);
 576
 577        /* Transfer the memory block */
 578        while (uCount-- != 0) {
 579                unsigned short val;
 580                if(get_user(val, pusBuffer++))
 581                        return -EFAULT;
 582                spin_lock_irqsave(&dsp_lock, flags);
 583                OutWordDsp(DSP_MsaDataDSISHigh, val);
 584                spin_unlock_irqrestore(&dsp_lock, flags);
 585
 586                PRINTK_3(TRACE_3780I,
 587                        "3780I::dsp3780I_WriteDStore uCount %x val %x\n",
 588                        uCount, val);
 589
 590                PaceMsaAccess(usDspBaseIO);
 591        }
 592
 593
 594        PRINTK_1(TRACE_3780I,
 595                "3780I::dsp3780D_WriteDStore exit bRC=true\n");
 596
 597        return 0;
 598}
 599
 600
 601int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
 602                        unsigned uCount, unsigned long ulDSPAddr)
 603{
 604        unsigned long flags;
 605        unsigned short __user *pusBuffer = pvBuffer;
 606
 607        PRINTK_5(TRACE_3780I,
 608                "3780i::dsp3780I_ReadIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
 609                usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
 610
 611        /*
 612        * Set the initial MSA address. To convert from an instruction store
 613        * address to an MSA address
 614        * shift the address two bits to the left and set bit 22
 615        */
 616        ulDSPAddr = (ulDSPAddr << 2) | (1 << 22);
 617        spin_lock_irqsave(&dsp_lock, flags);
 618        OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
 619        OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
 620        spin_unlock_irqrestore(&dsp_lock, flags);
 621
 622        /* Transfer the memory block */
 623        while (uCount-- != 0) {
 624                unsigned short val_lo, val_hi;
 625                spin_lock_irqsave(&dsp_lock, flags);
 626                val_lo = InWordDsp(DSP_MsaDataISLow);
 627                val_hi = InWordDsp(DSP_MsaDataDSISHigh);
 628                spin_unlock_irqrestore(&dsp_lock, flags);
 629                if(put_user(val_lo, pusBuffer++))
 630                        return -EFAULT;
 631                if(put_user(val_hi, pusBuffer++))
 632                        return -EFAULT;
 633
 634                PRINTK_4(TRACE_3780I,
 635                        "3780I::dsp3780I_ReadIStore uCount %x val_lo %x val_hi %x\n",
 636                        uCount, val_lo, val_hi);
 637
 638                PaceMsaAccess(usDspBaseIO);
 639
 640        }
 641
 642        PRINTK_1(TRACE_3780I,
 643                "3780I::dsp3780I_ReadIStore exit bRC=true\n");
 644
 645        return 0;
 646}
 647
 648
 649int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
 650                         unsigned uCount, unsigned long ulDSPAddr)
 651{
 652        unsigned long flags;
 653        unsigned short __user *pusBuffer = pvBuffer;
 654
 655        PRINTK_5(TRACE_3780I,
 656                "3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
 657                usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
 658
 659
 660        /*
 661        * Set the initial MSA address. To convert from an instruction store
 662        * address to an MSA address
 663        * shift the address two bits to the left and set bit 22
 664        */
 665        ulDSPAddr = (ulDSPAddr << 2) | (1 << 22);
 666        spin_lock_irqsave(&dsp_lock, flags);
 667        OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
 668        OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
 669        spin_unlock_irqrestore(&dsp_lock, flags);
 670
 671        /* Transfer the memory block */
 672        while (uCount-- != 0) {
 673                unsigned short val_lo, val_hi;
 674                if(get_user(val_lo, pusBuffer++))
 675                        return -EFAULT;
 676                if(get_user(val_hi, pusBuffer++))
 677                        return -EFAULT;
 678                spin_lock_irqsave(&dsp_lock, flags);
 679                OutWordDsp(DSP_MsaDataISLow, val_lo);
 680                OutWordDsp(DSP_MsaDataDSISHigh, val_hi);
 681                spin_unlock_irqrestore(&dsp_lock, flags);
 682
 683                PRINTK_4(TRACE_3780I,
 684                        "3780I::dsp3780I_WriteIStore uCount %x val_lo %x val_hi %x\n",
 685                        uCount, val_lo, val_hi);
 686
 687                PaceMsaAccess(usDspBaseIO);
 688
 689        }
 690
 691        PRINTK_1(TRACE_3780I,
 692                "3780I::dsp3780I_WriteIStore exit bRC=true\n");
 693
 694        return 0;
 695}
 696
 697
 698int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
 699                          unsigned short *pusIPCSource)
 700{
 701        unsigned long flags;
 702        DSP_HBRIDGE_CONTROL rHBridgeControl;
 703        unsigned short temp;
 704
 705
 706        PRINTK_3(TRACE_3780I,
 707                "3780i::dsp3780I_GetIPCSource entry usDspBaseIO %x pusIPCSource %p\n",
 708                usDspBaseIO, pusIPCSource);
 709
 710        /*
 711        * Disable DSP to PC interrupts, read the interrupt register,
 712        * clear the pending IPC bits, and reenable DSP to PC interrupts
 713        */
 714        spin_lock_irqsave(&dsp_lock, flags);
 715        MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
 716        rHBridgeControl.EnableDspInt = false;
 717        OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
 718
 719        *pusIPCSource = InWordDsp(DSP_Interrupt);
 720        temp = (unsigned short) ~(*pusIPCSource);
 721
 722        PRINTK_3(TRACE_3780I,
 723                "3780i::dsp3780I_GetIPCSource, usIPCSource %x ~ %x\n",
 724                *pusIPCSource, temp);
 725
 726        OutWordDsp(DSP_Interrupt, (unsigned short) ~(*pusIPCSource));
 727
 728        rHBridgeControl.EnableDspInt = true;
 729        OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
 730        spin_unlock_irqrestore(&dsp_lock, flags);
 731
 732
 733        PRINTK_2(TRACE_3780I,
 734                "3780i::dsp3780I_GetIPCSource exit usIPCSource %x\n",
 735                *pusIPCSource);
 736
 737        return 0;
 738}
 739