From 7f52eb009306b8047031eaf64169a7ce437a26e7 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 10 Jan 2006 19:47:37 -0800 Subject: [PATCH] spufs: Suspend/restore MFC DMA operations at SPU context switch. The SPE Book IV indicates that MFC DMA operations must be suspended and restored on SPU context switch (in Step 8). This patch adds that operation, which is missing from the current spufs implementation. Signed-off-by: Masato Noguchi Signed-off-by: Geoff Levand Acked-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/switch.c | 34 +++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'arch/powerpc/platforms/cell/spufs') diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 1061c12b2ed..212db28531f 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -169,11 +169,33 @@ static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu) struct spu_priv2 __iomem *priv2 = spu->priv2; /* Save, Step 8: - * Read and save MFC_CNTL[Ss]. - */ - if (csa) { - csa->priv2.mfc_control_RW = in_be64(&priv2->mfc_control_RW) & - MFC_CNTL_SUSPEND_DMA_STATUS_MASK; + * Suspend DMA and save MFC_CNTL. + */ + switch (in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_SUSPEND_DMA_STATUS_MASK) { + case MFC_CNTL_SUSPEND_IN_PROGRESS: + POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == + MFC_CNTL_SUSPEND_COMPLETE); + /* fall through */ + case MFC_CNTL_SUSPEND_COMPLETE: + if (csa) { + csa->priv2.mfc_control_RW = + in_be64(&priv2->mfc_control_RW) | + MFC_CNTL_SUSPEND_DMA_QUEUE; + } + break; + case MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION: + out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE); + POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == + MFC_CNTL_SUSPEND_COMPLETE); + if (csa) { + csa->priv2.mfc_control_RW = + in_be64(&priv2->mfc_control_RW) & + ~MFC_CNTL_SUSPEND_DMA_QUEUE; + } + break; } } @@ -237,6 +259,8 @@ static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu) eieio(); csa->spu_chnldata_RW[7] = in_be64(&priv2->spu_chnldata_RW); eieio(); + } else { + csa->priv2.mfc_control_RW &= ~MFC_CNTL_DECREMENTER_RUNNING; } } -- cgit v1.2.3