diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2008-12-21 04:54:28 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2008-12-21 04:54:28 -0500 |
commit | aaab5e83c2c25d94f7409bdc947a5cc383514e15 (patch) | |
tree | 929571b5bf2728ac8494b56d0c4965b2aaa47da8 | |
parent | e4efe3c271c5498ffe7e167eaff01514be2b9a77 (diff) |
powerpc/mpc5200: Disable bestcomm prefetching when ATA DMA enabled
When ATA DMA is enabled, bestcomm prefetching does not work. This
patch adds a function to disable bestcomm prefetch when the ATA
Bestcomm task is initialized.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r-- | arch/powerpc/sysdev/bestcomm/ata.c | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/bestcomm/bestcomm.c | 7 | ||||
-rw-r--r-- | arch/powerpc/sysdev/bestcomm/bestcomm_priv.h | 16 |
3 files changed, 21 insertions, 5 deletions
diff --git a/arch/powerpc/sysdev/bestcomm/ata.c b/arch/powerpc/sysdev/bestcomm/ata.c index 1f5258fb38c3..901c9f91e5dd 100644 --- a/arch/powerpc/sysdev/bestcomm/ata.c +++ b/arch/powerpc/sysdev/bestcomm/ata.c | |||
@@ -61,6 +61,9 @@ bcom_ata_init(int queue_len, int maxbufsize) | |||
61 | struct bcom_ata_var *var; | 61 | struct bcom_ata_var *var; |
62 | struct bcom_ata_inc *inc; | 62 | struct bcom_ata_inc *inc; |
63 | 63 | ||
64 | /* Prefetch breaks ATA DMA. Turn it off for ATA DMA */ | ||
65 | bcom_disable_prefetch(); | ||
66 | |||
64 | tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0); | 67 | tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0); |
65 | if (!tsk) | 68 | if (!tsk) |
66 | return NULL; | 69 | return NULL; |
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 446c9ea85b30..378ebd9aac18 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c | |||
@@ -279,7 +279,6 @@ bcom_engine_init(void) | |||
279 | int task; | 279 | int task; |
280 | phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa; | 280 | phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa; |
281 | unsigned int tdt_size, ctx_size, var_size, fdt_size; | 281 | unsigned int tdt_size, ctx_size, var_size, fdt_size; |
282 | u16 regval; | ||
283 | 282 | ||
284 | /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */ | 283 | /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */ |
285 | tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt); | 284 | tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt); |
@@ -331,10 +330,8 @@ bcom_engine_init(void) | |||
331 | out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS); | 330 | out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS); |
332 | 331 | ||
333 | /* Disable COMM Bus Prefetch on the original 5200; it's broken */ | 332 | /* Disable COMM Bus Prefetch on the original 5200; it's broken */ |
334 | if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) { | 333 | if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) |
335 | regval = in_be16(&bcom_eng->regs->PtdCntrl); | 334 | bcom_disable_prefetch(); |
336 | out_be16(&bcom_eng->regs->PtdCntrl, regval | 1); | ||
337 | } | ||
338 | 335 | ||
339 | /* Init lock */ | 336 | /* Init lock */ |
340 | spin_lock_init(&bcom_eng->lock); | 337 | spin_lock_init(&bcom_eng->lock); |
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h index 746f1551c8a5..eb0d1c883c31 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h +++ b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h | |||
@@ -241,6 +241,22 @@ extern void bcom_set_initiator(int task, int initiator); | |||
241 | 241 | ||
242 | #define TASK_ENABLE 0x8000 | 242 | #define TASK_ENABLE 0x8000 |
243 | 243 | ||
244 | /** | ||
245 | * bcom_disable_prefetch - Hook to disable bus prefetching | ||
246 | * | ||
247 | * ATA DMA and the original MPC5200 need this due to silicon bugs. At the | ||
248 | * moment disabling prefetch is a one-way street. There is no mechanism | ||
249 | * in place to turn prefetch back on after it has been disabled. There is | ||
250 | * no reason it couldn't be done, it would just be more complex to implement. | ||
251 | */ | ||
252 | static inline void bcom_disable_prefetch(void) | ||
253 | { | ||
254 | u16 regval; | ||
255 | |||
256 | regval = in_be16(&bcom_eng->regs->PtdCntrl); | ||
257 | out_be16(&bcom_eng->regs->PtdCntrl, regval | 1); | ||
258 | }; | ||
259 | |||
244 | static inline void | 260 | static inline void |
245 | bcom_enable_task(int task) | 261 | bcom_enable_task(int task) |
246 | { | 262 | { |