diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 1723 |
1 files changed, 1388 insertions, 335 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 2f93d46ae69a..15bd0477a3e8 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -32,26 +32,102 @@ | |||
32 | #include "atom.h" | 32 | #include "atom.h" |
33 | #include "avivod.h" | 33 | #include "avivod.h" |
34 | #include "evergreen_reg.h" | 34 | #include "evergreen_reg.h" |
35 | #include "evergreen_blit_shaders.h" | ||
35 | 36 | ||
36 | #define EVERGREEN_PFP_UCODE_SIZE 1120 | 37 | #define EVERGREEN_PFP_UCODE_SIZE 1120 |
37 | #define EVERGREEN_PM4_UCODE_SIZE 1376 | 38 | #define EVERGREEN_PM4_UCODE_SIZE 1376 |
38 | 39 | ||
39 | static void evergreen_gpu_init(struct radeon_device *rdev); | 40 | static void evergreen_gpu_init(struct radeon_device *rdev); |
40 | void evergreen_fini(struct radeon_device *rdev); | 41 | void evergreen_fini(struct radeon_device *rdev); |
42 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | ||
43 | |||
44 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) | ||
45 | { | ||
46 | /* enable the pflip int */ | ||
47 | radeon_irq_kms_pflip_irq_get(rdev, crtc); | ||
48 | } | ||
49 | |||
50 | void evergreen_post_page_flip(struct radeon_device *rdev, int crtc) | ||
51 | { | ||
52 | /* disable the pflip int */ | ||
53 | radeon_irq_kms_pflip_irq_put(rdev, crtc); | ||
54 | } | ||
55 | |||
56 | u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | ||
57 | { | ||
58 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
59 | u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset); | ||
60 | |||
61 | /* Lock the graphics update lock */ | ||
62 | tmp |= EVERGREEN_GRPH_UPDATE_LOCK; | ||
63 | WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
64 | |||
65 | /* update the scanout addresses */ | ||
66 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | ||
67 | upper_32_bits(crtc_base)); | ||
68 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
69 | (u32)crtc_base); | ||
70 | |||
71 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | ||
72 | upper_32_bits(crtc_base)); | ||
73 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
74 | (u32)crtc_base); | ||
75 | |||
76 | /* Wait for update_pending to go high. */ | ||
77 | while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)); | ||
78 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | ||
79 | |||
80 | /* Unlock the lock, so double-buffering can take place inside vblank */ | ||
81 | tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK; | ||
82 | WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
83 | |||
84 | /* Return current update_pending status: */ | ||
85 | return RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING; | ||
86 | } | ||
41 | 87 | ||
42 | /* get temperature in millidegrees */ | 88 | /* get temperature in millidegrees */ |
43 | u32 evergreen_get_temp(struct radeon_device *rdev) | 89 | int evergreen_get_temp(struct radeon_device *rdev) |
44 | { | 90 | { |
45 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> | 91 | u32 temp, toffset; |
46 | ASIC_T_SHIFT; | 92 | int actual_temp = 0; |
47 | u32 actual_temp = 0; | 93 | |
48 | 94 | if (rdev->family == CHIP_JUNIPER) { | |
49 | if ((temp >> 10) & 1) | 95 | toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >> |
50 | actual_temp = 0; | 96 | TOFFSET_SHIFT; |
51 | else if ((temp >> 9) & 1) | 97 | temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >> |
52 | actual_temp = 255; | 98 | TS0_ADC_DOUT_SHIFT; |
53 | else | 99 | |
54 | actual_temp = (temp >> 1) & 0xff; | 100 | if (toffset & 0x100) |
101 | actual_temp = temp / 2 - (0x200 - toffset); | ||
102 | else | ||
103 | actual_temp = temp / 2 + toffset; | ||
104 | |||
105 | actual_temp = actual_temp * 1000; | ||
106 | |||
107 | } else { | ||
108 | temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> | ||
109 | ASIC_T_SHIFT; | ||
110 | |||
111 | if (temp & 0x400) | ||
112 | actual_temp = -256; | ||
113 | else if (temp & 0x200) | ||
114 | actual_temp = 255; | ||
115 | else if (temp & 0x100) { | ||
116 | actual_temp = temp & 0x1ff; | ||
117 | actual_temp |= ~0x1ff; | ||
118 | } else | ||
119 | actual_temp = temp & 0xff; | ||
120 | |||
121 | actual_temp = (actual_temp * 1000) / 2; | ||
122 | } | ||
123 | |||
124 | return actual_temp; | ||
125 | } | ||
126 | |||
127 | int sumo_get_temp(struct radeon_device *rdev) | ||
128 | { | ||
129 | u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff; | ||
130 | int actual_temp = temp - 49; | ||
55 | 131 | ||
56 | return actual_temp * 1000; | 132 | return actual_temp * 1000; |
57 | } | 133 | } |
@@ -63,11 +139,22 @@ void evergreen_pm_misc(struct radeon_device *rdev) | |||
63 | struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; | 139 | struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; |
64 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; | 140 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; |
65 | 141 | ||
66 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | 142 | if (voltage->type == VOLTAGE_SW) { |
67 | if (voltage->voltage != rdev->pm.current_vddc) { | 143 | /* 0xff01 is a flag rather then an actual voltage */ |
68 | radeon_atom_set_voltage(rdev, voltage->voltage); | 144 | if (voltage->voltage == 0xff01) |
145 | return; | ||
146 | if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { | ||
147 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); | ||
69 | rdev->pm.current_vddc = voltage->voltage; | 148 | rdev->pm.current_vddc = voltage->voltage; |
70 | DRM_DEBUG("Setting: v: %d\n", voltage->voltage); | 149 | DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); |
150 | } | ||
151 | /* 0xff01 is a flag rather then an actual voltage */ | ||
152 | if (voltage->vddci == 0xff01) | ||
153 | return; | ||
154 | if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { | ||
155 | radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); | ||
156 | rdev->pm.current_vddci = voltage->vddci; | ||
157 | DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci); | ||
71 | } | 158 | } |
72 | } | 159 | } |
73 | } | 160 | } |
@@ -284,12 +371,458 @@ void evergreen_hpd_fini(struct radeon_device *rdev) | |||
284 | } | 371 | } |
285 | } | 372 | } |
286 | 373 | ||
374 | /* watermark setup */ | ||
375 | |||
376 | static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, | ||
377 | struct radeon_crtc *radeon_crtc, | ||
378 | struct drm_display_mode *mode, | ||
379 | struct drm_display_mode *other_mode) | ||
380 | { | ||
381 | u32 tmp; | ||
382 | /* | ||
383 | * Line Buffer Setup | ||
384 | * There are 3 line buffers, each one shared by 2 display controllers. | ||
385 | * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between | ||
386 | * the display controllers. The paritioning is done via one of four | ||
387 | * preset allocations specified in bits 2:0: | ||
388 | * first display controller | ||
389 | * 0 - first half of lb (3840 * 2) | ||
390 | * 1 - first 3/4 of lb (5760 * 2) | ||
391 | * 2 - whole lb (7680 * 2), other crtc must be disabled | ||
392 | * 3 - first 1/4 of lb (1920 * 2) | ||
393 | * second display controller | ||
394 | * 4 - second half of lb (3840 * 2) | ||
395 | * 5 - second 3/4 of lb (5760 * 2) | ||
396 | * 6 - whole lb (7680 * 2), other crtc must be disabled | ||
397 | * 7 - last 1/4 of lb (1920 * 2) | ||
398 | */ | ||
399 | /* this can get tricky if we have two large displays on a paired group | ||
400 | * of crtcs. Ideally for multiple large displays we'd assign them to | ||
401 | * non-linked crtcs for maximum line buffer allocation. | ||
402 | */ | ||
403 | if (radeon_crtc->base.enabled && mode) { | ||
404 | if (other_mode) | ||
405 | tmp = 0; /* 1/2 */ | ||
406 | else | ||
407 | tmp = 2; /* whole */ | ||
408 | } else | ||
409 | tmp = 0; | ||
410 | |||
411 | /* second controller of the pair uses second half of the lb */ | ||
412 | if (radeon_crtc->crtc_id % 2) | ||
413 | tmp += 4; | ||
414 | WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); | ||
415 | |||
416 | if (radeon_crtc->base.enabled && mode) { | ||
417 | switch (tmp) { | ||
418 | case 0: | ||
419 | case 4: | ||
420 | default: | ||
421 | if (ASIC_IS_DCE5(rdev)) | ||
422 | return 4096 * 2; | ||
423 | else | ||
424 | return 3840 * 2; | ||
425 | case 1: | ||
426 | case 5: | ||
427 | if (ASIC_IS_DCE5(rdev)) | ||
428 | return 6144 * 2; | ||
429 | else | ||
430 | return 5760 * 2; | ||
431 | case 2: | ||
432 | case 6: | ||
433 | if (ASIC_IS_DCE5(rdev)) | ||
434 | return 8192 * 2; | ||
435 | else | ||
436 | return 7680 * 2; | ||
437 | case 3: | ||
438 | case 7: | ||
439 | if (ASIC_IS_DCE5(rdev)) | ||
440 | return 2048 * 2; | ||
441 | else | ||
442 | return 1920 * 2; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | /* controller not enabled, so no lb used */ | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) | ||
451 | { | ||
452 | u32 tmp = RREG32(MC_SHARED_CHMAP); | ||
453 | |||
454 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
455 | case 0: | ||
456 | default: | ||
457 | return 1; | ||
458 | case 1: | ||
459 | return 2; | ||
460 | case 2: | ||
461 | return 4; | ||
462 | case 3: | ||
463 | return 8; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | struct evergreen_wm_params { | ||
468 | u32 dram_channels; /* number of dram channels */ | ||
469 | u32 yclk; /* bandwidth per dram data pin in kHz */ | ||
470 | u32 sclk; /* engine clock in kHz */ | ||
471 | u32 disp_clk; /* display clock in kHz */ | ||
472 | u32 src_width; /* viewport width */ | ||
473 | u32 active_time; /* active display time in ns */ | ||
474 | u32 blank_time; /* blank time in ns */ | ||
475 | bool interlaced; /* mode is interlaced */ | ||
476 | fixed20_12 vsc; /* vertical scale ratio */ | ||
477 | u32 num_heads; /* number of active crtcs */ | ||
478 | u32 bytes_per_pixel; /* bytes per pixel display + overlay */ | ||
479 | u32 lb_size; /* line buffer allocated to pipe */ | ||
480 | u32 vtaps; /* vertical scaler taps */ | ||
481 | }; | ||
482 | |||
483 | static u32 evergreen_dram_bandwidth(struct evergreen_wm_params *wm) | ||
484 | { | ||
485 | /* Calculate DRAM Bandwidth and the part allocated to display. */ | ||
486 | fixed20_12 dram_efficiency; /* 0.7 */ | ||
487 | fixed20_12 yclk, dram_channels, bandwidth; | ||
488 | fixed20_12 a; | ||
489 | |||
490 | a.full = dfixed_const(1000); | ||
491 | yclk.full = dfixed_const(wm->yclk); | ||
492 | yclk.full = dfixed_div(yclk, a); | ||
493 | dram_channels.full = dfixed_const(wm->dram_channels * 4); | ||
494 | a.full = dfixed_const(10); | ||
495 | dram_efficiency.full = dfixed_const(7); | ||
496 | dram_efficiency.full = dfixed_div(dram_efficiency, a); | ||
497 | bandwidth.full = dfixed_mul(dram_channels, yclk); | ||
498 | bandwidth.full = dfixed_mul(bandwidth, dram_efficiency); | ||
499 | |||
500 | return dfixed_trunc(bandwidth); | ||
501 | } | ||
502 | |||
503 | static u32 evergreen_dram_bandwidth_for_display(struct evergreen_wm_params *wm) | ||
504 | { | ||
505 | /* Calculate DRAM Bandwidth and the part allocated to display. */ | ||
506 | fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */ | ||
507 | fixed20_12 yclk, dram_channels, bandwidth; | ||
508 | fixed20_12 a; | ||
509 | |||
510 | a.full = dfixed_const(1000); | ||
511 | yclk.full = dfixed_const(wm->yclk); | ||
512 | yclk.full = dfixed_div(yclk, a); | ||
513 | dram_channels.full = dfixed_const(wm->dram_channels * 4); | ||
514 | a.full = dfixed_const(10); | ||
515 | disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */ | ||
516 | disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a); | ||
517 | bandwidth.full = dfixed_mul(dram_channels, yclk); | ||
518 | bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation); | ||
519 | |||
520 | return dfixed_trunc(bandwidth); | ||
521 | } | ||
522 | |||
523 | static u32 evergreen_data_return_bandwidth(struct evergreen_wm_params *wm) | ||
524 | { | ||
525 | /* Calculate the display Data return Bandwidth */ | ||
526 | fixed20_12 return_efficiency; /* 0.8 */ | ||
527 | fixed20_12 sclk, bandwidth; | ||
528 | fixed20_12 a; | ||
529 | |||
530 | a.full = dfixed_const(1000); | ||
531 | sclk.full = dfixed_const(wm->sclk); | ||
532 | sclk.full = dfixed_div(sclk, a); | ||
533 | a.full = dfixed_const(10); | ||
534 | return_efficiency.full = dfixed_const(8); | ||
535 | return_efficiency.full = dfixed_div(return_efficiency, a); | ||
536 | a.full = dfixed_const(32); | ||
537 | bandwidth.full = dfixed_mul(a, sclk); | ||
538 | bandwidth.full = dfixed_mul(bandwidth, return_efficiency); | ||
539 | |||
540 | return dfixed_trunc(bandwidth); | ||
541 | } | ||
542 | |||
543 | static u32 evergreen_dmif_request_bandwidth(struct evergreen_wm_params *wm) | ||
544 | { | ||
545 | /* Calculate the DMIF Request Bandwidth */ | ||
546 | fixed20_12 disp_clk_request_efficiency; /* 0.8 */ | ||
547 | fixed20_12 disp_clk, bandwidth; | ||
548 | fixed20_12 a; | ||
549 | |||
550 | a.full = dfixed_const(1000); | ||
551 | disp_clk.full = dfixed_const(wm->disp_clk); | ||
552 | disp_clk.full = dfixed_div(disp_clk, a); | ||
553 | a.full = dfixed_const(10); | ||
554 | disp_clk_request_efficiency.full = dfixed_const(8); | ||
555 | disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a); | ||
556 | a.full = dfixed_const(32); | ||
557 | bandwidth.full = dfixed_mul(a, disp_clk); | ||
558 | bandwidth.full = dfixed_mul(bandwidth, disp_clk_request_efficiency); | ||
559 | |||
560 | return dfixed_trunc(bandwidth); | ||
561 | } | ||
562 | |||
563 | static u32 evergreen_available_bandwidth(struct evergreen_wm_params *wm) | ||
564 | { | ||
565 | /* Calculate the Available bandwidth. Display can use this temporarily but not in average. */ | ||
566 | u32 dram_bandwidth = evergreen_dram_bandwidth(wm); | ||
567 | u32 data_return_bandwidth = evergreen_data_return_bandwidth(wm); | ||
568 | u32 dmif_req_bandwidth = evergreen_dmif_request_bandwidth(wm); | ||
569 | |||
570 | return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth)); | ||
571 | } | ||
572 | |||
573 | static u32 evergreen_average_bandwidth(struct evergreen_wm_params *wm) | ||
574 | { | ||
575 | /* Calculate the display mode Average Bandwidth | ||
576 | * DisplayMode should contain the source and destination dimensions, | ||
577 | * timing, etc. | ||
578 | */ | ||
579 | fixed20_12 bpp; | ||
580 | fixed20_12 line_time; | ||
581 | fixed20_12 src_width; | ||
582 | fixed20_12 bandwidth; | ||
583 | fixed20_12 a; | ||
584 | |||
585 | a.full = dfixed_const(1000); | ||
586 | line_time.full = dfixed_const(wm->active_time + wm->blank_time); | ||
587 | line_time.full = dfixed_div(line_time, a); | ||
588 | bpp.full = dfixed_const(wm->bytes_per_pixel); | ||
589 | src_width.full = dfixed_const(wm->src_width); | ||
590 | bandwidth.full = dfixed_mul(src_width, bpp); | ||
591 | bandwidth.full = dfixed_mul(bandwidth, wm->vsc); | ||
592 | bandwidth.full = dfixed_div(bandwidth, line_time); | ||
593 | |||
594 | return dfixed_trunc(bandwidth); | ||
595 | } | ||
596 | |||
597 | static u32 evergreen_latency_watermark(struct evergreen_wm_params *wm) | ||
598 | { | ||
599 | /* First calcualte the latency in ns */ | ||
600 | u32 mc_latency = 2000; /* 2000 ns. */ | ||
601 | u32 available_bandwidth = evergreen_available_bandwidth(wm); | ||
602 | u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth; | ||
603 | u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth; | ||
604 | u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */ | ||
605 | u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) + | ||
606 | (wm->num_heads * cursor_line_pair_return_time); | ||
607 | u32 latency = mc_latency + other_heads_data_return_time + dc_latency; | ||
608 | u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time; | ||
609 | fixed20_12 a, b, c; | ||
610 | |||
611 | if (wm->num_heads == 0) | ||
612 | return 0; | ||
613 | |||
614 | a.full = dfixed_const(2); | ||
615 | b.full = dfixed_const(1); | ||
616 | if ((wm->vsc.full > a.full) || | ||
617 | ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) || | ||
618 | (wm->vtaps >= 5) || | ||
619 | ((wm->vsc.full >= a.full) && wm->interlaced)) | ||
620 | max_src_lines_per_dst_line = 4; | ||
621 | else | ||
622 | max_src_lines_per_dst_line = 2; | ||
623 | |||
624 | a.full = dfixed_const(available_bandwidth); | ||
625 | b.full = dfixed_const(wm->num_heads); | ||
626 | a.full = dfixed_div(a, b); | ||
627 | |||
628 | b.full = dfixed_const(1000); | ||
629 | c.full = dfixed_const(wm->disp_clk); | ||
630 | b.full = dfixed_div(c, b); | ||
631 | c.full = dfixed_const(wm->bytes_per_pixel); | ||
632 | b.full = dfixed_mul(b, c); | ||
633 | |||
634 | lb_fill_bw = min(dfixed_trunc(a), dfixed_trunc(b)); | ||
635 | |||
636 | a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); | ||
637 | b.full = dfixed_const(1000); | ||
638 | c.full = dfixed_const(lb_fill_bw); | ||
639 | b.full = dfixed_div(c, b); | ||
640 | a.full = dfixed_div(a, b); | ||
641 | line_fill_time = dfixed_trunc(a); | ||
642 | |||
643 | if (line_fill_time < wm->active_time) | ||
644 | return latency; | ||
645 | else | ||
646 | return latency + (line_fill_time - wm->active_time); | ||
647 | |||
648 | } | ||
649 | |||
650 | static bool evergreen_average_bandwidth_vs_dram_bandwidth_for_display(struct evergreen_wm_params *wm) | ||
651 | { | ||
652 | if (evergreen_average_bandwidth(wm) <= | ||
653 | (evergreen_dram_bandwidth_for_display(wm) / wm->num_heads)) | ||
654 | return true; | ||
655 | else | ||
656 | return false; | ||
657 | }; | ||
658 | |||
659 | static bool evergreen_average_bandwidth_vs_available_bandwidth(struct evergreen_wm_params *wm) | ||
660 | { | ||
661 | if (evergreen_average_bandwidth(wm) <= | ||
662 | (evergreen_available_bandwidth(wm) / wm->num_heads)) | ||
663 | return true; | ||
664 | else | ||
665 | return false; | ||
666 | }; | ||
667 | |||
668 | static bool evergreen_check_latency_hiding(struct evergreen_wm_params *wm) | ||
669 | { | ||
670 | u32 lb_partitions = wm->lb_size / wm->src_width; | ||
671 | u32 line_time = wm->active_time + wm->blank_time; | ||
672 | u32 latency_tolerant_lines; | ||
673 | u32 latency_hiding; | ||
674 | fixed20_12 a; | ||
675 | |||
676 | a.full = dfixed_const(1); | ||
677 | if (wm->vsc.full > a.full) | ||
678 | latency_tolerant_lines = 1; | ||
679 | else { | ||
680 | if (lb_partitions <= (wm->vtaps + 1)) | ||
681 | latency_tolerant_lines = 1; | ||
682 | else | ||
683 | latency_tolerant_lines = 2; | ||
684 | } | ||
685 | |||
686 | latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time); | ||
687 | |||
688 | if (evergreen_latency_watermark(wm) <= latency_hiding) | ||
689 | return true; | ||
690 | else | ||
691 | return false; | ||
692 | } | ||
693 | |||
694 | static void evergreen_program_watermarks(struct radeon_device *rdev, | ||
695 | struct radeon_crtc *radeon_crtc, | ||
696 | u32 lb_size, u32 num_heads) | ||
697 | { | ||
698 | struct drm_display_mode *mode = &radeon_crtc->base.mode; | ||
699 | struct evergreen_wm_params wm; | ||
700 | u32 pixel_period; | ||
701 | u32 line_time = 0; | ||
702 | u32 latency_watermark_a = 0, latency_watermark_b = 0; | ||
703 | u32 priority_a_mark = 0, priority_b_mark = 0; | ||
704 | u32 priority_a_cnt = PRIORITY_OFF; | ||
705 | u32 priority_b_cnt = PRIORITY_OFF; | ||
706 | u32 pipe_offset = radeon_crtc->crtc_id * 16; | ||
707 | u32 tmp, arb_control3; | ||
708 | fixed20_12 a, b, c; | ||
709 | |||
710 | if (radeon_crtc->base.enabled && num_heads && mode) { | ||
711 | pixel_period = 1000000 / (u32)mode->clock; | ||
712 | line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535); | ||
713 | priority_a_cnt = 0; | ||
714 | priority_b_cnt = 0; | ||
715 | |||
716 | wm.yclk = rdev->pm.current_mclk * 10; | ||
717 | wm.sclk = rdev->pm.current_sclk * 10; | ||
718 | wm.disp_clk = mode->clock; | ||
719 | wm.src_width = mode->crtc_hdisplay; | ||
720 | wm.active_time = mode->crtc_hdisplay * pixel_period; | ||
721 | wm.blank_time = line_time - wm.active_time; | ||
722 | wm.interlaced = false; | ||
723 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
724 | wm.interlaced = true; | ||
725 | wm.vsc = radeon_crtc->vsc; | ||
726 | wm.vtaps = 1; | ||
727 | if (radeon_crtc->rmx_type != RMX_OFF) | ||
728 | wm.vtaps = 2; | ||
729 | wm.bytes_per_pixel = 4; /* XXX: get this from fb config */ | ||
730 | wm.lb_size = lb_size; | ||
731 | wm.dram_channels = evergreen_get_number_of_dram_channels(rdev); | ||
732 | wm.num_heads = num_heads; | ||
733 | |||
734 | /* set for high clocks */ | ||
735 | latency_watermark_a = min(evergreen_latency_watermark(&wm), (u32)65535); | ||
736 | /* set for low clocks */ | ||
737 | /* wm.yclk = low clk; wm.sclk = low clk */ | ||
738 | latency_watermark_b = min(evergreen_latency_watermark(&wm), (u32)65535); | ||
739 | |||
740 | /* possibly force display priority to high */ | ||
741 | /* should really do this at mode validation time... */ | ||
742 | if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm) || | ||
743 | !evergreen_average_bandwidth_vs_available_bandwidth(&wm) || | ||
744 | !evergreen_check_latency_hiding(&wm) || | ||
745 | (rdev->disp_priority == 2)) { | ||
746 | DRM_INFO("force priority to high\n"); | ||
747 | priority_a_cnt |= PRIORITY_ALWAYS_ON; | ||
748 | priority_b_cnt |= PRIORITY_ALWAYS_ON; | ||
749 | } | ||
750 | |||
751 | a.full = dfixed_const(1000); | ||
752 | b.full = dfixed_const(mode->clock); | ||
753 | b.full = dfixed_div(b, a); | ||
754 | c.full = dfixed_const(latency_watermark_a); | ||
755 | c.full = dfixed_mul(c, b); | ||
756 | c.full = dfixed_mul(c, radeon_crtc->hsc); | ||
757 | c.full = dfixed_div(c, a); | ||
758 | a.full = dfixed_const(16); | ||
759 | c.full = dfixed_div(c, a); | ||
760 | priority_a_mark = dfixed_trunc(c); | ||
761 | priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK; | ||
762 | |||
763 | a.full = dfixed_const(1000); | ||
764 | b.full = dfixed_const(mode->clock); | ||
765 | b.full = dfixed_div(b, a); | ||
766 | c.full = dfixed_const(latency_watermark_b); | ||
767 | c.full = dfixed_mul(c, b); | ||
768 | c.full = dfixed_mul(c, radeon_crtc->hsc); | ||
769 | c.full = dfixed_div(c, a); | ||
770 | a.full = dfixed_const(16); | ||
771 | c.full = dfixed_div(c, a); | ||
772 | priority_b_mark = dfixed_trunc(c); | ||
773 | priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; | ||
774 | } | ||
775 | |||
776 | /* select wm A */ | ||
777 | arb_control3 = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset); | ||
778 | tmp = arb_control3; | ||
779 | tmp &= ~LATENCY_WATERMARK_MASK(3); | ||
780 | tmp |= LATENCY_WATERMARK_MASK(1); | ||
781 | WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp); | ||
782 | WREG32(PIPE0_LATENCY_CONTROL + pipe_offset, | ||
783 | (LATENCY_LOW_WATERMARK(latency_watermark_a) | | ||
784 | LATENCY_HIGH_WATERMARK(line_time))); | ||
785 | /* select wm B */ | ||
786 | tmp = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset); | ||
787 | tmp &= ~LATENCY_WATERMARK_MASK(3); | ||
788 | tmp |= LATENCY_WATERMARK_MASK(2); | ||
789 | WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp); | ||
790 | WREG32(PIPE0_LATENCY_CONTROL + pipe_offset, | ||
791 | (LATENCY_LOW_WATERMARK(latency_watermark_b) | | ||
792 | LATENCY_HIGH_WATERMARK(line_time))); | ||
793 | /* restore original selection */ | ||
794 | WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, arb_control3); | ||
795 | |||
796 | /* write the priority marks */ | ||
797 | WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt); | ||
798 | WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt); | ||
799 | |||
800 | } | ||
801 | |||
287 | void evergreen_bandwidth_update(struct radeon_device *rdev) | 802 | void evergreen_bandwidth_update(struct radeon_device *rdev) |
288 | { | 803 | { |
289 | /* XXX */ | 804 | struct drm_display_mode *mode0 = NULL; |
805 | struct drm_display_mode *mode1 = NULL; | ||
806 | u32 num_heads = 0, lb_size; | ||
807 | int i; | ||
808 | |||
809 | radeon_update_display_priority(rdev); | ||
810 | |||
811 | for (i = 0; i < rdev->num_crtc; i++) { | ||
812 | if (rdev->mode_info.crtcs[i]->base.enabled) | ||
813 | num_heads++; | ||
814 | } | ||
815 | for (i = 0; i < rdev->num_crtc; i += 2) { | ||
816 | mode0 = &rdev->mode_info.crtcs[i]->base.mode; | ||
817 | mode1 = &rdev->mode_info.crtcs[i+1]->base.mode; | ||
818 | lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1); | ||
819 | evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads); | ||
820 | lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0); | ||
821 | evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads); | ||
822 | } | ||
290 | } | 823 | } |
291 | 824 | ||
292 | static int evergreen_mc_wait_for_idle(struct radeon_device *rdev) | 825 | int evergreen_mc_wait_for_idle(struct radeon_device *rdev) |
293 | { | 826 | { |
294 | unsigned i; | 827 | unsigned i; |
295 | u32 tmp; | 828 | u32 tmp; |
@@ -312,6 +845,8 @@ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
312 | unsigned i; | 845 | unsigned i; |
313 | u32 tmp; | 846 | u32 tmp; |
314 | 847 | ||
848 | WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
849 | |||
315 | WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); | 850 | WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); |
316 | for (i = 0; i < rdev->usec_timeout; i++) { | 851 | for (i = 0; i < rdev->usec_timeout; i++) { |
317 | /* read MC_STATUS */ | 852 | /* read MC_STATUS */ |
@@ -352,9 +887,15 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
352 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | | 887 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | |
353 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | | 888 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | |
354 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); | 889 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); |
355 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | 890 | if (rdev->flags & RADEON_IS_IGP) { |
356 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | 891 | WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); |
357 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | 892 | WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); |
893 | WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
894 | } else { | ||
895 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | ||
896 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | ||
897 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
898 | } | ||
358 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); | 899 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); |
359 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | 900 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); |
360 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 901 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
@@ -440,53 +981,73 @@ void evergreen_agp_enable(struct radeon_device *rdev) | |||
440 | WREG32(VM_CONTEXT1_CNTL, 0); | 981 | WREG32(VM_CONTEXT1_CNTL, 0); |
441 | } | 982 | } |
442 | 983 | ||
443 | static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | 984 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
444 | { | 985 | { |
445 | save->vga_control[0] = RREG32(D1VGA_CONTROL); | 986 | save->vga_control[0] = RREG32(D1VGA_CONTROL); |
446 | save->vga_control[1] = RREG32(D2VGA_CONTROL); | 987 | save->vga_control[1] = RREG32(D2VGA_CONTROL); |
447 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
448 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
449 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
450 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
451 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 988 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
452 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 989 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
453 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | 990 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); |
454 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | 991 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); |
455 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | 992 | if (rdev->num_crtc >= 4) { |
456 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | 993 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); |
457 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | 994 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); |
458 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | 995 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); |
996 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
997 | } | ||
998 | if (rdev->num_crtc >= 6) { | ||
999 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
1000 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
1001 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
1002 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
1003 | } | ||
459 | 1004 | ||
460 | /* Stop all video */ | 1005 | /* Stop all video */ |
461 | WREG32(VGA_RENDER_CONTROL, 0); | 1006 | WREG32(VGA_RENDER_CONTROL, 0); |
462 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | 1007 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); |
463 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | 1008 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); |
464 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | 1009 | if (rdev->num_crtc >= 4) { |
465 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | 1010 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); |
466 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | 1011 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); |
467 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | 1012 | } |
1013 | if (rdev->num_crtc >= 6) { | ||
1014 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
1015 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
1016 | } | ||
468 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1017 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
469 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1018 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
470 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1019 | if (rdev->num_crtc >= 4) { |
471 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1020 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
472 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1021 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
473 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 1022 | } |
1023 | if (rdev->num_crtc >= 6) { | ||
1024 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
1025 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
1026 | } | ||
474 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1027 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
475 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1028 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
476 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1029 | if (rdev->num_crtc >= 4) { |
477 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1030 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
478 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1031 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
479 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 1032 | } |
1033 | if (rdev->num_crtc >= 6) { | ||
1034 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
1035 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
1036 | } | ||
480 | 1037 | ||
481 | WREG32(D1VGA_CONTROL, 0); | 1038 | WREG32(D1VGA_CONTROL, 0); |
482 | WREG32(D2VGA_CONTROL, 0); | 1039 | WREG32(D2VGA_CONTROL, 0); |
483 | WREG32(EVERGREEN_D3VGA_CONTROL, 0); | 1040 | if (rdev->num_crtc >= 4) { |
484 | WREG32(EVERGREEN_D4VGA_CONTROL, 0); | 1041 | WREG32(EVERGREEN_D3VGA_CONTROL, 0); |
485 | WREG32(EVERGREEN_D5VGA_CONTROL, 0); | 1042 | WREG32(EVERGREEN_D4VGA_CONTROL, 0); |
486 | WREG32(EVERGREEN_D6VGA_CONTROL, 0); | 1043 | } |
1044 | if (rdev->num_crtc >= 6) { | ||
1045 | WREG32(EVERGREEN_D5VGA_CONTROL, 0); | ||
1046 | WREG32(EVERGREEN_D6VGA_CONTROL, 0); | ||
1047 | } | ||
487 | } | 1048 | } |
488 | 1049 | ||
489 | static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1050 | void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) |
490 | { | 1051 | { |
491 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, | 1052 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, |
492 | upper_32_bits(rdev->mc.vram_start)); | 1053 | upper_32_bits(rdev->mc.vram_start)); |
@@ -506,41 +1067,44 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ | |||
506 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, | 1067 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, |
507 | (u32)rdev->mc.vram_start); | 1068 | (u32)rdev->mc.vram_start); |
508 | 1069 | ||
509 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1070 | if (rdev->num_crtc >= 4) { |
510 | upper_32_bits(rdev->mc.vram_start)); | 1071 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, |
511 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1072 | upper_32_bits(rdev->mc.vram_start)); |
512 | upper_32_bits(rdev->mc.vram_start)); | 1073 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, |
513 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1074 | upper_32_bits(rdev->mc.vram_start)); |
514 | (u32)rdev->mc.vram_start); | 1075 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, |
515 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1076 | (u32)rdev->mc.vram_start); |
516 | (u32)rdev->mc.vram_start); | 1077 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, |
517 | 1078 | (u32)rdev->mc.vram_start); | |
518 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1079 | |
519 | upper_32_bits(rdev->mc.vram_start)); | 1080 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, |
520 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1081 | upper_32_bits(rdev->mc.vram_start)); |
521 | upper_32_bits(rdev->mc.vram_start)); | 1082 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, |
522 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1083 | upper_32_bits(rdev->mc.vram_start)); |
523 | (u32)rdev->mc.vram_start); | 1084 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, |
524 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1085 | (u32)rdev->mc.vram_start); |
525 | (u32)rdev->mc.vram_start); | 1086 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, |
526 | 1087 | (u32)rdev->mc.vram_start); | |
527 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1088 | } |
528 | upper_32_bits(rdev->mc.vram_start)); | 1089 | if (rdev->num_crtc >= 6) { |
529 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1090 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, |
530 | upper_32_bits(rdev->mc.vram_start)); | 1091 | upper_32_bits(rdev->mc.vram_start)); |
531 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1092 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, |
532 | (u32)rdev->mc.vram_start); | 1093 | upper_32_bits(rdev->mc.vram_start)); |
533 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1094 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, |
534 | (u32)rdev->mc.vram_start); | 1095 | (u32)rdev->mc.vram_start); |
535 | 1096 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | |
536 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1097 | (u32)rdev->mc.vram_start); |
537 | upper_32_bits(rdev->mc.vram_start)); | 1098 | |
538 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1099 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, |
539 | upper_32_bits(rdev->mc.vram_start)); | 1100 | upper_32_bits(rdev->mc.vram_start)); |
540 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1101 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, |
541 | (u32)rdev->mc.vram_start); | 1102 | upper_32_bits(rdev->mc.vram_start)); |
542 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1103 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, |
543 | (u32)rdev->mc.vram_start); | 1104 | (u32)rdev->mc.vram_start); |
1105 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
1106 | (u32)rdev->mc.vram_start); | ||
1107 | } | ||
544 | 1108 | ||
545 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); | 1109 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); |
546 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); | 1110 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); |
@@ -550,32 +1114,48 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ | |||
550 | /* Restore video state */ | 1114 | /* Restore video state */ |
551 | WREG32(D1VGA_CONTROL, save->vga_control[0]); | 1115 | WREG32(D1VGA_CONTROL, save->vga_control[0]); |
552 | WREG32(D2VGA_CONTROL, save->vga_control[1]); | 1116 | WREG32(D2VGA_CONTROL, save->vga_control[1]); |
553 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); | 1117 | if (rdev->num_crtc >= 4) { |
554 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); | 1118 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); |
555 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | 1119 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); |
556 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | 1120 | } |
1121 | if (rdev->num_crtc >= 6) { | ||
1122 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | ||
1123 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | ||
1124 | } | ||
557 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | 1125 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); |
558 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | 1126 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); |
559 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | 1127 | if (rdev->num_crtc >= 4) { |
560 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | 1128 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); |
561 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | 1129 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); |
562 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | 1130 | } |
1131 | if (rdev->num_crtc >= 6) { | ||
1132 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
1133 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
1134 | } | ||
563 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | 1135 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); |
564 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | 1136 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); |
565 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | 1137 | if (rdev->num_crtc >= 4) { |
566 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | 1138 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); |
567 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | 1139 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); |
568 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | 1140 | } |
1141 | if (rdev->num_crtc >= 6) { | ||
1142 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | ||
1143 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | ||
1144 | } | ||
569 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1145 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
570 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1146 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
571 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1147 | if (rdev->num_crtc >= 4) { |
572 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1148 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
573 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1149 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
574 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 1150 | } |
1151 | if (rdev->num_crtc >= 6) { | ||
1152 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
1153 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
1154 | } | ||
575 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 1155 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); |
576 | } | 1156 | } |
577 | 1157 | ||
578 | static void evergreen_mc_program(struct radeon_device *rdev) | 1158 | void evergreen_mc_program(struct radeon_device *rdev) |
579 | { | 1159 | { |
580 | struct evergreen_mc_save save; | 1160 | struct evergreen_mc_save save; |
581 | u32 tmp; | 1161 | u32 tmp; |
@@ -619,11 +1199,17 @@ static void evergreen_mc_program(struct radeon_device *rdev) | |||
619 | rdev->mc.vram_end >> 12); | 1199 | rdev->mc.vram_end >> 12); |
620 | } | 1200 | } |
621 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 1201 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); |
1202 | if (rdev->flags & RADEON_IS_IGP) { | ||
1203 | tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; | ||
1204 | tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; | ||
1205 | tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20; | ||
1206 | WREG32(MC_FUS_VM_FB_OFFSET, tmp); | ||
1207 | } | ||
622 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | 1208 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; |
623 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | 1209 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); |
624 | WREG32(MC_VM_FB_LOCATION, tmp); | 1210 | WREG32(MC_VM_FB_LOCATION, tmp); |
625 | WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); | 1211 | WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); |
626 | WREG32(HDP_NONSURFACE_INFO, (2 << 7)); | 1212 | WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30)); |
627 | WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); | 1213 | WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); |
628 | if (rdev->flags & RADEON_IS_AGP) { | 1214 | if (rdev->flags & RADEON_IS_AGP) { |
629 | WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); | 1215 | WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); |
@@ -646,6 +1232,22 @@ static void evergreen_mc_program(struct radeon_device *rdev) | |||
646 | /* | 1232 | /* |
647 | * CP. | 1233 | * CP. |
648 | */ | 1234 | */ |
1235 | void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | ||
1236 | { | ||
1237 | /* set to DX10/11 mode */ | ||
1238 | radeon_ring_write(rdev, PACKET3(PACKET3_MODE_CONTROL, 0)); | ||
1239 | radeon_ring_write(rdev, 1); | ||
1240 | /* FIXME: implement */ | ||
1241 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | ||
1242 | radeon_ring_write(rdev, | ||
1243 | #ifdef __BIG_ENDIAN | ||
1244 | (2 << 0) | | ||
1245 | #endif | ||
1246 | (ib->gpu_addr & 0xFFFFFFFC)); | ||
1247 | radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); | ||
1248 | radeon_ring_write(rdev, ib->length_dw); | ||
1249 | } | ||
1250 | |||
649 | 1251 | ||
650 | static int evergreen_cp_load_microcode(struct radeon_device *rdev) | 1252 | static int evergreen_cp_load_microcode(struct radeon_device *rdev) |
651 | { | 1253 | { |
@@ -656,7 +1258,11 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) | |||
656 | return -EINVAL; | 1258 | return -EINVAL; |
657 | 1259 | ||
658 | r700_cp_stop(rdev); | 1260 | r700_cp_stop(rdev); |
659 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); | 1261 | WREG32(CP_RB_CNTL, |
1262 | #ifdef __BIG_ENDIAN | ||
1263 | BUF_SWAP_32BIT | | ||
1264 | #endif | ||
1265 | RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | ||
660 | 1266 | ||
661 | fw_data = (const __be32 *)rdev->pfp_fw->data; | 1267 | fw_data = (const __be32 *)rdev->pfp_fw->data; |
662 | WREG32(CP_PFP_UCODE_ADDR, 0); | 1268 | WREG32(CP_PFP_UCODE_ADDR, 0); |
@@ -677,7 +1283,7 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) | |||
677 | 1283 | ||
678 | static int evergreen_cp_start(struct radeon_device *rdev) | 1284 | static int evergreen_cp_start(struct radeon_device *rdev) |
679 | { | 1285 | { |
680 | int r; | 1286 | int r, i; |
681 | uint32_t cp_me; | 1287 | uint32_t cp_me; |
682 | 1288 | ||
683 | r = radeon_ring_lock(rdev, 7); | 1289 | r = radeon_ring_lock(rdev, 7); |
@@ -697,16 +1303,44 @@ static int evergreen_cp_start(struct radeon_device *rdev) | |||
697 | cp_me = 0xff; | 1303 | cp_me = 0xff; |
698 | WREG32(CP_ME_CNTL, cp_me); | 1304 | WREG32(CP_ME_CNTL, cp_me); |
699 | 1305 | ||
700 | r = radeon_ring_lock(rdev, 4); | 1306 | r = radeon_ring_lock(rdev, evergreen_default_size + 19); |
701 | if (r) { | 1307 | if (r) { |
702 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | 1308 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); |
703 | return r; | 1309 | return r; |
704 | } | 1310 | } |
705 | /* init some VGT regs */ | 1311 | |
706 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); | 1312 | /* setup clear context state */ |
707 | radeon_ring_write(rdev, (VGT_VERTEX_REUSE_BLOCK_CNTL - PACKET3_SET_CONTEXT_REG_START) >> 2); | 1313 | radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); |
708 | radeon_ring_write(rdev, 0xe); | 1314 | radeon_ring_write(rdev, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); |
709 | radeon_ring_write(rdev, 0x10); | 1315 | |
1316 | for (i = 0; i < evergreen_default_size; i++) | ||
1317 | radeon_ring_write(rdev, evergreen_default_state[i]); | ||
1318 | |||
1319 | radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); | ||
1320 | radeon_ring_write(rdev, PACKET3_PREAMBLE_END_CLEAR_STATE); | ||
1321 | |||
1322 | /* set clear context state */ | ||
1323 | radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0)); | ||
1324 | radeon_ring_write(rdev, 0); | ||
1325 | |||
1326 | /* SQ_VTX_BASE_VTX_LOC */ | ||
1327 | radeon_ring_write(rdev, 0xc0026f00); | ||
1328 | radeon_ring_write(rdev, 0x00000000); | ||
1329 | radeon_ring_write(rdev, 0x00000000); | ||
1330 | radeon_ring_write(rdev, 0x00000000); | ||
1331 | |||
1332 | /* Clear consts */ | ||
1333 | radeon_ring_write(rdev, 0xc0036f00); | ||
1334 | radeon_ring_write(rdev, 0x00000bc4); | ||
1335 | radeon_ring_write(rdev, 0xffffffff); | ||
1336 | radeon_ring_write(rdev, 0xffffffff); | ||
1337 | radeon_ring_write(rdev, 0xffffffff); | ||
1338 | |||
1339 | radeon_ring_write(rdev, 0xc0026900); | ||
1340 | radeon_ring_write(rdev, 0x00000316); | ||
1341 | radeon_ring_write(rdev, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ | ||
1342 | radeon_ring_write(rdev, 0x00000010); /* */ | ||
1343 | |||
710 | radeon_ring_unlock_commit(rdev); | 1344 | radeon_ring_unlock_commit(rdev); |
711 | 1345 | ||
712 | return 0; | 1346 | return 0; |
@@ -731,7 +1365,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
731 | 1365 | ||
732 | /* Set ring buffer size */ | 1366 | /* Set ring buffer size */ |
733 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); | 1367 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); |
734 | tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; | 1368 | tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; |
735 | #ifdef __BIG_ENDIAN | 1369 | #ifdef __BIG_ENDIAN |
736 | tmp |= BUF_SWAP_32BIT; | 1370 | tmp |= BUF_SWAP_32BIT; |
737 | #endif | 1371 | #endif |
@@ -745,8 +1379,23 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
745 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); | 1379 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); |
746 | WREG32(CP_RB_RPTR_WR, 0); | 1380 | WREG32(CP_RB_RPTR_WR, 0); |
747 | WREG32(CP_RB_WPTR, 0); | 1381 | WREG32(CP_RB_WPTR, 0); |
748 | WREG32(CP_RB_RPTR_ADDR, rdev->cp.gpu_addr & 0xFFFFFFFF); | 1382 | |
749 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->cp.gpu_addr)); | 1383 | /* set the wb address wether it's enabled or not */ |
1384 | WREG32(CP_RB_RPTR_ADDR, | ||
1385 | #ifdef __BIG_ENDIAN | ||
1386 | RB_RPTR_SWAP(2) | | ||
1387 | #endif | ||
1388 | ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); | ||
1389 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); | ||
1390 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); | ||
1391 | |||
1392 | if (rdev->wb.enabled) | ||
1393 | WREG32(SCRATCH_UMSK, 0xff); | ||
1394 | else { | ||
1395 | tmp |= RB_NO_UPDATE; | ||
1396 | WREG32(SCRATCH_UMSK, 0); | ||
1397 | } | ||
1398 | |||
750 | mdelay(1); | 1399 | mdelay(1); |
751 | WREG32(CP_RB_CNTL, tmp); | 1400 | WREG32(CP_RB_CNTL, tmp); |
752 | 1401 | ||
@@ -813,11 +1462,17 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, | |||
813 | switch (rdev->family) { | 1462 | switch (rdev->family) { |
814 | case CHIP_CEDAR: | 1463 | case CHIP_CEDAR: |
815 | case CHIP_REDWOOD: | 1464 | case CHIP_REDWOOD: |
1465 | case CHIP_PALM: | ||
1466 | case CHIP_SUMO: | ||
1467 | case CHIP_SUMO2: | ||
1468 | case CHIP_TURKS: | ||
1469 | case CHIP_CAICOS: | ||
816 | force_no_swizzle = false; | 1470 | force_no_swizzle = false; |
817 | break; | 1471 | break; |
818 | case CHIP_CYPRESS: | 1472 | case CHIP_CYPRESS: |
819 | case CHIP_HEMLOCK: | 1473 | case CHIP_HEMLOCK: |
820 | case CHIP_JUNIPER: | 1474 | case CHIP_JUNIPER: |
1475 | case CHIP_BARTS: | ||
821 | default: | 1476 | default: |
822 | force_no_swizzle = true; | 1477 | force_no_swizzle = true; |
823 | break; | 1478 | break; |
@@ -912,6 +1567,48 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, | |||
912 | return backend_map; | 1567 | return backend_map; |
913 | } | 1568 | } |
914 | 1569 | ||
1570 | static void evergreen_program_channel_remap(struct radeon_device *rdev) | ||
1571 | { | ||
1572 | u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; | ||
1573 | |||
1574 | tmp = RREG32(MC_SHARED_CHMAP); | ||
1575 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
1576 | case 0: | ||
1577 | case 1: | ||
1578 | case 2: | ||
1579 | case 3: | ||
1580 | default: | ||
1581 | /* default mapping */ | ||
1582 | mc_shared_chremap = 0x00fac688; | ||
1583 | break; | ||
1584 | } | ||
1585 | |||
1586 | switch (rdev->family) { | ||
1587 | case CHIP_HEMLOCK: | ||
1588 | case CHIP_CYPRESS: | ||
1589 | case CHIP_BARTS: | ||
1590 | tcp_chan_steer_lo = 0x54763210; | ||
1591 | tcp_chan_steer_hi = 0x0000ba98; | ||
1592 | break; | ||
1593 | case CHIP_JUNIPER: | ||
1594 | case CHIP_REDWOOD: | ||
1595 | case CHIP_CEDAR: | ||
1596 | case CHIP_PALM: | ||
1597 | case CHIP_SUMO: | ||
1598 | case CHIP_SUMO2: | ||
1599 | case CHIP_TURKS: | ||
1600 | case CHIP_CAICOS: | ||
1601 | default: | ||
1602 | tcp_chan_steer_lo = 0x76543210; | ||
1603 | tcp_chan_steer_hi = 0x0000ba98; | ||
1604 | break; | ||
1605 | } | ||
1606 | |||
1607 | WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); | ||
1608 | WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); | ||
1609 | WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); | ||
1610 | } | ||
1611 | |||
915 | static void evergreen_gpu_init(struct radeon_device *rdev) | 1612 | static void evergreen_gpu_init(struct radeon_device *rdev) |
916 | { | 1613 | { |
917 | u32 cc_rb_backend_disable = 0; | 1614 | u32 cc_rb_backend_disable = 0; |
@@ -933,7 +1630,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
933 | u32 sq_stack_resource_mgmt_2; | 1630 | u32 sq_stack_resource_mgmt_2; |
934 | u32 sq_stack_resource_mgmt_3; | 1631 | u32 sq_stack_resource_mgmt_3; |
935 | u32 vgt_cache_invalidation; | 1632 | u32 vgt_cache_invalidation; |
936 | u32 hdp_host_path_cntl; | 1633 | u32 hdp_host_path_cntl, tmp; |
937 | int i, j, num_shader_engines, ps_thread_count; | 1634 | int i, j, num_shader_engines, ps_thread_count; |
938 | 1635 | ||
939 | switch (rdev->family) { | 1636 | switch (rdev->family) { |
@@ -1023,6 +1720,138 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1023 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | 1720 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; |
1024 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | 1721 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; |
1025 | break; | 1722 | break; |
1723 | case CHIP_PALM: | ||
1724 | rdev->config.evergreen.num_ses = 1; | ||
1725 | rdev->config.evergreen.max_pipes = 2; | ||
1726 | rdev->config.evergreen.max_tile_pipes = 2; | ||
1727 | rdev->config.evergreen.max_simds = 2; | ||
1728 | rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; | ||
1729 | rdev->config.evergreen.max_gprs = 256; | ||
1730 | rdev->config.evergreen.max_threads = 192; | ||
1731 | rdev->config.evergreen.max_gs_threads = 16; | ||
1732 | rdev->config.evergreen.max_stack_entries = 256; | ||
1733 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
1734 | rdev->config.evergreen.sx_max_export_size = 128; | ||
1735 | rdev->config.evergreen.sx_max_export_pos_size = 32; | ||
1736 | rdev->config.evergreen.sx_max_export_smx_size = 96; | ||
1737 | rdev->config.evergreen.max_hw_contexts = 4; | ||
1738 | rdev->config.evergreen.sq_num_cf_insts = 1; | ||
1739 | |||
1740 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; | ||
1741 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
1742 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
1743 | break; | ||
1744 | case CHIP_SUMO: | ||
1745 | rdev->config.evergreen.num_ses = 1; | ||
1746 | rdev->config.evergreen.max_pipes = 4; | ||
1747 | rdev->config.evergreen.max_tile_pipes = 2; | ||
1748 | if (rdev->pdev->device == 0x9648) | ||
1749 | rdev->config.evergreen.max_simds = 3; | ||
1750 | else if ((rdev->pdev->device == 0x9647) || | ||
1751 | (rdev->pdev->device == 0x964a)) | ||
1752 | rdev->config.evergreen.max_simds = 4; | ||
1753 | else | ||
1754 | rdev->config.evergreen.max_simds = 5; | ||
1755 | rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; | ||
1756 | rdev->config.evergreen.max_gprs = 256; | ||
1757 | rdev->config.evergreen.max_threads = 248; | ||
1758 | rdev->config.evergreen.max_gs_threads = 32; | ||
1759 | rdev->config.evergreen.max_stack_entries = 256; | ||
1760 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
1761 | rdev->config.evergreen.sx_max_export_size = 256; | ||
1762 | rdev->config.evergreen.sx_max_export_pos_size = 64; | ||
1763 | rdev->config.evergreen.sx_max_export_smx_size = 192; | ||
1764 | rdev->config.evergreen.max_hw_contexts = 8; | ||
1765 | rdev->config.evergreen.sq_num_cf_insts = 2; | ||
1766 | |||
1767 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; | ||
1768 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
1769 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
1770 | break; | ||
1771 | case CHIP_SUMO2: | ||
1772 | rdev->config.evergreen.num_ses = 1; | ||
1773 | rdev->config.evergreen.max_pipes = 4; | ||
1774 | rdev->config.evergreen.max_tile_pipes = 4; | ||
1775 | rdev->config.evergreen.max_simds = 2; | ||
1776 | rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; | ||
1777 | rdev->config.evergreen.max_gprs = 256; | ||
1778 | rdev->config.evergreen.max_threads = 248; | ||
1779 | rdev->config.evergreen.max_gs_threads = 32; | ||
1780 | rdev->config.evergreen.max_stack_entries = 512; | ||
1781 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
1782 | rdev->config.evergreen.sx_max_export_size = 256; | ||
1783 | rdev->config.evergreen.sx_max_export_pos_size = 64; | ||
1784 | rdev->config.evergreen.sx_max_export_smx_size = 192; | ||
1785 | rdev->config.evergreen.max_hw_contexts = 8; | ||
1786 | rdev->config.evergreen.sq_num_cf_insts = 2; | ||
1787 | |||
1788 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; | ||
1789 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
1790 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
1791 | break; | ||
1792 | case CHIP_BARTS: | ||
1793 | rdev->config.evergreen.num_ses = 2; | ||
1794 | rdev->config.evergreen.max_pipes = 4; | ||
1795 | rdev->config.evergreen.max_tile_pipes = 8; | ||
1796 | rdev->config.evergreen.max_simds = 7; | ||
1797 | rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses; | ||
1798 | rdev->config.evergreen.max_gprs = 256; | ||
1799 | rdev->config.evergreen.max_threads = 248; | ||
1800 | rdev->config.evergreen.max_gs_threads = 32; | ||
1801 | rdev->config.evergreen.max_stack_entries = 512; | ||
1802 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
1803 | rdev->config.evergreen.sx_max_export_size = 256; | ||
1804 | rdev->config.evergreen.sx_max_export_pos_size = 64; | ||
1805 | rdev->config.evergreen.sx_max_export_smx_size = 192; | ||
1806 | rdev->config.evergreen.max_hw_contexts = 8; | ||
1807 | rdev->config.evergreen.sq_num_cf_insts = 2; | ||
1808 | |||
1809 | rdev->config.evergreen.sc_prim_fifo_size = 0x100; | ||
1810 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
1811 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
1812 | break; | ||
1813 | case CHIP_TURKS: | ||
1814 | rdev->config.evergreen.num_ses = 1; | ||
1815 | rdev->config.evergreen.max_pipes = 4; | ||
1816 | rdev->config.evergreen.max_tile_pipes = 4; | ||
1817 | rdev->config.evergreen.max_simds = 6; | ||
1818 | rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; | ||
1819 | rdev->config.evergreen.max_gprs = 256; | ||
1820 | rdev->config.evergreen.max_threads = 248; | ||
1821 | rdev->config.evergreen.max_gs_threads = 32; | ||
1822 | rdev->config.evergreen.max_stack_entries = 256; | ||
1823 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
1824 | rdev->config.evergreen.sx_max_export_size = 256; | ||
1825 | rdev->config.evergreen.sx_max_export_pos_size = 64; | ||
1826 | rdev->config.evergreen.sx_max_export_smx_size = 192; | ||
1827 | rdev->config.evergreen.max_hw_contexts = 8; | ||
1828 | rdev->config.evergreen.sq_num_cf_insts = 2; | ||
1829 | |||
1830 | rdev->config.evergreen.sc_prim_fifo_size = 0x100; | ||
1831 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
1832 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
1833 | break; | ||
1834 | case CHIP_CAICOS: | ||
1835 | rdev->config.evergreen.num_ses = 1; | ||
1836 | rdev->config.evergreen.max_pipes = 4; | ||
1837 | rdev->config.evergreen.max_tile_pipes = 2; | ||
1838 | rdev->config.evergreen.max_simds = 2; | ||
1839 | rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; | ||
1840 | rdev->config.evergreen.max_gprs = 256; | ||
1841 | rdev->config.evergreen.max_threads = 192; | ||
1842 | rdev->config.evergreen.max_gs_threads = 16; | ||
1843 | rdev->config.evergreen.max_stack_entries = 256; | ||
1844 | rdev->config.evergreen.sx_num_of_sets = 4; | ||
1845 | rdev->config.evergreen.sx_max_export_size = 128; | ||
1846 | rdev->config.evergreen.sx_max_export_pos_size = 32; | ||
1847 | rdev->config.evergreen.sx_max_export_smx_size = 96; | ||
1848 | rdev->config.evergreen.max_hw_contexts = 4; | ||
1849 | rdev->config.evergreen.sq_num_cf_insts = 1; | ||
1850 | |||
1851 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; | ||
1852 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | ||
1853 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | ||
1854 | break; | ||
1026 | } | 1855 | } |
1027 | 1856 | ||
1028 | /* Initialize HDP */ | 1857 | /* Initialize HDP */ |
@@ -1051,7 +1880,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1051 | 1880 | ||
1052 | 1881 | ||
1053 | mc_shared_chmap = RREG32(MC_SHARED_CHMAP); | 1882 | mc_shared_chmap = RREG32(MC_SHARED_CHMAP); |
1054 | mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); | 1883 | if (rdev->flags & RADEON_IS_IGP) |
1884 | mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG); | ||
1885 | else | ||
1886 | mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); | ||
1055 | 1887 | ||
1056 | switch (rdev->config.evergreen.max_tile_pipes) { | 1888 | switch (rdev->config.evergreen.max_tile_pipes) { |
1057 | case 1: | 1889 | case 1: |
@@ -1164,10 +1996,11 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1164 | switch (rdev->family) { | 1996 | switch (rdev->family) { |
1165 | case CHIP_CYPRESS: | 1997 | case CHIP_CYPRESS: |
1166 | case CHIP_HEMLOCK: | 1998 | case CHIP_HEMLOCK: |
1999 | case CHIP_BARTS: | ||
1167 | gb_backend_map = 0x66442200; | 2000 | gb_backend_map = 0x66442200; |
1168 | break; | 2001 | break; |
1169 | case CHIP_JUNIPER: | 2002 | case CHIP_JUNIPER: |
1170 | gb_backend_map = 0x00006420; | 2003 | gb_backend_map = 0x00002200; |
1171 | break; | 2004 | break; |
1172 | default: | 2005 | default: |
1173 | gb_backend_map = | 2006 | gb_backend_map = |
@@ -1180,12 +2013,47 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1180 | } | 2013 | } |
1181 | } | 2014 | } |
1182 | 2015 | ||
1183 | rdev->config.evergreen.tile_config = gb_addr_config; | 2016 | /* setup tiling info dword. gb_addr_config is not adequate since it does |
2017 | * not have bank info, so create a custom tiling dword. | ||
2018 | * bits 3:0 num_pipes | ||
2019 | * bits 7:4 num_banks | ||
2020 | * bits 11:8 group_size | ||
2021 | * bits 15:12 row_size | ||
2022 | */ | ||
2023 | rdev->config.evergreen.tile_config = 0; | ||
2024 | switch (rdev->config.evergreen.max_tile_pipes) { | ||
2025 | case 1: | ||
2026 | default: | ||
2027 | rdev->config.evergreen.tile_config |= (0 << 0); | ||
2028 | break; | ||
2029 | case 2: | ||
2030 | rdev->config.evergreen.tile_config |= (1 << 0); | ||
2031 | break; | ||
2032 | case 4: | ||
2033 | rdev->config.evergreen.tile_config |= (2 << 0); | ||
2034 | break; | ||
2035 | case 8: | ||
2036 | rdev->config.evergreen.tile_config |= (3 << 0); | ||
2037 | break; | ||
2038 | } | ||
2039 | /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ | ||
2040 | if (rdev->flags & RADEON_IS_IGP) | ||
2041 | rdev->config.evergreen.tile_config |= 1 << 4; | ||
2042 | else | ||
2043 | rdev->config.evergreen.tile_config |= | ||
2044 | ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; | ||
2045 | rdev->config.evergreen.tile_config |= | ||
2046 | ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8; | ||
2047 | rdev->config.evergreen.tile_config |= | ||
2048 | ((gb_addr_config & 0x30000000) >> 28) << 12; | ||
2049 | |||
1184 | WREG32(GB_BACKEND_MAP, gb_backend_map); | 2050 | WREG32(GB_BACKEND_MAP, gb_backend_map); |
1185 | WREG32(GB_ADDR_CONFIG, gb_addr_config); | 2051 | WREG32(GB_ADDR_CONFIG, gb_addr_config); |
1186 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); | 2052 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); |
1187 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); | 2053 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); |
1188 | 2054 | ||
2055 | evergreen_program_channel_remap(rdev); | ||
2056 | |||
1189 | num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; | 2057 | num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; |
1190 | grbm_gfx_index = INSTANCE_BROADCAST_WRITES; | 2058 | grbm_gfx_index = INSTANCE_BROADCAST_WRITES; |
1191 | 2059 | ||
@@ -1268,9 +2136,18 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1268 | GS_PRIO(2) | | 2136 | GS_PRIO(2) | |
1269 | ES_PRIO(3)); | 2137 | ES_PRIO(3)); |
1270 | 2138 | ||
1271 | if (rdev->family == CHIP_CEDAR) | 2139 | switch (rdev->family) { |
2140 | case CHIP_CEDAR: | ||
2141 | case CHIP_PALM: | ||
2142 | case CHIP_SUMO: | ||
2143 | case CHIP_SUMO2: | ||
2144 | case CHIP_CAICOS: | ||
1272 | /* no vertex cache */ | 2145 | /* no vertex cache */ |
1273 | sq_config &= ~VC_ENABLE; | 2146 | sq_config &= ~VC_ENABLE; |
2147 | break; | ||
2148 | default: | ||
2149 | break; | ||
2150 | } | ||
1274 | 2151 | ||
1275 | sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT); | 2152 | sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT); |
1276 | 2153 | ||
@@ -1282,10 +2159,17 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1282 | sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); | 2159 | sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); |
1283 | sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); | 2160 | sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); |
1284 | 2161 | ||
1285 | if (rdev->family == CHIP_CEDAR) | 2162 | switch (rdev->family) { |
2163 | case CHIP_CEDAR: | ||
2164 | case CHIP_PALM: | ||
2165 | case CHIP_SUMO: | ||
2166 | case CHIP_SUMO2: | ||
1286 | ps_thread_count = 96; | 2167 | ps_thread_count = 96; |
1287 | else | 2168 | break; |
2169 | default: | ||
1288 | ps_thread_count = 128; | 2170 | ps_thread_count = 128; |
2171 | break; | ||
2172 | } | ||
1289 | 2173 | ||
1290 | sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count); | 2174 | sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count); |
1291 | sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); | 2175 | sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); |
@@ -1316,14 +2200,23 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1316 | WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | | 2200 | WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | |
1317 | FORCE_EOV_MAX_REZ_CNT(255))); | 2201 | FORCE_EOV_MAX_REZ_CNT(255))); |
1318 | 2202 | ||
1319 | if (rdev->family == CHIP_CEDAR) | 2203 | switch (rdev->family) { |
2204 | case CHIP_CEDAR: | ||
2205 | case CHIP_PALM: | ||
2206 | case CHIP_SUMO: | ||
2207 | case CHIP_SUMO2: | ||
2208 | case CHIP_CAICOS: | ||
1320 | vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY); | 2209 | vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY); |
1321 | else | 2210 | break; |
2211 | default: | ||
1322 | vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC); | 2212 | vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC); |
2213 | break; | ||
2214 | } | ||
1323 | vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO); | 2215 | vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO); |
1324 | WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); | 2216 | WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); |
1325 | 2217 | ||
1326 | WREG32(VGT_GS_VERTEX_REUSE, 16); | 2218 | WREG32(VGT_GS_VERTEX_REUSE, 16); |
2219 | WREG32(PA_SU_LINE_STIPPLE_VALUE, 0); | ||
1327 | WREG32(PA_SC_LINE_STIPPLE_STATE, 0); | 2220 | WREG32(PA_SC_LINE_STIPPLE_STATE, 0); |
1328 | 2221 | ||
1329 | WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14); | 2222 | WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14); |
@@ -1358,6 +2251,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1358 | for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) | 2251 | for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) |
1359 | WREG32(i, 0); | 2252 | WREG32(i, 0); |
1360 | 2253 | ||
2254 | tmp = RREG32(HDP_MISC_CNTL); | ||
2255 | tmp |= HDP_FLUSH_INVALIDATE_CACHE; | ||
2256 | WREG32(HDP_MISC_CNTL, tmp); | ||
2257 | |||
1361 | hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); | 2258 | hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); |
1362 | WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); | 2259 | WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); |
1363 | 2260 | ||
@@ -1374,7 +2271,10 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
1374 | 2271 | ||
1375 | /* Get VRAM informations */ | 2272 | /* Get VRAM informations */ |
1376 | rdev->mc.vram_is_ddr = true; | 2273 | rdev->mc.vram_is_ddr = true; |
1377 | tmp = RREG32(MC_ARB_RAMCFG); | 2274 | if (rdev->flags & RADEON_IS_IGP) |
2275 | tmp = RREG32(FUS_MC_ARB_RAMCFG); | ||
2276 | else | ||
2277 | tmp = RREG32(MC_ARB_RAMCFG); | ||
1378 | if (tmp & CHANSIZE_OVERRIDE) { | 2278 | if (tmp & CHANSIZE_OVERRIDE) { |
1379 | chansize = 16; | 2279 | chansize = 16; |
1380 | } else if (tmp & CHANSIZE_MASK) { | 2280 | } else if (tmp & CHANSIZE_MASK) { |
@@ -1403,12 +2303,17 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
1403 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); | 2303 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
1404 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); | 2304 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
1405 | /* Setup GPU memory space */ | 2305 | /* Setup GPU memory space */ |
1406 | /* size in MB on evergreen */ | 2306 | if (rdev->flags & RADEON_IS_IGP) { |
1407 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 2307 | /* size in bytes on fusion */ |
1408 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 2308 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
2309 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | ||
2310 | } else { | ||
2311 | /* size in MB on evergreen */ | ||
2312 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | ||
2313 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | ||
2314 | } | ||
1409 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 2315 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
1410 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 2316 | r700_vram_gtt_location(rdev, &rdev->mc); |
1411 | r600_vram_gtt_location(rdev, &rdev->mc); | ||
1412 | radeon_update_bandwidth_info(rdev); | 2317 | radeon_update_bandwidth_info(rdev); |
1413 | 2318 | ||
1414 | return 0; | 2319 | return 0; |
@@ -1416,16 +2321,40 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
1416 | 2321 | ||
1417 | bool evergreen_gpu_is_lockup(struct radeon_device *rdev) | 2322 | bool evergreen_gpu_is_lockup(struct radeon_device *rdev) |
1418 | { | 2323 | { |
1419 | /* FIXME: implement for evergreen */ | 2324 | u32 srbm_status; |
1420 | return false; | 2325 | u32 grbm_status; |
2326 | u32 grbm_status_se0, grbm_status_se1; | ||
2327 | struct r100_gpu_lockup *lockup = &rdev->config.evergreen.lockup; | ||
2328 | int r; | ||
2329 | |||
2330 | srbm_status = RREG32(SRBM_STATUS); | ||
2331 | grbm_status = RREG32(GRBM_STATUS); | ||
2332 | grbm_status_se0 = RREG32(GRBM_STATUS_SE0); | ||
2333 | grbm_status_se1 = RREG32(GRBM_STATUS_SE1); | ||
2334 | if (!(grbm_status & GUI_ACTIVE)) { | ||
2335 | r100_gpu_lockup_update(lockup, &rdev->cp); | ||
2336 | return false; | ||
2337 | } | ||
2338 | /* force CP activities */ | ||
2339 | r = radeon_ring_lock(rdev, 2); | ||
2340 | if (!r) { | ||
2341 | /* PACKET2 NOP */ | ||
2342 | radeon_ring_write(rdev, 0x80000000); | ||
2343 | radeon_ring_write(rdev, 0x80000000); | ||
2344 | radeon_ring_unlock_commit(rdev); | ||
2345 | } | ||
2346 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | ||
2347 | return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); | ||
1421 | } | 2348 | } |
1422 | 2349 | ||
1423 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | 2350 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) |
1424 | { | 2351 | { |
1425 | struct evergreen_mc_save save; | 2352 | struct evergreen_mc_save save; |
1426 | u32 srbm_reset = 0; | ||
1427 | u32 grbm_reset = 0; | 2353 | u32 grbm_reset = 0; |
1428 | 2354 | ||
2355 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | ||
2356 | return 0; | ||
2357 | |||
1429 | dev_info(rdev->dev, "GPU softreset \n"); | 2358 | dev_info(rdev->dev, "GPU softreset \n"); |
1430 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 2359 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", |
1431 | RREG32(GRBM_STATUS)); | 2360 | RREG32(GRBM_STATUS)); |
@@ -1462,16 +2391,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
1462 | udelay(50); | 2391 | udelay(50); |
1463 | WREG32(GRBM_SOFT_RESET, 0); | 2392 | WREG32(GRBM_SOFT_RESET, 0); |
1464 | (void)RREG32(GRBM_SOFT_RESET); | 2393 | (void)RREG32(GRBM_SOFT_RESET); |
1465 | |||
1466 | /* reset all the system blocks */ | ||
1467 | srbm_reset = SRBM_SOFT_RESET_ALL_MASK; | ||
1468 | |||
1469 | dev_info(rdev->dev, " SRBM_SOFT_RESET=0x%08X\n", srbm_reset); | ||
1470 | WREG32(SRBM_SOFT_RESET, srbm_reset); | ||
1471 | (void)RREG32(SRBM_SOFT_RESET); | ||
1472 | udelay(50); | ||
1473 | WREG32(SRBM_SOFT_RESET, 0); | ||
1474 | (void)RREG32(SRBM_SOFT_RESET); | ||
1475 | /* Wait a little for things to settle down */ | 2394 | /* Wait a little for things to settle down */ |
1476 | udelay(50); | 2395 | udelay(50); |
1477 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 2396 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", |
@@ -1482,10 +2401,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
1482 | RREG32(GRBM_STATUS_SE1)); | 2401 | RREG32(GRBM_STATUS_SE1)); |
1483 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2402 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
1484 | RREG32(SRBM_STATUS)); | 2403 | RREG32(SRBM_STATUS)); |
1485 | /* After reset we need to reinit the asic as GPU often endup in an | ||
1486 | * incoherent state. | ||
1487 | */ | ||
1488 | atom_asic_init(rdev->mode_info.atom_context); | ||
1489 | evergreen_mc_resume(rdev, &save); | 2404 | evergreen_mc_resume(rdev, &save); |
1490 | return 0; | 2405 | return 0; |
1491 | } | 2406 | } |
@@ -1525,17 +2440,25 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) | |||
1525 | WREG32(GRBM_INT_CNTL, 0); | 2440 | WREG32(GRBM_INT_CNTL, 0); |
1526 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2441 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
1527 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2442 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
1528 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 2443 | if (rdev->num_crtc >= 4) { |
1529 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 2444 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
1530 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 2445 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
1531 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 2446 | } |
2447 | if (rdev->num_crtc >= 6) { | ||
2448 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
2449 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
2450 | } | ||
1532 | 2451 | ||
1533 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2452 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
1534 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2453 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
1535 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 2454 | if (rdev->num_crtc >= 4) { |
1536 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 2455 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
1537 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 2456 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
1538 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 2457 | } |
2458 | if (rdev->num_crtc >= 6) { | ||
2459 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
2460 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
2461 | } | ||
1539 | 2462 | ||
1540 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | 2463 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); |
1541 | WREG32(DACB_AUTODETECT_INT_CONTROL, 0); | 2464 | WREG32(DACB_AUTODETECT_INT_CONTROL, 0); |
@@ -1561,9 +2484,10 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
1561 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; | 2484 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; |
1562 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; | 2485 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; |
1563 | u32 grbm_int_cntl = 0; | 2486 | u32 grbm_int_cntl = 0; |
2487 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | ||
1564 | 2488 | ||
1565 | if (!rdev->irq.installed) { | 2489 | if (!rdev->irq.installed) { |
1566 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | 2490 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
1567 | return -EINVAL; | 2491 | return -EINVAL; |
1568 | } | 2492 | } |
1569 | /* don't enable anything if the ih is disabled */ | 2493 | /* don't enable anything if the ih is disabled */ |
@@ -1584,28 +2508,35 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
1584 | if (rdev->irq.sw_int) { | 2508 | if (rdev->irq.sw_int) { |
1585 | DRM_DEBUG("evergreen_irq_set: sw int\n"); | 2509 | DRM_DEBUG("evergreen_irq_set: sw int\n"); |
1586 | cp_int_cntl |= RB_INT_ENABLE; | 2510 | cp_int_cntl |= RB_INT_ENABLE; |
2511 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | ||
1587 | } | 2512 | } |
1588 | if (rdev->irq.crtc_vblank_int[0]) { | 2513 | if (rdev->irq.crtc_vblank_int[0] || |
2514 | rdev->irq.pflip[0]) { | ||
1589 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); | 2515 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); |
1590 | crtc1 |= VBLANK_INT_MASK; | 2516 | crtc1 |= VBLANK_INT_MASK; |
1591 | } | 2517 | } |
1592 | if (rdev->irq.crtc_vblank_int[1]) { | 2518 | if (rdev->irq.crtc_vblank_int[1] || |
2519 | rdev->irq.pflip[1]) { | ||
1593 | DRM_DEBUG("evergreen_irq_set: vblank 1\n"); | 2520 | DRM_DEBUG("evergreen_irq_set: vblank 1\n"); |
1594 | crtc2 |= VBLANK_INT_MASK; | 2521 | crtc2 |= VBLANK_INT_MASK; |
1595 | } | 2522 | } |
1596 | if (rdev->irq.crtc_vblank_int[2]) { | 2523 | if (rdev->irq.crtc_vblank_int[2] || |
2524 | rdev->irq.pflip[2]) { | ||
1597 | DRM_DEBUG("evergreen_irq_set: vblank 2\n"); | 2525 | DRM_DEBUG("evergreen_irq_set: vblank 2\n"); |
1598 | crtc3 |= VBLANK_INT_MASK; | 2526 | crtc3 |= VBLANK_INT_MASK; |
1599 | } | 2527 | } |
1600 | if (rdev->irq.crtc_vblank_int[3]) { | 2528 | if (rdev->irq.crtc_vblank_int[3] || |
2529 | rdev->irq.pflip[3]) { | ||
1601 | DRM_DEBUG("evergreen_irq_set: vblank 3\n"); | 2530 | DRM_DEBUG("evergreen_irq_set: vblank 3\n"); |
1602 | crtc4 |= VBLANK_INT_MASK; | 2531 | crtc4 |= VBLANK_INT_MASK; |
1603 | } | 2532 | } |
1604 | if (rdev->irq.crtc_vblank_int[4]) { | 2533 | if (rdev->irq.crtc_vblank_int[4] || |
2534 | rdev->irq.pflip[4]) { | ||
1605 | DRM_DEBUG("evergreen_irq_set: vblank 4\n"); | 2535 | DRM_DEBUG("evergreen_irq_set: vblank 4\n"); |
1606 | crtc5 |= VBLANK_INT_MASK; | 2536 | crtc5 |= VBLANK_INT_MASK; |
1607 | } | 2537 | } |
1608 | if (rdev->irq.crtc_vblank_int[5]) { | 2538 | if (rdev->irq.crtc_vblank_int[5] || |
2539 | rdev->irq.pflip[5]) { | ||
1609 | DRM_DEBUG("evergreen_irq_set: vblank 5\n"); | 2540 | DRM_DEBUG("evergreen_irq_set: vblank 5\n"); |
1610 | crtc6 |= VBLANK_INT_MASK; | 2541 | crtc6 |= VBLANK_INT_MASK; |
1611 | } | 2542 | } |
@@ -1643,10 +2574,25 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
1643 | 2574 | ||
1644 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 2575 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
1645 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); | 2576 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); |
1646 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); | 2577 | if (rdev->num_crtc >= 4) { |
1647 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); | 2578 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); |
1648 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); | 2579 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); |
1649 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); | 2580 | } |
2581 | if (rdev->num_crtc >= 6) { | ||
2582 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); | ||
2583 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); | ||
2584 | } | ||
2585 | |||
2586 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); | ||
2587 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); | ||
2588 | if (rdev->num_crtc >= 4) { | ||
2589 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); | ||
2590 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); | ||
2591 | } | ||
2592 | if (rdev->num_crtc >= 6) { | ||
2593 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); | ||
2594 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); | ||
2595 | } | ||
1650 | 2596 | ||
1651 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | 2597 | WREG32(DC_HPD1_INT_CONTROL, hpd1); |
1652 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | 2598 | WREG32(DC_HPD2_INT_CONTROL, hpd2); |
@@ -1658,79 +2604,96 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
1658 | return 0; | 2604 | return 0; |
1659 | } | 2605 | } |
1660 | 2606 | ||
1661 | static inline void evergreen_irq_ack(struct radeon_device *rdev, | 2607 | static inline void evergreen_irq_ack(struct radeon_device *rdev) |
1662 | u32 *disp_int, | ||
1663 | u32 *disp_int_cont, | ||
1664 | u32 *disp_int_cont2, | ||
1665 | u32 *disp_int_cont3, | ||
1666 | u32 *disp_int_cont4, | ||
1667 | u32 *disp_int_cont5) | ||
1668 | { | 2608 | { |
1669 | u32 tmp; | 2609 | u32 tmp; |
1670 | 2610 | ||
1671 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | 2611 | rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS); |
1672 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | 2612 | rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); |
1673 | *disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); | 2613 | rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); |
1674 | *disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); | 2614 | rdev->irq.stat_regs.evergreen.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); |
1675 | *disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); | 2615 | rdev->irq.stat_regs.evergreen.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); |
1676 | *disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); | 2616 | rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); |
1677 | 2617 | rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); | |
1678 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) | 2618 | rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); |
2619 | if (rdev->num_crtc >= 4) { | ||
2620 | rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
2621 | rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
2622 | } | ||
2623 | if (rdev->num_crtc >= 6) { | ||
2624 | rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
2625 | rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
2626 | } | ||
2627 | |||
2628 | if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
2629 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
2630 | if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
2631 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
2632 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) | ||
1679 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); | 2633 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); |
1680 | if (*disp_int & LB_D1_VLINE_INTERRUPT) | 2634 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) |
1681 | WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); | 2635 | WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); |
1682 | 2636 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) | |
1683 | if (*disp_int_cont & LB_D2_VBLANK_INTERRUPT) | ||
1684 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); | 2637 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); |
1685 | if (*disp_int_cont & LB_D2_VLINE_INTERRUPT) | 2638 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) |
1686 | WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); | 2639 | WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); |
1687 | 2640 | ||
1688 | if (*disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) | 2641 | if (rdev->num_crtc >= 4) { |
1689 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); | 2642 | if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) |
1690 | if (*disp_int_cont2 & LB_D3_VLINE_INTERRUPT) | 2643 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); |
1691 | WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); | 2644 | if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) |
1692 | 2645 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | |
1693 | if (*disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) | 2646 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) |
1694 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); | 2647 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); |
1695 | if (*disp_int_cont3 & LB_D4_VLINE_INTERRUPT) | 2648 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) |
1696 | WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); | 2649 | WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); |
1697 | 2650 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) | |
1698 | if (*disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) | 2651 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); |
1699 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); | 2652 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) |
1700 | if (*disp_int_cont4 & LB_D5_VLINE_INTERRUPT) | 2653 | WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); |
1701 | WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); | 2654 | } |
1702 | 2655 | ||
1703 | if (*disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) | 2656 | if (rdev->num_crtc >= 6) { |
1704 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); | 2657 | if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) |
1705 | if (*disp_int_cont5 & LB_D6_VLINE_INTERRUPT) | 2658 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); |
1706 | WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); | 2659 | if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) |
1707 | 2660 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | |
1708 | if (*disp_int & DC_HPD1_INTERRUPT) { | 2661 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) |
2662 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); | ||
2663 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) | ||
2664 | WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); | ||
2665 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) | ||
2666 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); | ||
2667 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) | ||
2668 | WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); | ||
2669 | } | ||
2670 | |||
2671 | if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { | ||
1709 | tmp = RREG32(DC_HPD1_INT_CONTROL); | 2672 | tmp = RREG32(DC_HPD1_INT_CONTROL); |
1710 | tmp |= DC_HPDx_INT_ACK; | 2673 | tmp |= DC_HPDx_INT_ACK; |
1711 | WREG32(DC_HPD1_INT_CONTROL, tmp); | 2674 | WREG32(DC_HPD1_INT_CONTROL, tmp); |
1712 | } | 2675 | } |
1713 | if (*disp_int_cont & DC_HPD2_INTERRUPT) { | 2676 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { |
1714 | tmp = RREG32(DC_HPD2_INT_CONTROL); | 2677 | tmp = RREG32(DC_HPD2_INT_CONTROL); |
1715 | tmp |= DC_HPDx_INT_ACK; | 2678 | tmp |= DC_HPDx_INT_ACK; |
1716 | WREG32(DC_HPD2_INT_CONTROL, tmp); | 2679 | WREG32(DC_HPD2_INT_CONTROL, tmp); |
1717 | } | 2680 | } |
1718 | if (*disp_int_cont2 & DC_HPD3_INTERRUPT) { | 2681 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { |
1719 | tmp = RREG32(DC_HPD3_INT_CONTROL); | 2682 | tmp = RREG32(DC_HPD3_INT_CONTROL); |
1720 | tmp |= DC_HPDx_INT_ACK; | 2683 | tmp |= DC_HPDx_INT_ACK; |
1721 | WREG32(DC_HPD3_INT_CONTROL, tmp); | 2684 | WREG32(DC_HPD3_INT_CONTROL, tmp); |
1722 | } | 2685 | } |
1723 | if (*disp_int_cont3 & DC_HPD4_INTERRUPT) { | 2686 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { |
1724 | tmp = RREG32(DC_HPD4_INT_CONTROL); | 2687 | tmp = RREG32(DC_HPD4_INT_CONTROL); |
1725 | tmp |= DC_HPDx_INT_ACK; | 2688 | tmp |= DC_HPDx_INT_ACK; |
1726 | WREG32(DC_HPD4_INT_CONTROL, tmp); | 2689 | WREG32(DC_HPD4_INT_CONTROL, tmp); |
1727 | } | 2690 | } |
1728 | if (*disp_int_cont4 & DC_HPD5_INTERRUPT) { | 2691 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { |
1729 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 2692 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
1730 | tmp |= DC_HPDx_INT_ACK; | 2693 | tmp |= DC_HPDx_INT_ACK; |
1731 | WREG32(DC_HPD5_INT_CONTROL, tmp); | 2694 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
1732 | } | 2695 | } |
1733 | if (*disp_int_cont5 & DC_HPD6_INTERRUPT) { | 2696 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { |
1734 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 2697 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
1735 | tmp |= DC_HPDx_INT_ACK; | 2698 | tmp |= DC_HPDx_INT_ACK; |
1736 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 2699 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
@@ -1739,18 +2702,14 @@ static inline void evergreen_irq_ack(struct radeon_device *rdev, | |||
1739 | 2702 | ||
1740 | void evergreen_irq_disable(struct radeon_device *rdev) | 2703 | void evergreen_irq_disable(struct radeon_device *rdev) |
1741 | { | 2704 | { |
1742 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
1743 | u32 disp_int_cont3, disp_int_cont4, disp_int_cont5; | ||
1744 | |||
1745 | r600_disable_interrupts(rdev); | 2705 | r600_disable_interrupts(rdev); |
1746 | /* Wait and acknowledge irq */ | 2706 | /* Wait and acknowledge irq */ |
1747 | mdelay(1); | 2707 | mdelay(1); |
1748 | evergreen_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2, | 2708 | evergreen_irq_ack(rdev); |
1749 | &disp_int_cont3, &disp_int_cont4, &disp_int_cont5); | ||
1750 | evergreen_disable_interrupt_state(rdev); | 2709 | evergreen_disable_interrupt_state(rdev); |
1751 | } | 2710 | } |
1752 | 2711 | ||
1753 | static void evergreen_irq_suspend(struct radeon_device *rdev) | 2712 | void evergreen_irq_suspend(struct radeon_device *rdev) |
1754 | { | 2713 | { |
1755 | evergreen_irq_disable(rdev); | 2714 | evergreen_irq_disable(rdev); |
1756 | r600_rlc_stop(rdev); | 2715 | r600_rlc_stop(rdev); |
@@ -1760,8 +2719,10 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev) | |||
1760 | { | 2719 | { |
1761 | u32 wptr, tmp; | 2720 | u32 wptr, tmp; |
1762 | 2721 | ||
1763 | /* XXX use writeback */ | 2722 | if (rdev->wb.enabled) |
1764 | wptr = RREG32(IH_RB_WPTR); | 2723 | wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); |
2724 | else | ||
2725 | wptr = RREG32(IH_RB_WPTR); | ||
1765 | 2726 | ||
1766 | if (wptr & RB_OVERFLOW) { | 2727 | if (wptr & RB_OVERFLOW) { |
1767 | /* When a ring buffer overflow happen start parsing interrupt | 2728 | /* When a ring buffer overflow happen start parsing interrupt |
@@ -1780,56 +2741,55 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev) | |||
1780 | 2741 | ||
1781 | int evergreen_irq_process(struct radeon_device *rdev) | 2742 | int evergreen_irq_process(struct radeon_device *rdev) |
1782 | { | 2743 | { |
1783 | u32 wptr = evergreen_get_ih_wptr(rdev); | 2744 | u32 wptr; |
1784 | u32 rptr = rdev->ih.rptr; | 2745 | u32 rptr; |
1785 | u32 src_id, src_data; | 2746 | u32 src_id, src_data; |
1786 | u32 ring_index; | 2747 | u32 ring_index; |
1787 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
1788 | u32 disp_int_cont3, disp_int_cont4, disp_int_cont5; | ||
1789 | unsigned long flags; | 2748 | unsigned long flags; |
1790 | bool queue_hotplug = false; | 2749 | bool queue_hotplug = false; |
1791 | 2750 | ||
1792 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 2751 | if (!rdev->ih.enabled || rdev->shutdown) |
1793 | if (!rdev->ih.enabled) | ||
1794 | return IRQ_NONE; | 2752 | return IRQ_NONE; |
1795 | 2753 | ||
1796 | spin_lock_irqsave(&rdev->ih.lock, flags); | 2754 | wptr = evergreen_get_ih_wptr(rdev); |
2755 | rptr = rdev->ih.rptr; | ||
2756 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | ||
1797 | 2757 | ||
2758 | spin_lock_irqsave(&rdev->ih.lock, flags); | ||
1798 | if (rptr == wptr) { | 2759 | if (rptr == wptr) { |
1799 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 2760 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
1800 | return IRQ_NONE; | 2761 | return IRQ_NONE; |
1801 | } | 2762 | } |
1802 | if (rdev->shutdown) { | ||
1803 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
1804 | return IRQ_NONE; | ||
1805 | } | ||
1806 | |||
1807 | restart_ih: | 2763 | restart_ih: |
1808 | /* display interrupts */ | 2764 | /* display interrupts */ |
1809 | evergreen_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2, | 2765 | evergreen_irq_ack(rdev); |
1810 | &disp_int_cont3, &disp_int_cont4, &disp_int_cont5); | ||
1811 | 2766 | ||
1812 | rdev->ih.wptr = wptr; | 2767 | rdev->ih.wptr = wptr; |
1813 | while (rptr != wptr) { | 2768 | while (rptr != wptr) { |
1814 | /* wptr/rptr are in bytes! */ | 2769 | /* wptr/rptr are in bytes! */ |
1815 | ring_index = rptr / 4; | 2770 | ring_index = rptr / 4; |
1816 | src_id = rdev->ih.ring[ring_index] & 0xff; | 2771 | src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; |
1817 | src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; | 2772 | src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; |
1818 | 2773 | ||
1819 | switch (src_id) { | 2774 | switch (src_id) { |
1820 | case 1: /* D1 vblank/vline */ | 2775 | case 1: /* D1 vblank/vline */ |
1821 | switch (src_data) { | 2776 | switch (src_data) { |
1822 | case 0: /* D1 vblank */ | 2777 | case 0: /* D1 vblank */ |
1823 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { | 2778 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { |
1824 | drm_handle_vblank(rdev->ddev, 0); | 2779 | if (rdev->irq.crtc_vblank_int[0]) { |
1825 | wake_up(&rdev->irq.vblank_queue); | 2780 | drm_handle_vblank(rdev->ddev, 0); |
1826 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 2781 | rdev->pm.vblank_sync = true; |
2782 | wake_up(&rdev->irq.vblank_queue); | ||
2783 | } | ||
2784 | if (rdev->irq.pflip[0]) | ||
2785 | radeon_crtc_handle_flip(rdev, 0); | ||
2786 | rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; | ||
1827 | DRM_DEBUG("IH: D1 vblank\n"); | 2787 | DRM_DEBUG("IH: D1 vblank\n"); |
1828 | } | 2788 | } |
1829 | break; | 2789 | break; |
1830 | case 1: /* D1 vline */ | 2790 | case 1: /* D1 vline */ |
1831 | if (disp_int & LB_D1_VLINE_INTERRUPT) { | 2791 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { |
1832 | disp_int &= ~LB_D1_VLINE_INTERRUPT; | 2792 | rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; |
1833 | DRM_DEBUG("IH: D1 vline\n"); | 2793 | DRM_DEBUG("IH: D1 vline\n"); |
1834 | } | 2794 | } |
1835 | break; | 2795 | break; |
@@ -1841,16 +2801,21 @@ restart_ih: | |||
1841 | case 2: /* D2 vblank/vline */ | 2801 | case 2: /* D2 vblank/vline */ |
1842 | switch (src_data) { | 2802 | switch (src_data) { |
1843 | case 0: /* D2 vblank */ | 2803 | case 0: /* D2 vblank */ |
1844 | if (disp_int_cont & LB_D2_VBLANK_INTERRUPT) { | 2804 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { |
1845 | drm_handle_vblank(rdev->ddev, 1); | 2805 | if (rdev->irq.crtc_vblank_int[1]) { |
1846 | wake_up(&rdev->irq.vblank_queue); | 2806 | drm_handle_vblank(rdev->ddev, 1); |
1847 | disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; | 2807 | rdev->pm.vblank_sync = true; |
2808 | wake_up(&rdev->irq.vblank_queue); | ||
2809 | } | ||
2810 | if (rdev->irq.pflip[1]) | ||
2811 | radeon_crtc_handle_flip(rdev, 1); | ||
2812 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; | ||
1848 | DRM_DEBUG("IH: D2 vblank\n"); | 2813 | DRM_DEBUG("IH: D2 vblank\n"); |
1849 | } | 2814 | } |
1850 | break; | 2815 | break; |
1851 | case 1: /* D2 vline */ | 2816 | case 1: /* D2 vline */ |
1852 | if (disp_int_cont & LB_D2_VLINE_INTERRUPT) { | 2817 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { |
1853 | disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; | 2818 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; |
1854 | DRM_DEBUG("IH: D2 vline\n"); | 2819 | DRM_DEBUG("IH: D2 vline\n"); |
1855 | } | 2820 | } |
1856 | break; | 2821 | break; |
@@ -1862,16 +2827,21 @@ restart_ih: | |||
1862 | case 3: /* D3 vblank/vline */ | 2827 | case 3: /* D3 vblank/vline */ |
1863 | switch (src_data) { | 2828 | switch (src_data) { |
1864 | case 0: /* D3 vblank */ | 2829 | case 0: /* D3 vblank */ |
1865 | if (disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { | 2830 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { |
1866 | drm_handle_vblank(rdev->ddev, 2); | 2831 | if (rdev->irq.crtc_vblank_int[2]) { |
1867 | wake_up(&rdev->irq.vblank_queue); | 2832 | drm_handle_vblank(rdev->ddev, 2); |
1868 | disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; | 2833 | rdev->pm.vblank_sync = true; |
2834 | wake_up(&rdev->irq.vblank_queue); | ||
2835 | } | ||
2836 | if (rdev->irq.pflip[2]) | ||
2837 | radeon_crtc_handle_flip(rdev, 2); | ||
2838 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; | ||
1869 | DRM_DEBUG("IH: D3 vblank\n"); | 2839 | DRM_DEBUG("IH: D3 vblank\n"); |
1870 | } | 2840 | } |
1871 | break; | 2841 | break; |
1872 | case 1: /* D3 vline */ | 2842 | case 1: /* D3 vline */ |
1873 | if (disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { | 2843 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { |
1874 | disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; | 2844 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; |
1875 | DRM_DEBUG("IH: D3 vline\n"); | 2845 | DRM_DEBUG("IH: D3 vline\n"); |
1876 | } | 2846 | } |
1877 | break; | 2847 | break; |
@@ -1883,16 +2853,21 @@ restart_ih: | |||
1883 | case 4: /* D4 vblank/vline */ | 2853 | case 4: /* D4 vblank/vline */ |
1884 | switch (src_data) { | 2854 | switch (src_data) { |
1885 | case 0: /* D4 vblank */ | 2855 | case 0: /* D4 vblank */ |
1886 | if (disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { | 2856 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { |
1887 | drm_handle_vblank(rdev->ddev, 3); | 2857 | if (rdev->irq.crtc_vblank_int[3]) { |
1888 | wake_up(&rdev->irq.vblank_queue); | 2858 | drm_handle_vblank(rdev->ddev, 3); |
1889 | disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; | 2859 | rdev->pm.vblank_sync = true; |
2860 | wake_up(&rdev->irq.vblank_queue); | ||
2861 | } | ||
2862 | if (rdev->irq.pflip[3]) | ||
2863 | radeon_crtc_handle_flip(rdev, 3); | ||
2864 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; | ||
1890 | DRM_DEBUG("IH: D4 vblank\n"); | 2865 | DRM_DEBUG("IH: D4 vblank\n"); |
1891 | } | 2866 | } |
1892 | break; | 2867 | break; |
1893 | case 1: /* D4 vline */ | 2868 | case 1: /* D4 vline */ |
1894 | if (disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { | 2869 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { |
1895 | disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; | 2870 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; |
1896 | DRM_DEBUG("IH: D4 vline\n"); | 2871 | DRM_DEBUG("IH: D4 vline\n"); |
1897 | } | 2872 | } |
1898 | break; | 2873 | break; |
@@ -1904,16 +2879,21 @@ restart_ih: | |||
1904 | case 5: /* D5 vblank/vline */ | 2879 | case 5: /* D5 vblank/vline */ |
1905 | switch (src_data) { | 2880 | switch (src_data) { |
1906 | case 0: /* D5 vblank */ | 2881 | case 0: /* D5 vblank */ |
1907 | if (disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { | 2882 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { |
1908 | drm_handle_vblank(rdev->ddev, 4); | 2883 | if (rdev->irq.crtc_vblank_int[4]) { |
1909 | wake_up(&rdev->irq.vblank_queue); | 2884 | drm_handle_vblank(rdev->ddev, 4); |
1910 | disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; | 2885 | rdev->pm.vblank_sync = true; |
2886 | wake_up(&rdev->irq.vblank_queue); | ||
2887 | } | ||
2888 | if (rdev->irq.pflip[4]) | ||
2889 | radeon_crtc_handle_flip(rdev, 4); | ||
2890 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; | ||
1911 | DRM_DEBUG("IH: D5 vblank\n"); | 2891 | DRM_DEBUG("IH: D5 vblank\n"); |
1912 | } | 2892 | } |
1913 | break; | 2893 | break; |
1914 | case 1: /* D5 vline */ | 2894 | case 1: /* D5 vline */ |
1915 | if (disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { | 2895 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { |
1916 | disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; | 2896 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; |
1917 | DRM_DEBUG("IH: D5 vline\n"); | 2897 | DRM_DEBUG("IH: D5 vline\n"); |
1918 | } | 2898 | } |
1919 | break; | 2899 | break; |
@@ -1925,16 +2905,21 @@ restart_ih: | |||
1925 | case 6: /* D6 vblank/vline */ | 2905 | case 6: /* D6 vblank/vline */ |
1926 | switch (src_data) { | 2906 | switch (src_data) { |
1927 | case 0: /* D6 vblank */ | 2907 | case 0: /* D6 vblank */ |
1928 | if (disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { | 2908 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { |
1929 | drm_handle_vblank(rdev->ddev, 5); | 2909 | if (rdev->irq.crtc_vblank_int[5]) { |
1930 | wake_up(&rdev->irq.vblank_queue); | 2910 | drm_handle_vblank(rdev->ddev, 5); |
1931 | disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; | 2911 | rdev->pm.vblank_sync = true; |
2912 | wake_up(&rdev->irq.vblank_queue); | ||
2913 | } | ||
2914 | if (rdev->irq.pflip[5]) | ||
2915 | radeon_crtc_handle_flip(rdev, 5); | ||
2916 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; | ||
1932 | DRM_DEBUG("IH: D6 vblank\n"); | 2917 | DRM_DEBUG("IH: D6 vblank\n"); |
1933 | } | 2918 | } |
1934 | break; | 2919 | break; |
1935 | case 1: /* D6 vline */ | 2920 | case 1: /* D6 vline */ |
1936 | if (disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { | 2921 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { |
1937 | disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; | 2922 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; |
1938 | DRM_DEBUG("IH: D6 vline\n"); | 2923 | DRM_DEBUG("IH: D6 vline\n"); |
1939 | } | 2924 | } |
1940 | break; | 2925 | break; |
@@ -1946,43 +2931,43 @@ restart_ih: | |||
1946 | case 42: /* HPD hotplug */ | 2931 | case 42: /* HPD hotplug */ |
1947 | switch (src_data) { | 2932 | switch (src_data) { |
1948 | case 0: | 2933 | case 0: |
1949 | if (disp_int & DC_HPD1_INTERRUPT) { | 2934 | if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { |
1950 | disp_int &= ~DC_HPD1_INTERRUPT; | 2935 | rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; |
1951 | queue_hotplug = true; | 2936 | queue_hotplug = true; |
1952 | DRM_DEBUG("IH: HPD1\n"); | 2937 | DRM_DEBUG("IH: HPD1\n"); |
1953 | } | 2938 | } |
1954 | break; | 2939 | break; |
1955 | case 1: | 2940 | case 1: |
1956 | if (disp_int_cont & DC_HPD2_INTERRUPT) { | 2941 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { |
1957 | disp_int_cont &= ~DC_HPD2_INTERRUPT; | 2942 | rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; |
1958 | queue_hotplug = true; | 2943 | queue_hotplug = true; |
1959 | DRM_DEBUG("IH: HPD2\n"); | 2944 | DRM_DEBUG("IH: HPD2\n"); |
1960 | } | 2945 | } |
1961 | break; | 2946 | break; |
1962 | case 2: | 2947 | case 2: |
1963 | if (disp_int_cont2 & DC_HPD3_INTERRUPT) { | 2948 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { |
1964 | disp_int_cont2 &= ~DC_HPD3_INTERRUPT; | 2949 | rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; |
1965 | queue_hotplug = true; | 2950 | queue_hotplug = true; |
1966 | DRM_DEBUG("IH: HPD3\n"); | 2951 | DRM_DEBUG("IH: HPD3\n"); |
1967 | } | 2952 | } |
1968 | break; | 2953 | break; |
1969 | case 3: | 2954 | case 3: |
1970 | if (disp_int_cont3 & DC_HPD4_INTERRUPT) { | 2955 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { |
1971 | disp_int_cont3 &= ~DC_HPD4_INTERRUPT; | 2956 | rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; |
1972 | queue_hotplug = true; | 2957 | queue_hotplug = true; |
1973 | DRM_DEBUG("IH: HPD4\n"); | 2958 | DRM_DEBUG("IH: HPD4\n"); |
1974 | } | 2959 | } |
1975 | break; | 2960 | break; |
1976 | case 4: | 2961 | case 4: |
1977 | if (disp_int_cont4 & DC_HPD5_INTERRUPT) { | 2962 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { |
1978 | disp_int_cont4 &= ~DC_HPD5_INTERRUPT; | 2963 | rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; |
1979 | queue_hotplug = true; | 2964 | queue_hotplug = true; |
1980 | DRM_DEBUG("IH: HPD5\n"); | 2965 | DRM_DEBUG("IH: HPD5\n"); |
1981 | } | 2966 | } |
1982 | break; | 2967 | break; |
1983 | case 5: | 2968 | case 5: |
1984 | if (disp_int_cont5 & DC_HPD6_INTERRUPT) { | 2969 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { |
1985 | disp_int_cont5 &= ~DC_HPD6_INTERRUPT; | 2970 | rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; |
1986 | queue_hotplug = true; | 2971 | queue_hotplug = true; |
1987 | DRM_DEBUG("IH: HPD6\n"); | 2972 | DRM_DEBUG("IH: HPD6\n"); |
1988 | } | 2973 | } |
@@ -2000,9 +2985,10 @@ restart_ih: | |||
2000 | break; | 2985 | break; |
2001 | case 181: /* CP EOP event */ | 2986 | case 181: /* CP EOP event */ |
2002 | DRM_DEBUG("IH: CP EOP\n"); | 2987 | DRM_DEBUG("IH: CP EOP\n"); |
2988 | radeon_fence_process(rdev); | ||
2003 | break; | 2989 | break; |
2004 | case 233: /* GUI IDLE */ | 2990 | case 233: /* GUI IDLE */ |
2005 | DRM_DEBUG("IH: CP EOP\n"); | 2991 | DRM_DEBUG("IH: GUI idle\n"); |
2006 | rdev->pm.gui_idle = true; | 2992 | rdev->pm.gui_idle = true; |
2007 | wake_up(&rdev->irq.idle_queue); | 2993 | wake_up(&rdev->irq.idle_queue); |
2008 | break; | 2994 | break; |
@@ -2020,7 +3006,7 @@ restart_ih: | |||
2020 | if (wptr != rdev->ih.wptr) | 3006 | if (wptr != rdev->ih.wptr) |
2021 | goto restart_ih; | 3007 | goto restart_ih; |
2022 | if (queue_hotplug) | 3008 | if (queue_hotplug) |
2023 | queue_work(rdev->wq, &rdev->hotplug_work); | 3009 | schedule_work(&rdev->hotplug_work); |
2024 | rdev->ih.rptr = rptr; | 3010 | rdev->ih.rptr = rptr; |
2025 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3011 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
2026 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3012 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
@@ -2031,12 +3017,31 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
2031 | { | 3017 | { |
2032 | int r; | 3018 | int r; |
2033 | 3019 | ||
2034 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 3020 | /* enable pcie gen2 link */ |
2035 | r = r600_init_microcode(rdev); | 3021 | if (!ASIC_IS_DCE5(rdev)) |
3022 | evergreen_pcie_gen2_enable(rdev); | ||
3023 | |||
3024 | if (ASIC_IS_DCE5(rdev)) { | ||
3025 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { | ||
3026 | r = ni_init_microcode(rdev); | ||
3027 | if (r) { | ||
3028 | DRM_ERROR("Failed to load firmware!\n"); | ||
3029 | return r; | ||
3030 | } | ||
3031 | } | ||
3032 | r = ni_mc_load_microcode(rdev); | ||
2036 | if (r) { | 3033 | if (r) { |
2037 | DRM_ERROR("Failed to load firmware!\n"); | 3034 | DRM_ERROR("Failed to load MC firmware!\n"); |
2038 | return r; | 3035 | return r; |
2039 | } | 3036 | } |
3037 | } else { | ||
3038 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | ||
3039 | r = r600_init_microcode(rdev); | ||
3040 | if (r) { | ||
3041 | DRM_ERROR("Failed to load firmware!\n"); | ||
3042 | return r; | ||
3043 | } | ||
3044 | } | ||
2040 | } | 3045 | } |
2041 | 3046 | ||
2042 | evergreen_mc_program(rdev); | 3047 | evergreen_mc_program(rdev); |
@@ -2048,26 +3053,18 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
2048 | return r; | 3053 | return r; |
2049 | } | 3054 | } |
2050 | evergreen_gpu_init(rdev); | 3055 | evergreen_gpu_init(rdev); |
2051 | #if 0 | ||
2052 | if (!rdev->r600_blit.shader_obj) { | ||
2053 | r = r600_blit_init(rdev); | ||
2054 | if (r) { | ||
2055 | DRM_ERROR("radeon: failed blitter (%d).\n", r); | ||
2056 | return r; | ||
2057 | } | ||
2058 | } | ||
2059 | 3056 | ||
2060 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 3057 | r = evergreen_blit_init(rdev); |
2061 | if (unlikely(r != 0)) | ||
2062 | return r; | ||
2063 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
2064 | &rdev->r600_blit.shader_gpu_addr); | ||
2065 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
2066 | if (r) { | 3058 | if (r) { |
2067 | DRM_ERROR("failed to pin blit object %d\n", r); | 3059 | evergreen_blit_fini(rdev); |
2068 | return r; | 3060 | rdev->asic->copy = NULL; |
3061 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
2069 | } | 3062 | } |
2070 | #endif | 3063 | |
3064 | /* allocate wb buffer */ | ||
3065 | r = radeon_wb_init(rdev); | ||
3066 | if (r) | ||
3067 | return r; | ||
2071 | 3068 | ||
2072 | /* Enable IRQ */ | 3069 | /* Enable IRQ */ |
2073 | r = r600_irq_init(rdev); | 3070 | r = r600_irq_init(rdev); |
@@ -2087,8 +3084,6 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
2087 | r = evergreen_cp_resume(rdev); | 3084 | r = evergreen_cp_resume(rdev); |
2088 | if (r) | 3085 | if (r) |
2089 | return r; | 3086 | return r; |
2090 | /* write back buffer are not vital so don't worry about failure */ | ||
2091 | r600_wb_enable(rdev); | ||
2092 | 3087 | ||
2093 | return 0; | 3088 | return 0; |
2094 | } | 3089 | } |
@@ -2097,6 +3092,11 @@ int evergreen_resume(struct radeon_device *rdev) | |||
2097 | { | 3092 | { |
2098 | int r; | 3093 | int r; |
2099 | 3094 | ||
3095 | /* reset the asic, the gfx blocks are often in a bad state | ||
3096 | * after the driver is unloaded or after a resume | ||
3097 | */ | ||
3098 | if (radeon_asic_reset(rdev)) | ||
3099 | dev_warn(rdev->dev, "GPU reset failed !\n"); | ||
2100 | /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, | 3100 | /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, |
2101 | * posting will perform necessary task to bring back GPU into good | 3101 | * posting will perform necessary task to bring back GPU into good |
2102 | * shape. | 3102 | * shape. |
@@ -2106,13 +3106,13 @@ int evergreen_resume(struct radeon_device *rdev) | |||
2106 | 3106 | ||
2107 | r = evergreen_startup(rdev); | 3107 | r = evergreen_startup(rdev); |
2108 | if (r) { | 3108 | if (r) { |
2109 | DRM_ERROR("r600 startup failed on resume\n"); | 3109 | DRM_ERROR("evergreen startup failed on resume\n"); |
2110 | return r; | 3110 | return r; |
2111 | } | 3111 | } |
2112 | 3112 | ||
2113 | r = r600_ib_test(rdev); | 3113 | r = r600_ib_test(rdev); |
2114 | if (r) { | 3114 | if (r) { |
2115 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | 3115 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
2116 | return r; | 3116 | return r; |
2117 | } | 3117 | } |
2118 | 3118 | ||
@@ -2122,45 +3122,44 @@ int evergreen_resume(struct radeon_device *rdev) | |||
2122 | 3122 | ||
2123 | int evergreen_suspend(struct radeon_device *rdev) | 3123 | int evergreen_suspend(struct radeon_device *rdev) |
2124 | { | 3124 | { |
2125 | #if 0 | ||
2126 | int r; | 3125 | int r; |
2127 | #endif | 3126 | |
2128 | /* FIXME: we should wait for ring to be empty */ | 3127 | /* FIXME: we should wait for ring to be empty */ |
2129 | r700_cp_stop(rdev); | 3128 | r700_cp_stop(rdev); |
2130 | rdev->cp.ready = false; | 3129 | rdev->cp.ready = false; |
2131 | evergreen_irq_suspend(rdev); | 3130 | evergreen_irq_suspend(rdev); |
2132 | r600_wb_disable(rdev); | 3131 | radeon_wb_disable(rdev); |
2133 | evergreen_pcie_gart_disable(rdev); | 3132 | evergreen_pcie_gart_disable(rdev); |
2134 | #if 0 | 3133 | |
2135 | /* unpin shaders bo */ | 3134 | /* unpin shaders bo */ |
2136 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 3135 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
2137 | if (likely(r == 0)) { | 3136 | if (likely(r == 0)) { |
2138 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | 3137 | radeon_bo_unpin(rdev->r600_blit.shader_obj); |
2139 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | 3138 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
2140 | } | 3139 | } |
2141 | #endif | 3140 | |
2142 | return 0; | 3141 | return 0; |
2143 | } | 3142 | } |
2144 | 3143 | ||
2145 | static bool evergreen_card_posted(struct radeon_device *rdev) | 3144 | int evergreen_copy_blit(struct radeon_device *rdev, |
3145 | uint64_t src_offset, uint64_t dst_offset, | ||
3146 | unsigned num_pages, struct radeon_fence *fence) | ||
2146 | { | 3147 | { |
2147 | u32 reg; | 3148 | int r; |
2148 | |||
2149 | /* first check CRTCs */ | ||
2150 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | | ||
2151 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | | ||
2152 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | | ||
2153 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | | ||
2154 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | | ||
2155 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
2156 | if (reg & EVERGREEN_CRTC_MASTER_EN) | ||
2157 | return true; | ||
2158 | |||
2159 | /* then check MEM_SIZE, in case the crtcs are off */ | ||
2160 | if (RREG32(CONFIG_MEMSIZE)) | ||
2161 | return true; | ||
2162 | 3149 | ||
2163 | return false; | 3150 | mutex_lock(&rdev->r600_blit.mutex); |
3151 | rdev->r600_blit.vb_ib = NULL; | ||
3152 | r = evergreen_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); | ||
3153 | if (r) { | ||
3154 | if (rdev->r600_blit.vb_ib) | ||
3155 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); | ||
3156 | mutex_unlock(&rdev->r600_blit.mutex); | ||
3157 | return r; | ||
3158 | } | ||
3159 | evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); | ||
3160 | evergreen_blit_done_copy(rdev, fence); | ||
3161 | mutex_unlock(&rdev->r600_blit.mutex); | ||
3162 | return 0; | ||
2164 | } | 3163 | } |
2165 | 3164 | ||
2166 | /* Plan is to move initialization in that function and use | 3165 | /* Plan is to move initialization in that function and use |
@@ -2173,9 +3172,6 @@ int evergreen_init(struct radeon_device *rdev) | |||
2173 | { | 3172 | { |
2174 | int r; | 3173 | int r; |
2175 | 3174 | ||
2176 | r = radeon_dummy_page_init(rdev); | ||
2177 | if (r) | ||
2178 | return r; | ||
2179 | /* This don't do much */ | 3175 | /* This don't do much */ |
2180 | r = radeon_gem_init(rdev); | 3176 | r = radeon_gem_init(rdev); |
2181 | if (r) | 3177 | if (r) |
@@ -2187,14 +3183,19 @@ int evergreen_init(struct radeon_device *rdev) | |||
2187 | } | 3183 | } |
2188 | /* Must be an ATOMBIOS */ | 3184 | /* Must be an ATOMBIOS */ |
2189 | if (!rdev->is_atom_bios) { | 3185 | if (!rdev->is_atom_bios) { |
2190 | dev_err(rdev->dev, "Expecting atombios for R600 GPU\n"); | 3186 | dev_err(rdev->dev, "Expecting atombios for evergreen GPU\n"); |
2191 | return -EINVAL; | 3187 | return -EINVAL; |
2192 | } | 3188 | } |
2193 | r = radeon_atombios_init(rdev); | 3189 | r = radeon_atombios_init(rdev); |
2194 | if (r) | 3190 | if (r) |
2195 | return r; | 3191 | return r; |
3192 | /* reset the asic, the gfx blocks are often in a bad state | ||
3193 | * after the driver is unloaded or after a resume | ||
3194 | */ | ||
3195 | if (radeon_asic_reset(rdev)) | ||
3196 | dev_warn(rdev->dev, "GPU reset failed !\n"); | ||
2196 | /* Post card if necessary */ | 3197 | /* Post card if necessary */ |
2197 | if (!evergreen_card_posted(rdev)) { | 3198 | if (!radeon_card_posted(rdev)) { |
2198 | if (!rdev->bios) { | 3199 | if (!rdev->bios) { |
2199 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); | 3200 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); |
2200 | return -EINVAL; | 3201 | return -EINVAL; |
@@ -2246,8 +3247,8 @@ int evergreen_init(struct radeon_device *rdev) | |||
2246 | if (r) { | 3247 | if (r) { |
2247 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 3248 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
2248 | r700_cp_fini(rdev); | 3249 | r700_cp_fini(rdev); |
2249 | r600_wb_fini(rdev); | ||
2250 | r600_irq_fini(rdev); | 3250 | r600_irq_fini(rdev); |
3251 | radeon_wb_fini(rdev); | ||
2251 | radeon_irq_kms_fini(rdev); | 3252 | radeon_irq_kms_fini(rdev); |
2252 | evergreen_pcie_gart_fini(rdev); | 3253 | evergreen_pcie_gart_fini(rdev); |
2253 | rdev->accel_working = false; | 3254 | rdev->accel_working = false; |
@@ -2269,10 +3270,11 @@ int evergreen_init(struct radeon_device *rdev) | |||
2269 | 3270 | ||
2270 | void evergreen_fini(struct radeon_device *rdev) | 3271 | void evergreen_fini(struct radeon_device *rdev) |
2271 | { | 3272 | { |
2272 | /*r600_blit_fini(rdev);*/ | 3273 | evergreen_blit_fini(rdev); |
2273 | r700_cp_fini(rdev); | 3274 | r700_cp_fini(rdev); |
2274 | r600_wb_fini(rdev); | ||
2275 | r600_irq_fini(rdev); | 3275 | r600_irq_fini(rdev); |
3276 | radeon_wb_fini(rdev); | ||
3277 | radeon_ib_pool_fini(rdev); | ||
2276 | radeon_irq_kms_fini(rdev); | 3278 | radeon_irq_kms_fini(rdev); |
2277 | evergreen_pcie_gart_fini(rdev); | 3279 | evergreen_pcie_gart_fini(rdev); |
2278 | radeon_gem_fini(rdev); | 3280 | radeon_gem_fini(rdev); |
@@ -2282,5 +3284,56 @@ void evergreen_fini(struct radeon_device *rdev) | |||
2282 | radeon_atombios_fini(rdev); | 3284 | radeon_atombios_fini(rdev); |
2283 | kfree(rdev->bios); | 3285 | kfree(rdev->bios); |
2284 | rdev->bios = NULL; | 3286 | rdev->bios = NULL; |
2285 | radeon_dummy_page_fini(rdev); | 3287 | } |
3288 | |||
3289 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev) | ||
3290 | { | ||
3291 | u32 link_width_cntl, speed_cntl; | ||
3292 | |||
3293 | if (radeon_pcie_gen2 == 0) | ||
3294 | return; | ||
3295 | |||
3296 | if (rdev->flags & RADEON_IS_IGP) | ||
3297 | return; | ||
3298 | |||
3299 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3300 | return; | ||
3301 | |||
3302 | /* x2 cards have a special sequence */ | ||
3303 | if (ASIC_IS_X2(rdev)) | ||
3304 | return; | ||
3305 | |||
3306 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3307 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || | ||
3308 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
3309 | |||
3310 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3311 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3312 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3313 | |||
3314 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3315 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
3316 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3317 | |||
3318 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3319 | speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
3320 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3321 | |||
3322 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3323 | speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
3324 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3325 | |||
3326 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3327 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
3328 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3329 | |||
3330 | } else { | ||
3331 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3332 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
3333 | if (1) | ||
3334 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
3335 | else | ||
3336 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3337 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3338 | } | ||
2286 | } | 3339 | } |