diff options
Diffstat (limited to 'arch/mips/mm/pg-sb1.c')
-rw-r--r-- | arch/mips/mm/pg-sb1.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c index 1b6df7133c1e..148c65b9cd8b 100644 --- a/arch/mips/mm/pg-sb1.c +++ b/arch/mips/mm/pg-sb1.c | |||
@@ -60,7 +60,8 @@ static inline void clear_page_cpu(void *page) | |||
60 | " .set noreorder \n" | 60 | " .set noreorder \n" |
61 | #ifdef CONFIG_CPU_HAS_PREFETCH | 61 | #ifdef CONFIG_CPU_HAS_PREFETCH |
62 | " daddiu %0, %0, 128 \n" | 62 | " daddiu %0, %0, 128 \n" |
63 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%0) \n" /* Prefetch the first 4 lines */ | 63 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%0) \n" |
64 | /* Prefetch the first 4 lines */ | ||
64 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%0) \n" | 65 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%0) \n" |
65 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -64(%0) \n" | 66 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -64(%0) \n" |
66 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%0) \n" | 67 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%0) \n" |
@@ -106,7 +107,8 @@ static inline void copy_page_cpu(void *to, void *from) | |||
106 | #ifdef CONFIG_CPU_HAS_PREFETCH | 107 | #ifdef CONFIG_CPU_HAS_PREFETCH |
107 | " daddiu %0, %0, 128 \n" | 108 | " daddiu %0, %0, 128 \n" |
108 | " daddiu %1, %1, 128 \n" | 109 | " daddiu %1, %1, 128 \n" |
109 | " pref " SB1_PREF_LOAD_STREAMED_HINT ", -128(%0)\n" /* Prefetch the first 4 lines */ | 110 | " pref " SB1_PREF_LOAD_STREAMED_HINT ", -128(%0)\n" |
111 | /* Prefetch the first 4 lines */ | ||
110 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n" | 112 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n" |
111 | " pref " SB1_PREF_LOAD_STREAMED_HINT ", -96(%0)\n" | 113 | " pref " SB1_PREF_LOAD_STREAMED_HINT ", -96(%0)\n" |
112 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%1)\n" | 114 | " pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%1)\n" |
@@ -207,66 +209,73 @@ typedef struct dmadscr_s { | |||
207 | u64 pad_b; | 209 | u64 pad_b; |
208 | } dmadscr_t; | 210 | } dmadscr_t; |
209 | 211 | ||
210 | static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES))); | 212 | static dmadscr_t page_descr[DM_NUM_CHANNELS] |
213 | __attribute__((aligned(SMP_CACHE_BYTES))); | ||
211 | 214 | ||
212 | void sb1_dma_init(void) | 215 | void sb1_dma_init(void) |
213 | { | 216 | { |
214 | int cpu = smp_processor_id(); | 217 | int i; |
215 | u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1); | ||
216 | 218 | ||
217 | bus_writeq(base_val, | 219 | for (i = 0; i < DM_NUM_CHANNELS; i++) { |
218 | (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); | 220 | const u64 base_val = CPHYSADDR(&page_descr[i]) | |
219 | bus_writeq(base_val | M_DM_DSCR_BASE_RESET, | 221 | V_DM_DSCR_BASE_RINGSZ(1); |
220 | (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); | 222 | volatile void *base_reg = |
221 | bus_writeq(base_val | M_DM_DSCR_BASE_ENABL, | 223 | IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE)); |
222 | (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); | 224 | |
225 | __raw_writeq(base_val, base_reg); | ||
226 | __raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg); | ||
227 | __raw_writeq(base_val | M_DM_DSCR_BASE_ENABL, base_reg); | ||
228 | } | ||
223 | } | 229 | } |
224 | 230 | ||
225 | void clear_page(void *page) | 231 | void clear_page(void *page) |
226 | { | 232 | { |
227 | int cpu = smp_processor_id(); | 233 | u64 to_phys = CPHYSADDR(page); |
234 | unsigned int cpu = smp_processor_id(); | ||
228 | 235 | ||
229 | /* if the page is above Kseg0, use old way */ | 236 | /* if the page is not in KSEG0, use old way */ |
230 | if ((long)KSEGX(page) != (long)CKSEG0) | 237 | if ((long)KSEGX(page) != (long)CKSEG0) |
231 | return clear_page_cpu(page); | 238 | return clear_page_cpu(page); |
232 | 239 | ||
233 | page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; | 240 | page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM | |
241 | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; | ||
234 | page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); | 242 | page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); |
235 | bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT))); | 243 | __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT))); |
236 | 244 | ||
237 | /* | 245 | /* |
238 | * Don't really want to do it this way, but there's no | 246 | * Don't really want to do it this way, but there's no |
239 | * reliable way to delay completion detection. | 247 | * reliable way to delay completion detection. |
240 | */ | 248 | */ |
241 | while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & | 249 | while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG))) |
242 | M_DM_DSCR_BASE_INTERRUPT)))) | 250 | & M_DM_DSCR_BASE_INTERRUPT)) |
243 | ; | 251 | ; |
244 | bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); | 252 | __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); |
245 | } | 253 | } |
246 | 254 | ||
247 | void copy_page(void *to, void *from) | 255 | void copy_page(void *to, void *from) |
248 | { | 256 | { |
249 | unsigned long from_phys = CPHYSADDR(from); | 257 | u64 from_phys = CPHYSADDR(from); |
250 | unsigned long to_phys = CPHYSADDR(to); | 258 | u64 to_phys = CPHYSADDR(to); |
251 | int cpu = smp_processor_id(); | 259 | unsigned int cpu = smp_processor_id(); |
252 | 260 | ||
253 | /* if either page is above Kseg0, use old way */ | 261 | /* if any page is not in KSEG0, use old way */ |
254 | if ((long)KSEGX(to) != (long)CKSEG0 | 262 | if ((long)KSEGX(to) != (long)CKSEG0 |
255 | || (long)KSEGX(from) != (long)CKSEG0) | 263 | || (long)KSEGX(from) != (long)CKSEG0) |
256 | return copy_page_cpu(to, from); | 264 | return copy_page_cpu(to, from); |
257 | 265 | ||
258 | page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; | 266 | page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST | |
259 | page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); | 267 | M_DM_DSCRA_INTERRUPT; |
260 | bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT))); | 268 | page_descr[cpu].dscr_b = from_phys | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); |
269 | __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT))); | ||
261 | 270 | ||
262 | /* | 271 | /* |
263 | * Don't really want to do it this way, but there's no | 272 | * Don't really want to do it this way, but there's no |
264 | * reliable way to delay completion detection. | 273 | * reliable way to delay completion detection. |
265 | */ | 274 | */ |
266 | while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & | 275 | while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG))) |
267 | M_DM_DSCR_BASE_INTERRUPT)))) | 276 | & M_DM_DSCR_BASE_INTERRUPT)) |
268 | ; | 277 | ; |
269 | bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); | 278 | __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); |
270 | } | 279 | } |
271 | 280 | ||
272 | #else /* !CONFIG_SIBYTE_DMA_PAGEOPS */ | 281 | #else /* !CONFIG_SIBYTE_DMA_PAGEOPS */ |