aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2008-04-24 18:15:40 +1000
committerJeremy Kerr <jk@ozlabs.org>2008-05-05 13:33:42 +1000
commit55d7cd74d44e7e0597f95db25c12f3e6c5e7916f (patch)
tree1a0d468ad5fccb3033d0b57435efcdfa93b2bd78 /arch/powerpc/platforms/cell/spufs
parent[POWERPC] spufs: fix save of mfc_cntl register (diff)
downloadlinux-dev-55d7cd74d44e7e0597f95db25c12f3e6c5e7916f.tar.xz
linux-dev-55d7cd74d44e7e0597f95db25c12f3e6c5e7916f.zip
[POWERPC] spufs: fix post-stopped update of MFC_CNTL register
We currently have two issues with the MFC save code: * save_mfc_decr doesn't handle a transition of 1 -> 0 of the Ds bit * The Q bit may be stale in the CSA This change fixes the first issue by clearing the relevant bits from the MFC_CNTL value in the CSA before or-ing in the updated status. Also, we add the Q bit to the updated status. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs')
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 4131784216bb..53361d0c070f 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -250,16 +250,21 @@ static inline void save_spu_status(struct spu_state *csa, struct spu *spu)
}
}
-static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu)
+static inline void save_mfc_stopped_status(struct spu_state *csa,
+ struct spu *spu)
{
struct spu_priv2 __iomem *priv2 = spu->priv2;
+ const u64 mask = MFC_CNTL_DECREMENTER_RUNNING |
+ MFC_CNTL_DMA_QUEUES_EMPTY;
/* Save, Step 12:
* Read MFC_CNTL[Ds]. Update saved copy of
* CSA.MFC_CNTL[Ds].
+ *
+ * update: do the same with MFC_CNTL[Q].
*/
- csa->priv2.mfc_control_RW |=
- in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING;
+ csa->priv2.mfc_control_RW &= ~mask;
+ csa->priv2.mfc_control_RW |= in_be64(&priv2->mfc_control_RW) & mask;
}
static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu)
@@ -1791,7 +1796,7 @@ static int quiece_spu(struct spu_state *prev, struct spu *spu)
save_spu_runcntl(prev, spu); /* Step 9. */
save_mfc_sr1(prev, spu); /* Step 10. */
save_spu_status(prev, spu); /* Step 11. */
- save_mfc_decr(prev, spu); /* Step 12. */
+ save_mfc_stopped_status(prev, spu); /* Step 12. */
halt_mfc_decr(prev, spu); /* Step 13. */
save_timebase(prev, spu); /* Step 14. */
remove_other_spu_access(prev, spu); /* Step 15. */