aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorGajanan Bhat <gajanan.bhat@intel.com>2014-08-06 16:28:24 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-08-08 11:43:59 -0400
commit0948c2651413d56c90d7ee9c99d75bef82d4c351 (patch)
treefe34563921c75641f0138f34c43ab5a122ca8038 /drivers/gpu/drm/i915/intel_pm.c
parente2fcdaa9c951c51d558fea2cc020d89b382d702e (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.c87
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
1274static bool vlv_compute_drain_latency(struct drm_device *dev, 1274static 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
1313static void vlv_update_drain_latency(struct drm_crtc *crtc) 1304static 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)