diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 217 |
1 files changed, 145 insertions, 72 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e5b3c6dbd467..d17e76d32e03 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -502,6 +502,68 @@ static void ring_setup_phys_status_page(struct intel_engine_cs *ring) | |||
502 | I915_WRITE(HWS_PGA, addr); | 502 | I915_WRITE(HWS_PGA, addr); |
503 | } | 503 | } |
504 | 504 | ||
505 | static void intel_ring_setup_status_page(struct intel_engine_cs *ring) | ||
506 | { | ||
507 | struct drm_device *dev = ring->dev; | ||
508 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | ||
509 | u32 mmio = 0; | ||
510 | |||
511 | /* The ring status page addresses are no longer next to the rest of | ||
512 | * the ring registers as of gen7. | ||
513 | */ | ||
514 | if (IS_GEN7(dev)) { | ||
515 | switch (ring->id) { | ||
516 | case RCS: | ||
517 | mmio = RENDER_HWS_PGA_GEN7; | ||
518 | break; | ||
519 | case BCS: | ||
520 | mmio = BLT_HWS_PGA_GEN7; | ||
521 | break; | ||
522 | /* | ||
523 | * VCS2 actually doesn't exist on Gen7. Only shut up | ||
524 | * gcc switch check warning | ||
525 | */ | ||
526 | case VCS2: | ||
527 | case VCS: | ||
528 | mmio = BSD_HWS_PGA_GEN7; | ||
529 | break; | ||
530 | case VECS: | ||
531 | mmio = VEBOX_HWS_PGA_GEN7; | ||
532 | break; | ||
533 | } | ||
534 | } else if (IS_GEN6(ring->dev)) { | ||
535 | mmio = RING_HWS_PGA_GEN6(ring->mmio_base); | ||
536 | } else { | ||
537 | /* XXX: gen8 returns to sanity */ | ||
538 | mmio = RING_HWS_PGA(ring->mmio_base); | ||
539 | } | ||
540 | |||
541 | I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); | ||
542 | POSTING_READ(mmio); | ||
543 | |||
544 | /* | ||
545 | * Flush the TLB for this page | ||
546 | * | ||
547 | * FIXME: These two bits have disappeared on gen8, so a question | ||
548 | * arises: do we still need this and if so how should we go about | ||
549 | * invalidating the TLB? | ||
550 | */ | ||
551 | if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) { | ||
552 | u32 reg = RING_INSTPM(ring->mmio_base); | ||
553 | |||
554 | /* ring should be idle before issuing a sync flush*/ | ||
555 | WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); | ||
556 | |||
557 | I915_WRITE(reg, | ||
558 | _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | | ||
559 | INSTPM_SYNC_FLUSH)); | ||
560 | if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, | ||
561 | 1000)) | ||
562 | DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", | ||
563 | ring->name); | ||
564 | } | ||
565 | } | ||
566 | |||
505 | static bool stop_ring(struct intel_engine_cs *ring) | 567 | static bool stop_ring(struct intel_engine_cs *ring) |
506 | { | 568 | { |
507 | struct drm_i915_private *dev_priv = to_i915(ring->dev); | 569 | struct drm_i915_private *dev_priv = to_i915(ring->dev); |
@@ -788,12 +850,14 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) | |||
788 | * workaround for for a possible hang in the unlikely event a TLB | 850 | * workaround for for a possible hang in the unlikely event a TLB |
789 | * invalidation occurs during a PSD flush. | 851 | * invalidation occurs during a PSD flush. |
790 | */ | 852 | */ |
791 | /* WaForceEnableNonCoherent:bdw */ | ||
792 | /* WaHdcDisableFetchWhenMasked:bdw */ | ||
793 | /* WaDisableFenceDestinationToSLM:bdw (GT3 pre-production) */ | ||
794 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | 853 | WA_SET_BIT_MASKED(HDC_CHICKEN0, |
854 | /* WaForceEnableNonCoherent:bdw */ | ||
795 | HDC_FORCE_NON_COHERENT | | 855 | HDC_FORCE_NON_COHERENT | |
856 | /* WaForceContextSaveRestoreNonCoherent:bdw */ | ||
857 | HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | | ||
858 | /* WaHdcDisableFetchWhenMasked:bdw */ | ||
796 | HDC_DONOT_FETCH_MEM_WHEN_MASKED | | 859 | HDC_DONOT_FETCH_MEM_WHEN_MASKED | |
860 | /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ | ||
797 | (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); | 861 | (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); |
798 | 862 | ||
799 | /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: | 863 | /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: |
@@ -870,6 +934,78 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) | |||
870 | GEN6_WIZ_HASHING_MASK, | 934 | GEN6_WIZ_HASHING_MASK, |
871 | GEN6_WIZ_HASHING_16x4); | 935 | GEN6_WIZ_HASHING_16x4); |
872 | 936 | ||
937 | if (INTEL_REVID(dev) == SKL_REVID_C0 || | ||
938 | INTEL_REVID(dev) == SKL_REVID_D0) | ||
939 | /* WaBarrierPerformanceFixDisable:skl */ | ||
940 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | ||
941 | HDC_FENCE_DEST_SLM_DISABLE | | ||
942 | HDC_BARRIER_PERFORMANCE_DISABLE); | ||
943 | |||
944 | return 0; | ||
945 | } | ||
946 | |||
947 | static int gen9_init_workarounds(struct intel_engine_cs *ring) | ||
948 | { | ||
949 | struct drm_device *dev = ring->dev; | ||
950 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
951 | |||
952 | /* WaDisablePartialInstShootdown:skl */ | ||
953 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | ||
954 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); | ||
955 | |||
956 | /* Syncing dependencies between camera and graphics */ | ||
957 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, | ||
958 | GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); | ||
959 | |||
960 | if (INTEL_REVID(dev) == SKL_REVID_A0 || | ||
961 | INTEL_REVID(dev) == SKL_REVID_B0) { | ||
962 | /* WaDisableDgMirrorFixInHalfSliceChicken5:skl */ | ||
963 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, | ||
964 | GEN9_DG_MIRROR_FIX_ENABLE); | ||
965 | } | ||
966 | |||
967 | if (IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_B0) { | ||
968 | /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl */ | ||
969 | WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1, | ||
970 | GEN9_RHWO_OPTIMIZATION_DISABLE); | ||
971 | WA_SET_BIT_MASKED(GEN9_SLICE_COMMON_ECO_CHICKEN0, | ||
972 | DISABLE_PIXEL_MASK_CAMMING); | ||
973 | } | ||
974 | |||
975 | if (INTEL_REVID(dev) >= SKL_REVID_C0) { | ||
976 | /* WaEnableYV12BugFixInHalfSliceChicken7:skl */ | ||
977 | WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, | ||
978 | GEN9_ENABLE_YV12_BUGFIX); | ||
979 | } | ||
980 | |||
981 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { | ||
982 | /* | ||
983 | *Use Force Non-Coherent whenever executing a 3D context. This | ||
984 | * is a workaround for a possible hang in the unlikely event | ||
985 | * a TLB invalidation occurs during a PSD flush. | ||
986 | */ | ||
987 | /* WaForceEnableNonCoherent:skl */ | ||
988 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | ||
989 | HDC_FORCE_NON_COHERENT); | ||
990 | } | ||
991 | |||
992 | /* Wa4x4STCOptimizationDisable:skl */ | ||
993 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); | ||
994 | |||
995 | /* WaDisablePartialResolveInVc:skl */ | ||
996 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE); | ||
997 | |||
998 | /* WaCcsTlbPrefetchDisable:skl */ | ||
999 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, | ||
1000 | GEN9_CCS_TLB_PREFETCH_ENABLE); | ||
1001 | |||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | static int skl_init_workarounds(struct intel_engine_cs *ring) | ||
1006 | { | ||
1007 | gen9_init_workarounds(ring); | ||
1008 | |||
873 | return 0; | 1009 | return 0; |
874 | } | 1010 | } |
875 | 1011 | ||
@@ -888,6 +1024,11 @@ int init_workarounds_ring(struct intel_engine_cs *ring) | |||
888 | if (IS_CHERRYVIEW(dev)) | 1024 | if (IS_CHERRYVIEW(dev)) |
889 | return chv_init_workarounds(ring); | 1025 | return chv_init_workarounds(ring); |
890 | 1026 | ||
1027 | if (IS_SKYLAKE(dev)) | ||
1028 | return skl_init_workarounds(ring); | ||
1029 | else if (IS_GEN9(dev)) | ||
1030 | return gen9_init_workarounds(ring); | ||
1031 | |||
891 | return 0; | 1032 | return 0; |
892 | } | 1033 | } |
893 | 1034 | ||
@@ -1386,68 +1527,6 @@ i8xx_ring_put_irq(struct intel_engine_cs *ring) | |||
1386 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | 1527 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
1387 | } | 1528 | } |
1388 | 1529 | ||
1389 | void intel_ring_setup_status_page(struct intel_engine_cs *ring) | ||
1390 | { | ||
1391 | struct drm_device *dev = ring->dev; | ||
1392 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | ||
1393 | u32 mmio = 0; | ||
1394 | |||
1395 | /* The ring status page addresses are no longer next to the rest of | ||
1396 | * the ring registers as of gen7. | ||
1397 | */ | ||
1398 | if (IS_GEN7(dev)) { | ||
1399 | switch (ring->id) { | ||
1400 | case RCS: | ||
1401 | mmio = RENDER_HWS_PGA_GEN7; | ||
1402 | break; | ||
1403 | case BCS: | ||
1404 | mmio = BLT_HWS_PGA_GEN7; | ||
1405 | break; | ||
1406 | /* | ||
1407 | * VCS2 actually doesn't exist on Gen7. Only shut up | ||
1408 | * gcc switch check warning | ||
1409 | */ | ||
1410 | case VCS2: | ||
1411 | case VCS: | ||
1412 | mmio = BSD_HWS_PGA_GEN7; | ||
1413 | break; | ||
1414 | case VECS: | ||
1415 | mmio = VEBOX_HWS_PGA_GEN7; | ||
1416 | break; | ||
1417 | } | ||
1418 | } else if (IS_GEN6(ring->dev)) { | ||
1419 | mmio = RING_HWS_PGA_GEN6(ring->mmio_base); | ||
1420 | } else { | ||
1421 | /* XXX: gen8 returns to sanity */ | ||
1422 | mmio = RING_HWS_PGA(ring->mmio_base); | ||
1423 | } | ||
1424 | |||
1425 | I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); | ||
1426 | POSTING_READ(mmio); | ||
1427 | |||
1428 | /* | ||
1429 | * Flush the TLB for this page | ||
1430 | * | ||
1431 | * FIXME: These two bits have disappeared on gen8, so a question | ||
1432 | * arises: do we still need this and if so how should we go about | ||
1433 | * invalidating the TLB? | ||
1434 | */ | ||
1435 | if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) { | ||
1436 | u32 reg = RING_INSTPM(ring->mmio_base); | ||
1437 | |||
1438 | /* ring should be idle before issuing a sync flush*/ | ||
1439 | WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); | ||
1440 | |||
1441 | I915_WRITE(reg, | ||
1442 | _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | | ||
1443 | INSTPM_SYNC_FLUSH)); | ||
1444 | if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, | ||
1445 | 1000)) | ||
1446 | DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", | ||
1447 | ring->name); | ||
1448 | } | ||
1449 | } | ||
1450 | |||
1451 | static int | 1530 | static int |
1452 | bsd_ring_flush(struct intel_engine_cs *ring, | 1531 | bsd_ring_flush(struct intel_engine_cs *ring, |
1453 | u32 invalidate_domains, | 1532 | u32 invalidate_domains, |
@@ -2612,19 +2691,13 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) | |||
2612 | } | 2691 | } |
2613 | 2692 | ||
2614 | /** | 2693 | /** |
2615 | * Initialize the second BSD ring for Broadwell GT3. | 2694 | * Initialize the second BSD ring (eg. Broadwell GT3, Skylake GT3) |
2616 | * It is noted that this only exists on Broadwell GT3. | ||
2617 | */ | 2695 | */ |
2618 | int intel_init_bsd2_ring_buffer(struct drm_device *dev) | 2696 | int intel_init_bsd2_ring_buffer(struct drm_device *dev) |
2619 | { | 2697 | { |
2620 | struct drm_i915_private *dev_priv = dev->dev_private; | 2698 | struct drm_i915_private *dev_priv = dev->dev_private; |
2621 | struct intel_engine_cs *ring = &dev_priv->ring[VCS2]; | 2699 | struct intel_engine_cs *ring = &dev_priv->ring[VCS2]; |
2622 | 2700 | ||
2623 | if ((INTEL_INFO(dev)->gen != 8)) { | ||
2624 | DRM_ERROR("No dual-BSD ring on non-BDW machine\n"); | ||
2625 | return -EINVAL; | ||
2626 | } | ||
2627 | |||
2628 | ring->name = "bsd2 ring"; | 2701 | ring->name = "bsd2 ring"; |
2629 | ring->id = VCS2; | 2702 | ring->id = VCS2; |
2630 | 2703 | ||