[alsa-devel] [PATCH 4/5] asihpi: replace volatile with barriers
Eliot Blennerhassett
linux at audioscience.com
Thu Mar 6 02:51:02 CET 2008
Replace volatile with barriers where required.
Other minor cleanups.
Signed-off-by: Eliot Blennerhassett <linux at audioscience.com
---
diff -r 6def4892d3f5 pci/asihpi/hpi6205.c
--- a/pci/asihpi/hpi6205.c Mon Mar 03 11:05:48 2008 +0100
+++ b/pci/asihpi/hpi6205.c Thu Mar 06 12:21:54 2008 +1300
@@ -27,6 +27,7 @@
(C) Copyright AudioScience Inc. 1998-2003
*******************************************************************************/
#define SOURCEFILE_NAME "hpi6205.c"
+
#include "hpi.h"
#include "hpidebug.h"
#include "hpi6205.h"
@@ -35,42 +36,42 @@
/*****************************************************************************/
/* HPI6205 specific error codes */
-#define HPI6205_ERROR_BASE 1000
-#define HPI6205_ERROR_MEM_ALLOC 1001
-#define HPI6205_ERROR_6205_NO_IRQ 1002
-#define HPI6205_ERROR_6205_INIT_FAILED 1003
+#define HPI6205_ERROR_BASE 1000
+/*#define HPI6205_ERROR_MEM_ALLOC 1001 */
+#define HPI6205_ERROR_6205_NO_IRQ 1002
+#define HPI6205_ERROR_6205_INIT_FAILED 1003
/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
-#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
-#define HPI6205_ERROR_6205_REG 1006
-#define HPI6205_ERROR_6205_DSPPAGE 1007
-#define HPI6205_ERROR_BAD_DSPINDEX 1008
-#define HPI6205_ERROR_C6713_HPIC 1009
-#define HPI6205_ERROR_C6713_HPIA 1010
-#define HPI6205_ERROR_C6713_PLL 1011
-#define HPI6205_ERROR_DSP_INTMEM 1012
-#define HPI6205_ERROR_DSP_EXTMEM 1013
-#define HPI6205_ERROR_DSP_PLD 1014
-#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
-#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
-#define HPI6205_ERROR_6205_EEPROM 1017
-#define HPI6205_ERROR_DSP_EMIF 1018
+#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
+#define HPI6205_ERROR_6205_REG 1006
+#define HPI6205_ERROR_6205_DSPPAGE 1007
+#define HPI6205_ERROR_BAD_DSPINDEX 1008
+#define HPI6205_ERROR_C6713_HPIC 1009
+#define HPI6205_ERROR_C6713_HPIA 1010
+#define HPI6205_ERROR_C6713_PLL 1011
+#define HPI6205_ERROR_DSP_INTMEM 1012
+#define HPI6205_ERROR_DSP_EXTMEM 1013
+#define HPI6205_ERROR_DSP_PLD 1014
+#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
+#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
+#define HPI6205_ERROR_6205_EEPROM 1017
+#define HPI6205_ERROR_DSP_EMIF 1018
#define Hpi6205_Error(nDspIndex, err) (err)
/*****************************************************************************/
/* for C6205 PCI i/f */
/* Host Status Register (HSR) bitfields */
-#define C6205_HSR_INTSRC 0x01
-#define C6205_HSR_INTAVAL 0x02
-#define C6205_HSR_INTAM 0x04
-#define C6205_HSR_CFGERR 0x08
-#define C6205_HSR_EEREAD 0x10
+#define C6205_HSR_INTSRC 0x01
+#define C6205_HSR_INTAVAL 0x02
+#define C6205_HSR_INTAM 0x04
+#define C6205_HSR_CFGERR 0x08
+#define C6205_HSR_EEREAD 0x10
/* Host-to-DSP Control Register (HDCR) bitfields */
-#define C6205_HDCR_WARMRESET 0x01
-#define C6205_HDCR_DSPINT 0x02
-#define C6205_HDCR_PCIBOOT 0x04
+#define C6205_HDCR_WARMRESET 0x01
+#define C6205_HDCR_DSPINT 0x02
+#define C6205_HDCR_PCIBOOT 0x04
/* DSP Page Register (DSPP) bitfields, */
/* defines 4 Mbyte page that BAR0 points to */
-#define C6205_DSPP_MAP1 0x400
+#define C6205_DSPP_MAP1 0x400
/* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
* BAR1 maps to non-prefetchable 8 Mbyte memory block
@@ -79,7 +80,7 @@
* needs to be added to the BAR1 base address set in the PCI config reg
*/
#define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
-#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
+#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
#define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
#define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
@@ -87,23 +88,23 @@
#define C6205_BAR0_TIMER1_CTL (0x01980000L)
/* For first 6713 in CE1 space, using DA17,16,2 */
-#define HPICL_ADDR 0x01400000L
-#define HPICH_ADDR 0x01400004L
-#define HPIAL_ADDR 0x01410000L
-#define HPIAH_ADDR 0x01410004L
-#define HPIDIL_ADDR 0x01420000L
-#define HPIDIH_ADDR 0x01420004L
-#define HPIDL_ADDR 0x01430000L
-#define HPIDH_ADDR 0x01430004L
-
-#define C6713_EMIF_GCTL 0x01800000
-#define C6713_EMIF_CE1 0x01800004
-#define C6713_EMIF_CE0 0x01800008
-#define C6713_EMIF_CE2 0x01800010
-#define C6713_EMIF_CE3 0x01800014
-#define C6713_EMIF_SDRAMCTL 0x01800018
-#define C6713_EMIF_SDRAMTIMING 0x0180001C
-#define C6713_EMIF_SDRAMEXT 0x01800020
+#define HPICL_ADDR 0x01400000L
+#define HPICH_ADDR 0x01400004L
+#define HPIAL_ADDR 0x01410000L
+#define HPIAH_ADDR 0x01410004L
+#define HPIDIL_ADDR 0x01420000L
+#define HPIDIH_ADDR 0x01420004L
+#define HPIDL_ADDR 0x01430000L
+#define HPIDH_ADDR 0x01430004L
+
+#define C6713_EMIF_GCTL 0x01800000
+#define C6713_EMIF_CE1 0x01800004
+#define C6713_EMIF_CE0 0x01800008
+#define C6713_EMIF_CE2 0x01800010
+#define C6713_EMIF_CE3 0x01800014
+#define C6713_EMIF_SDRAMCTL 0x01800018
+#define C6713_EMIF_SDRAMTIMING 0x0180001C
+#define C6713_EMIF_SDRAMEXT 0x01800020
struct hpi_hw_obj {
/* PCI registers */
@@ -114,7 +115,7 @@ struct hpi_hw_obj {
u32 dwDspPage;
struct consistent_dma_area hLockedMem;
- volatile struct bus_master_interface *pInterfaceBuffer;
+ struct bus_master_interface *pInterfaceBuffer;
u16 flagOStreamJustReset[HPI_MAX_STREAMS];
/* a non-NULL handle means there is an HPI allocated buffer */
@@ -134,6 +135,17 @@ struct hpi_hw_obj {
/* local prototypes */
#define CheckBeforeBBMCopy(status, pBBMData, lFirstWrite, lSecondWrite)
+
+static int WaitDspAck(
+ struct hpi_hw_obj *pHw6205,
+ int state,
+ int timeout_us
+);
+
+static void SendDspCommand(
+ struct hpi_hw_obj *pHw6205,
+ int cmd
+);
static u16 Hpi6205_AdapterBootLoadDsp(
struct hpi_adapter_obj *pao,
@@ -312,11 +324,13 @@ static void ControlMessage(
switch (phm->wFunction) {
case HPI_CONTROL_GET_STATE:
- if (pao->wHasControlCache)
+ if (pao->wHasControlCache) {
+ rmb(); /* make sure we see updates DMAed from DSP */
if (HpiCheckControlCache
(&pHw6205->pControlCache[phm->u.c.
wControlIndex], phm, phr))
break;
+ }
HW_Message(pao, phm, phr);
break;
case HPI_CONTROL_GET_INFO:
@@ -597,7 +611,7 @@ static u16 CreateAdapterObj(
)
{
struct hpi_hw_obj *pHw6205 = pao->priv;
- volatile struct bus_master_interface *interface;
+ struct bus_master_interface *interface;
u32 dwPhysAddr;
u32 dwTimeOut = HPI6205_TIMEOUT;
u32 dwTemp1;
@@ -631,6 +645,7 @@ static u16 CreateAdapterObj(
HPI_DEBUG_LOG(DEBUG, "Interface buffer address %p\n",
pHw6205->pInterfaceBuffer);
+
if (pHw6205->pInterfaceBuffer) {
memset((void *)pHw6205->pInterfaceBuffer, 0,
sizeof(struct bus_master_interface));
@@ -647,7 +662,7 @@ static u16 CreateAdapterObj(
/* allow boot load even if mem alloc wont work */
if (!pHw6205->pInterfaceBuffer)
- return (Hpi6205_Error(0, HPI6205_ERROR_MEM_ALLOC));
+ return (Hpi6205_Error(0, HPI_ERROR_MEMORY_ALLOC));
interface = pHw6205->pInterfaceBuffer;
@@ -671,14 +686,8 @@ static u16 CreateAdapterObj(
iowrite32(C6205_HSR_INTSRC, pHw6205->prHSR);
/* make sure the DSP has started ok */
- dwTimeOut = 100;
- while ((interface->dwDspAck != H620_HIF_RESET) && dwTimeOut) {
- dwTimeOut--;
- HpiOs_DelayMicroSeconds(10000);
- }
-
- if (dwTimeOut == 0) {
- HPI_DEBUG_LOG(ERROR, "Timed out waiting ack \n");
+ if (!WaitDspAck(pHw6205, H620_HIF_RESET, HPI6205_TIMEOUT)) {
+ HPI_DEBUG_LOG(ERROR, "Timed out waiting reset state \n");
return (Hpi6205_Error(0, HPI6205_ERROR_6205_INIT_FAILED));
}
/* Note that *pao, *pHw6205 are zeroed after allocation,
@@ -746,14 +755,7 @@ static u16 CreateAdapterObj(
}
}
}
- /* set interface to idle */
- interface->dwHostCmd = H620_HIF_IDLE;
- /* interrupt the DSP again */
- dwTemp1 = ioread32(pHw6205->prHDCR);
- dwTemp1 |= (u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
- dwTemp1 &= ~(u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
+ SendDspCommand(pHw6205, H620_HIF_IDLE);
{
struct hpi_message hM;
@@ -789,7 +791,7 @@ static u16 CreateAdapterObj(
}
HPI_DEBUG_LOG(VERBOSE, "Get adapter info OK\n");
- pao->wOpen = 0; /* upon creation the adapter is closed */
+ pao->wOpen = 0; /* upon creation the adapter is closed */
HPI_DEBUG_LOG(INFO, "Bootload DSP OK\n");
return (0);
@@ -872,8 +874,7 @@ static void OutStreamHostBufferAllocate(
u32 dwCommand = phm->u.d.u.Buffer.dwCommand;
/*u16 wStreamIndex = phm->u.d.wStreamIndex; */
struct hpi_hw_obj *pHw6205 = pao->priv;
- volatile struct bus_master_interface *interface =
- pHw6205->pInterfaceBuffer;
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
HPI_InitResponse(phr, phm->wObject, phm->wFunction, 0);
@@ -941,7 +942,7 @@ static void OutStreamHostBufferAllocate(
/* GRANT phase. Set up the BBM status, tell the DSP about
the buffer so it can start using BBM.
*/
- volatile struct hostbuffer_status_6205 *status;
+ struct hostbuffer_status_6205 *status;
if (phm->u.d.u.Buffer.
dwBufferSize & (phm->u.d.u.Buffer.dwBufferSize - 1)) {
@@ -1005,7 +1006,7 @@ static void OutStreamHostBufferFree(
}
static long OutStreamGetSpaceAvailable(
- volatile struct hostbuffer_status_6205 *status
+ struct hostbuffer_status_6205 *status
)
{
return status->dwSizeInBytes - ((long)(status->dwHostIndex) -
@@ -1019,9 +1020,8 @@ static void OutStreamWrite(
)
{
struct hpi_hw_obj *pHw6205 = pao->priv;
- volatile struct bus_master_interface *interface =
- pHw6205->pInterfaceBuffer;
- volatile struct hostbuffer_status_6205 *status;
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
+ struct hostbuffer_status_6205 *status;
long dwSpaceAvailable;
if (!pHw6205->OutStreamHostBufferSize[phm->u.d.wStreamIndex]) {
/* there is no BBM buffer */
@@ -1126,9 +1126,8 @@ static void OutStreamGetInfo(
)
{
struct hpi_hw_obj *pHw6205 = pao->priv;
- volatile struct bus_master_interface *interface =
- pHw6205->pInterfaceBuffer;
- volatile struct hostbuffer_status_6205 *status;
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
+ struct hostbuffer_status_6205 *status;
if (!pHw6205->OutStreamHostBufferSize[phm->u.d.wStreamIndex]) {
HW_Message(pao, phm, phr);
@@ -1188,13 +1187,13 @@ static void InStreamHostBufferAllocate(
u16 err = 0;
u32 dwCommand = phm->u.d.u.Buffer.dwCommand;
struct hpi_hw_obj *pHw6205 = pao->priv;
- volatile struct bus_master_interface *interface =
- pHw6205->pInterfaceBuffer;
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
HPI_InitResponse(phr, phm->wObject, phm->wFunction, 0);
if (dwCommand == HPI_BUFFER_CMD_EXTERNAL ||
dwCommand == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
+
phm->u.d.u.Buffer.dwBufferSize =
roundup_pow_of_two(phm->u.d.u.Buffer.dwBufferSize);
phr->u.d.u.stream_info.dwDataAvailable =
@@ -1247,7 +1246,7 @@ static void InStreamHostBufferAllocate(
if (dwCommand == HPI_BUFFER_CMD_EXTERNAL ||
dwCommand == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
- volatile struct hostbuffer_status_6205 *status;
+ struct hostbuffer_status_6205 *status;
if (phm->u.d.u.Buffer.
dwBufferSize & (phm->u.d.u.Buffer.dwBufferSize - 1)) {
@@ -1267,6 +1266,7 @@ static void InStreamHostBufferAllocate(
status->dwDSPIndex = 0;
status->dwHostIndex = status->dwDSPIndex;
status->dwSizeInBytes = phm->u.d.u.Buffer.dwBufferSize;
+
HW_Message(pao, phm, phr);
if (phr->wError
&& HpiOs_LockedMem_Valid(&pHw6205->
@@ -1297,10 +1297,10 @@ static void InStreamHostBufferFree(
}
if (dwCommand == HPI_BUFFER_CMD_EXTERNAL ||
- dwCommand == HPI_BUFFER_CMD_INTERNAL_FREE) {
+ dwCommand == HPI_BUFFER_CMD_INTERNAL_FREE)
HpiOs_LockedMem_Free(&pHw6205->
InStreamHostBuffers[phm->u.d.wStreamIndex]);
- }
+
} else {
/* Should HPI_ERROR_INVALID_OPERATION be returned
if no host buffer is allocated? */
@@ -1321,7 +1321,7 @@ static void InStreamStart(
}
static long InStreamGetBytesAvailable(
- volatile struct hostbuffer_status_6205 *status
+ struct hostbuffer_status_6205 *status
)
{
return (long)(status->dwDSPIndex) - (long)(status->dwHostIndex);
@@ -1334,9 +1334,8 @@ static void InStreamRead(
)
{
struct hpi_hw_obj *pHw6205 = pao->priv;
- volatile struct bus_master_interface *interface =
- pHw6205->pInterfaceBuffer;
- volatile struct hostbuffer_status_6205 *status;
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
+ struct hostbuffer_status_6205 *status;
long dwDataAvailable;
u8 *pBBMData;
long lFirstRead;
@@ -1387,9 +1386,8 @@ static void InStreamGetInfo(
)
{
struct hpi_hw_obj *pHw6205 = pao->priv;
- volatile struct bus_master_interface *interface =
- pHw6205->pInterfaceBuffer;
- volatile struct hostbuffer_status_6205 *status;
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
+ struct hostbuffer_status_6205 *status;
if (!pHw6205->InStreamHostBufferSize[phm->u.d.wStreamIndex]) {
HW_Message(pao, phm, phr);
return;
@@ -1451,7 +1449,7 @@ static u16 Hpi6205_AdapterBootLoadDsp(
dwTemp = C6205_HDCR_WARMRESET;
iowrite32(dwTemp, pHw6205->prHDCR);
HpiOs_DelayMicroSeconds(1000);
-/* for(i=0;i<1000; i++) dwTemp = ioread32(pao,pHw6205->prHDCR); */
+/* for(i=0;i<1000; i++) dwTemp = ioread32(pao,pHw6205->prHDCR); */
/* check that PCI i/f was configured by EEPROM */
dwTemp = ioread32(pHw6205->prHSR);
@@ -1620,7 +1618,7 @@ static u16 Hpi6205_AdapterBootLoadDsp(
if (pHw6205->pInterfaceBuffer) {
/* we need to tell the card the physical PCI address */
u32 dwPhysicalPCIaddress;
- volatile struct bus_master_interface *interface =
+ struct bus_master_interface *interface =
pHw6205->pInterfaceBuffer;
u32 dwHostMailboxAddressOnDsp;
u32 dwPhysicalPCIaddressVerify = 0;
@@ -1628,6 +1626,7 @@ static u16 Hpi6205_AdapterBootLoadDsp(
/* set ack so we know when DSP is ready to go */
/* (dwDspAck will be changed to HIF_RESET) */
interface->dwDspAck = H620_HIF_UNKNOWN;
+ wmb(); /* ensure ack is written before dsp writes back */
err = HpiOs_LockedMem_GetPhysAddr(&pHw6205->hLockedMem,
&dwPhysicalPCIaddress);
@@ -1715,7 +1714,7 @@ static u16 BootLoader_WriteMem32(
struct hpi_hw_obj *pHw6205 = pao->priv;
u16 err = 0;
__iomem u32 *pData;
- /* u32 dwVerifyData=0; */
+ /* u32 dwVerifyData=0; */
if (nDSPIndex == 0) {
/* DSP 0 is always C6205 */
@@ -1771,8 +1770,8 @@ static u16 BootLoader_ConfigEMIF(
/* Set the EMIF */
/* memory map of C6205 */
- /* 00000000-0000FFFF 16Kx32 internal program */
- /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
+ /* 00000000-0000FFFF 16Kx32 internal program */
+ /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
/* EMIF config */
/*------------ */
@@ -1899,7 +1898,7 @@ static u16 BootLoader_ConfigEMIF(
BootLoader_WriteMem32(pao, nDSPIndex, 0x01B7C120, 0x8002);
/* peri = 189/2 */
BootLoader_WriteMem32(pao, nDSPIndex, 0x01B7C11C, 0x8001);
- /* cpu = 189/1 */
+ /* cpu = 189/1 */
BootLoader_WriteMem32(pao, nDSPIndex, 0x01B7C118, 0x8000);
HpiOs_DelayMicroSeconds(1000);
/* ** SGT test to take GPO3 high when we start the PLL */
@@ -1980,15 +1979,15 @@ static u16 BootLoader_TestMemory(
dwTestAddr);
if (dwData != dwTestData) {
HPI_DEBUG_LOG(VERBOSE,
- "Memtest error details "
+ "Memtest error details "
"%08x %08x %08x %i\n",
dwTestAddr, dwTestData,
dwData, nDSPIndex);
return (1); /* error */
}
dwTestData = dwTestData << 1;
- } /* for(j) */
- } /* for(i) */
+ } /* for(j) */
+ } /* for(i) */
/* for the next 100 locations test each location, leaving it as zero */
/* write a zero to the next word in memory before we read */
@@ -2001,7 +2000,7 @@ static u16 BootLoader_TestMemory(
dwData = BootLoader_ReadMem32(pao, nDSPIndex, dwTestAddr);
if (dwData != dwTestData) {
HPI_DEBUG_LOG(VERBOSE,
- "Memtest error details "
+ "Memtest error details "
"%08x %08x %08x %i\n",
dwTestAddr, dwTestData, dwData, nDSPIndex);
return (1); /* error */
@@ -2015,7 +2014,7 @@ static u16 BootLoader_TestMemory(
dwTestAddr = dwStartAddress + (u32)i *4;
BootLoader_WriteMem32(pao, nDSPIndex, dwTestAddr, 0x0);
}
- return (0); /*success! */
+ return (0); /*success! */
}
static u16 BootLoader_TestInternalMemory(
@@ -2134,22 +2133,14 @@ static short Hpi6205_TransferData(
/*u8 *pData =(u8 *)phm->u.d.u.Data.dwpbData; */
/*u16 wTimeOut=8; */
u16 err = 0;
- u32 dwTimeOut, dwTemp1, dwTemp2;
- volatile struct bus_master_interface *interface =
- pHw6205->pInterfaceBuffer;
+ u32 dwTimeOut, dwTemp2;
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
dwDataSize &= ~3L; /* round dwDataSize down to nearest 4 bytes */
/* make sure state is IDLE */
- dwTimeOut = HPI6205_TIMEOUT;
- dwTemp2 = 0;
- while ((interface->dwDspAck != H620_HIF_IDLE) && dwTimeOut--)
- HpiOs_DelayMicroSeconds(1);
-
- if (interface->dwDspAck != H620_HIF_IDLE)
+ if (!WaitDspAck(pHw6205, H620_HIF_IDLE, HPI6205_TIMEOUT))
return HPI_ERROR_DSP_HARDWARE;
-
- interface->dwHostCmd = nOperation;
while (dwDataTransferred < dwDataSize) {
u32 nThisCopy = dwDataSize - dwDataTransferred;
@@ -2162,13 +2153,7 @@ static short Hpi6205_TransferData(
&pData[dwDataTransferred], nThisCopy);
interface->dwTransferSizeInBytes = nThisCopy;
-
- /* interrupt the DSP */
- dwTemp1 = ioread32(pHw6205->prHDCR);
- dwTemp1 |= (u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
- dwTemp1 &= ~(u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
+ SendDspCommand(pHw6205, nOperation);
/* spin waiting on the result */
dwTimeOut = HPI6205_TIMEOUT;
@@ -2212,20 +2197,55 @@ static short Hpi6205_TransferData(
if (interface->dwDspAck != nOperation)
HPI_DEBUG_LOG(DEBUG, "interface->dwDspAck=%d, expected %d\n",
interface->dwDspAck, nOperation);
- /* err=HPI_ERROR_DSP_HARDWARE; */
-
- /* set interface back to idle */
- interface->dwHostCmd = H620_HIF_IDLE;
- /* interrupt the DSP again */
- dwTemp1 = ioread32(pHw6205->prHDCR);
- dwTemp1 |= (u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
- dwTemp1 &= ~(u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
+ /* err=HPI_ERROR_DSP_HARDWARE; */
+
+ SendDspCommand(pHw6205, H620_HIF_IDLE);
return err;
}
+/* wait for up to timeout_us microseconds for the DSP
+ to signal state by DMA into dwDspAck
+*/
+static int WaitDspAck(
+ struct hpi_hw_obj *pHw6205,
+ int state,
+ int timeout_us
+)
+{
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
+ int t = timeout_us / 4;
+
+ rmb(); /* ensure interface->dwDspAck is up to date */
+ while ((interface->dwDspAck != state) && t--) {
+ HpiOs_DelayMicroSeconds(4);
+ rmb(); /* DSP changes dwDspAck by DMA */
+ }
+
+ /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
+ return t;
+}
+
+/* set the busmaster interface to cmd, then interrupt the DSP */
+static void SendDspCommand(
+ struct hpi_hw_obj *pHw6205,
+ int cmd
+)
+{
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
+
+ u32 r;
+
+ interface->dwHostCmd = cmd;
+ wmb(); /* DSP gets state by DMA, make sure it is written to memory */
+ /* before we interrupt the DSP */
+ r = ioread32(pHw6205->prHDCR);
+ r |= (u32)C6205_HDCR_DSPINT;
+ iowrite32(r, pHw6205->prHDCR);
+ r &= ~(u32)C6205_HDCR_DSPINT;
+ iowrite32(r, pHw6205->prHDCR);
+}
+
static unsigned int messageCount;
static u16 Hpi6205_MessageResponseSequence(
@@ -2234,46 +2254,26 @@ static u16 Hpi6205_MessageResponseSequen
struct hpi_response *phr
)
{
- u32 dwTemp1, dwTemp2, dwTimeOut, dwTimeOut2;
+ u32 dwTemp2, dwTimeOut, dwTimeOut2;
struct hpi_hw_obj *pHw6205 = pao->priv;
- volatile struct bus_master_interface *interface =
- pHw6205->pInterfaceBuffer;
+ struct bus_master_interface *interface = pHw6205->pInterfaceBuffer;
u16 err = 0;
messageCount++;
/* Assume buffer of type struct bus_master_interface
is allocated "noncacheable" */
- /* make sure state is IDLE */
- dwTimeOut = HPI6205_TIMEOUT;
- dwTemp2 = 0;
- while ((interface->dwDspAck != H620_HIF_IDLE) && --dwTimeOut)
- HpiOs_DelayMicroSeconds(1);
-
- if (dwTimeOut == 0) {
+ if (!WaitDspAck(pHw6205, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
HPI_DEBUG_LOG(DEBUG, "Timeout waiting for idle\n");
return (Hpi6205_Error
(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT));
}
interface->u.MessageBuffer = *phm;
/* signal we want a response */
- interface->dwHostCmd = H620_HIF_GET_RESP;
-
- /* interrupt the DSP */
- dwTemp1 = ioread32(pHw6205->prHDCR);
- dwTemp1 |= (u32)C6205_HDCR_DSPINT;
- HpiOs_DelayMicroSeconds(1);
- iowrite32(dwTemp1, pHw6205->prHDCR);
- dwTemp1 &= ~(u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
-
- /* spin waiting on state change (start of msg process) */
- dwTimeOut2 = HPI6205_TIMEOUT;
- dwTemp2 = 0;
- while ((interface->dwDspAck != H620_HIF_GET_RESP) && --dwTimeOut2) {
- dwTemp2 = ioread32(pHw6205->prHSR);
- dwTemp2 &= C6205_HSR_INTSRC;
- }
+ SendDspCommand(pHw6205, H620_HIF_GET_RESP);
+
+ dwTimeOut2 = WaitDspAck(pHw6205, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
+
if (dwTimeOut2 == 0) {
HPI_DEBUG_LOG(DEBUG,
"(%u)Timed out waiting for "
@@ -2284,16 +2284,16 @@ static u16 Hpi6205_MessageResponseSequen
"(%u)Transition to GET_RESP after %u\n",
messageCount, HPI6205_TIMEOUT - dwTimeOut2);
}
-
/* spin waiting on HIF interrupt flag (end of msg process) */
dwTimeOut = HPI6205_TIMEOUT;
dwTemp2 = 0;
while ((dwTemp2 == 0) && --dwTimeOut) {
dwTemp2 = ioread32(pHw6205->prHSR);
dwTemp2 &= C6205_HSR_INTSRC;
- /* HpiOs_DelayMicroSeconds(5); */
+ HpiOs_DelayMicroSeconds(1);
}
if (dwTemp2 == C6205_HSR_INTSRC) {
+ rmb(); /* ensure we see latest value for dwDspAck */
if ((interface->dwDspAck != H620_HIF_GET_RESP)) {
HPI_DEBUG_LOG(DEBUG,
"(%u)interface->dwDspAck(0x%x) != "
@@ -2306,12 +2306,12 @@ static u16 Hpi6205_MessageResponseSequen
messageCount, HPI6205_TIMEOUT - dwTimeOut);
}
- }
-/* need to handle this differently... */
- else
+ } else {
+ /* can we do anything else in response to the error ? */
HPI_DEBUG_LOG(ERROR,
"Interrupt from HIF module BAD (wFunction %x)\n",
phm->wFunction);
+ }
/* reset the interrupt from the DSP */
iowrite32(C6205_HSR_INTSRC, pHw6205->prHSR);
@@ -2321,15 +2321,8 @@ static u16 Hpi6205_MessageResponseSequen
*phr = interface->u.ResponseBuffer;
/* set interface back to idle */
- interface->dwHostCmd = H620_HIF_IDLE;
- /* interrupt the DSP again */
- dwTemp1 = ioread32(pHw6205->prHDCR);
- dwTemp1 |= (u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
- dwTemp1 &= ~(u32)C6205_HDCR_DSPINT;
- iowrite32(dwTemp1, pHw6205->prHDCR);
-
-/* EWB move timeoutcheck to after IDLE command, maybe recover? */
+ SendDspCommand(pHw6205, H620_HIF_IDLE);
+
if ((dwTimeOut == 0) || (dwTimeOut2 == 0)) {
HPI_DEBUG_LOG(DEBUG, "Something timed out!\n");
return Hpi6205_Error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
@@ -2337,13 +2330,7 @@ static u16 Hpi6205_MessageResponseSequen
/* special case for adapter close - */
/* wait for the DSP to indicate it is idle */
if (phm->wFunction == HPI_ADAPTER_CLOSE) {
- /* make sure state is IDLE */
- dwTimeOut = HPI6205_TIMEOUT;
- dwTemp2 = 0;
- while ((interface->dwDspAck != H620_HIF_IDLE) && --dwTimeOut)
- HpiOs_DelayMicroSeconds(1);
-
- if (dwTimeOut == 0) {
+ if (!WaitDspAck(pHw6205, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
HPI_DEBUG_LOG(DEBUG,
"Timeout waiting for idle "
"(on AdapterClose)\n");
diff -r 6def4892d3f5 pci/asihpi/hpicmn.c
--- a/pci/asihpi/hpicmn.c Mon Mar 03 11:05:48 2008 +0100
+++ b/pci/asihpi/hpicmn.c Thu Mar 06 12:21:31 2008 +1300
@@ -148,7 +148,7 @@ static void SubSysGetAdapters(
/* input: NONE */
/* output: wNumAdapters */
- /* awAdapter[] */
+ /* awAdapter[] */
/* */
short i;
@@ -178,7 +178,7 @@ static void SubSysGetAdapters(
* It returns nonzero if a cache hit occurred, zero otherwise.
*/
short HpiCheckControlCache(
- volatile struct hpi_control_cache_single *pC,
+ struct hpi_control_cache_single *pC,
struct hpi_message *phm,
struct hpi_response *phr
)
@@ -301,7 +301,7 @@ Multiplexer does so use sent values
Multiplexer does so use sent values
*/
void HpiSyncControlCache(
- volatile struct hpi_control_cache_single *pC,
+ struct hpi_control_cache_single *pC,
struct hpi_message *phm,
struct hpi_response *phr
)
diff -r 6def4892d3f5 pci/asihpi/hpicmn.h
--- a/pci/asihpi/hpicmn.h Mon Mar 03 11:05:48 2008 +0100
+++ b/pci/asihpi/hpicmn.h Thu Mar 06 12:21:30 2008 +1300
@@ -44,12 +44,12 @@ void HpiDeleteAdapter(
);
short HpiCheckControlCache(
- volatile struct hpi_control_cache_single *pC,
+ struct hpi_control_cache_single *pC,
struct hpi_message *phm,
struct hpi_response *phr
);
void HpiSyncControlCache(
- volatile struct hpi_control_cache_single *pC,
+ struct hpi_control_cache_single *pC,
struct hpi_message *phm,
struct hpi_response *phr
);
More information about the Alsa-devel
mailing list