diff options
author | Gajanan Bhat <gajanan.bhat@intel.com> | 2012-03-28 16:39:30 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-03-28 17:55:36 -0400 |
commit | 12a3c0551137425a9678d1b9f0495b625550f092 (patch) | |
tree | 96f0dfa07499e8defc100db3dcc0782bc60a7f7b /drivers | |
parent | fb046853ad66e64c96a2598f3fdd4cf5fbabc0d1 (diff) |
drm/i915: program drain latency regs on ValleyView
This patch adds support for programming drain latency registers of Pondicherry
memory arbiter of Valleyview.
v2: clarify function names (Daniel)
fix summary typo (Daniel)
v3: add parens (Ben)
make drain function return bool (Ben)
Acked-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com>
Reviewed-by: Shobhit Kumar <shobhit.kumar@intel.com>
Reviewed-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com>
Reviewed-by: Jesse Barnes <jesse.barnes@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 77 |
2 files changed, 93 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 58914b4f5357..2f6576d7ba20 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -2555,6 +2555,22 @@ | |||
2555 | #define DSPFW_HPLL_CURSOR_MASK (0x3f<<16) | 2555 | #define DSPFW_HPLL_CURSOR_MASK (0x3f<<16) |
2556 | #define DSPFW_HPLL_SR_MASK (0x1ff) | 2556 | #define DSPFW_HPLL_SR_MASK (0x1ff) |
2557 | 2557 | ||
2558 | /* drain latency register values*/ | ||
2559 | #define DRAIN_LATENCY_PRECISION_32 32 | ||
2560 | #define DRAIN_LATENCY_PRECISION_16 16 | ||
2561 | #define VLV_DDL1 0x70050 | ||
2562 | #define DDL_CURSORA_PRECISION_32 (1<<31) | ||
2563 | #define DDL_CURSORA_PRECISION_16 (0<<31) | ||
2564 | #define DDL_CURSORA_SHIFT 24 | ||
2565 | #define DDL_PLANEA_PRECISION_32 (1<<7) | ||
2566 | #define DDL_PLANEA_PRECISION_16 (0<<7) | ||
2567 | #define VLV_DDL2 0x70054 | ||
2568 | #define DDL_CURSORB_PRECISION_32 (1<<31) | ||
2569 | #define DDL_CURSORB_PRECISION_16 (0<<31) | ||
2570 | #define DDL_CURSORB_SHIFT 24 | ||
2571 | #define DDL_PLANEB_PRECISION_32 (1<<7) | ||
2572 | #define DDL_PLANEB_PRECISION_16 (0<<7) | ||
2573 | |||
2558 | /* FIFO watermark sizes etc */ | 2574 | /* FIFO watermark sizes etc */ |
2559 | #define G4X_FIFO_LINE_SIZE 64 | 2575 | #define G4X_FIFO_LINE_SIZE 64 |
2560 | #define I915_FIFO_LINE_SIZE 64 | 2576 | #define I915_FIFO_LINE_SIZE 64 |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2af082db744c..6cd5744c1d9a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4235,6 +4235,81 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
4235 | display, cursor); | 4235 | display, cursor); |
4236 | } | 4236 | } |
4237 | 4237 | ||
4238 | static bool vlv_compute_drain_latency(struct drm_device *dev, | ||
4239 | int plane, | ||
4240 | int *plane_prec_mult, | ||
4241 | int *plane_dl, | ||
4242 | int *cursor_prec_mult, | ||
4243 | int *cursor_dl) | ||
4244 | { | ||
4245 | struct drm_crtc *crtc; | ||
4246 | int clock, pixel_size; | ||
4247 | int entries; | ||
4248 | |||
4249 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
4250 | if (crtc->fb == NULL || !crtc->enabled) | ||
4251 | return false; | ||
4252 | |||
4253 | clock = crtc->mode.clock; /* VESA DOT Clock */ | ||
4254 | pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */ | ||
4255 | |||
4256 | entries = (clock / 1000) * pixel_size; | ||
4257 | *plane_prec_mult = (entries > 256) ? | ||
4258 | DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_16; | ||
4259 | *plane_dl = (64 * (*plane_prec_mult) * 4) / ((clock / 1000) * | ||
4260 | pixel_size); | ||
4261 | |||
4262 | entries = (clock / 1000) * 4; /* BPP is always 4 for cursor */ | ||
4263 | *cursor_prec_mult = (entries > 256) ? | ||
4264 | DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_16; | ||
4265 | *cursor_dl = (64 * (*cursor_prec_mult) * 4) / ((clock / 1000) * 4); | ||
4266 | |||
4267 | return true; | ||
4268 | } | ||
4269 | |||
4270 | /* | ||
4271 | * Update drain latency registers of memory arbiter | ||
4272 | * | ||
4273 | * Valleyview SoC has a new memory arbiter and needs drain latency registers | ||
4274 | * to be programmed. Each plane has a drain latency multiplier and a drain | ||
4275 | * latency value. | ||
4276 | */ | ||
4277 | |||
4278 | static void vlv_update_drain_latency(struct drm_device *dev) | ||
4279 | { | ||
4280 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4281 | int planea_prec, planea_dl, planeb_prec, planeb_dl; | ||
4282 | int cursora_prec, cursora_dl, cursorb_prec, cursorb_dl; | ||
4283 | int plane_prec_mult, cursor_prec_mult; /* Precision multiplier is | ||
4284 | either 16 or 32 */ | ||
4285 | |||
4286 | /* For plane A, Cursor A */ | ||
4287 | if (vlv_compute_drain_latency(dev, 0, &plane_prec_mult, &planea_dl, | ||
4288 | &cursor_prec_mult, &cursora_dl)) { | ||
4289 | cursora_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
4290 | DDL_CURSORA_PRECISION_32 : DDL_CURSORA_PRECISION_16; | ||
4291 | planea_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
4292 | DDL_PLANEA_PRECISION_32 : DDL_PLANEA_PRECISION_16; | ||
4293 | |||
4294 | I915_WRITE(VLV_DDL1, cursora_prec | | ||
4295 | (cursora_dl << DDL_CURSORA_SHIFT) | | ||
4296 | planea_prec | planea_dl); | ||
4297 | } | ||
4298 | |||
4299 | /* For plane B, Cursor B */ | ||
4300 | if (vlv_compute_drain_latency(dev, 1, &plane_prec_mult, &planeb_dl, | ||
4301 | &cursor_prec_mult, &cursorb_dl)) { | ||
4302 | cursorb_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
4303 | DDL_CURSORB_PRECISION_32 : DDL_CURSORB_PRECISION_16; | ||
4304 | planeb_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
4305 | DDL_PLANEB_PRECISION_32 : DDL_PLANEB_PRECISION_16; | ||
4306 | |||
4307 | I915_WRITE(VLV_DDL2, cursorb_prec | | ||
4308 | (cursorb_dl << DDL_CURSORB_SHIFT) | | ||
4309 | planeb_prec | planeb_dl); | ||
4310 | } | ||
4311 | } | ||
4312 | |||
4238 | #define single_plane_enabled(mask) is_power_of_2(mask) | 4313 | #define single_plane_enabled(mask) is_power_of_2(mask) |
4239 | 4314 | ||
4240 | static void valleyview_update_wm(struct drm_device *dev) | 4315 | static void valleyview_update_wm(struct drm_device *dev) |
@@ -4245,6 +4320,8 @@ static void valleyview_update_wm(struct drm_device *dev) | |||
4245 | int plane_sr, cursor_sr; | 4320 | int plane_sr, cursor_sr; |
4246 | unsigned int enabled = 0; | 4321 | unsigned int enabled = 0; |
4247 | 4322 | ||
4323 | vlv_update_drain_latency(dev); | ||
4324 | |||
4248 | if (g4x_compute_wm0(dev, 0, | 4325 | if (g4x_compute_wm0(dev, 0, |
4249 | &valleyview_wm_info, latency_ns, | 4326 | &valleyview_wm_info, latency_ns, |
4250 | &valleyview_cursor_wm_info, latency_ns, | 4327 | &valleyview_cursor_wm_info, latency_ns, |