drm/radeon: save/restore the PD addr on suspend/resume
[deliverable/linux.git] / drivers / gpu / drm / radeon / si.c
index 9e854fd016dabac99c081896209ce9f732dc34f0..739e0a5349f8dcaf8a47203c4fc23a47217e2b10 100644 (file)
@@ -42,6 +42,14 @@ MODULE_FIRMWARE("radeon/TAHITI_mc.bin");
 MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
 MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
 MODULE_FIRMWARE("radeon/TAHITI_smc.bin");
+
+MODULE_FIRMWARE("radeon/tahiti_pfp.bin");
+MODULE_FIRMWARE("radeon/tahiti_me.bin");
+MODULE_FIRMWARE("radeon/tahiti_ce.bin");
+MODULE_FIRMWARE("radeon/tahiti_mc.bin");
+MODULE_FIRMWARE("radeon/tahiti_rlc.bin");
+MODULE_FIRMWARE("radeon/tahiti_smc.bin");
+
 MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
@@ -49,6 +57,14 @@ MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
+
+MODULE_FIRMWARE("radeon/pitcairn_pfp.bin");
+MODULE_FIRMWARE("radeon/pitcairn_me.bin");
+MODULE_FIRMWARE("radeon/pitcairn_ce.bin");
+MODULE_FIRMWARE("radeon/pitcairn_mc.bin");
+MODULE_FIRMWARE("radeon/pitcairn_rlc.bin");
+MODULE_FIRMWARE("radeon/pitcairn_smc.bin");
+
 MODULE_FIRMWARE("radeon/VERDE_pfp.bin");
 MODULE_FIRMWARE("radeon/VERDE_me.bin");
 MODULE_FIRMWARE("radeon/VERDE_ce.bin");
@@ -56,6 +72,14 @@ MODULE_FIRMWARE("radeon/VERDE_mc.bin");
 MODULE_FIRMWARE("radeon/VERDE_mc2.bin");
 MODULE_FIRMWARE("radeon/VERDE_rlc.bin");
 MODULE_FIRMWARE("radeon/VERDE_smc.bin");
+
+MODULE_FIRMWARE("radeon/verde_pfp.bin");
+MODULE_FIRMWARE("radeon/verde_me.bin");
+MODULE_FIRMWARE("radeon/verde_ce.bin");
+MODULE_FIRMWARE("radeon/verde_mc.bin");
+MODULE_FIRMWARE("radeon/verde_rlc.bin");
+MODULE_FIRMWARE("radeon/verde_smc.bin");
+
 MODULE_FIRMWARE("radeon/OLAND_pfp.bin");
 MODULE_FIRMWARE("radeon/OLAND_me.bin");
 MODULE_FIRMWARE("radeon/OLAND_ce.bin");
@@ -63,6 +87,14 @@ MODULE_FIRMWARE("radeon/OLAND_mc.bin");
 MODULE_FIRMWARE("radeon/OLAND_mc2.bin");
 MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
 MODULE_FIRMWARE("radeon/OLAND_smc.bin");
+
+MODULE_FIRMWARE("radeon/oland_pfp.bin");
+MODULE_FIRMWARE("radeon/oland_me.bin");
+MODULE_FIRMWARE("radeon/oland_ce.bin");
+MODULE_FIRMWARE("radeon/oland_mc.bin");
+MODULE_FIRMWARE("radeon/oland_rlc.bin");
+MODULE_FIRMWARE("radeon/oland_smc.bin");
+
 MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
 MODULE_FIRMWARE("radeon/HAINAN_me.bin");
 MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
@@ -71,6 +103,13 @@ MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
 MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
 MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
 
