diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 818 |
1 files changed, 622 insertions, 196 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 40c12295c0bd..c27b6140bfd1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -309,6 +309,9 @@ static void gen7_enable_fbc(struct drm_crtc *crtc) | |||
309 | 309 | ||
310 | dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN; | 310 | dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN; |
311 | 311 | ||
312 | if (dev_priv->fbc.false_color) | ||
313 | dpfc_ctl |= FBC_CTL_FALSE_COLOR; | ||
314 | |||
312 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); | 315 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); |
313 | 316 | ||
314 | if (IS_IVYBRIDGE(dev)) { | 317 | if (IS_IVYBRIDGE(dev)) { |
@@ -342,6 +345,16 @@ bool intel_fbc_enabled(struct drm_device *dev) | |||
342 | return dev_priv->display.fbc_enabled(dev); | 345 | return dev_priv->display.fbc_enabled(dev); |
343 | } | 346 | } |
344 | 347 | ||
348 | void gen8_fbc_sw_flush(struct drm_device *dev, u32 value) | ||
349 | { | ||
350 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
351 | |||
352 | if (!IS_GEN8(dev)) | ||
353 | return; | ||
354 | |||
355 | I915_WRITE(MSG_FBC_REND_STATE, value); | ||
356 | } | ||
357 | |||
345 | static void intel_fbc_work_fn(struct work_struct *__work) | 358 | static void intel_fbc_work_fn(struct work_struct *__work) |
346 | { | 359 | { |
347 | struct intel_fbc_work *work = | 360 | struct intel_fbc_work *work = |
@@ -578,6 +591,12 @@ void intel_update_fbc(struct drm_device *dev) | |||
578 | DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); | 591 | DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); |
579 | goto out_disable; | 592 | goto out_disable; |
580 | } | 593 | } |
594 | if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) && | ||
595 | to_intel_plane(crtc->primary)->rotation != BIT(DRM_ROTATE_0)) { | ||
596 | if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE)) | ||
597 | DRM_DEBUG_KMS("Rotation unsupported, disabling\n"); | ||
598 | goto out_disable; | ||
599 | } | ||
581 | 600 | ||
582 | /* If the kernel debugger is active, always disable compression */ | 601 | /* If the kernel debugger is active, always disable compression */ |
583 | if (in_dbg_master()) | 602 | if (in_dbg_master()) |
@@ -853,7 +872,7 @@ void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) | |||
853 | * A value of 5us seems to be a good balance; safe for very low end | 872 | * A value of 5us seems to be a good balance; safe for very low end |
854 | * platforms but not overly aggressive on lower latency configs. | 873 | * platforms but not overly aggressive on lower latency configs. |
855 | */ | 874 | */ |
856 | static const int latency_ns = 5000; | 875 | static const int pessimal_latency_ns = 5000; |
857 | 876 | ||
858 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) | 877 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) |
859 | { | 878 | { |
@@ -982,13 +1001,20 @@ static const struct intel_watermark_params i915_wm_info = { | |||
982 | .guard_size = 2, | 1001 | .guard_size = 2, |
983 | .cacheline_size = I915_FIFO_LINE_SIZE, | 1002 | .cacheline_size = I915_FIFO_LINE_SIZE, |
984 | }; | 1003 | }; |
985 | static const struct intel_watermark_params i830_wm_info = { | 1004 | static const struct intel_watermark_params i830_a_wm_info = { |
986 | .fifo_size = I855GM_FIFO_SIZE, | 1005 | .fifo_size = I855GM_FIFO_SIZE, |
987 | .max_wm = I915_MAX_WM, | 1006 | .max_wm = I915_MAX_WM, |
988 | .default_wm = 1, | 1007 | .default_wm = 1, |
989 | .guard_size = 2, | 1008 | .guard_size = 2, |
990 | .cacheline_size = I830_FIFO_LINE_SIZE, | 1009 | .cacheline_size = I830_FIFO_LINE_SIZE, |
991 | }; | 1010 | }; |
1011 | static const struct intel_watermark_params i830_bc_wm_info = { | ||
1012 | .fifo_size = I855GM_FIFO_SIZE, | ||
1013 | .max_wm = I915_MAX_WM/2, | ||
1014 | .default_wm = 1, | ||
1015 | .guard_size = 2, | ||
1016 | .cacheline_size = I830_FIFO_LINE_SIZE, | ||
1017 | }; | ||
992 | static const struct intel_watermark_params i845_wm_info = { | 1018 | static const struct intel_watermark_params i845_wm_info = { |
993 | .fifo_size = I830_FIFO_SIZE, | 1019 | .fifo_size = I830_FIFO_SIZE, |
994 | .max_wm = I915_MAX_WM, | 1020 | .max_wm = I915_MAX_WM, |
@@ -1044,6 +1070,17 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
1044 | wm_size = wm->max_wm; | 1070 | wm_size = wm->max_wm; |
1045 | if (wm_size <= 0) | 1071 | if (wm_size <= 0) |
1046 | wm_size = wm->default_wm; | 1072 | wm_size = wm->default_wm; |
1073 | |||
1074 | /* | ||
1075 | * Bspec seems to indicate that the value shouldn't be lower than | ||
1076 | * 'burst size + 1'. Certainly 830 is quite unhappy with low values. | ||
1077 | * Lets go for 8 which is the burst size since certain platforms | ||
1078 | * already use a hardcoded 8 (which is what the spec says should be | ||
1079 | * done). | ||
1080 | */ | ||
1081 | if (wm_size <= 8) | ||
1082 | wm_size = 8; | ||
1083 | |||
1047 | return wm_size; | 1084 | return wm_size; |
1048 | } | 1085 | } |
1049 | 1086 | ||
@@ -1268,33 +1305,27 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
1268 | display, cursor); | 1305 | display, cursor); |
1269 | } | 1306 | } |
1270 | 1307 | ||
1271 | static bool vlv_compute_drain_latency(struct drm_device *dev, | 1308 | static bool vlv_compute_drain_latency(struct drm_crtc *crtc, |
1272 | int plane, | 1309 | int pixel_size, |
1273 | int *plane_prec_mult, | 1310 | int *prec_mult, |
1274 | int *plane_dl, | 1311 | int *drain_latency) |
1275 | int *cursor_prec_mult, | ||
1276 | int *cursor_dl) | ||
1277 | { | 1312 | { |
1278 | struct drm_crtc *crtc; | ||
1279 | int clock, pixel_size; | ||
1280 | int entries; | 1313 | int entries; |
1314 | int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; | ||
1281 | 1315 | ||
1282 | crtc = intel_get_crtc_for_plane(dev, plane); | 1316 | if (WARN(clock == 0, "Pixel clock is zero!\n")) |
1283 | if (!intel_crtc_active(crtc)) | ||
1284 | return false; | 1317 | return false; |
1285 | 1318 | ||
1286 | clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; | 1319 | if (WARN(pixel_size == 0, "Pixel size is zero!\n")) |
1287 | pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ | 1320 | return false; |
1288 | 1321 | ||
1289 | entries = (clock / 1000) * pixel_size; | 1322 | entries = DIV_ROUND_UP(clock, 1000) * pixel_size; |
1290 | *plane_prec_mult = (entries > 128) ? | 1323 | *prec_mult = (entries > 128) ? DRAIN_LATENCY_PRECISION_64 : |
1291 | DRAIN_LATENCY_PRECISION_64 : DRAIN_LATENCY_PRECISION_32; | 1324 | DRAIN_LATENCY_PRECISION_32; |
1292 | *plane_dl = (64 * (*plane_prec_mult) * 4) / entries; | 1325 | *drain_latency = (64 * (*prec_mult) * 4) / entries; |
1293 | 1326 | ||
1294 | entries = (clock / 1000) * 4; /* BPP is always 4 for cursor */ | 1327 | if (*drain_latency > DRAIN_LATENCY_MASK) |
1295 | *cursor_prec_mult = (entries > 128) ? | 1328 | *drain_latency = DRAIN_LATENCY_MASK; |
1296 | DRAIN_LATENCY_PRECISION_64 : DRAIN_LATENCY_PRECISION_32; | ||
1297 | *cursor_dl = (64 * (*cursor_prec_mult) * 4) / entries; | ||
1298 | 1329 | ||
1299 | return true; | 1330 | return true; |
1300 | } | 1331 | } |
@@ -1307,39 +1338,48 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, | |||
1307 | * latency value. | 1338 | * latency value. |
1308 | */ | 1339 | */ |
1309 | 1340 | ||
1310 | static void vlv_update_drain_latency(struct drm_device *dev) | 1341 | static void vlv_update_drain_latency(struct drm_crtc *crtc) |
1311 | { | 1342 | { |
1312 | struct drm_i915_private *dev_priv = dev->dev_private; | 1343 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
1313 | int planea_prec, planea_dl, planeb_prec, planeb_dl; | 1344 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1314 | int cursora_prec, cursora_dl, cursorb_prec, cursorb_dl; | 1345 | int pixel_size; |
1315 | int plane_prec_mult, cursor_prec_mult; /* Precision multiplier is | 1346 | int drain_latency; |
1316 | either 16 or 32 */ | 1347 | enum pipe pipe = intel_crtc->pipe; |
1348 | int plane_prec, prec_mult, plane_dl; | ||
1349 | |||
1350 | plane_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_PLANE_PRECISION_64 | | ||
1351 | DRAIN_LATENCY_MASK | DDL_CURSOR_PRECISION_64 | | ||
1352 | (DRAIN_LATENCY_MASK << DDL_CURSOR_SHIFT)); | ||
1317 | 1353 | ||
1318 | /* For plane A, Cursor A */ | 1354 | if (!intel_crtc_active(crtc)) { |
1319 | if (vlv_compute_drain_latency(dev, 0, &plane_prec_mult, &planea_dl, | 1355 | I915_WRITE(VLV_DDL(pipe), plane_dl); |
1320 | &cursor_prec_mult, &cursora_dl)) { | 1356 | return; |
1321 | cursora_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | 1357 | } |
1322 | DDL_CURSORA_PRECISION_32 : DDL_CURSORA_PRECISION_64; | ||
1323 | planea_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
1324 | DDL_PLANEA_PRECISION_32 : DDL_PLANEA_PRECISION_64; | ||
1325 | 1358 | ||
1326 | I915_WRITE(VLV_DDL1, cursora_prec | | 1359 | /* Primary plane Drain Latency */ |
1327 | (cursora_dl << DDL_CURSORA_SHIFT) | | 1360 | pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ |
1328 | planea_prec | planea_dl); | 1361 | if (vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { |
1362 | plane_prec = (prec_mult == DRAIN_LATENCY_PRECISION_64) ? | ||
1363 | DDL_PLANE_PRECISION_64 : | ||
1364 | DDL_PLANE_PRECISION_32; | ||
1365 | plane_dl |= plane_prec | drain_latency; | ||
1329 | } | 1366 | } |
1330 | 1367 | ||
1331 | /* For plane B, Cursor B */ | 1368 | /* Cursor Drain Latency |
1332 | if (vlv_compute_drain_latency(dev, 1, &plane_prec_mult, &planeb_dl, | 1369 | * BPP is always 4 for cursor |
1333 | &cursor_prec_mult, &cursorb_dl)) { | 1370 | */ |
1334 | cursorb_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | 1371 | pixel_size = 4; |
1335 | DDL_CURSORB_PRECISION_32 : DDL_CURSORB_PRECISION_64; | ||
1336 | planeb_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
1337 | DDL_PLANEB_PRECISION_32 : DDL_PLANEB_PRECISION_64; | ||
1338 | 1372 | ||
1339 | I915_WRITE(VLV_DDL2, cursorb_prec | | 1373 | /* Program cursor DL only if it is enabled */ |
1340 | (cursorb_dl << DDL_CURSORB_SHIFT) | | 1374 | if (intel_crtc->cursor_base && |
1341 | planeb_prec | planeb_dl); | 1375 | vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { |
1376 | plane_prec = (prec_mult == DRAIN_LATENCY_PRECISION_64) ? | ||
1377 | DDL_CURSOR_PRECISION_64 : | ||
1378 | DDL_CURSOR_PRECISION_32; | ||
1379 | plane_dl |= plane_prec | (drain_latency << DDL_CURSOR_SHIFT); | ||
1342 | } | 1380 | } |
1381 | |||
1382 | I915_WRITE(VLV_DDL(pipe), plane_dl); | ||
1343 | } | 1383 | } |
1344 | 1384 | ||
1345 | #define single_plane_enabled(mask) is_power_of_2(mask) | 1385 | #define single_plane_enabled(mask) is_power_of_2(mask) |
@@ -1355,20 +1395,92 @@ static void valleyview_update_wm(struct drm_crtc *crtc) | |||
1355 | unsigned int enabled = 0; | 1395 | unsigned int enabled = 0; |
1356 | bool cxsr_enabled; | 1396 | bool cxsr_enabled; |
1357 | 1397 | ||
1358 | vlv_update_drain_latency(dev); | 1398 | vlv_update_drain_latency(crtc); |
1399 | |||
1400 | if (g4x_compute_wm0(dev, PIPE_A, | ||
1401 | &valleyview_wm_info, pessimal_latency_ns, | ||
1402 | &valleyview_cursor_wm_info, pessimal_latency_ns, | ||
1403 | &planea_wm, &cursora_wm)) | ||
1404 | enabled |= 1 << PIPE_A; | ||
1405 | |||
1406 | if (g4x_compute_wm0(dev, PIPE_B, | ||
1407 | &valleyview_wm_info, pessimal_latency_ns, | ||
1408 | &valleyview_cursor_wm_info, pessimal_latency_ns, | ||
1409 | &planeb_wm, &cursorb_wm)) | ||
1410 | enabled |= 1 << PIPE_B; | ||
1411 | |||
1412 | if (single_plane_enabled(enabled) && | ||
1413 | g4x_compute_srwm(dev, ffs(enabled) - 1, | ||
1414 | sr_latency_ns, | ||
1415 | &valleyview_wm_info, | ||
1416 | &valleyview_cursor_wm_info, | ||
1417 | &plane_sr, &ignore_cursor_sr) && | ||
1418 | g4x_compute_srwm(dev, ffs(enabled) - 1, | ||
1419 | 2*sr_latency_ns, | ||
1420 | &valleyview_wm_info, | ||
1421 | &valleyview_cursor_wm_info, | ||
1422 | &ignore_plane_sr, &cursor_sr)) { | ||
1423 | cxsr_enabled = true; | ||
1424 | } else { | ||
1425 | cxsr_enabled = false; | ||
1426 | intel_set_memory_cxsr(dev_priv, false); | ||
1427 | plane_sr = cursor_sr = 0; | ||
1428 | } | ||
1429 | |||
1430 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, " | ||
1431 | "B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | ||
1432 | planea_wm, cursora_wm, | ||
1433 | planeb_wm, cursorb_wm, | ||
1434 | plane_sr, cursor_sr); | ||
1435 | |||
1436 | I915_WRITE(DSPFW1, | ||
1437 | (plane_sr << DSPFW_SR_SHIFT) | | ||
1438 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | | ||
1439 | (planeb_wm << DSPFW_PLANEB_SHIFT) | | ||
1440 | (planea_wm << DSPFW_PLANEA_SHIFT)); | ||
1441 | I915_WRITE(DSPFW2, | ||
1442 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | | ||
1443 | (cursora_wm << DSPFW_CURSORA_SHIFT)); | ||
1444 | I915_WRITE(DSPFW3, | ||
1445 | (I915_READ(DSPFW3) & ~DSPFW_CURSOR_SR_MASK) | | ||
1446 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | ||
1447 | |||
1448 | if (cxsr_enabled) | ||
1449 | intel_set_memory_cxsr(dev_priv, true); | ||
1450 | } | ||
1451 | |||
1452 | static void cherryview_update_wm(struct drm_crtc *crtc) | ||
1453 | { | ||
1454 | struct drm_device *dev = crtc->dev; | ||
1455 | static const int sr_latency_ns = 12000; | ||
1456 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1457 | int planea_wm, planeb_wm, planec_wm; | ||
1458 | int cursora_wm, cursorb_wm, cursorc_wm; | ||
1459 | int plane_sr, cursor_sr; | ||
1460 | int ignore_plane_sr, ignore_cursor_sr; | ||
1461 | unsigned int enabled = 0; | ||
1462 | bool cxsr_enabled; | ||
1463 | |||
1464 | vlv_update_drain_latency(crtc); | ||
1359 | 1465 | ||
1360 | if (g4x_compute_wm0(dev, PIPE_A, | 1466 | if (g4x_compute_wm0(dev, PIPE_A, |
1361 | &valleyview_wm_info, latency_ns, | 1467 | &valleyview_wm_info, pessimal_latency_ns, |
1362 | &valleyview_cursor_wm_info, latency_ns, | 1468 | &valleyview_cursor_wm_info, pessimal_latency_ns, |
1363 | &planea_wm, &cursora_wm)) | 1469 | &planea_wm, &cursora_wm)) |
1364 | enabled |= 1 << PIPE_A; | 1470 | enabled |= 1 << PIPE_A; |
1365 | 1471 | ||
1366 | if (g4x_compute_wm0(dev, PIPE_B, | 1472 | if (g4x_compute_wm0(dev, PIPE_B, |
1367 | &valleyview_wm_info, latency_ns, | 1473 | &valleyview_wm_info, pessimal_latency_ns, |
1368 | &valleyview_cursor_wm_info, latency_ns, | 1474 | &valleyview_cursor_wm_info, pessimal_latency_ns, |
1369 | &planeb_wm, &cursorb_wm)) | 1475 | &planeb_wm, &cursorb_wm)) |
1370 | enabled |= 1 << PIPE_B; | 1476 | enabled |= 1 << PIPE_B; |
1371 | 1477 | ||
1478 | if (g4x_compute_wm0(dev, PIPE_C, | ||
1479 | &valleyview_wm_info, pessimal_latency_ns, | ||
1480 | &valleyview_cursor_wm_info, pessimal_latency_ns, | ||
1481 | &planec_wm, &cursorc_wm)) | ||
1482 | enabled |= 1 << PIPE_C; | ||
1483 | |||
1372 | if (single_plane_enabled(enabled) && | 1484 | if (single_plane_enabled(enabled) && |
1373 | g4x_compute_srwm(dev, ffs(enabled) - 1, | 1485 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
1374 | sr_latency_ns, | 1486 | sr_latency_ns, |
@@ -1387,27 +1499,66 @@ static void valleyview_update_wm(struct drm_crtc *crtc) | |||
1387 | plane_sr = cursor_sr = 0; | 1499 | plane_sr = cursor_sr = 0; |
1388 | } | 1500 | } |
1389 | 1501 | ||
1390 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | 1502 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, " |
1503 | "B: plane=%d, cursor=%d, C: plane=%d, cursor=%d, " | ||
1504 | "SR: plane=%d, cursor=%d\n", | ||
1391 | planea_wm, cursora_wm, | 1505 | planea_wm, cursora_wm, |
1392 | planeb_wm, cursorb_wm, | 1506 | planeb_wm, cursorb_wm, |
1507 | planec_wm, cursorc_wm, | ||
1393 | plane_sr, cursor_sr); | 1508 | plane_sr, cursor_sr); |
1394 | 1509 | ||
1395 | I915_WRITE(DSPFW1, | 1510 | I915_WRITE(DSPFW1, |
1396 | (plane_sr << DSPFW_SR_SHIFT) | | 1511 | (plane_sr << DSPFW_SR_SHIFT) | |
1397 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | | 1512 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | |
1398 | (planeb_wm << DSPFW_PLANEB_SHIFT) | | 1513 | (planeb_wm << DSPFW_PLANEB_SHIFT) | |
1399 | planea_wm); | 1514 | (planea_wm << DSPFW_PLANEA_SHIFT)); |
1400 | I915_WRITE(DSPFW2, | 1515 | I915_WRITE(DSPFW2, |
1401 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | | 1516 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | |
1402 | (cursora_wm << DSPFW_CURSORA_SHIFT)); | 1517 | (cursora_wm << DSPFW_CURSORA_SHIFT)); |
1403 | I915_WRITE(DSPFW3, | 1518 | I915_WRITE(DSPFW3, |
1404 | (I915_READ(DSPFW3) & ~DSPFW_CURSOR_SR_MASK) | | 1519 | (I915_READ(DSPFW3) & ~DSPFW_CURSOR_SR_MASK) | |
1405 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | 1520 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
1521 | I915_WRITE(DSPFW9_CHV, | ||
1522 | (I915_READ(DSPFW9_CHV) & ~(DSPFW_PLANEC_MASK | | ||
1523 | DSPFW_CURSORC_MASK)) | | ||
1524 | (planec_wm << DSPFW_PLANEC_SHIFT) | | ||
1525 | (cursorc_wm << DSPFW_CURSORC_SHIFT)); | ||
1406 | 1526 | ||
1407 | if (cxsr_enabled) | 1527 | if (cxsr_enabled) |
1408 | intel_set_memory_cxsr(dev_priv, true); | 1528 | intel_set_memory_cxsr(dev_priv, true); |
1409 | } | 1529 | } |
1410 | 1530 | ||
1531 | static void valleyview_update_sprite_wm(struct drm_plane *plane, | ||
1532 | struct drm_crtc *crtc, | ||
1533 | uint32_t sprite_width, | ||
1534 | uint32_t sprite_height, | ||
1535 | int pixel_size, | ||
1536 | bool enabled, bool scaled) | ||
1537 | { | ||
1538 | struct drm_device *dev = crtc->dev; | ||
1539 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1540 | int pipe = to_intel_plane(plane)->pipe; | ||
1541 | int sprite = to_intel_plane(plane)->plane; | ||
1542 | int drain_latency; | ||
1543 | int plane_prec; | ||
1544 | int sprite_dl; | ||
1545 | int prec_mult; | ||
1546 | |||
1547 | sprite_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_SPRITE_PRECISION_64(sprite) | | ||
1548 | (DRAIN_LATENCY_MASK << DDL_SPRITE_SHIFT(sprite))); | ||
1549 | |||
1550 | if (enabled && vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, | ||
1551 | &drain_latency)) { | ||
1552 | plane_prec = (prec_mult == DRAIN_LATENCY_PRECISION_64) ? | ||
1553 | DDL_SPRITE_PRECISION_64(sprite) : | ||
1554 | DDL_SPRITE_PRECISION_32(sprite); | ||
1555 | sprite_dl |= plane_prec | | ||
1556 | (drain_latency << DDL_SPRITE_SHIFT(sprite)); | ||
1557 | } | ||
1558 | |||
1559 | I915_WRITE(VLV_DDL(pipe), sprite_dl); | ||
1560 | } | ||
1561 | |||
1411 | static void g4x_update_wm(struct drm_crtc *crtc) | 1562 | static void g4x_update_wm(struct drm_crtc *crtc) |
1412 | { | 1563 | { |
1413 | struct drm_device *dev = crtc->dev; | 1564 | struct drm_device *dev = crtc->dev; |
@@ -1419,14 +1570,14 @@ static void g4x_update_wm(struct drm_crtc *crtc) | |||
1419 | bool cxsr_enabled; | 1570 | bool cxsr_enabled; |
1420 | 1571 | ||
1421 | if (g4x_compute_wm0(dev, PIPE_A, | 1572 | if (g4x_compute_wm0(dev, PIPE_A, |
1422 | &g4x_wm_info, latency_ns, | 1573 | &g4x_wm_info, pessimal_latency_ns, |
1423 | &g4x_cursor_wm_info, latency_ns, | 1574 | &g4x_cursor_wm_info, pessimal_latency_ns, |
1424 | &planea_wm, &cursora_wm)) | 1575 | &planea_wm, &cursora_wm)) |
1425 | enabled |= 1 << PIPE_A; | 1576 | enabled |= 1 << PIPE_A; |
1426 | 1577 | ||
1427 | if (g4x_compute_wm0(dev, PIPE_B, | 1578 | if (g4x_compute_wm0(dev, PIPE_B, |
1428 | &g4x_wm_info, latency_ns, | 1579 | &g4x_wm_info, pessimal_latency_ns, |
1429 | &g4x_cursor_wm_info, latency_ns, | 1580 | &g4x_cursor_wm_info, pessimal_latency_ns, |
1430 | &planeb_wm, &cursorb_wm)) | 1581 | &planeb_wm, &cursorb_wm)) |
1431 | enabled |= 1 << PIPE_B; | 1582 | enabled |= 1 << PIPE_B; |
1432 | 1583 | ||
@@ -1443,7 +1594,8 @@ static void g4x_update_wm(struct drm_crtc *crtc) | |||
1443 | plane_sr = cursor_sr = 0; | 1594 | plane_sr = cursor_sr = 0; |
1444 | } | 1595 | } |
1445 | 1596 | ||
1446 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | 1597 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, " |
1598 | "B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | ||
1447 | planea_wm, cursora_wm, | 1599 | planea_wm, cursora_wm, |
1448 | planeb_wm, cursorb_wm, | 1600 | planeb_wm, cursorb_wm, |
1449 | plane_sr, cursor_sr); | 1601 | plane_sr, cursor_sr); |
@@ -1452,7 +1604,7 @@ static void g4x_update_wm(struct drm_crtc *crtc) | |||
1452 | (plane_sr << DSPFW_SR_SHIFT) | | 1604 | (plane_sr << DSPFW_SR_SHIFT) | |
1453 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | | 1605 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | |
1454 | (planeb_wm << DSPFW_PLANEB_SHIFT) | | 1606 | (planeb_wm << DSPFW_PLANEB_SHIFT) | |
1455 | planea_wm); | 1607 | (planea_wm << DSPFW_PLANEA_SHIFT)); |
1456 | I915_WRITE(DSPFW2, | 1608 | I915_WRITE(DSPFW2, |
1457 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | | 1609 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | |
1458 | (cursora_wm << DSPFW_CURSORA_SHIFT)); | 1610 | (cursora_wm << DSPFW_CURSORA_SHIFT)); |
@@ -1526,8 +1678,11 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) | |||
1526 | 1678 | ||
1527 | /* 965 has limitations... */ | 1679 | /* 965 has limitations... */ |
1528 | I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | | 1680 | I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | |
1529 | (8 << 16) | (8 << 8) | (8 << 0)); | 1681 | (8 << DSPFW_CURSORB_SHIFT) | |
1530 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | 1682 | (8 << DSPFW_PLANEB_SHIFT) | |
1683 | (8 << DSPFW_PLANEA_SHIFT)); | ||
1684 | I915_WRITE(DSPFW2, (8 << DSPFW_CURSORA_SHIFT) | | ||
1685 | (8 << DSPFW_PLANEC_SHIFT_OLD)); | ||
1531 | /* update cursor SR watermark */ | 1686 | /* update cursor SR watermark */ |
1532 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | 1687 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
1533 | 1688 | ||
@@ -1552,7 +1707,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
1552 | else if (!IS_GEN2(dev)) | 1707 | else if (!IS_GEN2(dev)) |
1553 | wm_info = &i915_wm_info; | 1708 | wm_info = &i915_wm_info; |
1554 | else | 1709 | else |
1555 | wm_info = &i830_wm_info; | 1710 | wm_info = &i830_a_wm_info; |
1556 | 1711 | ||
1557 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); | 1712 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
1558 | crtc = intel_get_crtc_for_plane(dev, 0); | 1713 | crtc = intel_get_crtc_for_plane(dev, 0); |
@@ -1565,10 +1720,16 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
1565 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; | 1720 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
1566 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, | 1721 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1567 | wm_info, fifo_size, cpp, | 1722 | wm_info, fifo_size, cpp, |
1568 | latency_ns); | 1723 | pessimal_latency_ns); |
1569 | enabled = crtc; | 1724 | enabled = crtc; |
1570 | } else | 1725 | } else { |
1571 | planea_wm = fifo_size - wm_info->guard_size; | 1726 | planea_wm = fifo_size - wm_info->guard_size; |
1727 | if (planea_wm > (long)wm_info->max_wm) | ||
1728 | planea_wm = wm_info->max_wm; | ||
1729 | } | ||
1730 | |||
1731 | if (IS_GEN2(dev)) | ||
1732 | wm_info = &i830_bc_wm_info; | ||
1572 | 1733 | ||
1573 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); | 1734 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); |
1574 | crtc = intel_get_crtc_for_plane(dev, 1); | 1735 | crtc = intel_get_crtc_for_plane(dev, 1); |
@@ -1581,13 +1742,16 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
1581 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; | 1742 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
1582 | planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock, | 1743 | planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1583 | wm_info, fifo_size, cpp, | 1744 | wm_info, fifo_size, cpp, |
1584 | latency_ns); | 1745 | pessimal_latency_ns); |
1585 | if (enabled == NULL) | 1746 | if (enabled == NULL) |
1586 | enabled = crtc; | 1747 | enabled = crtc; |
1587 | else | 1748 | else |
1588 | enabled = NULL; | 1749 | enabled = NULL; |
1589 | } else | 1750 | } else { |
1590 | planeb_wm = fifo_size - wm_info->guard_size; | 1751 | planeb_wm = fifo_size - wm_info->guard_size; |
1752 | if (planeb_wm > (long)wm_info->max_wm) | ||
1753 | planeb_wm = wm_info->max_wm; | ||
1754 | } | ||
1591 | 1755 | ||
1592 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); | 1756 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); |
1593 | 1757 | ||
@@ -1674,7 +1838,7 @@ static void i845_update_wm(struct drm_crtc *unused_crtc) | |||
1674 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, | 1838 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1675 | &i845_wm_info, | 1839 | &i845_wm_info, |
1676 | dev_priv->display.get_fifo_size(dev, 0), | 1840 | dev_priv->display.get_fifo_size(dev, 0), |
1677 | 4, latency_ns); | 1841 | 4, pessimal_latency_ns); |
1678 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; | 1842 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; |
1679 | fwater_lo |= (3<<8) | planea_wm; | 1843 | fwater_lo |= (3<<8) | planea_wm; |
1680 | 1844 | ||
@@ -2527,7 +2691,7 @@ static struct intel_pipe_wm *ilk_find_best_result(struct drm_device *dev, | |||
2527 | #define WM_DIRTY_FBC (1 << 24) | 2691 | #define WM_DIRTY_FBC (1 << 24) |
2528 | #define WM_DIRTY_DDB (1 << 25) | 2692 | #define WM_DIRTY_DDB (1 << 25) |
2529 | 2693 | ||
2530 | static unsigned int ilk_compute_wm_dirty(struct drm_device *dev, | 2694 | static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv, |
2531 | const struct ilk_wm_values *old, | 2695 | const struct ilk_wm_values *old, |
2532 | const struct ilk_wm_values *new) | 2696 | const struct ilk_wm_values *new) |
2533 | { | 2697 | { |
@@ -2535,7 +2699,7 @@ static unsigned int ilk_compute_wm_dirty(struct drm_device *dev, | |||
2535 | enum pipe pipe; | 2699 | enum pipe pipe; |
2536 | int wm_lp; | 2700 | int wm_lp; |
2537 | 2701 | ||
2538 | for_each_pipe(pipe) { | 2702 | for_each_pipe(dev_priv, pipe) { |
2539 | if (old->wm_linetime[pipe] != new->wm_linetime[pipe]) { | 2703 | if (old->wm_linetime[pipe] != new->wm_linetime[pipe]) { |
2540 | dirty |= WM_DIRTY_LINETIME(pipe); | 2704 | dirty |= WM_DIRTY_LINETIME(pipe); |
2541 | /* Must disable LP1+ watermarks too */ | 2705 | /* Must disable LP1+ watermarks too */ |
@@ -2621,7 +2785,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv, | |||
2621 | unsigned int dirty; | 2785 | unsigned int dirty; |
2622 | uint32_t val; | 2786 | uint32_t val; |
2623 | 2787 | ||
2624 | dirty = ilk_compute_wm_dirty(dev, previous, results); | 2788 | dirty = ilk_compute_wm_dirty(dev_priv, previous, results); |
2625 | if (!dirty) | 2789 | if (!dirty) |
2626 | return; | 2790 | return; |
2627 | 2791 | ||
@@ -3327,13 +3491,18 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) | |||
3327 | WARN_ON(val > dev_priv->rps.max_freq_softlimit); | 3491 | WARN_ON(val > dev_priv->rps.max_freq_softlimit); |
3328 | WARN_ON(val < dev_priv->rps.min_freq_softlimit); | 3492 | WARN_ON(val < dev_priv->rps.min_freq_softlimit); |
3329 | 3493 | ||
3330 | DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", | 3494 | if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), |
3331 | vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), | 3495 | "Odd GPU freq value\n")) |
3332 | dev_priv->rps.cur_freq, | 3496 | val &= ~1; |
3333 | vlv_gpu_freq(dev_priv, val), val); | 3497 | |
3498 | if (val != dev_priv->rps.cur_freq) { | ||
3499 | DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", | ||
3500 | vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), | ||
3501 | dev_priv->rps.cur_freq, | ||
3502 | vlv_gpu_freq(dev_priv, val), val); | ||
3334 | 3503 | ||
3335 | if (val != dev_priv->rps.cur_freq) | ||
3336 | vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); | 3504 | vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); |
3505 | } | ||
3337 | 3506 | ||
3338 | I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); | 3507 | I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); |
3339 | 3508 | ||
@@ -3406,8 +3575,14 @@ static void valleyview_disable_rps(struct drm_device *dev) | |||
3406 | { | 3575 | { |
3407 | struct drm_i915_private *dev_priv = dev->dev_private; | 3576 | struct drm_i915_private *dev_priv = dev->dev_private; |
3408 | 3577 | ||
3578 | /* we're doing forcewake before Disabling RC6, | ||
3579 | * This what the BIOS expects when going into suspend */ | ||
3580 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | ||
3581 | |||
3409 | I915_WRITE(GEN6_RC_CONTROL, 0); | 3582 | I915_WRITE(GEN6_RC_CONTROL, 0); |
3410 | 3583 | ||
3584 | gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); | ||
3585 | |||
3411 | gen6_disable_rps_interrupts(dev); | 3586 | gen6_disable_rps_interrupts(dev); |
3412 | } | 3587 | } |
3413 | 3588 | ||
@@ -3598,7 +3773,6 @@ static void gen6_enable_rps(struct drm_device *dev) | |||
3598 | struct drm_i915_private *dev_priv = dev->dev_private; | 3773 | struct drm_i915_private *dev_priv = dev->dev_private; |
3599 | struct intel_engine_cs *ring; | 3774 | struct intel_engine_cs *ring; |
3600 | u32 rp_state_cap; | 3775 | u32 rp_state_cap; |
3601 | u32 gt_perf_status; | ||
3602 | u32 rc6vids, pcu_mbox = 0, rc6_mask = 0; | 3776 | u32 rc6vids, pcu_mbox = 0, rc6_mask = 0; |
3603 | u32 gtfifodbg; | 3777 | u32 gtfifodbg; |
3604 | int rc6_mode; | 3778 | int rc6_mode; |
@@ -3623,7 +3797,6 @@ static void gen6_enable_rps(struct drm_device *dev) | |||
3623 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | 3797 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); |
3624 | 3798 | ||
3625 | rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | 3799 | rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); |
3626 | gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); | ||
3627 | 3800 | ||
3628 | parse_rp_state_cap(dev_priv, rp_state_cap); | 3801 | parse_rp_state_cap(dev_priv, rp_state_cap); |
3629 | 3802 | ||
@@ -3965,11 +4138,27 @@ static void valleyview_cleanup_pctx(struct drm_device *dev) | |||
3965 | static void valleyview_init_gt_powersave(struct drm_device *dev) | 4138 | static void valleyview_init_gt_powersave(struct drm_device *dev) |
3966 | { | 4139 | { |
3967 | struct drm_i915_private *dev_priv = dev->dev_private; | 4140 | struct drm_i915_private *dev_priv = dev->dev_private; |
4141 | u32 val; | ||
3968 | 4142 | ||
3969 | valleyview_setup_pctx(dev); | 4143 | valleyview_setup_pctx(dev); |
3970 | 4144 | ||
3971 | mutex_lock(&dev_priv->rps.hw_lock); | 4145 | mutex_lock(&dev_priv->rps.hw_lock); |
3972 | 4146 | ||
4147 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); | ||
4148 | switch ((val >> 6) & 3) { | ||
4149 | case 0: | ||
4150 | case 1: | ||
4151 | dev_priv->mem_freq = 800; | ||
4152 | break; | ||
4153 | case 2: | ||
4154 | dev_priv->mem_freq = 1066; | ||
4155 | break; | ||
4156 | case 3: | ||
4157 | dev_priv->mem_freq = 1333; | ||
4158 | break; | ||
4159 | } | ||
4160 | DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq); | ||
4161 | |||
3973 | dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv); | 4162 | dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv); |
3974 | dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; | 4163 | dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; |
3975 | DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", | 4164 | DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", |
@@ -4004,11 +4193,38 @@ static void valleyview_init_gt_powersave(struct drm_device *dev) | |||
4004 | static void cherryview_init_gt_powersave(struct drm_device *dev) | 4193 | static void cherryview_init_gt_powersave(struct drm_device *dev) |
4005 | { | 4194 | { |
4006 | struct drm_i915_private *dev_priv = dev->dev_private; | 4195 | struct drm_i915_private *dev_priv = dev->dev_private; |
4196 | u32 val; | ||
4007 | 4197 | ||
4008 | cherryview_setup_pctx(dev); | 4198 | cherryview_setup_pctx(dev); |
4009 | 4199 | ||
4010 | mutex_lock(&dev_priv->rps.hw_lock); | 4200 | mutex_lock(&dev_priv->rps.hw_lock); |
4011 | 4201 | ||
4202 | val = vlv_punit_read(dev_priv, CCK_FUSE_REG); | ||
4203 | switch ((val >> 2) & 0x7) { | ||
4204 | case 0: | ||
4205 | case 1: | ||
4206 | dev_priv->rps.cz_freq = 200; | ||
4207 | dev_priv->mem_freq = 1600; | ||
4208 | break; | ||
4209 | case 2: | ||
4210 | dev_priv->rps.cz_freq = 267; | ||
4211 | dev_priv->mem_freq = 1600; | ||
4212 | break; | ||
4213 | case 3: | ||
4214 | dev_priv->rps.cz_freq = 333; | ||
4215 | dev_priv->mem_freq = 2000; | ||
4216 | break; | ||
4217 | case 4: | ||
4218 | dev_priv->rps.cz_freq = 320; | ||
4219 | dev_priv->mem_freq = 1600; | ||
4220 | break; | ||
4221 | case 5: | ||
4222 | dev_priv->rps.cz_freq = 400; | ||
4223 | dev_priv->mem_freq = 1600; | ||
4224 | break; | ||
4225 | } | ||
4226 | DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq); | ||
4227 | |||
4012 | dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv); | 4228 | dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv); |
4013 | dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; | 4229 | dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; |
4014 | DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", | 4230 | DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", |
@@ -4030,6 +4246,12 @@ static void cherryview_init_gt_powersave(struct drm_device *dev) | |||
4030 | vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq), | 4246 | vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq), |
4031 | dev_priv->rps.min_freq); | 4247 | dev_priv->rps.min_freq); |
4032 | 4248 | ||
4249 | WARN_ONCE((dev_priv->rps.max_freq | | ||
4250 | dev_priv->rps.efficient_freq | | ||
4251 | dev_priv->rps.rp1_freq | | ||
4252 | dev_priv->rps.min_freq) & 1, | ||
4253 | "Odd GPU freq values\n"); | ||
4254 | |||
4033 | /* Preserve min/max settings in case of re-init */ | 4255 | /* Preserve min/max settings in case of re-init */ |
4034 | if (dev_priv->rps.max_freq_softlimit == 0) | 4256 | if (dev_priv->rps.max_freq_softlimit == 0) |
4035 | dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; | 4257 | dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; |
@@ -5088,7 +5310,7 @@ static void g4x_disable_trickle_feed(struct drm_device *dev) | |||
5088 | struct drm_i915_private *dev_priv = dev->dev_private; | 5310 | struct drm_i915_private *dev_priv = dev->dev_private; |
5089 | int pipe; | 5311 | int pipe; |
5090 | 5312 | ||
5091 | for_each_pipe(pipe) { | 5313 | for_each_pipe(dev_priv, pipe) { |
5092 | I915_WRITE(DSPCNTR(pipe), | 5314 | I915_WRITE(DSPCNTR(pipe), |
5093 | I915_READ(DSPCNTR(pipe)) | | 5315 | I915_READ(DSPCNTR(pipe)) | |
5094 | DISPPLANE_TRICKLE_FEED_DISABLE); | 5316 | DISPPLANE_TRICKLE_FEED_DISABLE); |
@@ -5203,7 +5425,7 @@ static void cpt_init_clock_gating(struct drm_device *dev) | |||
5203 | /* The below fixes the weird display corruption, a few pixels shifted | 5425 | /* The below fixes the weird display corruption, a few pixels shifted |
5204 | * downward, on (only) LVDS of some HP laptops with IVY. | 5426 | * downward, on (only) LVDS of some HP laptops with IVY. |
5205 | */ | 5427 | */ |
5206 | for_each_pipe(pipe) { | 5428 | for_each_pipe(dev_priv, pipe) { |
5207 | val = I915_READ(TRANS_CHICKEN2(pipe)); | 5429 | val = I915_READ(TRANS_CHICKEN2(pipe)); |
5208 | val |= TRANS_CHICKEN2_TIMING_OVERRIDE; | 5430 | val |= TRANS_CHICKEN2_TIMING_OVERRIDE; |
5209 | val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; | 5431 | val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; |
@@ -5215,7 +5437,7 @@ static void cpt_init_clock_gating(struct drm_device *dev) | |||
5215 | I915_WRITE(TRANS_CHICKEN2(pipe), val); | 5437 | I915_WRITE(TRANS_CHICKEN2(pipe), val); |
5216 | } | 5438 | } |
5217 | /* WADP0ClockGatingDisable */ | 5439 | /* WADP0ClockGatingDisable */ |
5218 | for_each_pipe(pipe) { | 5440 | for_each_pipe(dev_priv, pipe) { |
5219 | I915_WRITE(TRANS_CHICKEN1(pipe), | 5441 | I915_WRITE(TRANS_CHICKEN1(pipe), |
5220 | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); | 5442 | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); |
5221 | } | 5443 | } |
@@ -5383,7 +5605,7 @@ static void lpt_suspend_hw(struct drm_device *dev) | |||
5383 | } | 5605 | } |
5384 | } | 5606 | } |
5385 | 5607 | ||
5386 | static void gen8_init_clock_gating(struct drm_device *dev) | 5608 | static void broadwell_init_clock_gating(struct drm_device *dev) |
5387 | { | 5609 | { |
5388 | struct drm_i915_private *dev_priv = dev->dev_private; | 5610 | struct drm_i915_private *dev_priv = dev->dev_private; |
5389 | enum pipe pipe; | 5611 | enum pipe pipe; |
@@ -5395,37 +5617,12 @@ static void gen8_init_clock_gating(struct drm_device *dev) | |||
5395 | /* FIXME(BDW): Check all the w/a, some might only apply to | 5617 | /* FIXME(BDW): Check all the w/a, some might only apply to |
5396 | * pre-production hw. */ | 5618 | * pre-production hw. */ |
5397 | 5619 | ||
5398 | /* WaDisablePartialInstShootdown:bdw */ | ||
5399 | I915_WRITE(GEN8_ROW_CHICKEN, | ||
5400 | _MASKED_BIT_ENABLE(PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE)); | ||
5401 | 5620 | ||
5402 | /* WaDisableThreadStallDopClockGating:bdw */ | ||
5403 | /* FIXME: Unclear whether we really need this on production bdw. */ | ||
5404 | I915_WRITE(GEN8_ROW_CHICKEN, | ||
5405 | _MASKED_BIT_ENABLE(STALL_DOP_GATING_DISABLE)); | ||
5406 | |||
5407 | /* | ||
5408 | * This GEN8_CENTROID_PIXEL_OPT_DIS W/A is only needed for | ||
5409 | * pre-production hardware | ||
5410 | */ | ||
5411 | I915_WRITE(HALF_SLICE_CHICKEN3, | ||
5412 | _MASKED_BIT_ENABLE(GEN8_CENTROID_PIXEL_OPT_DIS)); | ||
5413 | I915_WRITE(HALF_SLICE_CHICKEN3, | ||
5414 | _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS)); | ||
5415 | I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_BWGTLB_DISABLE)); | 5621 | I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_BWGTLB_DISABLE)); |
5416 | 5622 | ||
5417 | I915_WRITE(_3D_CHICKEN3, | 5623 | I915_WRITE(_3D_CHICKEN3, |
5418 | _MASKED_BIT_ENABLE(_3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(2))); | 5624 | _MASKED_BIT_ENABLE(_3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(2))); |
5419 | 5625 | ||
5420 | I915_WRITE(COMMON_SLICE_CHICKEN2, | ||
5421 | _MASKED_BIT_ENABLE(GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE)); | ||
5422 | |||
5423 | I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, | ||
5424 | _MASKED_BIT_ENABLE(GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE)); | ||
5425 | |||
5426 | /* WaDisableDopClockGating:bdw May not be needed for production */ | ||
5427 | I915_WRITE(GEN7_ROW_CHICKEN2, | ||
5428 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); | ||
5429 | 5626 | ||
5430 | /* WaSwitchSolVfFArbitrationPriority:bdw */ | 5627 | /* WaSwitchSolVfFArbitrationPriority:bdw */ |
5431 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); | 5628 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); |
@@ -5435,37 +5632,18 @@ static void gen8_init_clock_gating(struct drm_device *dev) | |||
5435 | I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); | 5632 | I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); |
5436 | 5633 | ||
5437 | /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ | 5634 | /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ |
5438 | for_each_pipe(pipe) { | 5635 | for_each_pipe(dev_priv, pipe) { |
5439 | I915_WRITE(CHICKEN_PIPESL_1(pipe), | 5636 | I915_WRITE(CHICKEN_PIPESL_1(pipe), |
5440 | I915_READ(CHICKEN_PIPESL_1(pipe)) | | 5637 | I915_READ(CHICKEN_PIPESL_1(pipe)) | |
5441 | BDW_DPRS_MASK_VBLANK_SRD); | 5638 | BDW_DPRS_MASK_VBLANK_SRD); |
5442 | } | 5639 | } |
5443 | 5640 | ||
5444 | /* Use Force Non-Coherent whenever executing a 3D context. This is a | ||
5445 | * workaround for for a possible hang in the unlikely event a TLB | ||
5446 | * invalidation occurs during a PSD flush. | ||
5447 | */ | ||
5448 | I915_WRITE(HDC_CHICKEN0, | ||
5449 | I915_READ(HDC_CHICKEN0) | | ||
5450 | _MASKED_BIT_ENABLE(HDC_FORCE_NON_COHERENT)); | ||
5451 | |||
5452 | /* WaVSRefCountFullforceMissDisable:bdw */ | 5641 | /* WaVSRefCountFullforceMissDisable:bdw */ |
5453 | /* WaDSRefCountFullforceMissDisable:bdw */ | 5642 | /* WaDSRefCountFullforceMissDisable:bdw */ |
5454 | I915_WRITE(GEN7_FF_THREAD_MODE, | 5643 | I915_WRITE(GEN7_FF_THREAD_MODE, |
5455 | I915_READ(GEN7_FF_THREAD_MODE) & | 5644 | I915_READ(GEN7_FF_THREAD_MODE) & |
5456 | ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME)); | 5645 | ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME)); |
5457 | 5646 | ||
5458 | /* | ||
5459 | * BSpec recommends 8x4 when MSAA is used, | ||
5460 | * however in practice 16x4 seems fastest. | ||
5461 | * | ||
5462 | * Note that PS/WM thread counts depend on the WIZ hashing | ||
5463 | * disable bit, which we don't touch here, but it's good | ||
5464 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | ||
5465 | */ | ||
5466 | I915_WRITE(GEN7_GT_MODE, | ||
5467 | GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4); | ||
5468 | |||
5469 | I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL, | 5647 | I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL, |
5470 | _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); | 5648 | _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); |
5471 | 5649 | ||
@@ -5473,9 +5651,7 @@ static void gen8_init_clock_gating(struct drm_device *dev) | |||
5473 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | | 5651 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
5474 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); | 5652 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
5475 | 5653 | ||
5476 | /* Wa4x4STCOptimizationDisable:bdw */ | 5654 | lpt_init_clock_gating(dev); |
5477 | I915_WRITE(CACHE_MODE_1, | ||
5478 | _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE)); | ||
5479 | } | 5655 | } |
5480 | 5656 | ||
5481 | static void haswell_init_clock_gating(struct drm_device *dev) | 5657 | static void haswell_init_clock_gating(struct drm_device *dev) |
@@ -5631,24 +5807,6 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) | |||
5631 | static void valleyview_init_clock_gating(struct drm_device *dev) | 5807 | static void valleyview_init_clock_gating(struct drm_device *dev) |
5632 | { | 5808 | { |
5633 | struct drm_i915_private *dev_priv = dev->dev_private; | 5809 | struct drm_i915_private *dev_priv = dev->dev_private; |
5634 | u32 val; | ||
5635 | |||
5636 | mutex_lock(&dev_priv->rps.hw_lock); | ||
5637 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); | ||
5638 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
5639 | switch ((val >> 6) & 3) { | ||
5640 | case 0: | ||
5641 | case 1: | ||
5642 | dev_priv->mem_freq = 800; | ||
5643 | break; | ||
5644 | case 2: | ||
5645 | dev_priv->mem_freq = 1066; | ||
5646 | break; | ||
5647 | case 3: | ||
5648 | dev_priv->mem_freq = 1333; | ||
5649 | break; | ||
5650 | } | ||
5651 | DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq); | ||
5652 | 5810 | ||
5653 | I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); | 5811 | I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); |
5654 | 5812 | ||
@@ -5724,48 +5882,11 @@ static void valleyview_init_clock_gating(struct drm_device *dev) | |||
5724 | static void cherryview_init_clock_gating(struct drm_device *dev) | 5882 | static void cherryview_init_clock_gating(struct drm_device *dev) |
5725 | { | 5883 | { |
5726 | struct drm_i915_private *dev_priv = dev->dev_private; | 5884 | struct drm_i915_private *dev_priv = dev->dev_private; |
5727 | u32 val; | ||
5728 | |||
5729 | mutex_lock(&dev_priv->rps.hw_lock); | ||
5730 | val = vlv_punit_read(dev_priv, CCK_FUSE_REG); | ||
5731 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
5732 | switch ((val >> 2) & 0x7) { | ||
5733 | case 0: | ||
5734 | case 1: | ||
5735 | dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_200; | ||
5736 | dev_priv->mem_freq = 1600; | ||
5737 | break; | ||
5738 | case 2: | ||
5739 | dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_267; | ||
5740 | dev_priv->mem_freq = 1600; | ||
5741 | break; | ||
5742 | case 3: | ||
5743 | dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_333; | ||
5744 | dev_priv->mem_freq = 2000; | ||
5745 | break; | ||
5746 | case 4: | ||
5747 | dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_320; | ||
5748 | dev_priv->mem_freq = 1600; | ||
5749 | break; | ||
5750 | case 5: | ||
5751 | dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_400; | ||
5752 | dev_priv->mem_freq = 1600; | ||
5753 | break; | ||
5754 | } | ||
5755 | DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq); | ||
5756 | 5885 | ||
5757 | I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); | 5886 | I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); |
5758 | 5887 | ||
5759 | I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE); | 5888 | I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE); |
5760 | 5889 | ||
5761 | /* WaDisablePartialInstShootdown:chv */ | ||
5762 | I915_WRITE(GEN8_ROW_CHICKEN, | ||
5763 | _MASKED_BIT_ENABLE(PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE)); | ||
5764 | |||
5765 | /* WaDisableThreadStallDopClockGating:chv */ | ||
5766 | I915_WRITE(GEN8_ROW_CHICKEN, | ||
5767 | _MASKED_BIT_ENABLE(STALL_DOP_GATING_DISABLE)); | ||
5768 | |||
5769 | /* WaVSRefCountFullforceMissDisable:chv */ | 5890 | /* WaVSRefCountFullforceMissDisable:chv */ |
5770 | /* WaDSRefCountFullforceMissDisable:chv */ | 5891 | /* WaDSRefCountFullforceMissDisable:chv */ |
5771 | I915_WRITE(GEN7_FF_THREAD_MODE, | 5892 | I915_WRITE(GEN7_FF_THREAD_MODE, |
@@ -5784,10 +5905,6 @@ static void cherryview_init_clock_gating(struct drm_device *dev) | |||
5784 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | | 5905 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
5785 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); | 5906 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
5786 | 5907 | ||
5787 | /* WaDisableSamplerPowerBypass:chv (pre-production hw) */ | ||
5788 | I915_WRITE(HALF_SLICE_CHICKEN3, | ||
5789 | _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS)); | ||
5790 | |||
5791 | /* WaDisableGunitClockGating:chv (pre-production hw) */ | 5908 | /* WaDisableGunitClockGating:chv (pre-production hw) */ |
5792 | I915_WRITE(VLV_GUNIT_CLOCK_GATE, I915_READ(VLV_GUNIT_CLOCK_GATE) | | 5909 | I915_WRITE(VLV_GUNIT_CLOCK_GATE, I915_READ(VLV_GUNIT_CLOCK_GATE) | |
5793 | GINT_DIS); | 5910 | GINT_DIS); |
@@ -5797,8 +5914,6 @@ static void cherryview_init_clock_gating(struct drm_device *dev) | |||
5797 | _MASKED_BIT_ENABLE(GEN8_FF_DOP_CLOCK_GATE_DISABLE)); | 5914 | _MASKED_BIT_ENABLE(GEN8_FF_DOP_CLOCK_GATE_DISABLE)); |
5798 | 5915 | ||
5799 | /* WaDisableDopClockGating:chv (pre-production hw) */ | 5916 | /* WaDisableDopClockGating:chv (pre-production hw) */ |
5800 | I915_WRITE(GEN7_ROW_CHICKEN2, | ||
5801 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); | ||
5802 | I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | | 5917 | I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | |
5803 | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); | 5918 | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); |
5804 | } | 5919 | } |
@@ -5883,6 +5998,9 @@ static void gen3_init_clock_gating(struct drm_device *dev) | |||
5883 | 5998 | ||
5884 | /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ | 5999 | /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ |
5885 | I915_WRITE(MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); | 6000 | I915_WRITE(MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); |
6001 | |||
6002 | I915_WRITE(MI_ARB_STATE, | ||
6003 | _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); | ||
5886 | } | 6004 | } |
5887 | 6005 | ||
5888 | static void i85x_init_clock_gating(struct drm_device *dev) | 6006 | static void i85x_init_clock_gating(struct drm_device *dev) |
@@ -5894,6 +6012,9 @@ static void i85x_init_clock_gating(struct drm_device *dev) | |||
5894 | /* interrupts should cause a wake up from C3 */ | 6012 | /* interrupts should cause a wake up from C3 */ |
5895 | I915_WRITE(MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | | 6013 | I915_WRITE(MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | |
5896 | _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); | 6014 | _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); |
6015 | |||
6016 | I915_WRITE(MEM_MODE, | ||
6017 | _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); | ||
5897 | } | 6018 | } |
5898 | 6019 | ||
5899 | static void i830_init_clock_gating(struct drm_device *dev) | 6020 | static void i830_init_clock_gating(struct drm_device *dev) |
@@ -5901,6 +6022,10 @@ static void i830_init_clock_gating(struct drm_device *dev) | |||
5901 | struct drm_i915_private *dev_priv = dev->dev_private; | 6022 | struct drm_i915_private *dev_priv = dev->dev_private; |
5902 | 6023 | ||
5903 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); | 6024 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); |
6025 | |||
6026 | I915_WRITE(MEM_MODE, | ||
6027 | _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) | | ||
6028 | _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); | ||
5904 | } | 6029 | } |
5905 | 6030 | ||
5906 | void intel_init_clock_gating(struct drm_device *dev) | 6031 | void intel_init_clock_gating(struct drm_device *dev) |
@@ -6203,6 +6328,8 @@ static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, | |||
6203 | spin_unlock_irq(&dev_priv->irq_lock); | 6328 | spin_unlock_irq(&dev_priv->irq_lock); |
6204 | 6329 | ||
6205 | vlv_set_power_well(dev_priv, power_well, false); | 6330 | vlv_set_power_well(dev_priv, power_well, false); |
6331 | |||
6332 | vlv_power_sequencer_reset(dev_priv); | ||
6206 | } | 6333 | } |
6207 | 6334 | ||
6208 | static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | 6335 | static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, |
@@ -6238,12 +6365,11 @@ static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | |||
6238 | static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | 6365 | static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, |
6239 | struct i915_power_well *power_well) | 6366 | struct i915_power_well *power_well) |
6240 | { | 6367 | { |
6241 | struct drm_device *dev = dev_priv->dev; | ||
6242 | enum pipe pipe; | 6368 | enum pipe pipe; |
6243 | 6369 | ||
6244 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); | 6370 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); |
6245 | 6371 | ||
6246 | for_each_pipe(pipe) | 6372 | for_each_pipe(dev_priv, pipe) |
6247 | assert_pll_disabled(dev_priv, pipe); | 6373 | assert_pll_disabled(dev_priv, pipe); |
6248 | 6374 | ||
6249 | /* Assert common reset */ | 6375 | /* Assert common reset */ |
@@ -6252,6 +6378,153 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | |||
6252 | vlv_set_power_well(dev_priv, power_well, false); | 6378 | vlv_set_power_well(dev_priv, power_well, false); |
6253 | } | 6379 | } |
6254 | 6380 | ||
6381 | static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | ||
6382 | struct i915_power_well *power_well) | ||
6383 | { | ||
6384 | enum dpio_phy phy; | ||
6385 | |||
6386 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && | ||
6387 | power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); | ||
6388 | |||
6389 | /* | ||
6390 | * Enable the CRI clock source so we can get at the | ||
6391 | * display and the reference clock for VGA | ||
6392 | * hotplug / manual detection. | ||
6393 | */ | ||
6394 | if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { | ||
6395 | phy = DPIO_PHY0; | ||
6396 | I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | | ||
6397 | DPLL_REFA_CLK_ENABLE_VLV); | ||
6398 | I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | | ||
6399 | DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV); | ||
6400 | } else { | ||
6401 | phy = DPIO_PHY1; | ||
6402 | I915_WRITE(DPLL(PIPE_C), I915_READ(DPLL(PIPE_C)) | | ||
6403 | DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV); | ||
6404 | } | ||
6405 | udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ | ||
6406 | vlv_set_power_well(dev_priv, power_well, true); | ||
6407 | |||
6408 | /* Poll for phypwrgood signal */ | ||
6409 | if (wait_for(I915_READ(DISPLAY_PHY_STATUS) & PHY_POWERGOOD(phy), 1)) | ||
6410 | DRM_ERROR("Display PHY %d is not power up\n", phy); | ||
6411 | |||
6412 | I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) | | ||
6413 | PHY_COM_LANE_RESET_DEASSERT(phy)); | ||
6414 | } | ||
6415 | |||
6416 | static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | ||
6417 | struct i915_power_well *power_well) | ||
6418 | { | ||
6419 | enum dpio_phy phy; | ||
6420 | |||
6421 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && | ||
6422 | power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); | ||
6423 | |||
6424 | if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { | ||
6425 | phy = DPIO_PHY0; | ||
6426 | assert_pll_disabled(dev_priv, PIPE_A); | ||
6427 | assert_pll_disabled(dev_priv, PIPE_B); | ||
6428 | } else { | ||
6429 | phy = DPIO_PHY1; | ||
6430 | assert_pll_disabled(dev_priv, PIPE_C); | ||
6431 | } | ||
6432 | |||
6433 | I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) & | ||
6434 | ~PHY_COM_LANE_RESET_DEASSERT(phy)); | ||
6435 | |||
6436 | vlv_set_power_well(dev_priv, power_well, false); | ||
6437 | } | ||
6438 | |||
6439 | static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv, | ||
6440 | struct i915_power_well *power_well) | ||
6441 | { | ||
6442 | enum pipe pipe = power_well->data; | ||
6443 | bool enabled; | ||
6444 | u32 state, ctrl; | ||
6445 | |||
6446 | mutex_lock(&dev_priv->rps.hw_lock); | ||
6447 | |||
6448 | state = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe); | ||
6449 | /* | ||
6450 | * We only ever set the power-on and power-gate states, anything | ||
6451 | * else is unexpected. | ||
6452 | */ | ||
6453 | WARN_ON(state != DP_SSS_PWR_ON(pipe) && state != DP_SSS_PWR_GATE(pipe)); | ||
6454 | enabled = state == DP_SSS_PWR_ON(pipe); | ||
6455 | |||
6456 | /* | ||
6457 | * A transient state at this point would mean some unexpected party | ||
6458 | * is poking at the power controls too. | ||
6459 | */ | ||
6460 | ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSC_MASK(pipe); | ||
6461 | WARN_ON(ctrl << 16 != state); | ||
6462 | |||
6463 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
6464 | |||
6465 | return enabled; | ||
6466 | } | ||
6467 | |||
6468 | static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv, | ||
6469 | struct i915_power_well *power_well, | ||
6470 | bool enable) | ||
6471 | { | ||
6472 | enum pipe pipe = power_well->data; | ||
6473 | u32 state; | ||
6474 | u32 ctrl; | ||
6475 | |||
6476 | state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe); | ||
6477 | |||
6478 | mutex_lock(&dev_priv->rps.hw_lock); | ||
6479 | |||
6480 | #define COND \ | ||
6481 | ((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe)) == state) | ||
6482 | |||
6483 | if (COND) | ||
6484 | goto out; | ||
6485 | |||
6486 | ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); | ||
6487 | ctrl &= ~DP_SSC_MASK(pipe); | ||
6488 | ctrl |= enable ? DP_SSC_PWR_ON(pipe) : DP_SSC_PWR_GATE(pipe); | ||
6489 | vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, ctrl); | ||
6490 | |||
6491 | if (wait_for(COND, 100)) | ||
6492 | DRM_ERROR("timout setting power well state %08x (%08x)\n", | ||
6493 | state, | ||
6494 | vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ)); | ||
6495 | |||
6496 | #undef COND | ||
6497 | |||
6498 | out: | ||
6499 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
6500 | } | ||
6501 | |||
6502 | static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv, | ||
6503 | struct i915_power_well *power_well) | ||
6504 | { | ||
6505 | chv_set_pipe_power_well(dev_priv, power_well, power_well->count > 0); | ||
6506 | } | ||
6507 | |||
6508 | static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, | ||
6509 | struct i915_power_well *power_well) | ||
6510 | { | ||
6511 | WARN_ON_ONCE(power_well->data != PIPE_A && | ||
6512 | power_well->data != PIPE_B && | ||
6513 | power_well->data != PIPE_C); | ||
6514 | |||
6515 | chv_set_pipe_power_well(dev_priv, power_well, true); | ||
6516 | } | ||
6517 | |||
6518 | static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, | ||
6519 | struct i915_power_well *power_well) | ||
6520 | { | ||
6521 | WARN_ON_ONCE(power_well->data != PIPE_A && | ||
6522 | power_well->data != PIPE_B && | ||
6523 | power_well->data != PIPE_C); | ||
6524 | |||
6525 | chv_set_pipe_power_well(dev_priv, power_well, false); | ||
6526 | } | ||
6527 | |||
6255 | static void check_power_well_state(struct drm_i915_private *dev_priv, | 6528 | static void check_power_well_state(struct drm_i915_private *dev_priv, |
6256 | struct i915_power_well *power_well) | 6529 | struct i915_power_well *power_well) |
6257 | { | 6530 | { |
@@ -6443,6 +6716,39 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); | |||
6443 | BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ | 6716 | BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ |
6444 | BIT(POWER_DOMAIN_INIT)) | 6717 | BIT(POWER_DOMAIN_INIT)) |
6445 | 6718 | ||
6719 | #define CHV_PIPE_A_POWER_DOMAINS ( \ | ||
6720 | BIT(POWER_DOMAIN_PIPE_A) | \ | ||
6721 | BIT(POWER_DOMAIN_INIT)) | ||
6722 | |||
6723 | #define CHV_PIPE_B_POWER_DOMAINS ( \ | ||
6724 | BIT(POWER_DOMAIN_PIPE_B) | \ | ||
6725 | BIT(POWER_DOMAIN_INIT)) | ||
6726 | |||
6727 | #define CHV_PIPE_C_POWER_DOMAINS ( \ | ||
6728 | BIT(POWER_DOMAIN_PIPE_C) | \ | ||
6729 | BIT(POWER_DOMAIN_INIT)) | ||
6730 | |||
6731 | #define CHV_DPIO_CMN_BC_POWER_DOMAINS ( \ | ||
6732 | BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ | ||
6733 | BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ | ||
6734 | BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ | ||
6735 | BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ | ||
6736 | BIT(POWER_DOMAIN_INIT)) | ||
6737 | |||
6738 | #define CHV_DPIO_CMN_D_POWER_DOMAINS ( \ | ||
6739 | BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ | ||
6740 | BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ | ||
6741 | BIT(POWER_DOMAIN_INIT)) | ||
6742 | |||
6743 | #define CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS ( \ | ||
6744 | BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ | ||
6745 | BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ | ||
6746 | BIT(POWER_DOMAIN_INIT)) | ||
6747 | |||
6748 | #define CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS ( \ | ||
6749 | BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ | ||
6750 | BIT(POWER_DOMAIN_INIT)) | ||
6751 | |||
6446 | static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { | 6752 | static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { |
6447 | .sync_hw = i9xx_always_on_power_well_noop, | 6753 | .sync_hw = i9xx_always_on_power_well_noop, |
6448 | .enable = i9xx_always_on_power_well_noop, | 6754 | .enable = i9xx_always_on_power_well_noop, |
@@ -6450,6 +6756,20 @@ static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { | |||
6450 | .is_enabled = i9xx_always_on_power_well_enabled, | 6756 | .is_enabled = i9xx_always_on_power_well_enabled, |
6451 | }; | 6757 | }; |
6452 | 6758 | ||
6759 | static const struct i915_power_well_ops chv_pipe_power_well_ops = { | ||
6760 | .sync_hw = chv_pipe_power_well_sync_hw, | ||
6761 | .enable = chv_pipe_power_well_enable, | ||
6762 | .disable = chv_pipe_power_well_disable, | ||
6763 | .is_enabled = chv_pipe_power_well_enabled, | ||
6764 | }; | ||
6765 | |||
6766 | static const struct i915_power_well_ops chv_dpio_cmn_power_well_ops = { | ||
6767 | .sync_hw = vlv_power_well_sync_hw, | ||
6768 | .enable = chv_dpio_cmn_power_well_enable, | ||
6769 | .disable = chv_dpio_cmn_power_well_disable, | ||
6770 | .is_enabled = vlv_power_well_enabled, | ||
6771 | }; | ||
6772 | |||
6453 | static struct i915_power_well i9xx_always_on_power_well[] = { | 6773 | static struct i915_power_well i9xx_always_on_power_well[] = { |
6454 | { | 6774 | { |
6455 | .name = "always-on", | 6775 | .name = "always-on", |
@@ -6572,6 +6892,107 @@ static struct i915_power_well vlv_power_wells[] = { | |||
6572 | }, | 6892 | }, |
6573 | }; | 6893 | }; |
6574 | 6894 | ||
6895 | static struct i915_power_well chv_power_wells[] = { | ||
6896 | { | ||
6897 | .name = "always-on", | ||
6898 | .always_on = 1, | ||
6899 | .domains = VLV_ALWAYS_ON_POWER_DOMAINS, | ||
6900 | .ops = &i9xx_always_on_power_well_ops, | ||
6901 | }, | ||
6902 | #if 0 | ||
6903 | { | ||
6904 | .name = "display", | ||
6905 | .domains = VLV_DISPLAY_POWER_DOMAINS, | ||
6906 | .data = PUNIT_POWER_WELL_DISP2D, | ||
6907 | .ops = &vlv_display_power_well_ops, | ||
6908 | }, | ||
6909 | { | ||
6910 | .name = "pipe-a", | ||
6911 | .domains = CHV_PIPE_A_POWER_DOMAINS, | ||
6912 | .data = PIPE_A, | ||
6913 | .ops = &chv_pipe_power_well_ops, | ||
6914 | }, | ||
6915 | { | ||
6916 | .name = "pipe-b", | ||
6917 | .domains = CHV_PIPE_B_POWER_DOMAINS, | ||
6918 | .data = PIPE_B, | ||
6919 | .ops = &chv_pipe_power_well_ops, | ||
6920 | }, | ||
6921 | { | ||
6922 | .name = "pipe-c", | ||
6923 | .domains = CHV_PIPE_C_POWER_DOMAINS, | ||
6924 | .data = PIPE_C, | ||
6925 | .ops = &chv_pipe_power_well_ops, | ||
6926 | }, | ||
6927 | #endif | ||
6928 | { | ||
6929 | .name = "dpio-common-bc", | ||
6930 | /* | ||
6931 | * XXX: cmnreset for one PHY seems to disturb the other. | ||
6932 | * As a workaround keep both powered on at the same | ||
6933 | * time for now. | ||
6934 | */ | ||
6935 | .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS | CHV_DPIO_CMN_D_POWER_DOMAINS, | ||
6936 | .data = PUNIT_POWER_WELL_DPIO_CMN_BC, | ||
6937 | .ops = &chv_dpio_cmn_power_well_ops, | ||
6938 | }, | ||
6939 | { | ||
6940 | .name = "dpio-common-d", | ||
6941 | /* | ||
6942 | * XXX: cmnreset for one PHY seems to disturb the other. | ||
6943 | * As a workaround keep both powered on at the same | ||
6944 | * time for now. | ||
6945 | */ | ||
6946 | .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS | CHV_DPIO_CMN_D_POWER_DOMAINS, | ||
6947 | .data = PUNIT_POWER_WELL_DPIO_CMN_D, | ||
6948 | .ops = &chv_dpio_cmn_power_well_ops, | ||
6949 | }, | ||
6950 | #if 0 | ||
6951 | { | ||
6952 | .name = "dpio-tx-b-01", | ||
6953 | .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | | ||
6954 | VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS, | ||
6955 | .ops = &vlv_dpio_power_well_ops, | ||
6956 | .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, | ||
6957 | }, | ||
6958 | { | ||
6959 | .name = "dpio-tx-b-23", | ||
6960 | .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | | ||
6961 | VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS, | ||
6962 | .ops = &vlv_dpio_power_well_ops, | ||
6963 | .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, | ||
6964 | }, | ||
6965 | { | ||
6966 | .name = "dpio-tx-c-01", | ||
6967 | .domains = VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | ||
6968 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | ||
6969 | .ops = &vlv_dpio_power_well_ops, | ||
6970 | .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, | ||
6971 | }, | ||
6972 | { | ||
6973 | .name = "dpio-tx-c-23", | ||
6974 | .domains = VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | ||
6975 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | ||
6976 | .ops = &vlv_dpio_power_well_ops, | ||
6977 | .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, | ||
6978 | }, | ||
6979 | { | ||
6980 | .name = "dpio-tx-d-01", | ||
6981 | .domains = CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS | | ||
6982 | CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS, | ||
6983 | .ops = &vlv_dpio_power_well_ops, | ||
6984 | .data = PUNIT_POWER_WELL_DPIO_TX_D_LANES_01, | ||
6985 | }, | ||
6986 | { | ||
6987 | .name = "dpio-tx-d-23", | ||
6988 | .domains = CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS | | ||
6989 | CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS, | ||
6990 | .ops = &vlv_dpio_power_well_ops, | ||
6991 | .data = PUNIT_POWER_WELL_DPIO_TX_D_LANES_23, | ||
6992 | }, | ||
6993 | #endif | ||
6994 | }; | ||
6995 | |||
6575 | static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, | 6996 | static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, |
6576 | enum punit_power_well power_well_id) | 6997 | enum punit_power_well power_well_id) |
6577 | { | 6998 | { |
@@ -6608,6 +7029,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) | |||
6608 | } else if (IS_BROADWELL(dev_priv->dev)) { | 7029 | } else if (IS_BROADWELL(dev_priv->dev)) { |
6609 | set_power_wells(power_domains, bdw_power_wells); | 7030 | set_power_wells(power_domains, bdw_power_wells); |
6610 | hsw_pwr = power_domains; | 7031 | hsw_pwr = power_domains; |
7032 | } else if (IS_CHERRYVIEW(dev_priv->dev)) { | ||
7033 | set_power_wells(power_domains, chv_power_wells); | ||
6611 | } else if (IS_VALLEYVIEW(dev_priv->dev)) { | 7034 | } else if (IS_VALLEYVIEW(dev_priv->dev)) { |
6612 | set_power_wells(power_domains, vlv_power_wells); | 7035 | set_power_wells(power_domains, vlv_power_wells); |
6613 | } else { | 7036 | } else { |
@@ -6833,13 +7256,15 @@ void intel_init_pm(struct drm_device *dev) | |||
6833 | else if (IS_HASWELL(dev)) | 7256 | else if (IS_HASWELL(dev)) |
6834 | dev_priv->display.init_clock_gating = haswell_init_clock_gating; | 7257 | dev_priv->display.init_clock_gating = haswell_init_clock_gating; |
6835 | else if (INTEL_INFO(dev)->gen == 8) | 7258 | else if (INTEL_INFO(dev)->gen == 8) |
6836 | dev_priv->display.init_clock_gating = gen8_init_clock_gating; | 7259 | dev_priv->display.init_clock_gating = broadwell_init_clock_gating; |
6837 | } else if (IS_CHERRYVIEW(dev)) { | 7260 | } else if (IS_CHERRYVIEW(dev)) { |
6838 | dev_priv->display.update_wm = valleyview_update_wm; | 7261 | dev_priv->display.update_wm = cherryview_update_wm; |
7262 | dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm; | ||
6839 | dev_priv->display.init_clock_gating = | 7263 | dev_priv->display.init_clock_gating = |
6840 | cherryview_init_clock_gating; | 7264 | cherryview_init_clock_gating; |
6841 | } else if (IS_VALLEYVIEW(dev)) { | 7265 | } else if (IS_VALLEYVIEW(dev)) { |
6842 | dev_priv->display.update_wm = valleyview_update_wm; | 7266 | dev_priv->display.update_wm = valleyview_update_wm; |
7267 | dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm; | ||
6843 | dev_priv->display.init_clock_gating = | 7268 | dev_priv->display.init_clock_gating = |
6844 | valleyview_init_clock_gating; | 7269 | valleyview_init_clock_gating; |
6845 | } else if (IS_PINEVIEW(dev)) { | 7270 | } else if (IS_PINEVIEW(dev)) { |
@@ -7025,6 +7450,7 @@ static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) | |||
7025 | return -1; | 7450 | return -1; |
7026 | } | 7451 | } |
7027 | 7452 | ||
7453 | /* CHV needs even values */ | ||
7028 | opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv->rps.cz_freq) * 2); | 7454 | opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv->rps.cz_freq) * 2); |
7029 | 7455 | ||
7030 | return opcode; | 7456 | return opcode; |