Fix SDOCM00115189. Ported from Appleton. DEV.TCP3D_LLD.02.01.00.03
authorPragat Chaudhari <pragatc@ti.com>
Thu, 12 Mar 2015 21:14:19 +0000 (17:14 -0400)
committerPragat Chaudhari <pragatc@ti.com>
Thu, 12 Mar 2015 21:14:19 +0000 (17:14 -0400)
TCP3D LLD: Spurious EDMA transactions lead to driver stoppage, caused by premature LLD state updates

docs/ReleaseNotes_TCP3DDriver.doc
docs/ReleaseNotes_TCP3DDriver.pdf
package.xdc
src/tcp3d_drv.c
src/tcp3d_drv_priv.h

index 5276302cc1ccc59f39b37df4704057a24556bf1a..2099ef7cc6fdba9dc310956fdce710630522c85e 100644 (file)
Binary files a/docs/ReleaseNotes_TCP3DDriver.doc and b/docs/ReleaseNotes_TCP3DDriver.doc differ
index 8eee99418b0897bcad3209f5524d65a4685b4c12..261a48854d45d3458fcc8f50a0ad288c012a3854 100644 (file)
Binary files a/docs/ReleaseNotes_TCP3DDriver.pdf and b/docs/ReleaseNotes_TCP3DDriver.pdf differ
index 596360fbd3f123e4054603c7e8e43dbe618f5fe4..001cc66f09be3649c93a0945cd4237f595d756bd 100755 (executable)
@@ -9,7 +9,7 @@
  * Copyright (C) 2012, 2014, Texas Instruments, Inc.\r
  *****************************************************************************/\r
 \r