+MODULE_FIRMWARE("radeon/hainan_pfp.bin");
+MODULE_FIRMWARE("radeon/hainan_me.bin");
+MODULE_FIRMWARE("radeon/hainan_ce.bin");
+MODULE_FIRMWARE("radeon/hainan_mc.bin");
+MODULE_FIRMWARE("radeon/hainan_rlc.bin");
+MODULE_FIRMWARE("radeon/hainan_smc.bin");
+
 static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh);
 static void si_pcie_gen3_enable(struct radeon_device *rdev);
 static void si_program_aspm(struct radeon_device *rdev);
@@ -1470,38 +1509,54 @@ static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
 /* ucode loading */
 int si_mc_load_microcode(struct radeon_device *rdev)
 {
-       const __be32 *fw_data;
+       const __be32 *fw_data = NULL;
+       const __le32 *new_fw_data = NULL;
        u32 running, blackout = 0;
-       u32 *io_mc_regs;
+       u32 *io_mc_regs = NULL;
+       const __le32 *new_io_mc_regs = NULL;
        int i, regs_size, ucode_size;
 
        if (!rdev->mc_fw)
                return -EINVAL;
 
-       ucode_size = rdev->mc_fw->size / 4;
+       if (rdev->new_fw) {
+               const struct mc_firmware_header_v1_0 *hdr =
+                       (const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data;
+
+               radeon_ucode_print_mc_hdr(&hdr->header);
+               regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
+               new_io_mc_regs = (const __le32 *)
+                       (rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
+               ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+               new_fw_data = (const __le32 *)
+                       (rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+       } else {
+               ucode_size = rdev->mc_fw->size / 4;
 
-       switch (rdev->family) {
-       case CHIP_TAHITI:
-               io_mc_regs = (u32 *)&tahiti_io_mc_regs;
-               regs_size = TAHITI_IO_MC_REGS_SIZE;
-               break;
-       case CHIP_PITCAIRN:
-               io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
-               regs_size = TAHITI_IO_MC_REGS_SIZE;
-               break;
-       case CHIP_VERDE:
-       default:
-               io_mc_regs = (u32 *)&verde_io_mc_regs;
-               regs_size = TAHITI_IO_MC_REGS_SIZE;
-               break;
-       case CHIP_OLAND:
-               io_mc_regs = (u32 *)&oland_io_mc_regs;
-               regs_size = TAHITI_IO_MC_REGS_SIZE;
-               break;
-       case CHIP_HAINAN:
-               io_mc_regs = (u32 *)&hainan_io_mc_regs;
-               regs_size = TAHITI_IO_MC_REGS_SIZE;
-               break;
+               switch (rdev->family) {
+               case CHIP_TAHITI:
+                       io_mc_regs = (u32 *)&tahiti_io_mc_regs;
+                       regs_size = TAHITI_IO_MC_REGS_SIZE;
+                       break;
+               case CHIP_PITCAIRN:
+                       io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
+                       regs_size = TAHITI_IO_MC_REGS_SIZE;
+                       break;
+               case CHIP_VERDE:
+               default:
+                       io_mc_regs = (u32 *)&verde_io_mc_regs;
+                       regs_size = TAHITI_IO_MC_REGS_SIZE;
+                       break;
+               case CHIP_OLAND:
+                       io_mc_regs = (u32 *)&oland_io_mc_regs;
+                       regs_size = TAHITI_IO_MC_REGS_SIZE;
+                       break;
+               case CHIP_HAINAN:
+                       io_mc_regs = (u32 *)&hainan_io_mc_regs;
+                       regs_size = TAHITI_IO_MC_REGS_SIZE;
+                       break;
+               }
+               fw_data = (const __be32 *)rdev->mc_fw->data;
        }
 
        running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
@@ -1518,13 +1573,21 @@ int si_mc_load_microcode(struct radeon_device *rdev)
 
                /* load mc io regs */
                for (i = 0; i < regs_size; i++) {
-                       WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
-                       WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+                       if (rdev->new_fw) {
+                               WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++));
+                               WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++));
+                       } else {
+                               WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
+                               WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+                       }
                }
                /* load the MC ucode */
-               fw_data = (const __be32 *)rdev->mc_fw->data;
-               for (i = 0; i < ucode_size; i++)
-                       WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+               for (i = 0; i < ucode_size; i++) {
+                       if (rdev->new_fw)
+                               WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++));
+                       else
+                               WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+               }
 
                /* put the engine back into the active state */
                WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
