diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 310 |
3 files changed, 334 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 22821994b35a..864e75d762e6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -933,7 +933,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
933 | drm_i915_private_t *dev_priv = dev->dev_private; | 933 | drm_i915_private_t *dev_priv = dev->dev_private; |
934 | bool sr_enabled = false; | 934 | bool sr_enabled = false; |
935 | 935 | ||
936 | if (IS_GEN5(dev)) | 936 | if (HAS_PCH_SPLIT(dev)) |
937 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; | 937 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; |
938 | else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) | 938 | else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) |
939 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; | 939 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b284c13fd632..61ef98db9ff0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -596,6 +596,8 @@ | |||
596 | 596 | ||
597 | #define ILK_DISPLAY_CHICKEN1 0x42000 | 597 | #define ILK_DISPLAY_CHICKEN1 0x42000 |
598 | #define ILK_FBCQ_DIS (1<<22) | 598 | #define ILK_FBCQ_DIS (1<<22) |
599 | #define ILK_PABSTRETCH_DIS (1<<21) | ||
600 | |||
599 | 601 | ||
600 | /* | 602 | /* |
601 | * GPIO regs | 603 | * GPIO regs |
@@ -955,6 +957,8 @@ | |||
955 | */ | 957 | */ |
956 | #define MCHBAR_MIRROR_BASE 0x10000 | 958 | #define MCHBAR_MIRROR_BASE 0x10000 |
957 | 959 | ||
960 | #define MCHBAR_MIRROR_BASE_SNB 0x140000 | ||
961 | |||
958 | /** 915-945 and GM965 MCH register controlling DRAM channel access */ | 962 | /** 915-945 and GM965 MCH register controlling DRAM channel access */ |
959 | #define DCC 0x10200 | 963 | #define DCC 0x10200 |
960 | #define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) | 964 | #define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) |
@@ -2346,6 +2350,40 @@ | |||
2346 | 2350 | ||
2347 | #define ILK_FIFO_LINE_SIZE 64 | 2351 | #define ILK_FIFO_LINE_SIZE 64 |
2348 | 2352 | ||
2353 | /* define the WM info on Sandybridge */ | ||
2354 | #define SNB_DISPLAY_FIFO 128 | ||
2355 | #define SNB_DISPLAY_MAXWM 0x7f /* bit 16:22 */ | ||
2356 | #define SNB_DISPLAY_DFTWM 8 | ||
2357 | #define SNB_CURSOR_FIFO 32 | ||
2358 | #define SNB_CURSOR_MAXWM 0x1f /* bit 4:0 */ | ||
2359 | #define SNB_CURSOR_DFTWM 8 | ||
2360 | |||
2361 | #define SNB_DISPLAY_SR_FIFO 512 | ||
2362 | #define SNB_DISPLAY_MAX_SRWM 0x1ff /* bit 16:8 */ | ||
2363 | #define SNB_DISPLAY_DFT_SRWM 0x3f | ||
2364 | #define SNB_CURSOR_SR_FIFO 64 | ||
2365 | #define SNB_CURSOR_MAX_SRWM 0x3f /* bit 5:0 */ | ||
2366 | #define SNB_CURSOR_DFT_SRWM 8 | ||
2367 | |||
2368 | #define SNB_FBC_MAX_SRWM 0xf /* bit 23:20 */ | ||
2369 | |||
2370 | #define SNB_FIFO_LINE_SIZE 64 | ||
2371 | |||
2372 | |||
2373 | /* the address where we get all kinds of latency value */ | ||
2374 | #define SSKPD 0x5d10 | ||
2375 | #define SSKPD_WM_MASK 0x3f | ||
2376 | #define SSKPD_WM0_SHIFT 0 | ||
2377 | #define SSKPD_WM1_SHIFT 8 | ||
2378 | #define SSKPD_WM2_SHIFT 16 | ||
2379 | #define SSKPD_WM3_SHIFT 24 | ||
2380 | |||
2381 | #define SNB_LATENCY(shift) (I915_READ(MCHBAR_MIRROR_BASE_SNB + SSKPD) >> (shift) & SSKPD_WM_MASK) | ||
2382 | #define SNB_READ_WM0_LATENCY() SNB_LATENCY(SSKPD_WM0_SHIFT) | ||
2383 | #define SNB_READ_WM1_LATENCY() SNB_LATENCY(SSKPD_WM1_SHIFT) | ||
2384 | #define SNB_READ_WM2_LATENCY() SNB_LATENCY(SSKPD_WM2_SHIFT) | ||
2385 | #define SNB_READ_WM3_LATENCY() SNB_LATENCY(SSKPD_WM3_SHIFT) | ||
2386 | |||
2349 | /* | 2387 | /* |
2350 | * The two pipe frame counter registers are not synchronized, so | 2388 | * The two pipe frame counter registers are not synchronized, so |
2351 | * reading a stable value is somewhat tricky. The following code | 2389 | * reading a stable value is somewhat tricky. The following code |
@@ -2651,6 +2689,8 @@ | |||
2651 | #define ILK_VSDPFD_FULL (1<<21) | 2689 | #define ILK_VSDPFD_FULL (1<<21) |
2652 | #define ILK_DSPCLK_GATE 0x42020 | 2690 | #define ILK_DSPCLK_GATE 0x42020 |
2653 | #define ILK_DPARB_CLK_GATE (1<<5) | 2691 | #define ILK_DPARB_CLK_GATE (1<<5) |
2692 | #define ILK_DPFD_CLK_GATE (1<<7) | ||
2693 | |||
2654 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ | 2694 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ |
2655 | #define ILK_CLK_FBC (1<<7) | 2695 | #define ILK_CLK_FBC (1<<7) |
2656 | #define ILK_DPFC_DIS1 (1<<8) | 2696 | #define ILK_DPFC_DIS1 (1<<8) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 840bfc3ae719..eaf2bc6b537d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2845,6 +2845,39 @@ static struct intel_watermark_params ironlake_cursor_srwm_info = { | |||
2845 | ILK_FIFO_LINE_SIZE | 2845 | ILK_FIFO_LINE_SIZE |
2846 | }; | 2846 | }; |
2847 | 2847 | ||
2848 | static struct intel_watermark_params sandybridge_display_wm_info = { | ||
2849 | SNB_DISPLAY_FIFO, | ||
2850 | SNB_DISPLAY_MAXWM, | ||
2851 | SNB_DISPLAY_DFTWM, | ||
2852 | 2, | ||
2853 | SNB_FIFO_LINE_SIZE | ||
2854 | }; | ||
2855 | |||
2856 | static struct intel_watermark_params sandybridge_cursor_wm_info = { | ||
2857 | SNB_CURSOR_FIFO, | ||
2858 | SNB_CURSOR_MAXWM, | ||
2859 | SNB_CURSOR_DFTWM, | ||
2860 | 2, | ||
2861 | SNB_FIFO_LINE_SIZE | ||
2862 | }; | ||
2863 | |||
2864 | static struct intel_watermark_params sandybridge_display_srwm_info = { | ||
2865 | SNB_DISPLAY_SR_FIFO, | ||
2866 | SNB_DISPLAY_MAX_SRWM, | ||
2867 | SNB_DISPLAY_DFT_SRWM, | ||
2868 | 2, | ||
2869 | SNB_FIFO_LINE_SIZE | ||
2870 | }; | ||
2871 | |||
2872 | static struct intel_watermark_params sandybridge_cursor_srwm_info = { | ||
2873 | SNB_CURSOR_SR_FIFO, | ||
2874 | SNB_CURSOR_MAX_SRWM, | ||
2875 | SNB_CURSOR_DFT_SRWM, | ||
2876 | 2, | ||
2877 | SNB_FIFO_LINE_SIZE | ||
2878 | }; | ||
2879 | |||
2880 | |||
2848 | /** | 2881 | /** |
2849 | * intel_calculate_wm - calculate watermark level | 2882 | * intel_calculate_wm - calculate watermark level |
2850 | * @clock_in_khz: pixel clock | 2883 | * @clock_in_khz: pixel clock |
@@ -3378,6 +3411,10 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, | |||
3378 | 3411 | ||
3379 | static bool ironlake_compute_wm0(struct drm_device *dev, | 3412 | static bool ironlake_compute_wm0(struct drm_device *dev, |
3380 | int pipe, | 3413 | int pipe, |
3414 | const struct intel_watermark_params *display, | ||
3415 | int display_latency, | ||
3416 | const struct intel_watermark_params *cursor, | ||
3417 | int cursor_latency, | ||
3381 | int *plane_wm, | 3418 | int *plane_wm, |
3382 | int *cursor_wm) | 3419 | int *cursor_wm) |
3383 | { | 3420 | { |
@@ -3395,22 +3432,20 @@ static bool ironlake_compute_wm0(struct drm_device *dev, | |||
3395 | pixel_size = crtc->fb->bits_per_pixel / 8; | 3432 | pixel_size = crtc->fb->bits_per_pixel / 8; |
3396 | 3433 | ||
3397 | /* Use the small buffer method to calculate plane watermark */ | 3434 | /* Use the small buffer method to calculate plane watermark */ |
3398 | entries = ((clock * pixel_size / 1000) * ILK_LP0_PLANE_LATENCY) / 1000; | 3435 | entries = ((clock * pixel_size / 1000) * display_latency * 100) / 1000; |
3399 | entries = DIV_ROUND_UP(entries, | 3436 | entries = DIV_ROUND_UP(entries, display->cacheline_size); |
3400 | ironlake_display_wm_info.cacheline_size); | 3437 | *plane_wm = entries + display->guard_size; |
3401 | *plane_wm = entries + ironlake_display_wm_info.guard_size; | 3438 | if (*plane_wm > (int)display->max_wm) |
3402 | if (*plane_wm > (int)ironlake_display_wm_info.max_wm) | 3439 | *plane_wm = display->max_wm; |
3403 | *plane_wm = ironlake_display_wm_info.max_wm; | ||
3404 | 3440 | ||
3405 | /* Use the large buffer method to calculate cursor watermark */ | 3441 | /* Use the large buffer method to calculate cursor watermark */ |
3406 | line_time_us = ((htotal * 1000) / clock); | 3442 | line_time_us = ((htotal * 1000) / clock); |
3407 | line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; | 3443 | line_count = (cursor_latency * 100 / line_time_us + 1000) / 1000; |
3408 | entries = line_count * 64 * pixel_size; | 3444 | entries = line_count * 64 * pixel_size; |
3409 | entries = DIV_ROUND_UP(entries, | 3445 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
3410 | ironlake_cursor_wm_info.cacheline_size); | 3446 | *cursor_wm = entries + cursor->guard_size; |
3411 | *cursor_wm = entries + ironlake_cursor_wm_info.guard_size; | 3447 | if (*cursor_wm > (int)cursor->max_wm) |
3412 | if (*cursor_wm > ironlake_cursor_wm_info.max_wm) | 3448 | *cursor_wm = (int)cursor->max_wm; |
3413 | *cursor_wm = ironlake_cursor_wm_info.max_wm; | ||
3414 | 3449 | ||
3415 | return true; | 3450 | return true; |
3416 | } | 3451 | } |
@@ -3425,7 +3460,12 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
3425 | int tmp; | 3460 | int tmp; |
3426 | 3461 | ||
3427 | enabled = 0; | 3462 | enabled = 0; |
3428 | if (ironlake_compute_wm0(dev, 0, &plane_wm, &cursor_wm)) { | 3463 | if (ironlake_compute_wm0(dev, 0, |
3464 | &ironlake_display_wm_info, | ||
3465 | ILK_LP0_PLANE_LATENCY, | ||
3466 | &ironlake_cursor_wm_info, | ||
3467 | ILK_LP0_CURSOR_LATENCY, | ||
3468 | &plane_wm, &cursor_wm)) { | ||
3429 | I915_WRITE(WM0_PIPEA_ILK, | 3469 | I915_WRITE(WM0_PIPEA_ILK, |
3430 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | 3470 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
3431 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | 3471 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
@@ -3434,7 +3474,12 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
3434 | enabled++; | 3474 | enabled++; |
3435 | } | 3475 | } |
3436 | 3476 | ||
3437 | if (ironlake_compute_wm0(dev, 1, &plane_wm, &cursor_wm)) { | 3477 | if (ironlake_compute_wm0(dev, 1, |
3478 | &ironlake_display_wm_info, | ||
3479 | ILK_LP0_PLANE_LATENCY, | ||
3480 | &ironlake_cursor_wm_info, | ||
3481 | ILK_LP0_CURSOR_LATENCY, | ||
3482 | &plane_wm, &cursor_wm)) { | ||
3438 | I915_WRITE(WM0_PIPEB_ILK, | 3483 | I915_WRITE(WM0_PIPEB_ILK, |
3439 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | 3484 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
3440 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | 3485 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
@@ -3500,6 +3545,197 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
3500 | /* XXX setup WM2 and WM3 */ | 3545 | /* XXX setup WM2 and WM3 */ |
3501 | } | 3546 | } |
3502 | 3547 | ||
3548 | /* | ||
3549 | * Check the wm result. | ||
3550 | * | ||
3551 | * If any calculated watermark values is larger than the maximum value that | ||
3552 | * can be programmed into the associated watermark register, that watermark | ||
3553 | * must be disabled. | ||
3554 | * | ||
3555 | * Also return true if all of those watermark values is 0, which is set by | ||
3556 | * sandybridge_compute_srwm, to indicate the latency is ZERO. | ||
3557 | */ | ||
3558 | static bool sandybridge_check_srwm(struct drm_device *dev, int level, | ||
3559 | int fbc_wm, int display_wm, int cursor_wm) | ||
3560 | { | ||
3561 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3562 | |||
3563 | DRM_DEBUG_KMS("watermark %d: display plane %d, fbc lines %d," | ||
3564 | " cursor %d\n", level, display_wm, fbc_wm, cursor_wm); | ||
3565 | |||
3566 | if (fbc_wm > SNB_FBC_MAX_SRWM) { | ||
3567 | DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", | ||
3568 | fbc_wm, SNB_FBC_MAX_SRWM, level); | ||
3569 | |||
3570 | /* fbc has it's own way to disable FBC WM */ | ||
3571 | I915_WRITE(DISP_ARB_CTL, | ||
3572 | I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS); | ||
3573 | return false; | ||
3574 | } | ||
3575 | |||
3576 | if (display_wm > SNB_DISPLAY_MAX_SRWM) { | ||
3577 | DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", | ||
3578 | display_wm, SNB_DISPLAY_MAX_SRWM, level); | ||
3579 | return false; | ||
3580 | } | ||
3581 | |||
3582 | if (cursor_wm > SNB_CURSOR_MAX_SRWM) { | ||
3583 | DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", | ||
3584 | cursor_wm, SNB_CURSOR_MAX_SRWM, level); | ||
3585 | return false; | ||
3586 | } | ||
3587 | |||
3588 | if (!(fbc_wm || display_wm || cursor_wm)) { | ||
3589 | DRM_DEBUG_KMS("latency %d is 0, disabling wm%d+\n", level, level); | ||
3590 | return false; | ||
3591 | } | ||
3592 | |||
3593 | return true; | ||
3594 | } | ||
3595 | |||
3596 | /* | ||
3597 | * Compute watermark values of WM[1-3], | ||
3598 | */ | ||
3599 | static bool sandybridge_compute_srwm(struct drm_device *dev, int level, | ||
3600 | int hdisplay, int htotal, int pixel_size, | ||
3601 | int clock, int latency_ns, int *fbc_wm, | ||
3602 | int *display_wm, int *cursor_wm) | ||
3603 | { | ||
3604 | |||
3605 | unsigned long line_time_us; | ||
3606 | int small, large; | ||
3607 | int entries; | ||
3608 | int line_count, line_size; | ||
3609 | |||
3610 | if (!latency_ns) { | ||
3611 | *fbc_wm = *display_wm = *cursor_wm = 0; | ||
3612 | return false; | ||
3613 | } | ||
3614 | |||
3615 | line_time_us = (htotal * 1000) / clock; | ||
3616 | line_count = (latency_ns / line_time_us + 1000) / 1000; | ||
3617 | line_size = hdisplay * pixel_size; | ||
3618 | |||
3619 | /* Use the minimum of the small and large buffer method for primary */ | ||
3620 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | ||
3621 | large = line_count * line_size; | ||
3622 | |||
3623 | entries = DIV_ROUND_UP(min(small, large), | ||
3624 | sandybridge_display_srwm_info.cacheline_size); | ||
3625 | *display_wm = entries + sandybridge_display_srwm_info.guard_size; | ||
3626 | |||
3627 | /* | ||
3628 | * Spec said: | ||
3629 | * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 | ||
3630 | */ | ||
3631 | *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; | ||
3632 | |||
3633 | /* calculate the self-refresh watermark for display cursor */ | ||
3634 | entries = line_count * pixel_size * 64; | ||
3635 | entries = DIV_ROUND_UP(entries, | ||
3636 | sandybridge_cursor_srwm_info.cacheline_size); | ||
3637 | *cursor_wm = entries + sandybridge_cursor_srwm_info.guard_size; | ||
3638 | |||
3639 | return sandybridge_check_srwm(dev, level, | ||
3640 | *fbc_wm, *display_wm, *cursor_wm); | ||
3641 | } | ||
3642 | |||
3643 | static void sandybridge_update_wm(struct drm_device *dev, | ||
3644 | int planea_clock, int planeb_clock, | ||
3645 | int hdisplay, int htotal, | ||
3646 | int pixel_size) | ||
3647 | { | ||
3648 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3649 | int latency = SNB_READ_WM0_LATENCY(); | ||
3650 | int fbc_wm, plane_wm, cursor_wm, enabled; | ||
3651 | int clock; | ||
3652 | |||
3653 | enabled = 0; | ||
3654 | if (ironlake_compute_wm0(dev, 0, | ||
3655 | &sandybridge_display_wm_info, latency, | ||
3656 | &sandybridge_cursor_wm_info, latency, | ||
3657 | &plane_wm, &cursor_wm)) { | ||
3658 | I915_WRITE(WM0_PIPEA_ILK, | ||
3659 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3660 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
3661 | " plane %d, " "cursor: %d\n", | ||
3662 | plane_wm, cursor_wm); | ||
3663 | enabled++; | ||
3664 | } | ||
3665 | |||
3666 | if (ironlake_compute_wm0(dev, 1, | ||
3667 | &sandybridge_display_wm_info, latency, | ||
3668 | &sandybridge_cursor_wm_info, latency, | ||
3669 | &plane_wm, &cursor_wm)) { | ||
3670 | I915_WRITE(WM0_PIPEB_ILK, | ||
3671 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3672 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
3673 | " plane %d, cursor: %d\n", | ||
3674 | plane_wm, cursor_wm); | ||
3675 | enabled++; | ||
3676 | } | ||
3677 | |||
3678 | /* | ||
3679 | * Calculate and update the self-refresh watermark only when one | ||
3680 | * display plane is used. | ||
3681 | * | ||
3682 | * SNB support 3 levels of watermark. | ||
3683 | * | ||
3684 | * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, | ||
3685 | * and disabled in the descending order | ||
3686 | * | ||
3687 | */ | ||
3688 | I915_WRITE(WM3_LP_ILK, 0); | ||
3689 | I915_WRITE(WM2_LP_ILK, 0); | ||
3690 | I915_WRITE(WM1_LP_ILK, 0); | ||
3691 | |||
3692 | if (enabled != 1) | ||
3693 | return; | ||
3694 | |||
3695 | clock = planea_clock ? planea_clock : planeb_clock; | ||
3696 | |||
3697 | /* WM1 */ | ||
3698 | if (!sandybridge_compute_srwm(dev, 1, hdisplay, htotal, pixel_size, | ||
3699 | clock, SNB_READ_WM1_LATENCY() * 500, | ||
3700 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3701 | return; | ||
3702 | |||
3703 | I915_WRITE(WM1_LP_ILK, | ||
3704 | WM1_LP_SR_EN | | ||
3705 | (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
3706 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
3707 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3708 | cursor_wm); | ||
3709 | |||
3710 | /* WM2 */ | ||
3711 | if (!sandybridge_compute_srwm(dev, 2, | ||
3712 | hdisplay, htotal, pixel_size, | ||
3713 | clock, SNB_READ_WM2_LATENCY() * 500, | ||
3714 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3715 | return; | ||
3716 | |||
3717 | I915_WRITE(WM2_LP_ILK, | ||
3718 | WM2_LP_EN | | ||
3719 | (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
3720 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
3721 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3722 | cursor_wm); | ||
3723 | |||
3724 | /* WM3 */ | ||
3725 | if (!sandybridge_compute_srwm(dev, 3, | ||
3726 | hdisplay, htotal, pixel_size, | ||
3727 | clock, SNB_READ_WM3_LATENCY() * 500, | ||
3728 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3729 | return; | ||
3730 | |||
3731 | I915_WRITE(WM3_LP_ILK, | ||
3732 | WM3_LP_EN | | ||
3733 | (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
3734 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
3735 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3736 | cursor_wm); | ||
3737 | } | ||
3738 | |||
3503 | /** | 3739 | /** |
3504 | * intel_update_watermarks - update FIFO watermark values based on current modes | 3740 | * intel_update_watermarks - update FIFO watermark values based on current modes |
3505 | * | 3741 | * |
@@ -5975,9 +6211,9 @@ void intel_enable_clock_gating(struct drm_device *dev) | |||
5975 | I915_WRITE(DISP_ARB_CTL, | 6211 | I915_WRITE(DISP_ARB_CTL, |
5976 | (I915_READ(DISP_ARB_CTL) | | 6212 | (I915_READ(DISP_ARB_CTL) | |
5977 | DISP_FBC_WM_DIS)); | 6213 | DISP_FBC_WM_DIS)); |
5978 | I915_WRITE(WM3_LP_ILK, 0); | 6214 | I915_WRITE(WM3_LP_ILK, 0); |
5979 | I915_WRITE(WM2_LP_ILK, 0); | 6215 | I915_WRITE(WM2_LP_ILK, 0); |
5980 | I915_WRITE(WM1_LP_ILK, 0); | 6216 | I915_WRITE(WM1_LP_ILK, 0); |
5981 | } | 6217 | } |
5982 | /* | 6218 | /* |
5983 | * Based on the document from hardware guys the following bits | 6219 | * Based on the document from hardware guys the following bits |
@@ -6010,6 +6246,38 @@ void intel_enable_clock_gating(struct drm_device *dev) | |||
6010 | _3D_CHICKEN2_WM_READ_PIPELINED); | 6246 | _3D_CHICKEN2_WM_READ_PIPELINED); |
6011 | } | 6247 | } |
6012 | 6248 | ||
6249 | if (IS_GEN6(dev)) { | ||
6250 | I915_WRITE(WM3_LP_ILK, 0); | ||
6251 | I915_WRITE(WM2_LP_ILK, 0); | ||
6252 | I915_WRITE(WM1_LP_ILK, 0); | ||
6253 | |||
6254 | /* | ||
6255 | * According to the spec the following bits should be | ||
6256 | * set in order to enable memory self-refresh and fbc: | ||
6257 | * The bit21 and bit22 of 0x42000 | ||
6258 | * The bit21 and bit22 of 0x42004 | ||
6259 | * The bit5 and bit7 of 0x42020 | ||
6260 | * The bit14 of 0x70180 | ||
6261 | * The bit14 of 0x71180 | ||
6262 | */ | ||
6263 | I915_WRITE(ILK_DISPLAY_CHICKEN1, | ||
6264 | I915_READ(ILK_DISPLAY_CHICKEN1) | | ||
6265 | ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); | ||
6266 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
6267 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
6268 | ILK_DPARB_GATE | ILK_VSDPFD_FULL); | ||
6269 | I915_WRITE(ILK_DSPCLK_GATE, | ||
6270 | I915_READ(ILK_DSPCLK_GATE) | | ||
6271 | ILK_DPARB_CLK_GATE | | ||
6272 | ILK_DPFD_CLK_GATE); | ||
6273 | |||
6274 | I915_WRITE(DSPACNTR, | ||
6275 | I915_READ(DSPACNTR) | | ||
6276 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
6277 | I915_WRITE(DSPBCNTR, | ||
6278 | I915_READ(DSPBCNTR) | | ||
6279 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
6280 | } | ||
6013 | } else if (IS_G4X(dev)) { | 6281 | } else if (IS_G4X(dev)) { |
6014 | uint32_t dspclk_gate; | 6282 | uint32_t dspclk_gate; |
6015 | I915_WRITE(RENCLK_GATE_D1, 0); | 6283 | I915_WRITE(RENCLK_GATE_D1, 0); |
@@ -6176,6 +6444,14 @@ static void intel_init_display(struct drm_device *dev) | |||
6176 | "Disable CxSR\n"); | 6444 | "Disable CxSR\n"); |
6177 | dev_priv->display.update_wm = NULL; | 6445 | dev_priv->display.update_wm = NULL; |
6178 | } | 6446 | } |
6447 | } else if (IS_GEN6(dev)) { | ||
6448 | if (SNB_READ_WM0_LATENCY()) { | ||
6449 | dev_priv->display.update_wm = sandybridge_update_wm; | ||
6450 | } else { | ||
6451 | DRM_DEBUG_KMS("Failed to read display plane latency. " | ||
6452 | "Disable CxSR\n"); | ||
6453 | dev_priv->display.update_wm = NULL; | ||
6454 | } | ||
6179 | } else | 6455 | } else |
6180 | dev_priv->display.update_wm = NULL; | 6456 | dev_priv->display.update_wm = NULL; |
6181 | } else if (IS_PINEVIEW(dev)) { | 6457 | } else if (IS_PINEVIEW(dev)) { |