diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-24 12:43:27 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-25 06:22:10 -0500 |
commit | d210246ab1106d77df91a4185b9d3b75a63be81f (patch) | |
tree | 561884ea504167d42b419d234a43ae5caa8da760 /drivers | |
parent | 29ee399131395d8b607803874a206b9daf714025 (diff) |
drm/i915: Refactor self-refresh watermark calculations
Move the plane->mode config to the point of use rather than repeatedly
querying the same information.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 387 |
2 files changed, 200 insertions, 191 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1aca8ba612e4..33b5134fc017 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -202,9 +202,7 @@ struct drm_i915_display_funcs { | |||
202 | void (*disable_fbc)(struct drm_device *dev); | 202 | void (*disable_fbc)(struct drm_device *dev); |
203 | int (*get_display_clock_speed)(struct drm_device *dev); | 203 | int (*get_display_clock_speed)(struct drm_device *dev); |
204 | int (*get_fifo_size)(struct drm_device *dev, int plane); | 204 | int (*get_fifo_size)(struct drm_device *dev, int plane); |
205 | void (*update_wm)(struct drm_device *dev, int planea_clock, | 205 | void (*update_wm)(struct drm_device *dev); |
206 | int planeb_clock, int sr_hdisplay, int sr_htotal, | ||
207 | int pixel_size); | ||
208 | /* clock updates for mode set */ | 206 | /* clock updates for mode set */ |
209 | /* cursor updates */ | 207 | /* cursor updates */ |
210 | /* render clock increase/decrease */ | 208 | /* render clock increase/decrease */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2fbc3da06c29..edc4535f9a66 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1895,7 +1895,7 @@ static void intel_update_fbc(struct drm_device *dev) | |||
1895 | * - going to an unsupported config (interlace, pixel multiply, etc.) | 1895 | * - going to an unsupported config (interlace, pixel multiply, etc.) |
1896 | */ | 1896 | */ |
1897 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { | 1897 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { |
1898 | if (tmp_crtc->enabled) { | 1898 | if (tmp_crtc->enabled && tmp_crtc->fb) { |
1899 | if (crtc) { | 1899 | if (crtc) { |
1900 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); | 1900 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); |
1901 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; | 1901 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; |
@@ -3207,77 +3207,77 @@ struct intel_watermark_params { | |||
3207 | }; | 3207 | }; |
3208 | 3208 | ||
3209 | /* Pineview has different values for various configs */ | 3209 | /* Pineview has different values for various configs */ |
3210 | static struct intel_watermark_params pineview_display_wm = { | 3210 | static const struct intel_watermark_params pineview_display_wm = { |
3211 | PINEVIEW_DISPLAY_FIFO, | 3211 | PINEVIEW_DISPLAY_FIFO, |
3212 | PINEVIEW_MAX_WM, | 3212 | PINEVIEW_MAX_WM, |
3213 | PINEVIEW_DFT_WM, | 3213 | PINEVIEW_DFT_WM, |
3214 | PINEVIEW_GUARD_WM, | 3214 | PINEVIEW_GUARD_WM, |
3215 | PINEVIEW_FIFO_LINE_SIZE | 3215 | PINEVIEW_FIFO_LINE_SIZE |
3216 | }; | 3216 | }; |
3217 | static struct intel_watermark_params pineview_display_hplloff_wm = { | 3217 | static const struct intel_watermark_params pineview_display_hplloff_wm = { |
3218 | PINEVIEW_DISPLAY_FIFO, | 3218 | PINEVIEW_DISPLAY_FIFO, |
3219 | PINEVIEW_MAX_WM, | 3219 | PINEVIEW_MAX_WM, |
3220 | PINEVIEW_DFT_HPLLOFF_WM, | 3220 | PINEVIEW_DFT_HPLLOFF_WM, |
3221 | PINEVIEW_GUARD_WM, | 3221 | PINEVIEW_GUARD_WM, |
3222 | PINEVIEW_FIFO_LINE_SIZE | 3222 | PINEVIEW_FIFO_LINE_SIZE |
3223 | }; | 3223 | }; |
3224 | static struct intel_watermark_params pineview_cursor_wm = { | 3224 | static const struct intel_watermark_params pineview_cursor_wm = { |
3225 | PINEVIEW_CURSOR_FIFO, | 3225 | PINEVIEW_CURSOR_FIFO, |
3226 | PINEVIEW_CURSOR_MAX_WM, | 3226 | PINEVIEW_CURSOR_MAX_WM, |
3227 | PINEVIEW_CURSOR_DFT_WM, | 3227 | PINEVIEW_CURSOR_DFT_WM, |
3228 | PINEVIEW_CURSOR_GUARD_WM, | 3228 | PINEVIEW_CURSOR_GUARD_WM, |
3229 | PINEVIEW_FIFO_LINE_SIZE, | 3229 | PINEVIEW_FIFO_LINE_SIZE, |
3230 | }; | 3230 | }; |
3231 | static struct intel_watermark_params pineview_cursor_hplloff_wm = { | 3231 | static const struct intel_watermark_params pineview_cursor_hplloff_wm = { |
3232 | PINEVIEW_CURSOR_FIFO, | 3232 | PINEVIEW_CURSOR_FIFO, |
3233 | PINEVIEW_CURSOR_MAX_WM, | 3233 | PINEVIEW_CURSOR_MAX_WM, |
3234 | PINEVIEW_CURSOR_DFT_WM, | 3234 | PINEVIEW_CURSOR_DFT_WM, |
3235 | PINEVIEW_CURSOR_GUARD_WM, | 3235 | PINEVIEW_CURSOR_GUARD_WM, |
3236 | PINEVIEW_FIFO_LINE_SIZE | 3236 | PINEVIEW_FIFO_LINE_SIZE |
3237 | }; | 3237 | }; |
3238 | static struct intel_watermark_params g4x_wm_info = { | 3238 | static const struct intel_watermark_params g4x_wm_info = { |
3239 | G4X_FIFO_SIZE, | 3239 | G4X_FIFO_SIZE, |
3240 | G4X_MAX_WM, | 3240 | G4X_MAX_WM, |
3241 | G4X_MAX_WM, | 3241 | G4X_MAX_WM, |
3242 | 2, | 3242 | 2, |
3243 | G4X_FIFO_LINE_SIZE, | 3243 | G4X_FIFO_LINE_SIZE, |
3244 | }; | 3244 | }; |
3245 | static struct intel_watermark_params g4x_cursor_wm_info = { | 3245 | static const struct intel_watermark_params g4x_cursor_wm_info = { |
3246 | I965_CURSOR_FIFO, | 3246 | I965_CURSOR_FIFO, |
3247 | I965_CURSOR_MAX_WM, | 3247 | I965_CURSOR_MAX_WM, |
3248 | I965_CURSOR_DFT_WM, | 3248 | I965_CURSOR_DFT_WM, |
3249 | 2, | 3249 | 2, |
3250 | G4X_FIFO_LINE_SIZE, | 3250 | G4X_FIFO_LINE_SIZE, |
3251 | }; | 3251 | }; |
3252 | static struct intel_watermark_params i965_cursor_wm_info = { | 3252 | static const struct intel_watermark_params i965_cursor_wm_info = { |
3253 | I965_CURSOR_FIFO, | 3253 | I965_CURSOR_FIFO, |
3254 | I965_CURSOR_MAX_WM, | 3254 | I965_CURSOR_MAX_WM, |
3255 | I965_CURSOR_DFT_WM, | 3255 | I965_CURSOR_DFT_WM, |
3256 | 2, | 3256 | 2, |
3257 | I915_FIFO_LINE_SIZE, | 3257 | I915_FIFO_LINE_SIZE, |
3258 | }; | 3258 | }; |
3259 | static struct intel_watermark_params i945_wm_info = { | 3259 | static const struct intel_watermark_params i945_wm_info = { |
3260 | I945_FIFO_SIZE, | 3260 | I945_FIFO_SIZE, |
3261 | I915_MAX_WM, | 3261 | I915_MAX_WM, |
3262 | 1, | 3262 | 1, |
3263 | 2, | 3263 | 2, |
3264 | I915_FIFO_LINE_SIZE | 3264 | I915_FIFO_LINE_SIZE |
3265 | }; | 3265 | }; |
3266 | static struct intel_watermark_params i915_wm_info = { | 3266 | static const struct intel_watermark_params i915_wm_info = { |
3267 | I915_FIFO_SIZE, | 3267 | I915_FIFO_SIZE, |
3268 | I915_MAX_WM, | 3268 | I915_MAX_WM, |
3269 | 1, | 3269 | 1, |
3270 | 2, | 3270 | 2, |
3271 | I915_FIFO_LINE_SIZE | 3271 | I915_FIFO_LINE_SIZE |
3272 | }; | 3272 | }; |
3273 | static struct intel_watermark_params i855_wm_info = { | 3273 | static const struct intel_watermark_params i855_wm_info = { |
3274 | I855GM_FIFO_SIZE, | 3274 | I855GM_FIFO_SIZE, |
3275 | I915_MAX_WM, | 3275 | I915_MAX_WM, |
3276 | 1, | 3276 | 1, |
3277 | 2, | 3277 | 2, |
3278 | I830_FIFO_LINE_SIZE | 3278 | I830_FIFO_LINE_SIZE |
3279 | }; | 3279 | }; |
3280 | static struct intel_watermark_params i830_wm_info = { | 3280 | static const struct intel_watermark_params i830_wm_info = { |
3281 | I830_FIFO_SIZE, | 3281 | I830_FIFO_SIZE, |
3282 | I915_MAX_WM, | 3282 | I915_MAX_WM, |
3283 | 1, | 3283 | 1, |
@@ -3285,31 +3285,28 @@ static struct intel_watermark_params i830_wm_info = { | |||
3285 | I830_FIFO_LINE_SIZE | 3285 | I830_FIFO_LINE_SIZE |
3286 | }; | 3286 | }; |
3287 | 3287 | ||
3288 | static struct intel_watermark_params ironlake_display_wm_info = { | 3288 | static const struct intel_watermark_params ironlake_display_wm_info = { |
3289 | ILK_DISPLAY_FIFO, | 3289 | ILK_DISPLAY_FIFO, |
3290 | ILK_DISPLAY_MAXWM, | 3290 | ILK_DISPLAY_MAXWM, |
3291 | ILK_DISPLAY_DFTWM, | 3291 | ILK_DISPLAY_DFTWM, |
3292 | 2, | 3292 | 2, |
3293 | ILK_FIFO_LINE_SIZE | 3293 | ILK_FIFO_LINE_SIZE |
3294 | }; | 3294 | }; |
3295 | 3295 | static const struct intel_watermark_params ironlake_cursor_wm_info = { | |
3296 | static struct intel_watermark_params ironlake_cursor_wm_info = { | ||
3297 | ILK_CURSOR_FIFO, | 3296 | ILK_CURSOR_FIFO, |
3298 | ILK_CURSOR_MAXWM, | 3297 | ILK_CURSOR_MAXWM, |
3299 | ILK_CURSOR_DFTWM, | 3298 | ILK_CURSOR_DFTWM, |
3300 | 2, | 3299 | 2, |
3301 | ILK_FIFO_LINE_SIZE | 3300 | ILK_FIFO_LINE_SIZE |
3302 | }; | 3301 | }; |
3303 | 3302 | static const struct intel_watermark_params ironlake_display_srwm_info = { | |
3304 | static struct intel_watermark_params ironlake_display_srwm_info = { | ||
3305 | ILK_DISPLAY_SR_FIFO, | 3303 | ILK_DISPLAY_SR_FIFO, |
3306 | ILK_DISPLAY_MAX_SRWM, | 3304 | ILK_DISPLAY_MAX_SRWM, |
3307 | ILK_DISPLAY_DFT_SRWM, | 3305 | ILK_DISPLAY_DFT_SRWM, |
3308 | 2, | 3306 | 2, |
3309 | ILK_FIFO_LINE_SIZE | 3307 | ILK_FIFO_LINE_SIZE |
3310 | }; | 3308 | }; |
3311 | 3309 | static const struct intel_watermark_params ironlake_cursor_srwm_info = { | |
3312 | static struct intel_watermark_params ironlake_cursor_srwm_info = { | ||
3313 | ILK_CURSOR_SR_FIFO, | 3310 | ILK_CURSOR_SR_FIFO, |
3314 | ILK_CURSOR_MAX_SRWM, | 3311 | ILK_CURSOR_MAX_SRWM, |
3315 | ILK_CURSOR_DFT_SRWM, | 3312 | ILK_CURSOR_DFT_SRWM, |
@@ -3317,31 +3314,28 @@ static struct intel_watermark_params ironlake_cursor_srwm_info = { | |||
3317 | ILK_FIFO_LINE_SIZE | 3314 | ILK_FIFO_LINE_SIZE |
3318 | }; | 3315 | }; |
3319 | 3316 | ||
3320 | static struct intel_watermark_params sandybridge_display_wm_info = { | 3317 | static const struct intel_watermark_params sandybridge_display_wm_info = { |
3321 | SNB_DISPLAY_FIFO, | 3318 | SNB_DISPLAY_FIFO, |
3322 | SNB_DISPLAY_MAXWM, | 3319 | SNB_DISPLAY_MAXWM, |
3323 | SNB_DISPLAY_DFTWM, | 3320 | SNB_DISPLAY_DFTWM, |
3324 | 2, | 3321 | 2, |
3325 | SNB_FIFO_LINE_SIZE | 3322 | SNB_FIFO_LINE_SIZE |
3326 | }; | 3323 | }; |
3327 | 3324 | static const struct intel_watermark_params sandybridge_cursor_wm_info = { | |
3328 | static struct intel_watermark_params sandybridge_cursor_wm_info = { | ||
3329 | SNB_CURSOR_FIFO, | 3325 | SNB_CURSOR_FIFO, |
3330 | SNB_CURSOR_MAXWM, | 3326 | SNB_CURSOR_MAXWM, |
3331 | SNB_CURSOR_DFTWM, | 3327 | SNB_CURSOR_DFTWM, |
3332 | 2, | 3328 | 2, |
3333 | SNB_FIFO_LINE_SIZE | 3329 | SNB_FIFO_LINE_SIZE |
3334 | }; | 3330 | }; |
3335 | 3331 | static const struct intel_watermark_params sandybridge_display_srwm_info = { | |
3336 | static struct intel_watermark_params sandybridge_display_srwm_info = { | ||
3337 | SNB_DISPLAY_SR_FIFO, | 3332 | SNB_DISPLAY_SR_FIFO, |
3338 | SNB_DISPLAY_MAX_SRWM, | 3333 | SNB_DISPLAY_MAX_SRWM, |
3339 | SNB_DISPLAY_DFT_SRWM, | 3334 | SNB_DISPLAY_DFT_SRWM, |
3340 | 2, | 3335 | 2, |
3341 | SNB_FIFO_LINE_SIZE | 3336 | SNB_FIFO_LINE_SIZE |
3342 | }; | 3337 | }; |
3343 | 3338 | static const struct intel_watermark_params sandybridge_cursor_srwm_info = { | |
3344 | static struct intel_watermark_params sandybridge_cursor_srwm_info = { | ||
3345 | SNB_CURSOR_SR_FIFO, | 3339 | SNB_CURSOR_SR_FIFO, |
3346 | SNB_CURSOR_MAX_SRWM, | 3340 | SNB_CURSOR_MAX_SRWM, |
3347 | SNB_CURSOR_DFT_SRWM, | 3341 | SNB_CURSOR_DFT_SRWM, |
@@ -3369,7 +3363,8 @@ static struct intel_watermark_params sandybridge_cursor_srwm_info = { | |||
3369 | * will occur, and a display engine hang could result. | 3363 | * will occur, and a display engine hang could result. |
3370 | */ | 3364 | */ |
3371 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | 3365 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, |
3372 | struct intel_watermark_params *wm, | 3366 | const struct intel_watermark_params *wm, |
3367 | int fifo_size, | ||
3373 | int pixel_size, | 3368 | int pixel_size, |
3374 | unsigned long latency_ns) | 3369 | unsigned long latency_ns) |
3375 | { | 3370 | { |
@@ -3387,7 +3382,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
3387 | 3382 | ||
3388 | DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required); | 3383 | DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required); |
3389 | 3384 | ||
3390 | wm_size = wm->fifo_size - (entries_required + wm->guard_size); | 3385 | wm_size = fifo_size - (entries_required + wm->guard_size); |
3391 | 3386 | ||
3392 | DRM_DEBUG_KMS("FIFO watermark level: %d\n", wm_size); | 3387 | DRM_DEBUG_KMS("FIFO watermark level: %d\n", wm_size); |
3393 | 3388 | ||
@@ -3560,15 +3555,28 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) | |||
3560 | return size; | 3555 | return size; |
3561 | } | 3556 | } |
3562 | 3557 | ||
3563 | static void pineview_update_wm(struct drm_device *dev, int planea_clock, | 3558 | static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) |
3564 | int planeb_clock, int sr_hdisplay, int unused, | 3559 | { |
3565 | int pixel_size) | 3560 | struct drm_crtc *crtc, *enabled = NULL; |
3561 | |||
3562 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
3563 | if (crtc->enabled && crtc->fb) { | ||
3564 | if (enabled) | ||
3565 | return NULL; | ||
3566 | enabled = crtc; | ||
3567 | } | ||
3568 | } | ||
3569 | |||
3570 | return enabled; | ||
3571 | } | ||
3572 | |||
3573 | static void pineview_update_wm(struct drm_device *dev) | ||
3566 | { | 3574 | { |
3567 | struct drm_i915_private *dev_priv = dev->dev_private; | 3575 | struct drm_i915_private *dev_priv = dev->dev_private; |
3576 | struct drm_crtc *crtc; | ||
3568 | const struct cxsr_latency *latency; | 3577 | const struct cxsr_latency *latency; |
3569 | u32 reg; | 3578 | u32 reg; |
3570 | unsigned long wm; | 3579 | unsigned long wm; |
3571 | int sr_clock; | ||
3572 | 3580 | ||
3573 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | 3581 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
3574 | dev_priv->fsb_freq, dev_priv->mem_freq); | 3582 | dev_priv->fsb_freq, dev_priv->mem_freq); |
@@ -3578,11 +3586,14 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3578 | return; | 3586 | return; |
3579 | } | 3587 | } |
3580 | 3588 | ||
3581 | if (!planea_clock || !planeb_clock) { | 3589 | crtc = single_enabled_crtc(dev); |
3582 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 3590 | if (crtc) { |
3591 | int clock = crtc->mode.clock; | ||
3592 | int pixel_size = crtc->fb->bits_per_pixel / 8; | ||
3583 | 3593 | ||
3584 | /* Display SR */ | 3594 | /* Display SR */ |
3585 | wm = intel_calculate_wm(sr_clock, &pineview_display_wm, | 3595 | wm = intel_calculate_wm(clock, &pineview_display_wm, |
3596 | pineview_display_wm.fifo_size, | ||
3586 | pixel_size, latency->display_sr); | 3597 | pixel_size, latency->display_sr); |
3587 | reg = I915_READ(DSPFW1); | 3598 | reg = I915_READ(DSPFW1); |
3588 | reg &= ~DSPFW_SR_MASK; | 3599 | reg &= ~DSPFW_SR_MASK; |
@@ -3591,7 +3602,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3591 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); | 3602 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); |
3592 | 3603 | ||
3593 | /* cursor SR */ | 3604 | /* cursor SR */ |
3594 | wm = intel_calculate_wm(sr_clock, &pineview_cursor_wm, | 3605 | wm = intel_calculate_wm(clock, &pineview_cursor_wm, |
3606 | pineview_display_wm.fifo_size, | ||
3595 | pixel_size, latency->cursor_sr); | 3607 | pixel_size, latency->cursor_sr); |
3596 | reg = I915_READ(DSPFW3); | 3608 | reg = I915_READ(DSPFW3); |
3597 | reg &= ~DSPFW_CURSOR_SR_MASK; | 3609 | reg &= ~DSPFW_CURSOR_SR_MASK; |
@@ -3599,7 +3611,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3599 | I915_WRITE(DSPFW3, reg); | 3611 | I915_WRITE(DSPFW3, reg); |
3600 | 3612 | ||
3601 | /* Display HPLL off SR */ | 3613 | /* Display HPLL off SR */ |
3602 | wm = intel_calculate_wm(sr_clock, &pineview_display_hplloff_wm, | 3614 | wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, |
3615 | pineview_display_hplloff_wm.fifo_size, | ||
3603 | pixel_size, latency->display_hpll_disable); | 3616 | pixel_size, latency->display_hpll_disable); |
3604 | reg = I915_READ(DSPFW3); | 3617 | reg = I915_READ(DSPFW3); |
3605 | reg &= ~DSPFW_HPLL_SR_MASK; | 3618 | reg &= ~DSPFW_HPLL_SR_MASK; |
@@ -3607,7 +3620,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3607 | I915_WRITE(DSPFW3, reg); | 3620 | I915_WRITE(DSPFW3, reg); |
3608 | 3621 | ||
3609 | /* cursor HPLL off SR */ | 3622 | /* cursor HPLL off SR */ |
3610 | wm = intel_calculate_wm(sr_clock, &pineview_cursor_hplloff_wm, | 3623 | wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, |
3624 | pineview_display_hplloff_wm.fifo_size, | ||
3611 | pixel_size, latency->cursor_hpll_disable); | 3625 | pixel_size, latency->cursor_hpll_disable); |
3612 | reg = I915_READ(DSPFW3); | 3626 | reg = I915_READ(DSPFW3); |
3613 | reg &= ~DSPFW_HPLL_CURSOR_MASK; | 3627 | reg &= ~DSPFW_HPLL_CURSOR_MASK; |
@@ -3709,12 +3723,14 @@ static bool g4x_check_srwm(struct drm_device *dev, | |||
3709 | } | 3723 | } |
3710 | 3724 | ||
3711 | static bool g4x_compute_srwm(struct drm_device *dev, | 3725 | static bool g4x_compute_srwm(struct drm_device *dev, |
3712 | int hdisplay, int htotal, | 3726 | int plane, |
3713 | int pixel_size, int clock, int latency_ns, | 3727 | int latency_ns, |
3714 | const struct intel_watermark_params *display, | 3728 | const struct intel_watermark_params *display, |
3715 | const struct intel_watermark_params *cursor, | 3729 | const struct intel_watermark_params *cursor, |
3716 | int *display_wm, int *cursor_wm) | 3730 | int *display_wm, int *cursor_wm) |
3717 | { | 3731 | { |
3732 | struct drm_crtc *crtc; | ||
3733 | int hdisplay, htotal, pixel_size, clock; | ||
3718 | unsigned long line_time_us; | 3734 | unsigned long line_time_us; |
3719 | int line_count, line_size; | 3735 | int line_count, line_size; |
3720 | int small, large; | 3736 | int small, large; |
@@ -3725,6 +3741,12 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
3725 | return false; | 3741 | return false; |
3726 | } | 3742 | } |
3727 | 3743 | ||
3744 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
3745 | hdisplay = crtc->mode.hdisplay; | ||
3746 | htotal = crtc->mode.htotal; | ||
3747 | clock = crtc->mode.clock; | ||
3748 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
3749 | |||
3728 | line_time_us = (htotal * 1000) / clock; | 3750 | line_time_us = (htotal * 1000) / clock; |
3729 | line_count = (latency_ns / line_time_us + 1000) / 1000; | 3751 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
3730 | line_size = hdisplay * pixel_size; | 3752 | line_size = hdisplay * pixel_size; |
@@ -3746,32 +3768,35 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
3746 | display, cursor); | 3768 | display, cursor); |
3747 | } | 3769 | } |
3748 | 3770 | ||
3749 | static void g4x_update_wm(struct drm_device *dev, | 3771 | static inline bool single_plane_enabled(unsigned int mask) |
3750 | int planea_clock, int planeb_clock, | 3772 | { |
3751 | int hdisplay, int htotal, int pixel_size) | 3773 | return mask && (mask & -mask) == 0; |
3774 | } | ||
3775 | |||
3776 | static void g4x_update_wm(struct drm_device *dev) | ||
3752 | { | 3777 | { |
3753 | static const int sr_latency_ns = 12000; | 3778 | static const int sr_latency_ns = 12000; |
3754 | struct drm_i915_private *dev_priv = dev->dev_private; | 3779 | struct drm_i915_private *dev_priv = dev->dev_private; |
3755 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | 3780 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
3756 | int enabled = 0, plane_sr, cursor_sr, clock; | 3781 | int plane_sr, cursor_sr; |
3782 | unsigned int enabled = 0; | ||
3757 | 3783 | ||
3758 | if (g4x_compute_wm0(dev, 0, | 3784 | if (g4x_compute_wm0(dev, 0, |
3759 | &g4x_wm_info, latency_ns, | 3785 | &g4x_wm_info, latency_ns, |
3760 | &g4x_cursor_wm_info, latency_ns, | 3786 | &g4x_cursor_wm_info, latency_ns, |
3761 | &planea_wm, &cursora_wm)) | 3787 | &planea_wm, &cursora_wm)) |
3762 | enabled++; | 3788 | enabled |= 1; |
3763 | 3789 | ||
3764 | if (g4x_compute_wm0(dev, 1, | 3790 | if (g4x_compute_wm0(dev, 1, |
3765 | &g4x_wm_info, latency_ns, | 3791 | &g4x_wm_info, latency_ns, |
3766 | &g4x_cursor_wm_info, latency_ns, | 3792 | &g4x_cursor_wm_info, latency_ns, |
3767 | &planeb_wm, &cursorb_wm)) | 3793 | &planeb_wm, &cursorb_wm)) |
3768 | enabled++; | 3794 | enabled |= 2; |
3769 | 3795 | ||
3770 | plane_sr = cursor_sr = 0; | 3796 | plane_sr = cursor_sr = 0; |
3771 | clock = planea_clock ? planea_clock : planeb_clock; | 3797 | if (single_plane_enabled(enabled) && |
3772 | if (enabled == 1 && | 3798 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
3773 | g4x_compute_srwm(dev, hdisplay, htotal, pixel_size, | 3799 | sr_latency_ns, |
3774 | clock, sr_latency_ns, | ||
3775 | &g4x_wm_info, | 3800 | &g4x_wm_info, |
3776 | &g4x_cursor_wm_info, | 3801 | &g4x_cursor_wm_info, |
3777 | &plane_sr, &cursor_sr)) | 3802 | &plane_sr, &cursor_sr)) |
@@ -3799,39 +3824,43 @@ static void g4x_update_wm(struct drm_device *dev, | |||
3799 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | 3824 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
3800 | } | 3825 | } |
3801 | 3826 | ||
3802 | static void i965_update_wm(struct drm_device *dev, int planea_clock, | 3827 | static void i965_update_wm(struct drm_device *dev) |
3803 | int planeb_clock, int sr_hdisplay, int sr_htotal, | ||
3804 | int pixel_size) | ||
3805 | { | 3828 | { |
3806 | struct drm_i915_private *dev_priv = dev->dev_private; | 3829 | struct drm_i915_private *dev_priv = dev->dev_private; |
3807 | unsigned long line_time_us; | 3830 | struct drm_crtc *crtc; |
3808 | int sr_clock, sr_entries, srwm = 1; | 3831 | int srwm = 1; |
3809 | int cursor_sr = 16; | 3832 | int cursor_sr = 16; |
3810 | 3833 | ||
3811 | /* Calc sr entries for one plane configs */ | 3834 | /* Calc sr entries for one plane configs */ |
3812 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | 3835 | crtc = single_enabled_crtc(dev); |
3836 | if (crtc) { | ||
3813 | /* self-refresh has much higher latency */ | 3837 | /* self-refresh has much higher latency */ |
3814 | static const int sr_latency_ns = 12000; | 3838 | static const int sr_latency_ns = 12000; |
3839 | int clock = crtc->mode.clock; | ||
3840 | int htotal = crtc->mode.htotal; | ||
3841 | int hdisplay = crtc->mode.hdisplay; | ||
3842 | int pixel_size = crtc->fb->bits_per_pixel / 8; | ||
3843 | unsigned long line_time_us; | ||
3844 | int entries; | ||
3815 | 3845 | ||
3816 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 3846 | line_time_us = ((htotal * 1000) / clock); |
3817 | line_time_us = ((sr_htotal * 1000) / sr_clock); | ||
3818 | 3847 | ||
3819 | /* Use ns/us then divide to preserve precision */ | 3848 | /* Use ns/us then divide to preserve precision */ |
3820 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 3849 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3821 | pixel_size * sr_hdisplay; | 3850 | pixel_size * hdisplay; |
3822 | sr_entries = DIV_ROUND_UP(sr_entries, I915_FIFO_LINE_SIZE); | 3851 | entries = DIV_ROUND_UP(entries, I915_FIFO_LINE_SIZE); |
3823 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | 3852 | DRM_DEBUG("self-refresh entries: %d\n", entries); |
3824 | srwm = I965_FIFO_SIZE - sr_entries; | 3853 | srwm = I965_FIFO_SIZE - entries; |
3825 | if (srwm < 0) | 3854 | if (srwm < 0) |
3826 | srwm = 1; | 3855 | srwm = 1; |
3827 | srwm &= 0x1ff; | 3856 | srwm &= 0x1ff; |
3828 | 3857 | ||
3829 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 3858 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3830 | pixel_size * 64; | 3859 | pixel_size * 64; |
3831 | sr_entries = DIV_ROUND_UP(sr_entries, | 3860 | entries = DIV_ROUND_UP(entries, |
3832 | i965_cursor_wm_info.cacheline_size); | 3861 | i965_cursor_wm_info.cacheline_size); |
3833 | cursor_sr = i965_cursor_wm_info.fifo_size - | 3862 | cursor_sr = i965_cursor_wm_info.fifo_size - |
3834 | (sr_entries + i965_cursor_wm_info.guard_size); | 3863 | (entries + i965_cursor_wm_info.guard_size); |
3835 | 3864 | ||
3836 | if (cursor_sr > i965_cursor_wm_info.max_wm) | 3865 | if (cursor_sr > i965_cursor_wm_info.max_wm) |
3837 | cursor_sr = i965_cursor_wm_info.max_wm; | 3866 | cursor_sr = i965_cursor_wm_info.max_wm; |
@@ -3859,39 +3888,50 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, | |||
3859 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | 3888 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
3860 | } | 3889 | } |
3861 | 3890 | ||
3862 | static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | 3891 | static void i9xx_update_wm(struct drm_device *dev) |
3863 | int planeb_clock, int sr_hdisplay, int sr_htotal, | ||
3864 | int pixel_size) | ||
3865 | { | 3892 | { |
3866 | struct drm_i915_private *dev_priv = dev->dev_private; | 3893 | struct drm_i915_private *dev_priv = dev->dev_private; |
3894 | const struct intel_watermark_params *wm_info; | ||
3867 | uint32_t fwater_lo; | 3895 | uint32_t fwater_lo; |
3868 | uint32_t fwater_hi; | 3896 | uint32_t fwater_hi; |
3869 | int total_size, cacheline_size, cwm, srwm = 1; | 3897 | int cwm, srwm = 1; |
3898 | int fifo_size; | ||
3870 | int planea_wm, planeb_wm; | 3899 | int planea_wm, planeb_wm; |
3871 | struct intel_watermark_params planea_params, planeb_params; | 3900 | struct drm_crtc *crtc, *enabled = NULL; |
3872 | unsigned long line_time_us; | ||
3873 | int sr_clock, sr_entries = 0, sr_enabled = 0; | ||
3874 | 3901 | ||
3875 | /* Create copies of the base settings for each pipe */ | 3902 | /* Create copies of the base settings for each pipe */ |
3876 | if (IS_CRESTLINE(dev) || IS_I945GM(dev)) | 3903 | if (IS_CRESTLINE(dev) || IS_I945GM(dev)) |
3877 | planea_params = planeb_params = i945_wm_info; | 3904 | wm_info = &i945_wm_info; |
3878 | else if (!IS_GEN2(dev)) | 3905 | else if (!IS_GEN2(dev)) |
3879 | planea_params = planeb_params = i915_wm_info; | 3906 | wm_info = &i915_wm_info; |
3880 | else | 3907 | else |
3881 | planea_params = planeb_params = i855_wm_info; | 3908 | wm_info = &i855_wm_info; |
3882 | 3909 | ||
3883 | /* Grab a couple of global values before we overwrite them */ | 3910 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
3884 | total_size = planea_params.fifo_size; | 3911 | crtc = intel_get_crtc_for_plane(dev, 0); |
3885 | cacheline_size = planea_params.cacheline_size; | 3912 | if (crtc->enabled && crtc->fb) { |
3886 | 3913 | planea_wm = intel_calculate_wm(crtc->mode.clock, | |
3887 | /* Update per-plane FIFO sizes */ | 3914 | wm_info, fifo_size, |
3888 | planea_params.fifo_size = dev_priv->display.get_fifo_size(dev, 0); | 3915 | crtc->fb->bits_per_pixel / 8, |
3889 | planeb_params.fifo_size = dev_priv->display.get_fifo_size(dev, 1); | 3916 | latency_ns); |
3917 | enabled = crtc; | ||
3918 | } else | ||
3919 | planea_wm = fifo_size - wm_info->guard_size; | ||
3920 | |||
3921 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); | ||
3922 | crtc = intel_get_crtc_for_plane(dev, 1); | ||
3923 | if (crtc->enabled && crtc->fb) { | ||
3924 | planeb_wm = intel_calculate_wm(crtc->mode.clock, | ||
3925 | wm_info, fifo_size, | ||
3926 | crtc->fb->bits_per_pixel / 8, | ||
3927 | latency_ns); | ||
3928 | if (enabled == NULL) | ||
3929 | enabled = crtc; | ||
3930 | else | ||
3931 | enabled = NULL; | ||
3932 | } else | ||
3933 | planeb_wm = fifo_size - wm_info->guard_size; | ||
3890 | 3934 | ||
3891 | planea_wm = intel_calculate_wm(planea_clock, &planea_params, | ||
3892 | pixel_size, latency_ns); | ||
3893 | planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params, | ||
3894 | pixel_size, latency_ns); | ||
3895 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); | 3935 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); |
3896 | 3936 | ||
3897 | /* | 3937 | /* |
@@ -3906,20 +3946,24 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
3906 | I915_WRITE(INSTPM, I915_READ(INSTPM) & ~INSTPM_SELF_EN); | 3946 | I915_WRITE(INSTPM, I915_READ(INSTPM) & ~INSTPM_SELF_EN); |
3907 | 3947 | ||
3908 | /* Calc sr entries for one plane configs */ | 3948 | /* Calc sr entries for one plane configs */ |
3909 | if (HAS_FW_BLC(dev) && sr_hdisplay && | 3949 | if (HAS_FW_BLC(dev) && enabled) { |
3910 | (!planea_clock || !planeb_clock)) { | ||
3911 | /* self-refresh has much higher latency */ | 3950 | /* self-refresh has much higher latency */ |
3912 | static const int sr_latency_ns = 6000; | 3951 | static const int sr_latency_ns = 6000; |
3952 | int clock = enabled->mode.clock; | ||
3953 | int htotal = enabled->mode.htotal; | ||
3954 | int hdisplay = enabled->mode.hdisplay; | ||
3955 | int pixel_size = enabled->fb->bits_per_pixel / 8; | ||
3956 | unsigned long line_time_us; | ||
3957 | int entries; | ||
3913 | 3958 | ||
3914 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 3959 | line_time_us = (htotal * 1000) / clock; |
3915 | line_time_us = ((sr_htotal * 1000) / sr_clock); | ||
3916 | 3960 | ||
3917 | /* Use ns/us then divide to preserve precision */ | 3961 | /* Use ns/us then divide to preserve precision */ |
3918 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 3962 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3919 | pixel_size * sr_hdisplay; | 3963 | pixel_size * hdisplay; |
3920 | sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); | 3964 | entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); |
3921 | DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries); | 3965 | DRM_DEBUG_KMS("self-refresh entries: %d\n", entries); |
3922 | srwm = total_size - sr_entries; | 3966 | srwm = wm_info->fifo_size - entries; |
3923 | if (srwm < 0) | 3967 | if (srwm < 0) |
3924 | srwm = 1; | 3968 | srwm = 1; |
3925 | 3969 | ||
@@ -3928,8 +3972,6 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
3928 | FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); | 3972 | FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); |
3929 | else if (IS_I915GM(dev)) | 3973 | else if (IS_I915GM(dev)) |
3930 | I915_WRITE(FW_BLC_SELF, srwm & 0x3f); | 3974 | I915_WRITE(FW_BLC_SELF, srwm & 0x3f); |
3931 | |||
3932 | sr_enabled = 1; | ||
3933 | } | 3975 | } |
3934 | 3976 | ||
3935 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | 3977 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
@@ -3945,28 +3987,35 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
3945 | I915_WRITE(FW_BLC, fwater_lo); | 3987 | I915_WRITE(FW_BLC, fwater_lo); |
3946 | I915_WRITE(FW_BLC2, fwater_hi); | 3988 | I915_WRITE(FW_BLC2, fwater_hi); |
3947 | 3989 | ||
3948 | if (sr_enabled) { | 3990 | if (HAS_FW_BLC(dev)) { |
3949 | if (IS_I945G(dev) || IS_I945GM(dev)) | 3991 | if (enabled) { |
3950 | I915_WRITE(FW_BLC_SELF, | 3992 | if (IS_I945G(dev) || IS_I945GM(dev)) |
3951 | FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); | 3993 | I915_WRITE(FW_BLC_SELF, |
3952 | else if (IS_I915GM(dev)) | 3994 | FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); |
3953 | I915_WRITE(INSTPM, I915_READ(INSTPM) | INSTPM_SELF_EN); | 3995 | else if (IS_I915GM(dev)) |
3954 | DRM_DEBUG_KMS("memory self refresh enabled\n"); | 3996 | I915_WRITE(INSTPM, I915_READ(INSTPM) | INSTPM_SELF_EN); |
3955 | } else | 3997 | DRM_DEBUG_KMS("memory self refresh enabled\n"); |
3956 | DRM_DEBUG_KMS("memory self refresh disabled\n"); | 3998 | } else |
3999 | DRM_DEBUG_KMS("memory self refresh disabled\n"); | ||
4000 | } | ||
3957 | } | 4001 | } |
3958 | 4002 | ||
3959 | static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, | 4003 | static void i830_update_wm(struct drm_device *dev) |
3960 | int unused2, int unused3, int pixel_size) | ||
3961 | { | 4004 | { |
3962 | struct drm_i915_private *dev_priv = dev->dev_private; | 4005 | struct drm_i915_private *dev_priv = dev->dev_private; |
3963 | uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; | 4006 | struct drm_crtc *crtc; |
4007 | uint32_t fwater_lo; | ||
3964 | int planea_wm; | 4008 | int planea_wm; |
3965 | 4009 | ||
3966 | i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0); | 4010 | crtc = single_enabled_crtc(dev); |
4011 | if (crtc == NULL) | ||
4012 | return; | ||
3967 | 4013 | ||
3968 | planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info, | 4014 | planea_wm = intel_calculate_wm(crtc->mode.clock, &i830_wm_info, |
3969 | pixel_size, latency_ns); | 4015 | dev_priv->display.get_fifo_size(dev, 0), |
4016 | crtc->fb->bits_per_pixel / 8, | ||
4017 | latency_ns); | ||
4018 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; | ||
3970 | fwater_lo |= (3<<8) | planea_wm; | 4019 | fwater_lo |= (3<<8) | planea_wm; |
3971 | 4020 | ||
3972 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); | 4021 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); |
@@ -4075,15 +4124,15 @@ static bool ironlake_check_srwm(struct drm_device *dev, int level, | |||
4075 | /* | 4124 | /* |
4076 | * Compute watermark values of WM[1-3], | 4125 | * Compute watermark values of WM[1-3], |
4077 | */ | 4126 | */ |
4078 | static bool ironlake_compute_srwm(struct drm_device *dev, int level, | 4127 | static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, |
4079 | int hdisplay, int htotal, | 4128 | int latency_ns, |
4080 | int pixel_size, int clock, int latency_ns, | ||
4081 | const struct intel_watermark_params *display, | 4129 | const struct intel_watermark_params *display, |
4082 | const struct intel_watermark_params *cursor, | 4130 | const struct intel_watermark_params *cursor, |
4083 | int *fbc_wm, int *display_wm, int *cursor_wm) | 4131 | int *fbc_wm, int *display_wm, int *cursor_wm) |
4084 | { | 4132 | { |
4085 | 4133 | struct drm_crtc *crtc; | |
4086 | unsigned long line_time_us; | 4134 | unsigned long line_time_us; |
4135 | int hdisplay, htotal, pixel_size, clock; | ||
4087 | int line_count, line_size; | 4136 | int line_count, line_size; |
4088 | int small, large; | 4137 | int small, large; |
4089 | int entries; | 4138 | int entries; |
@@ -4093,6 +4142,12 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, | |||
4093 | return false; | 4142 | return false; |
4094 | } | 4143 | } |
4095 | 4144 | ||
4145 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
4146 | hdisplay = crtc->mode.hdisplay; | ||
4147 | htotal = crtc->mode.htotal; | ||
4148 | clock = crtc->mode.clock; | ||
4149 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
4150 | |||
4096 | line_time_us = (htotal * 1000) / clock; | 4151 | line_time_us = (htotal * 1000) / clock; |
4097 | line_count = (latency_ns / line_time_us + 1000) / 1000; | 4152 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
4098 | line_size = hdisplay * pixel_size; | 4153 | line_size = hdisplay * pixel_size; |
@@ -4120,14 +4175,11 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, | |||
4120 | display, cursor); | 4175 | display, cursor); |
4121 | } | 4176 | } |
4122 | 4177 | ||
4123 | static void ironlake_update_wm(struct drm_device *dev, | 4178 | static void ironlake_update_wm(struct drm_device *dev) |
4124 | int planea_clock, int planeb_clock, | ||
4125 | int hdisplay, int htotal, | ||
4126 | int pixel_size) | ||
4127 | { | 4179 | { |
4128 | struct drm_i915_private *dev_priv = dev->dev_private; | 4180 | struct drm_i915_private *dev_priv = dev->dev_private; |
4129 | int fbc_wm, plane_wm, cursor_wm, enabled; | 4181 | int fbc_wm, plane_wm, cursor_wm; |
4130 | int clock; | 4182 | unsigned int enabled; |
4131 | 4183 | ||
4132 | enabled = 0; | 4184 | enabled = 0; |
4133 | if (ironlake_compute_wm0(dev, 0, | 4185 | if (ironlake_compute_wm0(dev, 0, |
@@ -4141,7 +4193,7 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
4141 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | 4193 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
4142 | " plane %d, " "cursor: %d\n", | 4194 | " plane %d, " "cursor: %d\n", |
4143 | plane_wm, cursor_wm); | 4195 | plane_wm, cursor_wm); |
4144 | enabled++; | 4196 | enabled |= 1; |
4145 | } | 4197 | } |
4146 | 4198 | ||
4147 | if (ironlake_compute_wm0(dev, 1, | 4199 | if (ironlake_compute_wm0(dev, 1, |
@@ -4155,7 +4207,7 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
4155 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | 4207 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
4156 | " plane %d, cursor: %d\n", | 4208 | " plane %d, cursor: %d\n", |
4157 | plane_wm, cursor_wm); | 4209 | plane_wm, cursor_wm); |
4158 | enabled++; | 4210 | enabled |= 2; |
4159 | } | 4211 | } |
4160 | 4212 | ||
4161 | /* | 4213 | /* |
@@ -4166,14 +4218,13 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
4166 | I915_WRITE(WM2_LP_ILK, 0); | 4218 | I915_WRITE(WM2_LP_ILK, 0); |
4167 | I915_WRITE(WM1_LP_ILK, 0); | 4219 | I915_WRITE(WM1_LP_ILK, 0); |
4168 | 4220 | ||
4169 | if (enabled != 1) | 4221 | if (!single_plane_enabled(enabled)) |
4170 | return; | 4222 | return; |
4171 | 4223 | enabled = ffs(enabled) - 1; | |
4172 | clock = planea_clock ? planea_clock : planeb_clock; | ||
4173 | 4224 | ||
4174 | /* WM1 */ | 4225 | /* WM1 */ |
4175 | if (!ironlake_compute_srwm(dev, 1, hdisplay, htotal, pixel_size, | 4226 | if (!ironlake_compute_srwm(dev, 1, enabled, |
4176 | clock, ILK_READ_WM1_LATENCY() * 500, | 4227 | ILK_READ_WM1_LATENCY() * 500, |
4177 | &ironlake_display_srwm_info, | 4228 | &ironlake_display_srwm_info, |
4178 | &ironlake_cursor_srwm_info, | 4229 | &ironlake_cursor_srwm_info, |
4179 | &fbc_wm, &plane_wm, &cursor_wm)) | 4230 | &fbc_wm, &plane_wm, &cursor_wm)) |
@@ -4187,8 +4238,8 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
4187 | cursor_wm); | 4238 | cursor_wm); |
4188 | 4239 | ||
4189 | /* WM2 */ | 4240 | /* WM2 */ |
4190 | if (!ironlake_compute_srwm(dev, 2, hdisplay, htotal, pixel_size, | 4241 | if (!ironlake_compute_srwm(dev, 2, enabled, |
4191 | clock, ILK_READ_WM2_LATENCY() * 500, | 4242 | ILK_READ_WM2_LATENCY() * 500, |
4192 | &ironlake_display_srwm_info, | 4243 | &ironlake_display_srwm_info, |
4193 | &ironlake_cursor_srwm_info, | 4244 | &ironlake_cursor_srwm_info, |
4194 | &fbc_wm, &plane_wm, &cursor_wm)) | 4245 | &fbc_wm, &plane_wm, &cursor_wm)) |
@@ -4207,15 +4258,12 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
4207 | */ | 4258 | */ |
4208 | } | 4259 | } |
4209 | 4260 | ||
4210 | static void sandybridge_update_wm(struct drm_device *dev, | 4261 | static void sandybridge_update_wm(struct drm_device *dev) |
4211 | int planea_clock, int planeb_clock, | ||
4212 | int hdisplay, int htotal, | ||
4213 | int pixel_size) | ||
4214 | { | 4262 | { |
4215 | struct drm_i915_private *dev_priv = dev->dev_private; | 4263 | struct drm_i915_private *dev_priv = dev->dev_private; |
4216 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | 4264 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ |
4217 | int fbc_wm, plane_wm, cursor_wm, enabled; | 4265 | int fbc_wm, plane_wm, cursor_wm; |
4218 | int clock; | 4266 | unsigned int enabled; |
4219 | 4267 | ||
4220 | enabled = 0; | 4268 | enabled = 0; |
4221 | if (ironlake_compute_wm0(dev, 0, | 4269 | if (ironlake_compute_wm0(dev, 0, |
@@ -4227,7 +4275,7 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
4227 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | 4275 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
4228 | " plane %d, " "cursor: %d\n", | 4276 | " plane %d, " "cursor: %d\n", |
4229 | plane_wm, cursor_wm); | 4277 | plane_wm, cursor_wm); |
4230 | enabled++; | 4278 | enabled |= 1; |
4231 | } | 4279 | } |
4232 | 4280 | ||
4233 | if (ironlake_compute_wm0(dev, 1, | 4281 | if (ironlake_compute_wm0(dev, 1, |
@@ -4239,7 +4287,7 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
4239 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | 4287 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
4240 | " plane %d, cursor: %d\n", | 4288 | " plane %d, cursor: %d\n", |
4241 | plane_wm, cursor_wm); | 4289 | plane_wm, cursor_wm); |
4242 | enabled++; | 4290 | enabled |= 2; |
4243 | } | 4291 | } |
4244 | 4292 | ||
4245 | /* | 4293 | /* |
@@ -4256,14 +4304,13 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
4256 | I915_WRITE(WM2_LP_ILK, 0); | 4304 | I915_WRITE(WM2_LP_ILK, 0); |
4257 | I915_WRITE(WM1_LP_ILK, 0); | 4305 | I915_WRITE(WM1_LP_ILK, 0); |
4258 | 4306 | ||
4259 | if (enabled != 1) | 4307 | if (!single_plane_enabled(enabled)) |
4260 | return; | 4308 | return; |
4261 | 4309 | enabled = ffs(enabled) - 1; | |
4262 | clock = planea_clock ? planea_clock : planeb_clock; | ||
4263 | 4310 | ||
4264 | /* WM1 */ | 4311 | /* WM1 */ |
4265 | if (!ironlake_compute_srwm(dev, 1, hdisplay, htotal, pixel_size, | 4312 | if (!ironlake_compute_srwm(dev, 1, enabled, |
4266 | clock, SNB_READ_WM1_LATENCY() * 500, | 4313 | SNB_READ_WM1_LATENCY() * 500, |
4267 | &sandybridge_display_srwm_info, | 4314 | &sandybridge_display_srwm_info, |
4268 | &sandybridge_cursor_srwm_info, | 4315 | &sandybridge_cursor_srwm_info, |
4269 | &fbc_wm, &plane_wm, &cursor_wm)) | 4316 | &fbc_wm, &plane_wm, &cursor_wm)) |
@@ -4277,9 +4324,8 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
4277 | cursor_wm); | 4324 | cursor_wm); |
4278 | 4325 | ||
4279 | /* WM2 */ | 4326 | /* WM2 */ |
4280 | if (!ironlake_compute_srwm(dev, 2, | 4327 | if (!ironlake_compute_srwm(dev, 2, enabled, |
4281 | hdisplay, htotal, pixel_size, | 4328 | SNB_READ_WM2_LATENCY() * 500, |
4282 | clock, SNB_READ_WM2_LATENCY() * 500, | ||
4283 | &sandybridge_display_srwm_info, | 4329 | &sandybridge_display_srwm_info, |
4284 | &sandybridge_cursor_srwm_info, | 4330 | &sandybridge_cursor_srwm_info, |
4285 | &fbc_wm, &plane_wm, &cursor_wm)) | 4331 | &fbc_wm, &plane_wm, &cursor_wm)) |
@@ -4293,9 +4339,8 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
4293 | cursor_wm); | 4339 | cursor_wm); |
4294 | 4340 | ||
4295 | /* WM3 */ | 4341 | /* WM3 */ |
4296 | if (!ironlake_compute_srwm(dev, 3, | 4342 | if (!ironlake_compute_srwm(dev, 3, enabled, |
4297 | hdisplay, htotal, pixel_size, | 4343 | SNB_READ_WM3_LATENCY() * 500, |
4298 | clock, SNB_READ_WM3_LATENCY() * 500, | ||
4299 | &sandybridge_display_srwm_info, | 4344 | &sandybridge_display_srwm_info, |
4300 | &sandybridge_cursor_srwm_info, | 4345 | &sandybridge_cursor_srwm_info, |
4301 | &fbc_wm, &plane_wm, &cursor_wm)) | 4346 | &fbc_wm, &plane_wm, &cursor_wm)) |
@@ -4344,43 +4389,9 @@ static void sandybridge_update_wm(struct drm_device *dev, | |||
4344 | static void intel_update_watermarks(struct drm_device *dev) | 4389 | static void intel_update_watermarks(struct drm_device *dev) |
4345 | { | 4390 | { |
4346 | struct drm_i915_private *dev_priv = dev->dev_private; | 4391 | struct drm_i915_private *dev_priv = dev->dev_private; |
4347 | struct drm_crtc *crtc; | ||
4348 | int sr_hdisplay = 0; | ||
4349 | unsigned long planea_clock = 0, planeb_clock = 0; | ||
4350 | int enabled = 0, pixel_size = 0; | ||
4351 | int sr_htotal = 0; | ||
4352 | |||
4353 | if (!dev_priv->display.update_wm) | ||
4354 | return; | ||
4355 | |||
4356 | /* Get the clock config from both planes */ | ||
4357 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
4358 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4359 | if (intel_crtc->active) { | ||
4360 | enabled++; | ||
4361 | if (intel_crtc->plane == 0) { | ||
4362 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", | ||
4363 | intel_crtc->pipe, crtc->mode.clock); | ||
4364 | planea_clock = crtc->mode.clock; | ||
4365 | } else { | ||
4366 | DRM_DEBUG_KMS("plane B (pipe %d) clock: %d\n", | ||
4367 | intel_crtc->pipe, crtc->mode.clock); | ||
4368 | planeb_clock = crtc->mode.clock; | ||
4369 | } | ||
4370 | sr_hdisplay = crtc->mode.hdisplay; | ||
4371 | sr_htotal = crtc->mode.htotal; | ||
4372 | if (crtc->fb) | ||
4373 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
4374 | else | ||
4375 | pixel_size = 4; /* by default */ | ||
4376 | } | ||
4377 | } | ||
4378 | |||
4379 | if (enabled <= 0) | ||
4380 | return; | ||
4381 | 4392 | ||
4382 | dev_priv->display.update_wm(dev, planea_clock, planeb_clock, | 4393 | if (dev_priv->display.update_wm) |
4383 | sr_hdisplay, sr_htotal, pixel_size); | 4394 | dev_priv->display.update_wm(dev); |
4384 | } | 4395 | } |
4385 | 4396 | ||
4386 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) | 4397 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) |