@@ -1553,18 +1616,19 @@ int si_mc_load_microcode(struct radeon_device *rdev)
 static int si_init_microcode(struct radeon_device *rdev)
 {
        const char *chip_name;
-       const char *rlc_chip_name;
+       const char *new_chip_name;
        size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
        size_t smc_req_size, mc2_req_size;
        char fw_name[30];
        int err;
+       int new_fw = 0;
 
        DRM_DEBUG("\n");
 
        switch (rdev->family) {
        case CHIP_TAHITI:
                chip_name = "TAHITI";
-               rlc_chip_name = "TAHITI";
+               new_chip_name = "tahiti";
                pfp_req_size = SI_PFP_UCODE_SIZE * 4;
                me_req_size = SI_PM4_UCODE_SIZE * 4;
                ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1575,7 +1639,7 @@ static int si_init_microcode(struct radeon_device *rdev)
                break;
        case CHIP_PITCAIRN:
                chip_name = "PITCAIRN";
-               rlc_chip_name = "PITCAIRN";
+               new_chip_name = "pitcairn";
                pfp_req_size = SI_PFP_UCODE_SIZE * 4;
                me_req_size = SI_PM4_UCODE_SIZE * 4;
                ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1586,7 +1650,7 @@ static int si_init_microcode(struct radeon_device *rdev)
                break;
        case CHIP_VERDE:
                chip_name = "VERDE";
-               rlc_chip_name = "VERDE";
+               new_chip_name = "verde";
                pfp_req_size = SI_PFP_UCODE_SIZE * 4;
                me_req_size = SI_PM4_UCODE_SIZE * 4;
                ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1597,7 +1661,7 @@ static int si_init_microcode(struct radeon_device *rdev)
                break;
        case CHIP_OLAND:
                chip_name = "OLAND";
-               rlc_chip_name = "OLAND";
+               new_chip_name = "oland";
                pfp_req_size = SI_PFP_UCODE_SIZE * 4;
                me_req_size = SI_PM4_UCODE_SIZE * 4;
                ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1607,7 +1671,7 @@ static int si_init_microcode(struct radeon_device *rdev)
                break;
        case CHIP_HAINAN:
                chip_name = "HAINAN";
-               rlc_chip_name = "HAINAN";
+               new_chip_name = "hainan";
                pfp_req_size = SI_PFP_UCODE_SIZE * 4;
                me_req_size = SI_PM4_UCODE_SIZE * 4;
                ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1618,86 +1682,178 @@ static int si_init_microcode(struct radeon_device *rdev)
        default: BUG();
        }
 
-       DRM_INFO("Loading %s Microcode\n", chip_name);
+       DRM_INFO("Loading %s Microcode\n", new_chip_name);
 
-       snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name);
        err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
-       if (err)
-               goto out;
-       if (rdev->pfp_fw->size != pfp_req_size) {
-               printk(KERN_ERR
-                      "si_cp: Bogus length %zu in firmware \"%s\"\n",
-                      rdev->pfp_fw->size, fw_name);
-               err = -EINVAL;
-               goto out;
+       if (err) {
+               snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+               err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
+               if (err)
+                       goto out;
+               if (rdev->pfp_fw->size != pfp_req_size) {
+                       printk(KERN_ERR
+                              "si_cp: Bogus length %zu in firmware \"%s\"\n",
+                              rdev->pfp_fw->size, fw_name);
+                       err = -EINVAL;
+                       goto out;
+               }
+       } else {
+               err = radeon_ucode_validate(rdev->pfp_fw);
+               if (err) {
+                       printk(KERN_ERR
+                              "si_cp: validation failed for firmware \"%s\"\n",
+                              fw_name);
+                       goto out;
+               } else {
+                       new_fw++;
+               }
        }
 
-       snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name);
        err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
