]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/gpu/drm/radeon/si.c
drm/radeon: fix halting UVD
[linux-imx.git] / drivers / gpu / drm / radeon / si.c
index f305768c3dfa8bcdcddbe0c4801c27fc8ed8370b..242c1ac83e2327a0ce6b32b720c9b208d54bc741 100644 (file)
@@ -4389,6 +4389,270 @@ void si_vm_fini(struct radeon_device *rdev)
 {
 }
 
+/**
+ * si_vm_decode_fault - print human readable fault info
+ *
+ * @rdev: radeon_device pointer
+ * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
+ * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
+ *
+ * Print human readable fault information (SI).
+ */
+static void si_vm_decode_fault(struct radeon_device *rdev,
+                              u32 status, u32 addr)
+{
+       u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
+       u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
+       u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
+       char *block;
+
+       if (rdev->family == CHIP_TAHITI) {
+               switch (mc_id) {
+               case 160:
+               case 144:
+               case 96:
+               case 80:
+               case 224:
+               case 208:
+               case 32:
+               case 16:
+                       block = "CB";
+                       break;
+               case 161:
+               case 145:
+               case 97:
+               case 81:
+               case 225:
+               case 209:
+               case 33:
+               case 17:
+                       block = "CB_FMASK";
+                       break;
+               case 162:
+               case 146:
+               case 98:
+               case 82:
+               case 226:
+               case 210:
+               case 34:
+               case 18:
+                       block = "CB_CMASK";
+                       break;
+               case 163:
+               case 147:
+               case 99:
+               case 83:
+               case 227:
+               case 211:
+               case 35:
+               case 19:
+                       block = "CB_IMMED";
+                       break;
+               case 164:
+               case 148:
+               case 100:
+               case 84:
+               case 228:
+               case 212:
+               case 36:
+               case 20:
+                       block = "DB";
+                       break;
+               case 165:
+               case 149:
+               case 101:
+               case 85:
+               case 229:
+               case 213:
+               case 37:
+               case 21:
+                       block = "DB_HTILE";
+                       break;
+               case 167:
+               case 151:
+               case 103:
+               case 87:
+               case 231:
+               case 215:
+               case 39:
+               case 23:
+                       block = "DB_STEN";
+                       break;
+               case 72:
+               case 68:
+               case 64:
+               case 8:
+               case 4:
+               case 0:
+               case 136:
+               case 132:
+               case 128:
+               case 200:
+               case 196:
+               case 192:
+                       block = "TC";
+                       break;
+               case 112:
+               case 48:
+                       block = "CP";
+                       break;
+               case 49:
+               case 177:
+               case 50:
+               case 178:
+                       block = "SH";
+                       break;
+               case 53:
+               case 190:
+                       block = "VGT";
+                       break;
+               case 117:
+                       block = "IH";
+                       break;
+               case 51:
+               case 115:
+                       block = "RLC";
+                       break;
+               case 119:
+               case 183:
+                       block = "DMA0";
+                       break;
+               case 61:
+                       block = "DMA1";
+                       break;
+               case 248:
+               case 120:
+                       block = "HDP";
+                       break;
+               default:
+                       block = "unknown";
+                       break;
+               }
+       } else {
+               switch (mc_id) {
+               case 32:
+               case 16:
+               case 96:
+               case 80:
+               case 160:
+               case 144:
+               case 224:
+               case 208:
+                       block = "CB";
+                       break;
+               case 33:
+               case 17:
+               case 97:
+               case 81:
+               case 161:
+               case 145:
+               case 225:
+               case 209:
+                       block = "CB_FMASK";
+                       break;
+               case 34:
+               case 18:
+               case 98:
+               case 82:
+               case 162:
+               case 146:
+               case 226:
+               case 210:
+                       block = "CB_CMASK";
+                       break;
+               case 35:
+               case 19:
+               case 99:
+               case 83:
+               case 163:
+               case 147:
+               case 227:
+               case 211:
+                       block = "CB_IMMED";
+                       break;
+               case 36:
+               case 20:
+               case 100:
+               case 84:
+               case 164:
+               case 148:
+               case 228:
+               case 212:
+                       block = "DB";
+                       break;
+               case 37:
+               case 21:
+               case 101:
+               case 85:
+               case 165:
+               case 149:
+               case 229:
+               case 213:
+                       block = "DB_HTILE";
+                       break;
+               case 39:
+               case 23:
+               case 103:
+               case 87:
+               case 167:
+               case 151:
+               case 231:
+               case 215:
+                       block = "DB_STEN";
+                       break;
+               case 72:
+               case 68:
+               case 8:
+               case 4:
+               case 136:
+               case 132:
+               case 200:
+               case 196:
+                       block = "TC";
+                       break;
+               case 112:
+               case 48:
+                       block = "CP";
+                       break;
+               case 49:
+               case 177:
+               case 50:
+               case 178:
+                       block = "SH";
+                       break;
+               case 53:
+                       block = "VGT";
+                       break;
+               case 117:
+                       block = "IH";
+                       break;
+               case 51:
+               case 115:
+                       block = "RLC";
+                       break;
+               case 119:
+               case 183:
+                       block = "DMA0";
+                       break;
+               case 61:
+                       block = "DMA1";
+                       break;
+               case 248:
+               case 120:
+                       block = "HDP";
+                       break;
+               default:
+                       block = "unknown";
+                       break;
+               }
+       }
+
+       printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
+              protections, vmid, addr,
+              (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
+              block, mc_id);
+}
+
 /**
  * si_vm_set_page - update the page tables using the CP
  *
@@ -4951,14 +5215,12 @@ static void si_enable_mc_ls(struct radeon_device *rdev,
 
 static void si_init_cg(struct radeon_device *rdev)
 {
-       bool has_uvd = true;
-
        si_enable_mgcg(rdev, true);
-       si_enable_cgcg(rdev, true);
+       si_enable_cgcg(rdev, false);
        /* disable MC LS on Tahiti */
        if (rdev->family == CHIP_TAHITI)
                si_enable_mc_ls(rdev, false);
