diff options
| author | Jeremy Kerr <jk@ozlabs.org> | 2008-04-24 04:15:40 -0400 |
|---|---|---|
| committer | Jeremy Kerr <jk@ozlabs.org> | 2008-05-04 23:33:42 -0400 |
| commit | 55d7cd74d44e7e0597f95db25c12f3e6c5e7916f (patch) | |
| tree | 1a0d468ad5fccb3033d0b57435efcdfa93b2bd78 | |
| parent | 1ca4264ee17745779c341966c5e61ac69bfd17a6 (diff) | |
[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>
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/switch.c | 13 |
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) | |||
| 250 | } | 250 | } |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu) | 253 | static inline void save_mfc_stopped_status(struct spu_state *csa, |
| 254 | struct spu *spu) | ||
| 254 | { | 255 | { |
| 255 | struct spu_priv2 __iomem *priv2 = spu->priv2; | 256 | struct spu_priv2 __iomem *priv2 = spu->priv2; |
| 257 | const u64 mask = MFC_CNTL_DECREMENTER_RUNNING | | ||
| 258 | MFC_CNTL_DMA_QUEUES_EMPTY; | ||
| 256 | 259 | ||
| 257 | /* Save, Step 12: | 260 | /* Save, Step 12: |
| 258 | * Read MFC_CNTL[Ds]. Update saved copy of | 261 | * Read MFC_CNTL[Ds]. Update saved copy of |
| 259 | * CSA.MFC_CNTL[Ds]. | 262 | * CSA.MFC_CNTL[Ds]. |
| 263 | * | ||
| 264 | * update: do the same with MFC_CNTL[Q]. | ||
| 260 | */ | 265 | */ |
| 261 | csa->priv2.mfc_control_RW |= | 266 | csa->priv2.mfc_control_RW &= ~mask; |
| 262 | in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING; | 267 | csa->priv2.mfc_control_RW |= in_be64(&priv2->mfc_control_RW) & mask; |
| 263 | } | 268 | } |
| 264 | 269 | ||
| 265 | static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu) | 270 | 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) | |||
| 1791 | save_spu_runcntl(prev, spu); /* Step 9. */ | 1796 | save_spu_runcntl(prev, spu); /* Step 9. */ |
| 1792 | save_mfc_sr1(prev, spu); /* Step 10. */ | 1797 | save_mfc_sr1(prev, spu); /* Step 10. */ |
| 1793 | save_spu_status(prev, spu); /* Step 11. */ | 1798 | save_spu_status(prev, spu); /* Step 11. */ |
| 1794 | save_mfc_decr(prev, spu); /* Step 12. */ | 1799 | save_mfc_stopped_status(prev, spu); /* Step 12. */ |
| 1795 | halt_mfc_decr(prev, spu); /* Step 13. */ | 1800 | halt_mfc_decr(prev, spu); /* Step 13. */ |
| 1796 | save_timebase(prev, spu); /* Step 14. */ | 1801 | save_timebase(prev, spu); /* Step 14. */ |
| 1797 | remove_other_spu_access(prev, spu); /* Step 15. */ | 1802 | remove_other_spu_access(prev, spu); /* Step 15. */ |