-       if (err)
-               goto out;
-       if (rdev->me_fw->size != me_req_size) {
-               printk(KERN_ERR
-                      "si_cp: Bogus length %zu in firmware \"%s\"\n",
-                      rdev->me_fw->size, fw_name);
-               err = -EINVAL;
+       if (err) {
+               snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+               err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
+               if (err)
+                       goto out;
+               if (rdev->me_fw->size != me_req_size) {
+                       printk(KERN_ERR
+                              "si_cp: Bogus length %zu in firmware \"%s\"\n",
+                              rdev->me_fw->size, fw_name);
+                       err = -EINVAL;
+               }
+       } else {
+               err = radeon_ucode_validate(rdev->me_fw);
+               if (err) {
+                       printk(KERN_ERR
+                              "si_cp: validation failed for firmware \"%s\"\n",
+                              fw_name);
+                       goto out;
+               } else {
+                       new_fw++;
+               }
        }
 
-       snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name);
        err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
-       if (err)
-               goto out;
-       if (rdev->ce_fw->size != ce_req_size) {
-               printk(KERN_ERR
-                      "si_cp: Bogus length %zu in firmware \"%s\"\n",
-                      rdev->ce_fw->size, fw_name);
-               err = -EINVAL;
+       if (err) {
+               snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
+               err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
+               if (err)
+                       goto out;
+               if (rdev->ce_fw->size != ce_req_size) {
+                       printk(KERN_ERR
+                              "si_cp: Bogus length %zu in firmware \"%s\"\n",
+                              rdev->ce_fw->size, fw_name);
+                       err = -EINVAL;
+               }
+       } else {
+               err = radeon_ucode_validate(rdev->ce_fw);
+               if (err) {
+                       printk(KERN_ERR
+                              "si_cp: validation failed for firmware \"%s\"\n",
+                              fw_name);
+                       goto out;
+               } else {
+                       new_fw++;
+               }
        }
 
-       snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name);
        err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
-       if (err)
-               goto out;
-       if (rdev->rlc_fw->size != rlc_req_size) {
-               printk(KERN_ERR
-                      "si_rlc: Bogus length %zu in firmware \"%s\"\n",
-                      rdev->rlc_fw->size, fw_name);
-               err = -EINVAL;
+       if (err) {
+               snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name);
+               err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
+               if (err)
+                       goto out;
+               if (rdev->rlc_fw->size != rlc_req_size) {
+                       printk(KERN_ERR
+                              "si_rlc: Bogus length %zu in firmware \"%s\"\n",
+                              rdev->rlc_fw->size, fw_name);
+                       err = -EINVAL;
+               }
+       } else {
+               err = radeon_ucode_validate(rdev->rlc_fw);
+               if (err) {
+                       printk(KERN_ERR
+                              "si_cp: validation failed for firmware \"%s\"\n",
+                              fw_name);
+                       goto out;
+               } else {
+                       new_fw++;
+               }
        }
 
-       snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name);
        err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
        if (err) {
-               snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+               snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
                err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
-               if (err)
+               if (err) {
+                       snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+                       err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
+                       if (err)
+                               goto out;
+               }
+               if ((rdev->mc_fw->size != mc_req_size) &&
+                   (rdev->mc_fw->size != mc2_req_size)) {
+                       printk(KERN_ERR
+                              "si_mc: Bogus length %zu in firmware \"%s\"\n",
+                              rdev->mc_fw->size, fw_name);
+                       err = -EINVAL;
+               }
+               DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
+       } else {
+               err = radeon_ucode_validate(rdev->mc_fw);
+               if (err) {
+                       printk(KERN_ERR
+                              "si_cp: validation failed for firmware \"%s\"\n",
+                              fw_name);
                        goto out;
+               } else {
+                       new_fw++;
+               }
        }
