diff options
author | Gajanan Bhat <gajanan.bhat@intel.com> | 2014-08-06 16:28:24 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-08-08 11:43:59 -0400 |
commit | 0948c2651413d56c90d7ee9c99d75bef82d4c351 (patch) | |
tree | fe34563921c75641f0138f34c43ab5a122ca8038 /drivers/gpu/drm/i915/intel_pm.c | |
parent | e2fcdaa9c951c51d558fea2cc020d89b382d702e (diff) |
drm/i915: Generalize drain latency computation
Modify drain latency computation to use it for any plane. Same function can be
used for primary, cursor and sprite planes.
v2: Adressed review comments by Imre and Ville.
- Moved clock round up in separate patch
- Added WARN check for clock and pixel size
- Simplified bit masking
- Use cursor_base instead of reg read
v3: Changed to bitwise shorthand operator for plane_dl assignment.
Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 42bb329b2d05..de27439636e8 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -1271,33 +1271,24 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
1271 | display, cursor); | 1271 | display, cursor); |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | static bool vlv_compute_drain_latency(struct drm_device *dev, | 1274 | static bool vlv_compute_drain_latency(struct drm_crtc *crtc, |
1275 | int plane, | 1275 | int pixel_size, |
1276 | int *plane_prec_mult, | 1276 | int *prec_mult, |
1277 | int *plane_dl, | 1277 | int *drain_latency) |
1278 | int *cursor_prec_mult, | ||
1279 | int *cursor_dl) | ||
1280 | { | 1278 | { |
1281 | struct drm_crtc *crtc; | ||
1282 | int clock, pixel_size; | ||
1283 | int entries; | 1279 | int entries; |
1280 | int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; | ||
1284 | 1281 | ||
1285 | crtc = intel_get_crtc_for_plane(dev, plane); | 1282 | if (WARN(clock == 0, "Pixel clock is zero!\n")) |
1286 | if (!intel_crtc_active(crtc)) | ||
1287 | return false; | 1283 | return false; |
1288 | 1284 | ||
1289 | clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; | 1285 | if (WARN(pixel_size == 0, "Pixel size is zero!\n")) |
1290 | pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ | 1286 | return false; |
1291 | 1287 | ||
1292 | entries = (clock / 1000) * pixel_size; | 1288 | entries = (clock / 1000) * pixel_size; |
1293 | *plane_prec_mult = (entries > 128) ? | 1289 | *prec_mult = (entries > 128) ? DRAIN_LATENCY_PRECISION_64 : |
1294 | DRAIN_LATENCY_PRECISION_64 : DRAIN_LATENCY_PRECISION_32; | 1290 | DRAIN_LATENCY_PRECISION_32; |
1295 | *plane_dl = (64 * (*plane_prec_mult) * 4) / entries; | 1291 | *drain_latency = (64 * (*prec_mult) * 4) / entries; |
1296 | |||
1297 | entries = (clock / 1000) * 4; /* BPP is always 4 for cursor */ | ||
1298 | *cursor_prec_mult = (entries > 128) ? | ||
1299 | DRAIN_LATENCY_PRECISION_64 : DRAIN_LATENCY_PRECISION_32; | ||
1300 | *cursor_dl = (64 * (*cursor_prec_mult) * 4) / entries; | ||
1301 | 1292 | ||
1302 | return true; | 1293 | return true; |
1303 | } | 1294 | } |
@@ -1312,24 +1303,46 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, | |||
1312 | 1303 | ||
1313 | static void vlv_update_drain_latency(struct drm_crtc *crtc) | 1304 | static void vlv_update_drain_latency(struct drm_crtc *crtc) |
1314 | { | 1305 | { |
1315 | struct drm_device *dev = crtc->dev; | 1306 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
1316 | struct drm_i915_private *dev_priv = dev->dev_private; | 1307 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1317 | enum pipe pipe = to_intel_crtc(crtc)->pipe; | 1308 | int pixel_size; |
1318 | int plane_prec, plane_dl; | 1309 | int drain_latency; |
1319 | int cursor_prec, cursor_dl; | 1310 | enum pipe pipe = intel_crtc->pipe; |
1320 | int plane_prec_mult, cursor_prec_mult; | 1311 | int plane_prec, prec_mult, plane_dl; |
1321 | 1312 | ||
1322 | if (vlv_compute_drain_latency(dev, pipe, &plane_prec_mult, &plane_dl, | 1313 | plane_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_PLANE_PRECISION_64 | |
1323 | &cursor_prec_mult, &cursor_dl)) { | 1314 | DRAIN_LATENCY_MASK | DDL_CURSOR_PRECISION_64 | |
1324 | cursor_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_64) ? | 1315 | (DRAIN_LATENCY_MASK << DDL_CURSOR_SHIFT)); |
1325 | DDL_CURSOR_PRECISION_64 : DDL_CURSOR_PRECISION_32; | 1316 | |
1326 | plane_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_64) ? | 1317 | if (!intel_crtc_active(crtc)) { |
1327 | DDL_PLANE_PRECISION_64 : DDL_PLANE_PRECISION_32; | 1318 | I915_WRITE(VLV_DDL(pipe), plane_dl); |
1328 | 1319 | return; | |
1329 | I915_WRITE(VLV_DDL(pipe), cursor_prec | | 1320 | } |
1330 | (cursor_dl << DDL_CURSOR_SHIFT) | | 1321 | |
1331 | plane_prec | (plane_dl << DDL_PLANE_SHIFT)); | 1322 | /* Primary plane Drain Latency */ |
1323 | pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ | ||
1324 | if (vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { | ||
1325 | plane_prec = (prec_mult == DRAIN_LATENCY_PRECISION_64) ? | ||
1326 | DDL_PLANE_PRECISION_64 : | ||
1327 | DDL_PLANE_PRECISION_32; | ||
1328 | plane_dl |= plane_prec | drain_latency; | ||
1332 | } | 1329 | } |
1330 | |||
1331 | /* Cursor Drain Latency | ||
1332 | * BPP is always 4 for cursor | ||
1333 | */ | ||
1334 | pixel_size = 4; | ||
1335 | |||
1336 | /* Program cursor DL only if it is enabled */ | ||
1337 | if (intel_crtc->cursor_base && | ||
1338 | vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { | ||
1339 | plane_prec = (prec_mult == DRAIN_LATENCY_PRECISION_64) ? | ||
1340 | DDL_CURSOR_PRECISION_64 : | ||
1341 | DDL_CURSOR_PRECISION_32; | ||
1342 | plane_dl |= plane_prec | (drain_latency << DDL_CURSOR_SHIFT); | ||
1343 | } | ||
1344 | |||
1345 | I915_WRITE(VLV_DDL(pipe), plane_dl); | ||
1333 | } | 1346 | } |
1334 | 1347 | ||
1335 | #define single_plane_enabled(mask) is_power_of_2(mask) | 1348 | #define single_plane_enabled(mask) is_power_of_2(mask) |