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/init.h> 54#include <linux/bitops.h> 55#include <linux/sched.h> /* cond_resched() */ 56 57#include <asm/io.h> 58#include <asm/uaccess.h> 59#include <asm/system.h> 60#include <asm/irq.h> 61#include "smapi.h" 62#include "mwavedd.h" 63#include "3780i.h" 64 65static DEFINE_SPINLOCK(dsp_lock); 66 67static void PaceMsaAccess(unsigned short usDspBaseIO) 68{ 69 cond_resched(); 70 udelay(100); 71 cond_resched(); 72} 73 74unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO, 75 unsigned long ulMsaAddr) 76{ 77 unsigned long flags; 78 unsigned short val; 79 80 PRINTK_3(TRACE_3780I, 81 "3780i::dsp3780I_ReadMsaCfg entry usDspBaseIO %x ulMsaAddr %lx\n", 82 usDspBaseIO, ulMsaAddr); 83 84 spin_lock_irqsave(&dsp_lock, flags); 85 OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr); 86 OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16)); 87 val = InWordDsp(DSP_MsaDataDSISHigh); 88 spin_unlock_irqrestore(&dsp_lock, flags); 89 90 PRINTK_2(TRACE_3780I, "3780i::dsp3780I_ReadMsaCfg exit val %x\n", val); 91 92 return val; 93} 94 95void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, 96 unsigned long ulMsaAddr, unsigned short usValue) 97{ 98 unsigned long flags; 99 100 PRINTK_4(TRACE_3780I, 101 "3780i::dsp3780i_WriteMsaCfg entry usDspBaseIO %x ulMsaAddr %lx usValue %x\n", 102 usDspBaseIO, ulMsaAddr, usValue); 103 104 spin_lock_irqsave(&dsp_lock, flags); 105 OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr); 106 OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16)); 107 OutWordDsp(DSP_MsaDataDSISHigh, usValue); 108 spin_unlock_irqrestore(&dsp_lock, flags); 109} 110 111static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, 112 unsigned char ucValue) 113{ 114 DSP_ISA_SLAVE_CONTROL rSlaveControl; 115 DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; 116 117 118 PRINTK_4(TRACE_3780I, 119 "3780i::dsp3780i_WriteGenCfg entry usDspBaseIO %x uIndex %x ucValue %x\n", 120 usDspBaseIO, uIndex, ucValue); 121 122 MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl); 123 124 PRINTK_2(TRACE_3780I, 125 "3780i::dsp3780i_WriteGenCfg rSlaveControl %x\n", 126 MKBYTE(rSlaveControl)); 127 128 rSlaveControl_Save = rSlaveControl; 129 rSlaveControl.ConfigMode = TRUE; 130 131 PRINTK_2(TRACE_3780I, 132 "3780i::dsp3780i_WriteGenCfg entry rSlaveControl+ConfigMode %x\n", 133 MKBYTE(rSlaveControl)); 134 135 OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl)); 136 OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex); 137 OutByteDsp(DSP_ConfigData, ucValue); 138 OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save)); 139 140 PRINTK_1(TRACE_3780I, "3780i::dsp3780i_WriteGenCfg exit\n"); 141 142 143} 144 145 146int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, 147 unsigned short *pIrqMap, 148 unsigned short *pDmaMap) 149{ 150 unsigned long flags; 151 unsigned short usDspBaseIO = pSettings->usDspBaseIO; 152 int i; 153 DSP_UART_CFG_1 rUartCfg1; 154 DSP_UART_CFG_2 rUartCfg2; 155 DSP_HBRIDGE_CFG_1 rHBridgeCfg1; 156 DSP_HBRIDGE_CFG_2 rHBridgeCfg2; 157 DSP_BUSMASTER_CFG_1 rBusmasterCfg1; 158 DSP_BUSMASTER_CFG_2 rBusmasterCfg2; 159 DSP_ISA_PROT_CFG rIsaProtCfg; 160 DSP_POWER_MGMT_CFG rPowerMgmtCfg; 161 DSP_HBUS_TIMER_CFG rHBusTimerCfg; 162 DSP_LBUS_TIMEOUT_DISABLE rLBusTimeoutDisable; 163 DSP_CHIP_RESET rChipReset; 164 DSP_CLOCK_CONTROL_1 rClockControl1; 165 DSP_CLOCK_CONTROL_2 rClockControl2; 166 DSP_ISA_SLAVE_CONTROL rSlaveControl; 167 DSP_HBRIDGE_CONTROL rHBridgeControl; 168 unsigned short ChipID = 0; 169 unsigned short tval; 170 171 172 PRINTK_2(TRACE_3780I, 173 "3780i::dsp3780I_EnableDSP entry pSettings->bDSPEnabled %x\n", 174 pSettings->bDSPEnabled); 175 176 177 if (!pSettings->bDSPEnabled) { 178 PRINTK_ERROR( KERN_ERR "3780i::dsp3780I_EnableDSP: Error: DSP not enabled. Aborting.\n" ); 179 return -EIO; 180 } 181 182 183 PRINTK_2(TRACE_3780I, 184 "3780i::dsp3780i_EnableDSP entry pSettings->bModemEnabled %x\n", 185 pSettings->bModemEnabled); 186 187 if (pSettings->bModemEnabled) { 188 rUartCfg1.Reserved = rUartCfg2.Reserved = 0; 189 rUartCfg1.IrqActiveLow = pSettings->bUartIrqActiveLow; 190 rUartCfg1.IrqPulse = pSettings->bUartIrqPulse; 191 rUartCfg1.Irq = 192 (unsigned char) pIrqMap[pSettings->usUartIrq]; 193 switch (pSettings->usUartBaseIO) { 194 case 0x03F8: 195 rUartCfg1.BaseIO = 0; 196 break; 197 case 0x02F8: 198 rUartCfg1.BaseIO = 1; 199 break; 200 case 0x03E8: 201 rUartCfg1.BaseIO = 2; 202 break; 203 case 0x02E8: 204 rUartCfg1.BaseIO = 3; 205 break; 206 } 207 rUartCfg2.Enable = TRUE; 208 } 209 210 rHBridgeCfg1.Reserved = rHBridgeCfg2.Reserved = 0; 211 rHBridgeCfg1.IrqActiveLow = pSettings->bDspIrqActiveLow; 212 rHBridgeCfg1.IrqPulse = pSettings->bDspIrqPulse; 213 rHBridgeCfg1.Irq = (unsigned char) pIrqMap[pSettings->usDspIrq]; 214 rHBridgeCfg1.AccessMode = 1; 215 rHBridgeCfg2.Enable = TRUE; 216 217 218 rBusmasterCfg2.Reserved = 0; 219 rBusmasterCfg1.Dma = (unsigned char) pDmaMap[pSettings->usDspDma]; 220 rBusmasterCfg1.NumTransfers = 221 (unsigned char) pSettings->usNumTransfers; 222 rBusmasterCfg1.ReRequest = (unsigned char) pSettings->usReRequest; 223 rBusmasterCfg1.MEMCS16 = pSettings->bEnableMEMCS16; 224 rBusmasterCfg2.IsaMemCmdWidth = 225 (unsigned char) pSettings->usIsaMemCmdWidth; 226 227 228 rIsaProtCfg.Reserved = 0; 229 rIsaProtCfg.GateIOCHRDY = pSettings->bGateIOCHRDY; 230 231 rPowerMgmtCfg.Reserved = 0; 232 rPowerMgmtCfg.Enable = pSettings->bEnablePwrMgmt; 233 234 rHBusTimerCfg.LoadValue = 235 (unsigned char) pSettings->usHBusTimerLoadValue; 236 237 rLBusTimeoutDisable.Reserved = 0; 238 rLBusTimeoutDisable.DisableTimeout = 239 pSettings->bDisableLBusTimeout; 240 241 MKWORD(rChipReset) = ~pSettings->usChipletEnable; 242 243 rClockControl1.Reserved1 = rClockControl1.Reserved2 = 0; 244 rClockControl1.N_Divisor = pSettings->usN_Divisor; 245 rClockControl1.M_Multiplier = pSettings->usM_Multiplier; 246 247 rClockControl2.Reserved = 0; 248 rClockControl2.PllBypass = pSettings->bPllBypass; 249 250 /* Issue a soft reset to the chip */ 251 /* Note: Since we may be coming in with 3780i clocks suspended, we must keep 252 * soft-reset active for 10ms. 253 */ 254 rSlaveControl.ClockControl = 0; 255 rSlaveControl.SoftReset = TRUE; 256 rSlaveControl.ConfigMode = FALSE; 257 rSlaveControl.Reserved = 0; 258 259 PRINTK_4(TRACE_3780I, 260 "3780i::dsp3780i_EnableDSP usDspBaseIO %x index %x taddr %x\n", 261 usDspBaseIO, DSP_IsaSlaveControl, 262 usDspBaseIO + DSP_IsaSlaveControl); 263 264 PRINTK_2(TRACE_3780I, 265 "3780i::dsp3780i_EnableDSP rSlaveContrl %x\n", 266 MKWORD(rSlaveControl)); 267 268 spin_lock_irqsave(&dsp_lock, flags); 269 OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); 270 MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl); 271 272 PRINTK_2(TRACE_3780I, 273 "3780i::dsp3780i_EnableDSP rSlaveControl 2 %x\n", tval); 274 275 276 for (i = 0; i < 11; i++) 277 udelay(2000); 278 279 rSlaveControl.SoftReset = FALSE; 280 OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); 281 282 MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl); 283 284 PRINTK_2(TRACE_3780I, 285 "3780i::dsp3780i_EnableDSP rSlaveControl 3 %x\n", tval); 286 287 288 /* Program our general configuration registers */ 289 WriteGenCfg(DSP_HBridgeCfg1Index, MKBYTE(rHBridgeCfg1)); 290 WriteGenCfg(DSP_HBridgeCfg2Index, MKBYTE(rHBridgeCfg2)); 291 WriteGenCfg(DSP_BusMasterCfg1Index, MKBYTE(rBusmasterCfg1)); 292 WriteGenCfg(DSP_BusMasterCfg2Index, MKBYTE(rBusmasterCfg2)); 293 WriteGenCfg(DSP_IsaProtCfgIndex, MKBYTE(rIsaProtCfg)); 294 WriteGenCfg(DSP_PowerMgCfgIndex, MKBYTE(rPowerMgmtCfg)); 295 WriteGenCfg(DSP_HBusTimerCfgIndex, MKBYTE(rHBusTimerCfg)); 296 297 if (pSettings->bModemEnabled) { 298 WriteGenCfg(DSP_UartCfg1Index, MKBYTE(rUartCfg1)); 299 WriteGenCfg(DSP_UartCfg2Index, MKBYTE(rUartCfg2)); 300 } 301 302 303 rHBridgeControl.EnableDspInt = FALSE; 304 rHBridgeControl.MemAutoInc = TRUE; 305 rHBridgeControl.IoAutoInc = FALSE; 306 rHBridgeControl.DiagnosticMode = FALSE; 307 308 PRINTK_3(TRACE_3780I, 309 "3780i::dsp3780i_EnableDSP DSP_HBridgeControl %x rHBridgeControl %x\n", 310 DSP_HBridgeControl, MKWORD(rHBridgeControl)); 311 312 OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); 313 spin_unlock_irqrestore(&dsp_lock, flags); 314 WriteMsaCfg(DSP_LBusTimeoutDisable, MKWORD(rLBusTimeoutDisable)); 315 WriteMsaCfg(DSP_ClockControl_1, MKWORD(rClockControl1)); 316 WriteMsaCfg(DSP_ClockControl_2, MKWORD(rClockControl2)); 317 WriteMsaCfg(DSP_ChipReset, MKWORD(rChipReset)); 318 319 ChipID = ReadMsaCfg(DSP_ChipID); 320 321 PRINTK_2(TRACE_3780I, 322 "3780i::dsp3780I_EnableDSP exiting bRC=TRUE, ChipID %x\n", 323 ChipID); 324 325 return 0; 326} 327 328int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings) 329{ 330 unsigned long flags; 331 unsigned short usDspBaseIO = pSettings->usDspBaseIO; 332 DSP_ISA_SLAVE_CONTROL rSlaveControl; 333 334 335 PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP entry\n"); 336 337 rSlaveControl.ClockControl = 0; 338 rSlaveControl.SoftReset = TRUE; 339 rSlaveControl.ConfigMode = FALSE; 340 rSlaveControl.Reserved = 0; 341 spin_lock_irqsave(&dsp_lock, flags); 342 OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); 343 344 udelay(5); 345 346 rSlaveControl.ClockControl = 1; 347 OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); 348 spin_unlock_irqrestore(&dsp_lock, flags); 349 350 udelay(5); 351 352 353 PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP exit\n"); 354 355 return 0; 356} 357 358int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings) 359{ 360 unsigned long flags; 361 unsigned short usDspBaseIO = pSettings->usDspBaseIO; 362 DSP_BOOT_DOMAIN rBootDomain; 363 DSP_HBRIDGE_CONTROL rHBridgeControl; 364 365 366 PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset entry\n"); 367 368 spin_lock_irqsave(&dsp_lock, flags); 369 /* Mask DSP to PC interrupt */ 370 MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); 371 372 PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rHBridgeControl %x\n", 373 MKWORD(rHBridgeControl)); 374 375 rHBridgeControl.EnableDspInt = FALSE; 376 OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); 377 spin_unlock_irqrestore(&dsp_lock, flags); 378 379 /* Reset the core via the boot domain register */ 380 rBootDomain.ResetCore = TRUE; 381 rBootDomain.Halt = TRUE; 382 rBootDomain.NMI = TRUE; 383 rBootDomain.Reserved = 0; 384 385 PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rBootDomain %x\n", 386 MKWORD(rBootDomain)); 387 388 WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); 389 390 /* Reset all the chiplets and then reactivate them */ 391 WriteMsaCfg(DSP_ChipReset, 0xFFFF); 392 udelay(5); 393 WriteMsaCfg(DSP_ChipReset, 394 (unsigned short) (~pSettings->usChipletEnable)); 395 396 397 PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset exit bRC=0\n"); 398 399 return 0; 400} 401 402 403int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings) 404{ 405 unsigned long flags; 406 unsigned short usDspBaseIO = pSettings->usDspBaseIO; 407 DSP_BOOT_DOMAIN rBootDomain; 408 DSP_HBRIDGE_CONTROL rHBridgeControl; 409 410 411 PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run entry\n"); 412 413 414 /* Transition the core to a running state */ 415 rBootDomain.ResetCore = TRUE; 416 rBootDomain.Halt = FALSE; 417 rBootDomain.NMI = TRUE; 418 rBootDomain.Reserved = 0; 419 WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); 420 421 udelay(5); 422 423 rBootDomain.ResetCore = FALSE; 424 WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); 425 udelay(5); 426 427 rBootDomain.NMI = FALSE; 428 WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); 429 udelay(5); 430 431 /* Enable DSP to PC interrupt */ 432 spin_lock_irqsave(&dsp_lock, flags); 433 MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); 434 rHBridgeControl.EnableDspInt = TRUE; 435 436 PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Run rHBridgeControl %x\n", 437 MKWORD(rHBridgeControl)); 438 439 OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); 440 spin_unlock_irqrestore(&dsp_lock, flags); 441 442 443 PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run exit bRC=TRUE\n"); 444 445 return 0; 446} 447 448 449int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer, 450 unsigned uCount, unsigned long ulDSPAddr) 451{ 452 unsigned long flags; 453 unsigned short __user *pusBuffer = pvBuffer; 454 unsigned short val; 455 456 457 PRINTK_5(TRACE_3780I, 458 "3780i::dsp3780I_ReadDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", 459 usDspBaseIO, pusBuffer, uCount, ulDSPAddr); 460 461 462 /* Set the initial MSA address. No adjustments need to be made to data store addresses */ 463 spin_lock_irqsave(&dsp_lock, flags); 464 OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); 465 OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); 466 spin_unlock_irqrestore(&dsp_lock, flags); 467 468 /* Transfer the memory block */ 469 while (uCount-- != 0) { 470 spin_lock_irqsave(&dsp_lock, flags); 471 val = InWordDsp(DSP_MsaDataDSISHigh); 472 spin_unlock_irqrestore(&dsp_lock, flags); 473 if(put_user(val, pusBuffer++)) 474 return -EFAULT; 475 476 PRINTK_3(TRACE_3780I, 477 "3780I::dsp3780I_ReadDStore uCount %x val %x\n", 478 uCount, val); 479 480 PaceMsaAccess(usDspBaseIO); 481 } 482 483 484 PRINTK_1(TRACE_3780I, 485 "3780I::dsp3780I_ReadDStore exit bRC=TRUE\n"); 486 487 return 0; 488} 489 490int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, 491 void __user *pvBuffer, unsigned uCount, 492 unsigned long ulDSPAddr) 493{ 494 unsigned long flags; 495 unsigned short __user *pusBuffer = pvBuffer; 496 unsigned short val; 497 498 499 PRINTK_5(TRACE_3780I, 500 "3780i::dsp3780I_ReadAndDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", 501 usDspBaseIO, pusBuffer, uCount, ulDSPAddr); 502 503 504 /* Set the initial MSA address. No adjustments need to be made to data store addresses */ 505 spin_lock_irqsave(&dsp_lock, flags); 506 OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); 507 OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); 508 spin_unlock_irqrestore(&dsp_lock, flags); 509 510 /* Transfer the memory block */ 511 while (uCount-- != 0) { 512 spin_lock_irqsave(&dsp_lock, flags); 513 val = InWordDsp(DSP_ReadAndClear); 514 spin_unlock_irqrestore(&dsp_lock, flags); 515 if(put_user(val, pusBuffer++)) 516 return -EFAULT; 517 518 PRINTK_3(TRACE_3780I, 519 "3780I::dsp3780I_ReadAndCleanDStore uCount %x val %x\n", 520 uCount, val); 521 522 PaceMsaAccess(usDspBaseIO); 523 } 524 525 526 PRINTK_1(TRACE_3780I, 527 "3780I::dsp3780I_ReadAndClearDStore exit bRC=TRUE\n"); 528 529 return 0; 530} 531 532 533int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer, 534 unsigned uCount, unsigned long ulDSPAddr) 535{ 536 unsigned long flags; 537 unsigned short __user *pusBuffer = pvBuffer; 538 539 540 PRINTK_5(TRACE_3780I, 541 "3780i::dsp3780D_WriteDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", 542 usDspBaseIO, pusBuffer, uCount, ulDSPAddr); 543 544 545 /* Set the initial MSA address. No adjustments need to be made to data store addresses */ 546 spin_lock_irqsave(&dsp_lock, flags); 547 OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); 548 OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); 549 spin_unlock_irqrestore(&dsp_lock, flags); 550 551 /* Transfer the memory block */ 552 while (uCount-- != 0) { 553 unsigned short val; 554 if(get_user(val, pusBuffer++)) 555 return -EFAULT; 556 spin_lock_irqsave(&dsp_lock, flags); 557 OutWordDsp(DSP_MsaDataDSISHigh, val); 558 spin_unlock_irqrestore(&dsp_lock, flags); 559 560 PRINTK_3(TRACE_3780I, 561 "3780I::dsp3780I_WriteDStore uCount %x val %x\n", 562 uCount, val); 563 564 PaceMsaAccess(usDspBaseIO); 565 } 566 567 568 PRINTK_1(TRACE_3780I, 569 "3780I::dsp3780D_WriteDStore exit bRC=TRUE\n"); 570 571 return 0; 572} 573 574 575int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer, 576 unsigned uCount, unsigned long ulDSPAddr) 577{ 578 unsigned long flags; 579 unsigned short __user *pusBuffer = pvBuffer; 580 581 PRINTK_5(TRACE_3780I, 582 "3780i::dsp3780I_ReadIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", 583 usDspBaseIO, pusBuffer, uCount, ulDSPAddr); 584 585 /* 586 * Set the initial MSA address. To convert from an instruction store 587 * address to an MSA address 588 * shift the address two bits to the left and set bit 22 589 */ 590 ulDSPAddr = (ulDSPAddr << 2) | (1 << 22); 591 spin_lock_irqsave(&dsp_lock, flags); 592 OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); 593 OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); 594 spin_unlock_irqrestore(&dsp_lock, flags); 595 596 /* Transfer the memory block */ 597 while (uCount-- != 0) { 598 unsigned short val_lo, val_hi; 599 spin_lock_irqsave(&dsp_lock, flags); 600 val_lo = InWordDsp(DSP_MsaDataISLow); 601 val_hi = InWordDsp(DSP_MsaDataDSISHigh); 602 spin_unlock_irqrestore(&dsp_lock, flags); 603 if(put_user(val_lo, pusBuffer++)) 604 return -EFAULT; 605 if(put_user(val_hi, pusBuffer++)) 606 return -EFAULT; 607 608 PRINTK_4(TRACE_3780I, 609 "3780I::dsp3780I_ReadIStore uCount %x val_lo %x val_hi %x\n", 610 uCount, val_lo, val_hi); 611 612 PaceMsaAccess(usDspBaseIO); 613 614 } 615 616 PRINTK_1(TRACE_3780I, 617 "3780I::dsp3780I_ReadIStore exit bRC=TRUE\n"); 618 619 return 0; 620} 621 622 623int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer, 624 unsigned uCount, unsigned long ulDSPAddr) 625{ 626 unsigned long flags; 627 unsigned short __user *pusBuffer = pvBuffer; 628 629 PRINTK_5(TRACE_3780I, 630 "3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n", 631 usDspBaseIO, pusBuffer, uCount, ulDSPAddr); 632 633 634 /* 635 * Set the initial MSA address. To convert from an instruction store 636 * address to an MSA address 637 * shift the address two bits to the left and set bit 22 638 */ 639 ulDSPAddr = (ulDSPAddr << 2) | (1 << 22); 640 spin_lock_irqsave(&dsp_lock, flags); 641 OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); 642 OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); 643 spin_unlock_irqrestore(&dsp_lock, flags); 644 645 /* Transfer the memory block */ 646 while (uCount-- != 0) { 647 unsigned short val_lo, val_hi; 648 if(get_user(val_lo, pusBuffer++)) 649 return -EFAULT; 650 if(get_user(val_hi, pusBuffer++)) 651 return -EFAULT; 652 spin_lock_irqsave(&dsp_lock, flags); 653 OutWordDsp(DSP_MsaDataISLow, val_lo); 654 OutWordDsp(DSP_MsaDataDSISHigh, val_hi); 655 spin_unlock_irqrestore(&dsp_lock, flags); 656 657 PRINTK_4(TRACE_3780I, 658 "3780I::dsp3780I_WriteIStore uCount %x val_lo %x val_hi %x\n", 659 uCount, val_lo, val_hi); 660 661 PaceMsaAccess(usDspBaseIO); 662 663 } 664 665 PRINTK_1(TRACE_3780I, 666 "3780I::dsp3780I_WriteIStore exit bRC=TRUE\n"); 667 668 return 0; 669} 670 671 672int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, 673 unsigned short *pusIPCSource) 674{ 675 unsigned long flags; 676 DSP_HBRIDGE_CONTROL rHBridgeControl; 677 unsigned short temp; 678 679 680 PRINTK_3(TRACE_3780I, 681 "3780i::dsp3780I_GetIPCSource entry usDspBaseIO %x pusIPCSource %p\n", 682 usDspBaseIO, pusIPCSource); 683 684 /* 685 * Disable DSP to PC interrupts, read the interrupt register, 686 * clear the pending IPC bits, and reenable DSP to PC interrupts 687 */ 688 spin_lock_irqsave(&dsp_lock, flags); 689 MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); 690 rHBridgeControl.EnableDspInt = FALSE; 691 OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); 692 693 *pusIPCSource = InWordDsp(DSP_Interrupt); 694 temp = (unsigned short) ~(*pusIPCSource); 695 696 PRINTK_3(TRACE_3780I, 697 "3780i::dsp3780I_GetIPCSource, usIPCSource %x ~ %x\n", 698 *pusIPCSource, temp); 699 700 OutWordDsp(DSP_Interrupt, (unsigned short) ~(*pusIPCSource)); 701 702 rHBridgeControl.EnableDspInt = TRUE; 703 OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); 704 spin_unlock_irqrestore(&dsp_lock, flags); 705 706 707 PRINTK_2(TRACE_3780I, 708 "3780i::dsp3780I_GetIPCSource exit usIPCSource %x\n", 709 *pusIPCSource); 710 711 return 0; 712} 713