-       if ((rdev->mc_fw->size != mc_req_size) &&
-           (rdev->mc_fw->size != mc2_req_size)) {
-               printk(KERN_ERR
-                      "si_mc: Bogus length %zu in firmware \"%s\"\n",
-                      rdev->mc_fw->size, fw_name);
-               err = -EINVAL;
-       }
-       DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
 
-       snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name);
        err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
        if (err) {
-               printk(KERN_ERR
-                      "smc: error loading firmware \"%s\"\n",
-                      fw_name);
-               release_firmware(rdev->smc_fw);
-               rdev->smc_fw = NULL;
-               err = 0;
-       } else if (rdev->smc_fw->size != smc_req_size) {
-               printk(KERN_ERR
-                      "si_smc: Bogus length %zu in firmware \"%s\"\n",
-                      rdev->smc_fw->size, fw_name);
-               err = -EINVAL;
+               snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
+               err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
+               if (err) {
+                       printk(KERN_ERR
+                              "smc: error loading firmware \"%s\"\n",
+                              fw_name);
+                       release_firmware(rdev->smc_fw);
+                       rdev->smc_fw = NULL;
+                       err = 0;
+               } else if (rdev->smc_fw->size != smc_req_size) {
+                       printk(KERN_ERR
+                              "si_smc: Bogus length %zu in firmware \"%s\"\n",
+                              rdev->smc_fw->size, fw_name);
+                       err = -EINVAL;
+               }
+       } else {
+               err = radeon_ucode_validate(rdev->smc_fw);
+               if (err) {
+                       printk(KERN_ERR
+                              "si_cp: validation failed for firmware \"%s\"\n",
+                              fw_name);
+                       goto out;
+               } else {
+                       new_fw++;
+               }
        }
 
+       if (new_fw == 0) {
+               rdev->new_fw = false;
+       } else if (new_fw < 6) {
+               printk(KERN_ERR "si_fw: mixing new and old firmware!\n");
+               err = -EINVAL;
+       } else {
+               rdev->new_fw = true;
+       }
 out:
        if (err) {
                if (err != -EINVAL)
@@ -2901,7 +3057,7 @@ static void si_gpu_init(struct radeon_device *rdev)
        u32 sx_debug_1;
        u32 hdp_host_path_cntl;
        u32 tmp;
-       int i, j, k;
+       int i, j;
 
        switch (rdev->family) {
        case CHIP_TAHITI:
@@ -3099,12 +3255,11 @@ static void si_gpu_init(struct radeon_device *rdev)
                     rdev->config.si.max_sh_per_se,
                     rdev->config.si.max_cu_per_sh);
 
+       rdev->config.si.active_cus = 0;
        for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
                for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
-                       for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) {
-                               rdev->config.si.active_cus +=
-                                       hweight32(si_get_cu_active_bitmap(rdev, i, j));
-                       }
+                       rdev->config.si.active_cus +=
+                               hweight32(si_get_cu_active_bitmap(rdev, i, j));
                }
        }
 