-       if (has_uvd) {
+       if (rdev->has_uvd) {
                si_enable_uvd_mgcg(rdev, true);
                si_init_uvd_internal_cg(rdev);
        }
@@ -4966,9 +5228,7 @@ static void si_init_cg(struct radeon_device *rdev)
 
 static void si_fini_cg(struct radeon_device *rdev)
 {
-       bool has_uvd = true;
-
-       if (has_uvd)
+       if (rdev->has_uvd)
                si_enable_uvd_mgcg(rdev, false);
        si_enable_cgcg(rdev, false);
        si_enable_mgcg(rdev, false);
@@ -4977,11 +5237,11 @@ static void si_fini_cg(struct radeon_device *rdev)
 static void si_init_pg(struct radeon_device *rdev)
 {
        bool has_pg = false;
-
+#if 0
        /* only cape verde supports PG */
        if (rdev->family == CHIP_VERDE)
                has_pg = true;
-
+#endif
        if (has_pg) {
                si_init_ao_cu_mask(rdev);
                si_init_dma_pg(rdev);
@@ -5755,6 +6015,7 @@ int si_irq_process(struct radeon_device *rdev)
        u32 ring_index;
        bool queue_hotplug = false;
        bool queue_thermal = false;
+       u32 status, addr;
 
        if (!rdev->ih.enabled || rdev->shutdown)
                return IRQ_NONE;
@@ -5990,11 +6251,14 @@ restart_ih:
                        break;
                case 146:
                case 147:
+                       addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
+                       status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
                        dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
                        dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
-                               RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+                               addr);
                        dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
-                               RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+                               status);
+                       si_vm_decode_fault(rdev, status, addr);
                        /* reset addr and status */
                        WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
                        break;
@@ -6357,7 +6621,7 @@ int si_suspend(struct radeon_device *rdev)
        si_cp_enable(rdev, false);
        cayman_dma_stop(rdev);
        if (rdev->has_uvd) {
-               r600_uvd_rbc_stop(rdev);
+               r600_uvd_stop(rdev);
                radeon_uvd_suspend(rdev);
        }
        si_irq_suspend(rdev);
@@ -6499,8 +6763,10 @@ void si_fini(struct radeon_device *rdev)
        radeon_vm_manager_fini(rdev);
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
-       if (rdev->has_uvd)
+       if (rdev->has_uvd) {
+               r600_uvd_stop(rdev);
                radeon_uvd_fini(rdev);
+       }
        si_pcie_gart_fini(rdev);
        r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
@@ -6785,6 +7051,9 @@ static void si_program_aspm(struct radeon_device *rdev)
        bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
        bool disable_clkreq = false;
 
+       if (radeon_aspm == 0)
+               return;
+
        if (!(rdev->flags & RADEON_IS_PCIE))
                return;