-package ti.drv.tcp3d[2, 01, 00, 02] {\r
+package ti.drv.tcp3d[2, 01, 00, 03] {\r
     module Settings;\r
 }\r
 \r
index 04e7859dab644e1430ab2d8a334b06b051b06dfe..7a29b81eac99a762c17a59dae04b19894520a183 100644 (file)
@@ -796,19 +796,6 @@ Tcp3d_Result Tcp3d_start (  INOUT Tcp3d_Instance    *inst,
      */\r
     if ( startMode == TCP3D_DRV_START_AUTO )\r
     {\r
-        /**\r
-         * Read the source address of L2P Channel PaRAM to get the current\r
-         * pseudo PaRAM pointer for PING/PONG paths. Then compare with the start\r
-         * pointer to get the out indexes.\r
-         */\r
-        currPrmPtr1 = (EDMA3_DRV_PaRAMRegs *) inst->pingPtrL2p->srcAddr;\r
-        currPrmPtr2 = (EDMA3_DRV_PaRAMRegs *) inst->pongPtrL2p->srcAddr;\r
-        pingOutIdx  = GET_CB_IDX(currPrmPtr1 - inst->startPrmPtr);\r
-        pongOutIdx  = GET_CB_IDX(currPrmPtr2 - inst->startPrmPtr);\r
-\r
-        /* Update the counters and indexes using the current out indexes */\r
-        Tcp3d_updateListVariables( inst, pingOutIdx, pongOutIdx );\r
-    \r
         /**\r
          * Start is needed in the following cases.\r
          *  - if the current out index is less than next in index\r
@@ -822,6 +809,21 @@ Tcp3d_Result Tcp3d_start (  INOUT Tcp3d_Instance    *inst,
         /* PING STOP */\r
         if ( inst->pingStop )\r
         {\r
+            /**\r
+             * Only update the list variables if the driver is stopped \r
+             * for the ping side.\r
+             */\r
+            /**\r
+             * Read the source address of L2P Channel PaRAM to get the current\r
+             * pseudo PaRAM pointer for PING paths. Then compare with the \r
+             * start pointer to get the out index. \r
+             */\r
+            currPrmPtr1 = (EDMA3_DRV_PaRAMRegs *) inst->pingPtrL2p->srcAddr;\r
+            pingOutIdx  = GET_CB_IDX(currPrmPtr1 - inst->startPrmPtr);\r
+\r
+            /* Update the counters and indexes using the current out indexes */\r
+            Tcp3d_updatePingListVariables( inst, pingOutIdx );\r
+\r
             if ( pingOutIdx < inst->nextPingInIdx )\r
             {\r
                 startNeeded |= 1;\r
@@ -832,9 +834,24 @@ Tcp3d_Result Tcp3d_start (  INOUT Tcp3d_Instance    *inst,
             }\r
         }\r
 \r
-        /* PING STOP */\r
+        /* PONG STOP */\r
         if ( inst->pongStop )\r
         {\r
+            /**\r
+             * Only update the list variables if the driver is stopped \r
+             * for the pong side.\r
+             */\r
+            /**\r
+             * Read the source address of L2P Channel PaRAM to get the current\r
+             * pseudo PaRAM pointer for PONG paths. Then compare with the \r
+             * start pointer to get the out index. \r
+             */\r
+            currPrmPtr2 = (EDMA3_DRV_PaRAMRegs *) inst->pongPtrL2p->srcAddr;\r
+            pongOutIdx  = GET_CB_IDX(currPrmPtr2 - inst->startPrmPtr);\r
+\r
+            /* Update the counters and indexes using the current out indexes */\r
+            Tcp3d_updatePongListVariables( inst, pongOutIdx );\r
+\r
             if ( pongOutIdx < inst->nextPongInIdx )\r
             {\r
                 startNeeded |= 2;\r
@@ -1059,12 +1076,12 @@ static void Tcp3d_setLocalVariables (IN Tcp3d_Instance   *tcp3dInst)
     /* Store pointers for the end of list (PING starts first in the list)*/\r
     prm = &tcp3dInst->pseudoParamBufPtr[(tcp3dInst->maxCodeBlocks-2)*TCP3D_DRV_LINK_CB];\r
     if ( tcp3dInst->maxCodeBlocks & 1 )\r
-    {  /* even */\r
+    {  \r
         tcp3dInst->endListParam[PING_INDEX] = prm;\r
         tcp3dInst->endListParam[PONG_INDEX] = prm+TCP3D_DRV_LINK_CB;\r
     }\r
     else\r
-    { /* odd */\r
+    { \r
         tcp3dInst->endListParam[PING_INDEX] = prm+TCP3D_DRV_LINK_CB;\r
         tcp3dInst->endListParam[PONG_INDEX] = prm;\r
     }\r
@@ -1144,11 +1161,10 @@ static void Tcp3d_resetRuntimeVariables (IN Tcp3d_Instance   *tcp3dInst)
     tcp3dInst->pongFreeCnt              = tcp3dInst->maxPongCbCnt;\r
 }\r
 \r
-static void Tcp3d_updateListVariables ( INOUT   Tcp3d_Instance  *inst,\r
-                                        IN      int32_t         pingOutIdx,\r
-                                        IN      int32_t         pongOutIdx )\r
+static void Tcp3d_updatePingListVariables ( INOUT  Tcp3d_Instance *inst,\r
+                                            IN     int32_t        pingOutIdx )\r
 {\r
-    int32_t                 indexDiff1, indexDiff2;\r
+    int32_t                 indexDiff1;\r
 \r
     /**\r
      * Load count adjustment is done following the steps described below.\r
@@ -1175,30 +1191,62 @@ static void Tcp3d_updateListVariables ( INOUT   Tcp3d_Instance  *inst,
     /* step2, step3 */\r
     inst->pingLoadCnt -= (indexDiff1>>1);\r
     /* step4 */\r
-    if ( ( (indexDiff1 < 0) || (inst->pingLastOutFlag) ) && (inst->pingWrapCheck) )\r
+    if ( ( (indexDiff1 < 0) || (inst->pingLastOutFlag) ) && \r
+                   (inst->pingWrapCheck) )\r
     {\r
         inst->pingLoadCnt   -= inst->maxPingCbCnt;\r
         inst->pingWrapCheck  = 0;\r
     }\r
 \r
-    /* Adjust the loaded count - PING */\r
+    /* update free counts - can be negative */\r
+    inst->pingFreeCnt       = ( inst->maxPingCbCnt - inst->pingLoadCnt );\r
+\r
+    /* update previous out index */\r
+    inst->prevPingOutIdx    = pingOutIdx;\r
+}\r
+\r
+static void Tcp3d_updatePongListVariables ( INOUT  Tcp3d_Instance *inst,\r
+                                            IN     int32_t        pongOutIdx )\r
+{\r
+    int32_t                 indexDiff2;\r
+\r
+    /**\r
+     * Load count adjustment is done following the steps described below.\r
+     * \r
+     * step1 : get index difference between current and previous indexes\r
+     * step2 : convert the index difference to count\r
+     * step3 : reduce the load count by index difference. It is possible that\r
+     *          the diffrence could be negative, which gets corrected after\r
+     *          step4 is completed.\r
+     * step4 : wrap is detected, reduce the load count by maximum one time.\r
+     *          The wrap detection is done either of the cases.\r
+     *              1) when index difference is negative\r
+     *              2) the last block decoding is detected\r
+     * \r
+     * NOTES:\r
+     *  - At reset/init, checking for wrap is enabled.\r
+     *  - Once the adjustment is done, checking is disabled until the last\r
+     *      block decoding is done.\r
+     */\r
+\r
+\r
+    /* Adjust the loaded count - PONG */\r
     /* step1 */\r
     indexDiff2 = ( pongOutIdx - inst->prevPongOutIdx );\r
     /* step2, step3 */\r
     inst->pongLoadCnt -= (indexDiff2>>1);\r
     /* step4 */\r
-    if ( ( (indexDiff2 < 0) || (inst->pongLastOutFlag) ) && (inst->pongWrapCheck) )\r
+    if ( ( (indexDiff2 < 0) || (inst->pongLastOutFlag) ) && \r
+                   (inst->pongWrapCheck) )\r
     {\r
         inst->pongLoadCnt   -= inst->maxPongCbCnt;\r
         inst->pongWrapCheck  = 0;\r
     }\r
 \r
     /* update free counts - can be negative */\r
-    inst->pingFreeCnt       = ( inst->maxPingCbCnt - inst->pingLoadCnt );\r
     inst->pongFreeCnt       = ( inst->maxPongCbCnt - inst->pongLoadCnt );\r
 \r
     /* update previous out index */\r
-    inst->prevPingOutIdx    = pingOutIdx;\r
     inst->prevPongOutIdx    = pongOutIdx;\r
 }\r
 \r
index 4af228282170c692388ee572a0f0652adca87268..a6790dd42f26950bb4f0493fc09f33c5735898ce 100644 (file)
@@ -136,8 +136,9 @@ static void Tcp3d_resetPseudoParam (IN Tcp3d_Instance   *tcp3dInst,
                                     IN uint32_t         codeBlocks);\r
 static void Tcp3d_setLocalVariables (IN Tcp3d_Instance  *tcp3dInst);\r
 static void Tcp3d_resetRuntimeVariables (IN Tcp3d_Instance  *tcp3dInst);\r
-static void Tcp3d_updateListVariables ( INOUT   Tcp3d_Instance  *inst,\r
-                                        IN      int32_t         pingOutIdx,\r
-                                        IN      int32_t         pongOutIdx );\r
+static void Tcp3d_updatePingListVariables ( INOUT  Tcp3d_Instance *inst,\r
+                                            IN     int32_t        pingOutIdx );\r
+static void Tcp3d_updatePongListVariables ( INOUT  Tcp3d_Instance *inst,\r
+                                            IN     int32_t        pongOutIdx );\r
 \r
 #endif /* _TCP3D_DRV_PRIV_H_ */\r