@@ -3282,34 +3437,77 @@ static void si_cp_enable(struct radeon_device *rdev, bool enable)
 
 static int si_cp_load_microcode(struct radeon_device *rdev)
 {
-       const __be32 *fw_data;
        int i;
 
-       if (!rdev->me_fw || !rdev->pfp_fw)
+       if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
                return -EINVAL;
 
        si_cp_enable(rdev, false);
 
-       /* PFP */
-       fw_data = (const __be32 *)rdev->pfp_fw->data;
-       WREG32(CP_PFP_UCODE_ADDR, 0);
-       for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
-               WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
-       WREG32(CP_PFP_UCODE_ADDR, 0);
-
-       /* CE */
-       fw_data = (const __be32 *)rdev->ce_fw->data;
-       WREG32(CP_CE_UCODE_ADDR, 0);
-       for (i = 0; i < SI_CE_UCODE_SIZE; i++)
-               WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
-       WREG32(CP_CE_UCODE_ADDR, 0);
-
-       /* ME */
-       fw_data = (const __be32 *)rdev->me_fw->data;
-       WREG32(CP_ME_RAM_WADDR, 0);
-       for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
-               WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
-       WREG32(CP_ME_RAM_WADDR, 0);
+       if (rdev->new_fw) {
+               const struct gfx_firmware_header_v1_0 *pfp_hdr =
+                       (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
+               const struct gfx_firmware_header_v1_0 *ce_hdr =
+                       (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
+               const struct gfx_firmware_header_v1_0 *me_hdr =
+                       (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
+               const __le32 *fw_data;
+               u32 fw_size;
+
+               radeon_ucode_print_gfx_hdr(&pfp_hdr->header);
+               radeon_ucode_print_gfx_hdr(&ce_hdr->header);
+               radeon_ucode_print_gfx_hdr(&me_hdr->header);
+
+               /* PFP */
+               fw_data = (const __le32 *)
+                       (rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
+               fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
+               WREG32(CP_PFP_UCODE_ADDR, 0);
+               for (i = 0; i < fw_size; i++)
+                       WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
+               WREG32(CP_PFP_UCODE_ADDR, 0);
+
+               /* CE */
+               fw_data = (const __le32 *)
+                       (rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
+               fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
+               WREG32(CP_CE_UCODE_ADDR, 0);
+               for (i = 0; i < fw_size; i++)
+                       WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
+               WREG32(CP_CE_UCODE_ADDR, 0);
+
+               /* ME */
+               fw_data = (const __be32 *)
+                       (rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
+               fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
+               WREG32(CP_ME_RAM_WADDR, 0);
+               for (i = 0; i < fw_size; i++)
+                       WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++));
+               WREG32(CP_ME_RAM_WADDR, 0);
+       } else {
+               const __be32 *fw_data;
+
+               /* PFP */
+               fw_data = (const __be32 *)rdev->pfp_fw->data;
+               WREG32(CP_PFP_UCODE_ADDR, 0);
+               for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
+                       WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
+               WREG32(CP_PFP_UCODE_ADDR, 0);
+
+               /* CE */
+               fw_data = (const __be32 *)rdev->ce_fw->data;
+               WREG32(CP_CE_UCODE_ADDR, 0);
+               for (i = 0; i < SI_CE_UCODE_SIZE; i++)
+                       WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
+               WREG32(CP_CE_UCODE_ADDR, 0);
+
+               /* ME */
+               fw_data = (const __be32 *)rdev->me_fw->data;
+               WREG32(CP_ME_RAM_WADDR, 0);
+               for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
+                       WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
+               WREG32(CP_ME_RAM_WADDR, 0);
+       }
 
        WREG32(CP_PFP_UCODE_ADDR, 0);
        WREG32(CP_CE_UCODE_ADDR, 0);
@@ -3342,7 +3540,7 @@ static int si_cp_start(struct radeon_device *rdev)
        radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
        radeon_ring_write(ring, 0xc000);
        radeon_ring_write(ring, 0xe000);
-       radeon_ring_unlock_commit(rdev, ring);
+       radeon_ring_unlock_commit(rdev, ring, false);
 
        si_cp_enable(rdev, true);
 
@@ -3371,7 +3569,7 @@ static int si_cp_start(struct radeon_device *rdev)
        radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
        radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */
 
-       radeon_ring_unlock_commit(rdev, ring);
+       radeon_ring_unlock_commit(rdev, ring, false);
 
        for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) {
                ring = &rdev->ring[i];
@@ -3381,7 +3579,7 @@ static int si_cp_start(struct radeon_device *rdev)
                radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0));
                radeon_ring_write(ring, 0);
 
-               radeon_ring_unlock_commit(rdev, ring);
+               radeon_ring_unlock_commit(rdev, ring, false);
        }
 
        return 0;
@@ -4048,7 +4246,6 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
        r = radeon_gart_table_vram_pin(rdev);
        if (r)
                return r;
-       radeon_gart_restore(rdev);
        /* Setup TLB control */
        WREG32(MC_VM_MX_L1_TLB_CNTL,
               (0xA << 7) |
@@ -4093,10 +4290,10 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
        for (i = 1; i < 16; i++) {
                if (i < 8)
                        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
-                              rdev->gart.table_addr >> 12);
+                              rdev->vm_manager.saved_table_addr[i]);
                else
                        WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
-                              rdev->gart.table_addr >> 12);
+                              rdev->vm_manager.saved_table_addr[i]);
        }
 
        /* enable context1-15 */
