aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2009-12-15 19:48:12 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 10:20:16 -0500
commit57ebb0342c12f00e7a6d15ba59bb6c3ee501c3af (patch)
treea81dd6557fea6e79d6ff277b0477126817a05dcd /drivers/misc/sgi-gru
parent563447d7eb04c9b382f90a132be126a21a635647 (diff)
gru: expicitly set instruction status to active
Explicitly set GRU instructions to "ACTIVE". This eliminates the need for barriers that would have been necessary to prevent reading the instruction "status" field before the GRU had actually started the instruction. Signed-off-by: Jack Steiner <steiner@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-gru')
-rw-r--r--drivers/misc/sgi-gru/gru_instructions.h119
-rw-r--r--drivers/misc/sgi-gru/gruhandles.c4
2 files changed, 67 insertions, 56 deletions
diff --git a/drivers/misc/sgi-gru/gru_instructions.h b/drivers/misc/sgi-gru/gru_instructions.h
index 32f358d9f429..41eb19a85bbc 100644
--- a/drivers/misc/sgi-gru/gru_instructions.h
+++ b/drivers/misc/sgi-gru/gru_instructions.h
@@ -34,17 +34,17 @@ extern void gru_wait_abort_proc(void *cb);
34#include <asm/intrinsics.h> 34#include <asm/intrinsics.h>
35#define __flush_cache(p) ia64_fc((unsigned long)p) 35#define __flush_cache(p) ia64_fc((unsigned long)p)
36/* Use volatile on IA64 to ensure ordering via st4.rel */ 36/* Use volatile on IA64 to ensure ordering via st4.rel */
37#define gru_ordered_store_int(p, v) \ 37#define gru_ordered_store_ulong(p, v) \
38 do { \ 38 do { \
39 barrier(); \ 39 barrier(); \
40 *((volatile int *)(p)) = v; /* force st.rel */ \ 40 *((volatile unsigned long *)(p)) = v; /* force st.rel */ \
41 } while (0) 41 } while (0)
42#elif defined(CONFIG_X86_64) 42#elif defined(CONFIG_X86_64)
43#define __flush_cache(p) clflush(p) 43#define __flush_cache(p) clflush(p)
44#define gru_ordered_store_int(p, v) \ 44#define gru_ordered_store_ulong(p, v) \
45 do { \ 45 do { \
46 barrier(); \ 46 barrier(); \
47 *(int *)p = v; \ 47 *(unsigned long *)p = v; \
48 } while (0) 48 } while (0)
49#else 49#else
50#error "Unsupported architecture" 50#error "Unsupported architecture"
@@ -129,8 +129,13 @@ struct gru_instruction_bits {
129 */ 129 */
130struct gru_instruction { 130struct gru_instruction {
131 /* DW 0 */ 131 /* DW 0 */
132 unsigned int op32; /* icmd,xtype,iaa0,ima,opc */ 132 union {
133 unsigned int tri0; 133 unsigned long op64; /* icmd,xtype,iaa0,ima,opc,tri0 */
134 struct {
135 unsigned int op32;
136 unsigned int tri0;
137 };
138 };
134 unsigned long tri1_bufsize; /* DW 1 */ 139 unsigned long tri1_bufsize; /* DW 1 */
135 unsigned long baddr0; /* DW 2 */ 140 unsigned long baddr0; /* DW 2 */
136 unsigned long nelem; /* DW 3 */ 141 unsigned long nelem; /* DW 3 */
@@ -140,7 +145,7 @@ struct gru_instruction {
140 unsigned long avalue; /* DW 7 */ 145 unsigned long avalue; /* DW 7 */
141}; 146};
142 147
143/* Some shifts and masks for the low 32 bits of a GRU command */ 148/* Some shifts and masks for the low 64 bits of a GRU command */
144#define GRU_CB_ICMD_SHFT 0 149#define GRU_CB_ICMD_SHFT 0
145#define GRU_CB_ICMD_MASK 0x1 150#define GRU_CB_ICMD_MASK 0x1
146#define GRU_CB_XTYPE_SHFT 8 151#define GRU_CB_XTYPE_SHFT 8
@@ -155,6 +160,10 @@ struct gru_instruction {
155#define GRU_CB_OPC_MASK 0xff 160#define GRU_CB_OPC_MASK 0xff
156#define GRU_CB_EXOPC_SHFT 24 161#define GRU_CB_EXOPC_SHFT 24
157#define GRU_CB_EXOPC_MASK 0xff 162#define GRU_CB_EXOPC_MASK 0xff
163#define GRU_IDEF2_SHFT 32
164#define GRU_IDEF2_MASK 0x3ffff
165#define GRU_ISTATUS_SHFT 56
166#define GRU_ISTATUS_MASK 0x3
158 167
159/* GRU instruction opcodes (opc field) */ 168/* GRU instruction opcodes (opc field) */
160#define OP_NOP 0x00 169#define OP_NOP 0x00
@@ -296,12 +305,14 @@ union gru_mesqhead {
296 305
297 306
298/* Generate the low word of a GRU instruction */ 307/* Generate the low word of a GRU instruction */
299static inline unsigned int 308static inline unsigned long
300__opword(unsigned char opcode, unsigned char exopc, unsigned char xtype, 309__opdword(unsigned char opcode, unsigned char exopc, unsigned char xtype,
301 unsigned char iaa0, unsigned char iaa1, 310 unsigned char iaa0, unsigned char iaa1,
302 unsigned char ima) 311 unsigned long idef2, unsigned char ima)
303{ 312{
304 return (1 << GRU_CB_ICMD_SHFT) | 313 return (1 << GRU_CB_ICMD_SHFT) |
314 ((unsigned long)CBS_ACTIVE << GRU_ISTATUS_SHFT) |
315 (idef2<< GRU_IDEF2_SHFT) |
305 (iaa0 << GRU_CB_IAA0_SHFT) | 316 (iaa0 << GRU_CB_IAA0_SHFT) |
306 (iaa1 << GRU_CB_IAA1_SHFT) | 317 (iaa1 << GRU_CB_IAA1_SHFT) |
307 (ima << GRU_CB_IMA_SHFT) | 318 (ima << GRU_CB_IMA_SHFT) |
@@ -319,12 +330,12 @@ static inline void gru_flush_cache(void *p)
319} 330}
320 331
321/* 332/*
322 * Store the lower 32 bits of the command including the "start" bit. Then 333 * Store the lower 64 bits of the command including the "start" bit. Then
323 * start the instruction executing. 334 * start the instruction executing.
324 */ 335 */
325static inline void gru_start_instruction(struct gru_instruction *ins, int op32) 336static inline void gru_start_instruction(struct gru_instruction *ins, unsigned long op64)
326{ 337{
327 gru_ordered_store_int(ins, op32); 338 gru_ordered_store_ulong(ins, op64);
328 mb(); 339 mb();
329 gru_flush_cache(ins); 340 gru_flush_cache(ins);
330} 341}
@@ -348,10 +359,9 @@ static inline void gru_vload_phys(void *cb, unsigned long gpa,
348 359
349 ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62); 360 ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
350 ins->nelem = 1; 361 ins->nelem = 1;
351 ins->tri0 = tri0;
352 ins->op1_stride = 1; 362 ins->op1_stride = 1;
353 gru_start_instruction(ins, __opword(OP_VLOAD, 0, XTYPE_DW, iaa, 0, 363 gru_start_instruction(ins, __opdword(OP_VLOAD, 0, XTYPE_DW, iaa, 0,
354 CB_IMA(hints))); 364 (unsigned long)tri0, CB_IMA(hints)));
355} 365}
356 366
357static inline void gru_vload(void *cb, unsigned long mem_addr, 367static inline void gru_vload(void *cb, unsigned long mem_addr,
@@ -362,10 +372,9 @@ static inline void gru_vload(void *cb, unsigned long mem_addr,
362 372
363 ins->baddr0 = (long)mem_addr; 373 ins->baddr0 = (long)mem_addr;
364 ins->nelem = nelem; 374 ins->nelem = nelem;
365 ins->tri0 = tri0;
366 ins->op1_stride = stride; 375 ins->op1_stride = stride;
367 gru_start_instruction(ins, __opword(OP_VLOAD, 0, xtype, IAA_RAM, 0, 376 gru_start_instruction(ins, __opdword(OP_VLOAD, 0, xtype, IAA_RAM, 0,
368 CB_IMA(hints))); 377 (unsigned long)tri0, CB_IMA(hints)));
369} 378}
370 379
371static inline void gru_vstore(void *cb, unsigned long mem_addr, 380static inline void gru_vstore(void *cb, unsigned long mem_addr,
@@ -376,10 +385,9 @@ static inline void gru_vstore(void *cb, unsigned long mem_addr,
376 385
377 ins->baddr0 = (long)mem_addr; 386 ins->baddr0 = (long)mem_addr;
378 ins->nelem = nelem; 387 ins->nelem = nelem;
379 ins->tri0 = tri0;
380 ins->op1_stride = stride; 388 ins->op1_stride = stride;
381 gru_start_instruction(ins, __opword(OP_VSTORE, 0, xtype, IAA_RAM, 0, 389 gru_start_instruction(ins, __opdword(OP_VSTORE, 0, xtype, IAA_RAM, 0,
382 CB_IMA(hints))); 390 tri0, CB_IMA(hints)));
383} 391}
384 392
385static inline void gru_ivload(void *cb, unsigned long mem_addr, 393static inline void gru_ivload(void *cb, unsigned long mem_addr,
@@ -390,10 +398,9 @@ static inline void gru_ivload(void *cb, unsigned long mem_addr,
390 398
391 ins->baddr0 = (long)mem_addr; 399 ins->baddr0 = (long)mem_addr;
392 ins->nelem = nelem; 400 ins->nelem = nelem;
393 ins->tri0 = tri0;
394 ins->tri1_bufsize = tri1; 401 ins->tri1_bufsize = tri1;
395 gru_start_instruction(ins, __opword(OP_IVLOAD, 0, xtype, IAA_RAM, 0, 402 gru_start_instruction(ins, __opdword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
396 CB_IMA(hints))); 403 tri0, CB_IMA(hints)));
397} 404}
398 405
399static inline void gru_ivstore(void *cb, unsigned long mem_addr, 406static inline void gru_ivstore(void *cb, unsigned long mem_addr,
@@ -404,10 +411,9 @@ static inline void gru_ivstore(void *cb, unsigned long mem_addr,
404 411
405 ins->baddr0 = (long)mem_addr; 412 ins->baddr0 = (long)mem_addr;
406 ins->nelem = nelem; 413 ins->nelem = nelem;
407 ins->tri0 = tri0;
408 ins->tri1_bufsize = tri1; 414 ins->tri1_bufsize = tri1;
409 gru_start_instruction(ins, __opword(OP_IVSTORE, 0, xtype, IAA_RAM, 0, 415 gru_start_instruction(ins, __opdword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
410 CB_IMA(hints))); 416 tri0, CB_IMA(hints)));
411} 417}
412 418
413static inline void gru_vset(void *cb, unsigned long mem_addr, 419static inline void gru_vset(void *cb, unsigned long mem_addr,
@@ -420,8 +426,8 @@ static inline void gru_vset(void *cb, unsigned long mem_addr,
420 ins->op2_value_baddr1 = value; 426 ins->op2_value_baddr1 = value;
421 ins->nelem = nelem; 427 ins->nelem = nelem;
422 ins->op1_stride = stride; 428 ins->op1_stride = stride;
423 gru_start_instruction(ins, __opword(OP_VSET, 0, xtype, IAA_RAM, 0, 429 gru_start_instruction(ins, __opdword(OP_VSET, 0, xtype, IAA_RAM, 0,
424 CB_IMA(hints))); 430 0, CB_IMA(hints)));
425} 431}
426 432
427static inline void gru_ivset(void *cb, unsigned long mem_addr, 433static inline void gru_ivset(void *cb, unsigned long mem_addr,
@@ -434,8 +440,8 @@ static inline void gru_ivset(void *cb, unsigned long mem_addr,
434 ins->op2_value_baddr1 = value; 440 ins->op2_value_baddr1 = value;
435 ins->nelem = nelem; 441 ins->nelem = nelem;
436 ins->tri1_bufsize = tri1; 442 ins->tri1_bufsize = tri1;
437 gru_start_instruction(ins, __opword(OP_IVSET, 0, xtype, IAA_RAM, 0, 443 gru_start_instruction(ins, __opdword(OP_IVSET, 0, xtype, IAA_RAM, 0,
438 CB_IMA(hints))); 444 0, CB_IMA(hints)));
439} 445}
440 446
441static inline void gru_vflush(void *cb, unsigned long mem_addr, 447static inline void gru_vflush(void *cb, unsigned long mem_addr,
@@ -447,15 +453,15 @@ static inline void gru_vflush(void *cb, unsigned long mem_addr,
447 ins->baddr0 = (long)mem_addr; 453 ins->baddr0 = (long)mem_addr;
448 ins->op1_stride = stride; 454 ins->op1_stride = stride;
449 ins->nelem = nelem; 455 ins->nelem = nelem;
450 gru_start_instruction(ins, __opword(OP_VFLUSH, 0, xtype, IAA_RAM, 0, 456 gru_start_instruction(ins, __opdword(OP_VFLUSH, 0, xtype, IAA_RAM, 0,
451 CB_IMA(hints))); 457 0, CB_IMA(hints)));
452} 458}
453 459
454static inline void gru_nop(void *cb, int hints) 460static inline void gru_nop(void *cb, int hints)
455{ 461{
456 struct gru_instruction *ins = (void *)cb; 462 struct gru_instruction *ins = (void *)cb;
457 463
458 gru_start_instruction(ins, __opword(OP_NOP, 0, 0, 0, 0, CB_IMA(hints))); 464 gru_start_instruction(ins, __opdword(OP_NOP, 0, 0, 0, 0, 0, CB_IMA(hints)));
459} 465}
460 466
461 467
@@ -469,10 +475,9 @@ static inline void gru_bcopy(void *cb, const unsigned long src,
469 ins->baddr0 = (long)src; 475 ins->baddr0 = (long)src;
470 ins->op2_value_baddr1 = (long)dest; 476 ins->op2_value_baddr1 = (long)dest;
471 ins->nelem = nelem; 477 ins->nelem = nelem;
472 ins->tri0 = tri0;
473 ins->tri1_bufsize = bufsize; 478 ins->tri1_bufsize = bufsize;
474 gru_start_instruction(ins, __opword(OP_BCOPY, 0, xtype, IAA_RAM, 479 gru_start_instruction(ins, __opdword(OP_BCOPY, 0, xtype, IAA_RAM,
475 IAA_RAM, CB_IMA(hints))); 480 IAA_RAM, tri0, CB_IMA(hints)));
476} 481}
477 482
478static inline void gru_bstore(void *cb, const unsigned long src, 483static inline void gru_bstore(void *cb, const unsigned long src,
@@ -484,9 +489,8 @@ static inline void gru_bstore(void *cb, const unsigned long src,
484 ins->baddr0 = (long)src; 489 ins->baddr0 = (long)src;
485 ins->op2_value_baddr1 = (long)dest; 490 ins->op2_value_baddr1 = (long)dest;
486 ins->nelem = nelem; 491 ins->nelem = nelem;
487 ins->tri0 = tri0; 492 gru_start_instruction(ins, __opdword(OP_BSTORE, 0, xtype, 0, IAA_RAM,
488 gru_start_instruction(ins, __opword(OP_BSTORE, 0, xtype, 0, IAA_RAM, 493 tri0, CB_IMA(hints)));
489 CB_IMA(hints)));
490} 494}
491 495
492static inline void gru_gamir(void *cb, int exopc, unsigned long src, 496static inline void gru_gamir(void *cb, int exopc, unsigned long src,
@@ -495,8 +499,8 @@ static inline void gru_gamir(void *cb, int exopc, unsigned long src,
495 struct gru_instruction *ins = (void *)cb; 499 struct gru_instruction *ins = (void *)cb;
496 500
497 ins->baddr0 = (long)src; 501 ins->baddr0 = (long)src;
498 gru_start_instruction(ins, __opword(OP_GAMIR, exopc, xtype, IAA_RAM, 0, 502 gru_start_instruction(ins, __opdword(OP_GAMIR, exopc, xtype, IAA_RAM, 0,
499 CB_IMA(hints))); 503 0, CB_IMA(hints)));
500} 504}
501 505
502static inline void gru_gamirr(void *cb, int exopc, unsigned long src, 506static inline void gru_gamirr(void *cb, int exopc, unsigned long src,
@@ -505,8 +509,8 @@ static inline void gru_gamirr(void *cb, int exopc, unsigned long src,
505 struct gru_instruction *ins = (void *)cb; 509 struct gru_instruction *ins = (void *)cb;
506 510
507 ins->baddr0 = (long)src; 511 ins->baddr0 = (long)src;
508 gru_start_instruction(ins, __opword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0, 512 gru_start_instruction(ins, __opdword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0,
509 CB_IMA(hints))); 513 0, CB_IMA(hints)));
510} 514}
511 515
512static inline void gru_gamer(void *cb, int exopc, unsigned long src, 516static inline void gru_gamer(void *cb, int exopc, unsigned long src,
@@ -519,8 +523,8 @@ static inline void gru_gamer(void *cb, int exopc, unsigned long src,
519 ins->baddr0 = (long)src; 523 ins->baddr0 = (long)src;
520 ins->op1_stride = operand1; 524 ins->op1_stride = operand1;
521 ins->op2_value_baddr1 = operand2; 525 ins->op2_value_baddr1 = operand2;
522 gru_start_instruction(ins, __opword(OP_GAMER, exopc, xtype, IAA_RAM, 0, 526 gru_start_instruction(ins, __opdword(OP_GAMER, exopc, xtype, IAA_RAM, 0,
523 CB_IMA(hints))); 527 0, CB_IMA(hints)));
524} 528}
525 529
526static inline void gru_gamerr(void *cb, int exopc, unsigned long src, 530static inline void gru_gamerr(void *cb, int exopc, unsigned long src,
@@ -532,8 +536,8 @@ static inline void gru_gamerr(void *cb, int exopc, unsigned long src,
532 ins->baddr0 = (long)src; 536 ins->baddr0 = (long)src;
533 ins->op1_stride = operand1; 537 ins->op1_stride = operand1;
534 ins->op2_value_baddr1 = operand2; 538 ins->op2_value_baddr1 = operand2;
535 gru_start_instruction(ins, __opword(OP_GAMERR, exopc, xtype, IAA_RAM, 0, 539 gru_start_instruction(ins, __opdword(OP_GAMERR, exopc, xtype, IAA_RAM, 0,
536 CB_IMA(hints))); 540 0, CB_IMA(hints)));
537} 541}
538 542
539static inline void gru_gamxr(void *cb, unsigned long src, 543static inline void gru_gamxr(void *cb, unsigned long src,
@@ -543,8 +547,8 @@ static inline void gru_gamxr(void *cb, unsigned long src,
543 547
544 ins->baddr0 = (long)src; 548 ins->baddr0 = (long)src;
545 ins->nelem = 4; 549 ins->nelem = 4;
546 gru_start_instruction(ins, __opword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW, 550 gru_start_instruction(ins, __opdword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW,
547 IAA_RAM, 0, CB_IMA(hints))); 551 IAA_RAM, 0, 0, CB_IMA(hints)));
548} 552}
549 553
550static inline void gru_mesq(void *cb, unsigned long queue, 554static inline void gru_mesq(void *cb, unsigned long queue,
@@ -555,9 +559,8 @@ static inline void gru_mesq(void *cb, unsigned long queue,
555 559
556 ins->baddr0 = (long)queue; 560 ins->baddr0 = (long)queue;
557 ins->nelem = nelem; 561 ins->nelem = nelem;
558 ins->tri0 = tri0; 562 gru_start_instruction(ins, __opdword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0,
559 gru_start_instruction(ins, __opword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0, 563 tri0, CB_IMA(hints)));
560 CB_IMA(hints)));
561} 564}
562 565
563static inline unsigned long gru_get_amo_value(void *cb) 566static inline unsigned long gru_get_amo_value(void *cb)
@@ -676,6 +679,14 @@ static inline void gru_wait_abort(void *cb)
676 gru_wait_abort_proc(cb); 679 gru_wait_abort_proc(cb);
677} 680}
678 681
682/*
683 * Get a pointer to the start of a gseg
684 * p - Any valid pointer within the gseg
685 */
686static inline void *gru_get_gseg_pointer (void *p)
687{
688 return (void *)((unsigned long)p & ~(GRU_GSEG_PAGESIZE - 1));
689}
679 690
680/* 691/*
681 * Get a pointer to a control block 692 * Get a pointer to a control block
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
index 4bc9ee811fbf..66d67d9bc9b6 100644
--- a/drivers/misc/sgi-gru/gruhandles.c
+++ b/drivers/misc/sgi-gru/gruhandles.c
@@ -54,8 +54,8 @@ static void start_instruction(void *h)
54{ 54{
55 unsigned long *w0 = h; 55 unsigned long *w0 = h;
56 56
57 wmb(); /* setting CMD bit must be last */ 57 wmb(); /* setting CMD/STATUS bits must be last */
58 *w0 = *w0 | 1; 58 *w0 = *w0 | 0x20001;
59 gru_flush_cache(h); 59 gru_flush_cache(h);
60} 60}
61 61