diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 80 |
2 files changed, 84 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 78f336e00836..1687edf68795 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -1799,17 +1799,29 @@ | |||
| 1799 | #define DSPARB_AEND_SHIFT 0 | 1799 | #define DSPARB_AEND_SHIFT 0 |
| 1800 | 1800 | ||
| 1801 | #define DSPFW1 0x70034 | 1801 | #define DSPFW1 0x70034 |
| 1802 | #define DSPFW_SR_SHIFT 23 | ||
| 1803 | #define DSPFW_CURSORB_SHIFT 16 | ||
| 1804 | #define DSPFW_PLANEB_SHIFT 8 | ||
| 1802 | #define DSPFW2 0x70038 | 1805 | #define DSPFW2 0x70038 |
| 1806 | #define DSPFW_CURSORA_MASK 0x00003f00 | ||
| 1807 | #define DSPFW_CURSORA_SHIFT 16 | ||
| 1803 | #define DSPFW3 0x7003c | 1808 | #define DSPFW3 0x7003c |
| 1809 | #define DSPFW_HPLL_SR_EN (1<<31) | ||
| 1810 | #define DSPFW_CURSOR_SR_SHIFT 24 | ||
| 1804 | #define IGD_SELF_REFRESH_EN (1<<30) | 1811 | #define IGD_SELF_REFRESH_EN (1<<30) |
| 1805 | 1812 | ||
| 1806 | /* FIFO watermark sizes etc */ | 1813 | /* FIFO watermark sizes etc */ |
| 1814 | #define G4X_FIFO_LINE_SIZE 64 | ||
| 1807 | #define I915_FIFO_LINE_SIZE 64 | 1815 | #define I915_FIFO_LINE_SIZE 64 |
| 1808 | #define I830_FIFO_LINE_SIZE 32 | 1816 | #define I830_FIFO_LINE_SIZE 32 |
| 1817 | |||
| 1818 | #define G4X_FIFO_SIZE 127 | ||
| 1809 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ | 1819 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ |
| 1810 | #define I915_FIFO_SIZE 95 | 1820 | #define I915_FIFO_SIZE 95 |
| 1811 | #define I855GM_FIFO_SIZE 127 /* In cachelines */ | 1821 | #define I855GM_FIFO_SIZE 127 /* In cachelines */ |
| 1812 | #define I830_FIFO_SIZE 95 | 1822 | #define I830_FIFO_SIZE 95 |
| 1823 | |||
| 1824 | #define G4X_MAX_WM 0x3f | ||
| 1813 | #define I915_MAX_WM 0x3f | 1825 | #define I915_MAX_WM 0x3f |
| 1814 | 1826 | ||
| 1815 | #define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ | 1827 | #define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e189fd6dedcf..47d6ff058991 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2143,6 +2143,13 @@ static struct intel_watermark_params igd_cursor_hplloff_wm = { | |||
| 2143 | IGD_CURSOR_GUARD_WM, | 2143 | IGD_CURSOR_GUARD_WM, |
| 2144 | IGD_FIFO_LINE_SIZE | 2144 | IGD_FIFO_LINE_SIZE |
| 2145 | }; | 2145 | }; |
| 2146 | static struct intel_watermark_params g4x_wm_info = { | ||
| 2147 | G4X_FIFO_SIZE, | ||
| 2148 | G4X_MAX_WM, | ||
| 2149 | G4X_MAX_WM, | ||
| 2150 | 2, | ||
| 2151 | G4X_FIFO_LINE_SIZE, | ||
| 2152 | }; | ||
| 2146 | static struct intel_watermark_params i945_wm_info = { | 2153 | static struct intel_watermark_params i945_wm_info = { |
| 2147 | I945_FIFO_SIZE, | 2154 | I945_FIFO_SIZE, |
| 2148 | I915_MAX_WM, | 2155 | I915_MAX_WM, |
| @@ -2433,17 +2440,74 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) | |||
| 2433 | return size; | 2440 | return size; |
| 2434 | } | 2441 | } |
| 2435 | 2442 | ||
| 2436 | static void g4x_update_wm(struct drm_device *dev, int unused, int unused2, | 2443 | static void g4x_update_wm(struct drm_device *dev, int planea_clock, |
| 2437 | int unused3, int unused4) | 2444 | int planeb_clock, int sr_hdisplay, int pixel_size) |
| 2438 | { | 2445 | { |
| 2439 | struct drm_i915_private *dev_priv = dev->dev_private; | 2446 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2440 | u32 fw_blc_self = I915_READ(FW_BLC_SELF); | 2447 | int total_size, cacheline_size; |
| 2448 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm, cursor_sr; | ||
| 2449 | struct intel_watermark_params planea_params, planeb_params; | ||
| 2450 | unsigned long line_time_us; | ||
| 2451 | int sr_clock, sr_entries = 0, entries_required; | ||
| 2441 | 2452 | ||
| 2442 | if (i915_powersave) | 2453 | /* Create copies of the base settings for each pipe */ |
| 2443 | fw_blc_self |= FW_BLC_SELF_EN; | 2454 | planea_params = planeb_params = g4x_wm_info; |
| 2444 | else | 2455 | |
| 2445 | fw_blc_self &= ~FW_BLC_SELF_EN; | 2456 | /* Grab a couple of global values before we overwrite them */ |
| 2446 | I915_WRITE(FW_BLC_SELF, fw_blc_self); | 2457 | total_size = planea_params.fifo_size; |
| 2458 | cacheline_size = planea_params.cacheline_size; | ||
| 2459 | |||
| 2460 | /* | ||
| 2461 | * Note: we need to make sure we don't overflow for various clock & | ||
| 2462 | * latency values. | ||
| 2463 | * clocks go from a few thousand to several hundred thousand. | ||
| 2464 | * latency is usually a few thousand | ||
| 2465 | */ | ||
| 2466 | entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) / | ||
| 2467 | 1000; | ||
| 2468 | entries_required /= G4X_FIFO_LINE_SIZE; | ||
| 2469 | planea_wm = entries_required + planea_params.guard_size; | ||
| 2470 | |||
| 2471 | entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) / | ||
| 2472 | 1000; | ||
| 2473 | entries_required /= G4X_FIFO_LINE_SIZE; | ||
| 2474 | planeb_wm = entries_required + planeb_params.guard_size; | ||
| 2475 | |||
| 2476 | cursora_wm = cursorb_wm = 16; | ||
| 2477 | cursor_sr = 32; | ||
| 2478 | |||
| 2479 | DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); | ||
| 2480 | |||
| 2481 | /* Calc sr entries for one plane configs */ | ||
| 2482 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | ||
| 2483 | /* self-refresh has much higher latency */ | ||
| 2484 | const static int sr_latency_ns = 12000; | ||
| 2485 | |||
| 2486 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
| 2487 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | ||
| 2488 | |||
| 2489 | /* Use ns/us then divide to preserve precision */ | ||
| 2490 | sr_entries = (((sr_latency_ns / line_time_us) + 1) * | ||
| 2491 | pixel_size * sr_hdisplay) / 1000; | ||
| 2492 | sr_entries = roundup(sr_entries / cacheline_size, 1); | ||
| 2493 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | ||
| 2494 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | ||
| 2495 | } | ||
| 2496 | |||
| 2497 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", | ||
| 2498 | planea_wm, planeb_wm, sr_entries); | ||
| 2499 | |||
| 2500 | planea_wm &= 0x3f; | ||
| 2501 | planeb_wm &= 0x3f; | ||
| 2502 | |||
| 2503 | I915_WRITE(DSPFW1, (sr_entries << DSPFW_SR_SHIFT) | | ||
| 2504 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | | ||
| 2505 | (planeb_wm << DSPFW_PLANEB_SHIFT) | planea_wm); | ||
| 2506 | I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | | ||
| 2507 | (cursora_wm << DSPFW_CURSORA_SHIFT)); | ||
| 2508 | /* HPLL off in SR has some issues on G4x... disable it */ | ||
| 2509 | I915_WRITE(DSPFW3, (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) | | ||
| 2510 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | ||
| 2447 | } | 2511 | } |
| 2448 | 2512 | ||
| 2449 | static void i965_update_wm(struct drm_device *dev, int unused, int unused2, | 2513 | static void i965_update_wm(struct drm_device *dev, int unused, int unused2, |