@@ -4128,6 +4325,17 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
 
 static void si_pcie_gart_disable(struct radeon_device *rdev)
 {
+       unsigned i;
+
+       for (i = 1; i < 16; ++i) {
+               uint32_t reg;
+               if (i < 8)
+                       reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2);
+               else
+                       reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2);
+               rdev->vm_manager.saved_table_addr[i] = RREG32(reg);
+       }
+
        /* Disable all tables */
        WREG32(VM_CONTEXT0_CNTL, 0);
        WREG32(VM_CONTEXT1_CNTL, 0);
@@ -4815,7 +5023,7 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
 
        /* write new base address */
        radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
-       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
                                 WRITE_DATA_DST_SEL(0)));
 
        if (vm->id < 8) {
@@ -4830,7 +5038,7 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
 
        /* flush hdp cache */
        radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
-       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
                                 WRITE_DATA_DST_SEL(0)));
        radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
        radeon_ring_write(ring, 0);
@@ -4838,7 +5046,7 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
 
        /* bits 0-15 are the VM contexts0-15 */
        radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
-       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+       radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
                                 WRITE_DATA_DST_SEL(0)));
        radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
        radeon_ring_write(ring, 0);
@@ -5592,7 +5800,6 @@ static void si_enable_lbpw(struct radeon_device *rdev, bool enable)
 static int si_rlc_resume(struct radeon_device *rdev)
 {
        u32 i;
-       const __be32 *fw_data;
 
        if (!rdev->rlc_fw)
                return -EINVAL;
@@ -5615,10 +5822,26 @@ static int si_rlc_resume(struct radeon_device *rdev)
        WREG32(RLC_MC_CNTL, 0);
        WREG32(RLC_UCODE_CNTL, 0);
 
-       fw_data = (const __be32 *)rdev->rlc_fw->data;
-       for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
-               WREG32(RLC_UCODE_ADDR, i);
-               WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+       if (rdev->new_fw) {
+               const struct rlc_firmware_header_v1_0 *hdr =
+                       (const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data;
+               u32 fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+               const __le32 *fw_data = (const __le32 *)
+                       (rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+
+               radeon_ucode_print_rlc_hdr(&hdr->header);
+
+               for (i = 0; i < fw_size; i++) {
+                       WREG32(RLC_UCODE_ADDR, i);
+                       WREG32(RLC_UCODE_DATA, le32_to_cpup(fw_data++));
+               }
+       } else {
+               const __be32 *fw_data =
+                       (const __be32 *)rdev->rlc_fw->data;
+               for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
+                       WREG32(RLC_UCODE_ADDR, i);
+                       WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+               }
        }
        WREG32(RLC_UCODE_ADDR, 0);
 
@@ -6318,7 +6541,8 @@ restart_ih:
                case 16: /* D5 page flip */
                case 18: /* D6 page flip */
                        DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
-                       radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
+                       if (radeon_use_pflipirq > 0)
+                               radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
                        break;
                case 42: /* HPD hotplug */
                        switch (src_data) {
This page took 0.041228 seconds and 5 git commands to generate.