diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/cik.c')
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 793 |
1 files changed, 597 insertions, 196 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 0b2471107137..fa9565957f9d 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -42,6 +42,16 @@ MODULE_FIRMWARE("radeon/BONAIRE_mc2.bin"); MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin"); MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin"); MODULE_FIRMWARE("radeon/BONAIRE_smc.bin"); + +MODULE_FIRMWARE("radeon/bonaire_pfp.bin"); +MODULE_FIRMWARE("radeon/bonaire_me.bin"); +MODULE_FIRMWARE("radeon/bonaire_ce.bin"); +MODULE_FIRMWARE("radeon/bonaire_mec.bin"); +MODULE_FIRMWARE("radeon/bonaire_mc.bin"); +MODULE_FIRMWARE("radeon/bonaire_rlc.bin"); +MODULE_FIRMWARE("radeon/bonaire_sdma.bin"); +MODULE_FIRMWARE("radeon/bonaire_smc.bin"); + MODULE_FIRMWARE("radeon/HAWAII_pfp.bin"); MODULE_FIRMWARE("radeon/HAWAII_me.bin"); MODULE_FIRMWARE("radeon/HAWAII_ce.bin"); @@ -51,18 +61,45 @@ MODULE_FIRMWARE("radeon/HAWAII_mc2.bin"); MODULE_FIRMWARE("radeon/HAWAII_rlc.bin"); MODULE_FIRMWARE("radeon/HAWAII_sdma.bin"); MODULE_FIRMWARE("radeon/HAWAII_smc.bin"); + +MODULE_FIRMWARE("radeon/hawaii_pfp.bin"); +MODULE_FIRMWARE("radeon/hawaii_me.bin"); +MODULE_FIRMWARE("radeon/hawaii_ce.bin"); +MODULE_FIRMWARE("radeon/hawaii_mec.bin"); +MODULE_FIRMWARE("radeon/hawaii_mc.bin"); +MODULE_FIRMWARE("radeon/hawaii_rlc.bin"); +MODULE_FIRMWARE("radeon/hawaii_sdma.bin"); +MODULE_FIRMWARE("radeon/hawaii_smc.bin"); + MODULE_FIRMWARE("radeon/KAVERI_pfp.bin"); MODULE_FIRMWARE("radeon/KAVERI_me.bin"); MODULE_FIRMWARE("radeon/KAVERI_ce.bin"); MODULE_FIRMWARE("radeon/KAVERI_mec.bin"); MODULE_FIRMWARE("radeon/KAVERI_rlc.bin"); MODULE_FIRMWARE("radeon/KAVERI_sdma.bin"); + +MODULE_FIRMWARE("radeon/kaveri_pfp.bin"); +MODULE_FIRMWARE("radeon/kaveri_me.bin"); +MODULE_FIRMWARE("radeon/kaveri_ce.bin"); +MODULE_FIRMWARE("radeon/kaveri_mec.bin"); +MODULE_FIRMWARE("radeon/kaveri_mec2.bin"); +MODULE_FIRMWARE("radeon/kaveri_rlc.bin"); +MODULE_FIRMWARE("radeon/kaveri_sdma.bin"); + MODULE_FIRMWARE("radeon/KABINI_pfp.bin"); MODULE_FIRMWARE("radeon/KABINI_me.bin"); MODULE_FIRMWARE("radeon/KABINI_ce.bin"); MODULE_FIRMWARE("radeon/KABINI_mec.bin"); MODULE_FIRMWARE("radeon/KABINI_rlc.bin"); MODULE_FIRMWARE("radeon/KABINI_sdma.bin"); + +MODULE_FIRMWARE("radeon/kabini_pfp.bin"); +MODULE_FIRMWARE("radeon/kabini_me.bin"); +MODULE_FIRMWARE("radeon/kabini_ce.bin"); +MODULE_FIRMWARE("radeon/kabini_mec.bin"); +MODULE_FIRMWARE("radeon/kabini_rlc.bin"); +MODULE_FIRMWARE("radeon/kabini_sdma.bin"); + MODULE_FIRMWARE("radeon/MULLINS_pfp.bin"); MODULE_FIRMWARE("radeon/MULLINS_me.bin"); MODULE_FIRMWARE("radeon/MULLINS_ce.bin"); @@ -70,6 +107,13 @@ MODULE_FIRMWARE("radeon/MULLINS_mec.bin"); MODULE_FIRMWARE("radeon/MULLINS_rlc.bin"); MODULE_FIRMWARE("radeon/MULLINS_sdma.bin"); +MODULE_FIRMWARE("radeon/mullins_pfp.bin"); +MODULE_FIRMWARE("radeon/mullins_me.bin"); +MODULE_FIRMWARE("radeon/mullins_ce.bin"); +MODULE_FIRMWARE("radeon/mullins_mec.bin"); +MODULE_FIRMWARE("radeon/mullins_rlc.bin"); +MODULE_FIRMWARE("radeon/mullins_sdma.bin"); + extern int r600_ih_ring_alloc(struct radeon_device *rdev); extern void r600_ih_ring_fini(struct radeon_device *rdev); extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); @@ -1760,27 +1804,44 @@ static void cik_srbm_select(struct radeon_device *rdev, */ int ci_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; - switch (rdev->family) { - case CHIP_BONAIRE: - io_mc_regs = (u32 *)&bonaire_io_mc_regs; - regs_size = BONAIRE_IO_MC_REGS_SIZE; - break; - case CHIP_HAWAII: - io_mc_regs = (u32 *)&hawaii_io_mc_regs; - regs_size = HAWAII_IO_MC_REGS_SIZE; - break; - default: - return -EINVAL; + 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_BONAIRE: + io_mc_regs = (u32 *)&bonaire_io_mc_regs; + regs_size = BONAIRE_IO_MC_REGS_SIZE; + break; + case CHIP_HAWAII: + io_mc_regs = (u32 *)&hawaii_io_mc_regs; + regs_size = HAWAII_IO_MC_REGS_SIZE; + break; + default: + return -EINVAL; + } + fw_data = (const __be32 *)rdev->mc_fw->data; } running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; @@ -1797,13 +1858,21 @@ int ci_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); @@ -1841,17 +1910,21 @@ int ci_mc_load_microcode(struct radeon_device *rdev) static int cik_init_microcode(struct radeon_device *rdev) { const char *chip_name; + const char *new_chip_name; size_t pfp_req_size, me_req_size, ce_req_size, mec_req_size, rlc_req_size, mc_req_size = 0, sdma_req_size, smc_req_size = 0, mc2_req_size = 0; char fw_name[30]; + int new_fw = 0; int err; + int num_fw; DRM_DEBUG("\n"); switch (rdev->family) { case CHIP_BONAIRE: chip_name = "BONAIRE"; + new_chip_name = "bonaire"; pfp_req_size = CIK_PFP_UCODE_SIZE * 4; me_req_size = CIK_ME_UCODE_SIZE * 4; ce_req_size = CIK_CE_UCODE_SIZE * 4; @@ -1861,9 +1934,11 @@ static int cik_init_microcode(struct radeon_device *rdev) mc2_req_size = BONAIRE_MC2_UCODE_SIZE * 4; sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4); + num_fw = 8; break; case CHIP_HAWAII: chip_name = "HAWAII"; + new_chip_name = "hawaii"; pfp_req_size = CIK_PFP_UCODE_SIZE * 4; me_req_size = CIK_ME_UCODE_SIZE * 4; ce_req_size = CIK_CE_UCODE_SIZE * 4; @@ -1873,142 +1948,285 @@ static int cik_init_microcode(struct radeon_device *rdev) mc2_req_size = HAWAII_MC2_UCODE_SIZE * 4; sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4); + num_fw = 8; break; case CHIP_KAVERI: chip_name = "KAVERI"; + new_chip_name = "kaveri"; pfp_req_size = CIK_PFP_UCODE_SIZE * 4; me_req_size = CIK_ME_UCODE_SIZE * 4; ce_req_size = CIK_CE_UCODE_SIZE * 4; mec_req_size = CIK_MEC_UCODE_SIZE * 4; rlc_req_size = KV_RLC_UCODE_SIZE * 4; sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; + num_fw = 7; break; case CHIP_KABINI: chip_name = "KABINI"; + new_chip_name = "kabini"; pfp_req_size = CIK_PFP_UCODE_SIZE * 4; me_req_size = CIK_ME_UCODE_SIZE * 4; ce_req_size = CIK_CE_UCODE_SIZE * 4; mec_req_size = CIK_MEC_UCODE_SIZE * 4; rlc_req_size = KB_RLC_UCODE_SIZE * 4; sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; + num_fw = 6; break; case CHIP_MULLINS: chip_name = "MULLINS"; + new_chip_name = "mullins"; pfp_req_size = CIK_PFP_UCODE_SIZE * 4; me_req_size = CIK_ME_UCODE_SIZE * 4; ce_req_size = CIK_CE_UCODE_SIZE * 4; mec_req_size = CIK_MEC_UCODE_SIZE * 4; rlc_req_size = ML_RLC_UCODE_SIZE * 4; sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; + num_fw = 6; break; 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 - "cik_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 + "cik_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 + "cik_fw: 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 - "cik_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 + "cik_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 + "cik_fw: 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 - "cik_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 + "cik_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 + "cik_fw: validation failed for firmware \"%s\"\n", + fw_name); + goto out; + } else { + new_fw++; + } } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", new_chip_name); err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev); - if (err) - goto out; - if (rdev->mec_fw->size != mec_req_size) { - printk(KERN_ERR - "cik_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->mec_fw->size, fw_name); - err = -EINVAL; + if (err) { + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name); + err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev); + if (err) + goto out; + if (rdev->mec_fw->size != mec_req_size) { + printk(KERN_ERR + "cik_cp: Bogus length %zu in firmware \"%s\"\n", + rdev->mec_fw->size, fw_name); + err = -EINVAL; + } + } else { + err = radeon_ucode_validate(rdev->mec_fw); + if (err) { + printk(KERN_ERR + "cik_fw: validation failed for firmware \"%s\"\n", + fw_name); + goto out; + } else { + new_fw++; + } } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name); + if (rdev->family == CHIP_KAVERI) { + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec2.bin", new_chip_name); + err = request_firmware(&rdev->mec2_fw, fw_name, rdev->dev); + if (err) { + goto out; + } else { + err = radeon_ucode_validate(rdev->mec2_fw); + if (err) { + goto out; + } else { + new_fw++; + } + } + } + + 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 - "cik_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 + "cik_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 + "cik_fw: validation failed for firmware \"%s\"\n", + fw_name); + goto out; + } else { + new_fw++; + } } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", new_chip_name); err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev); - if (err) - goto out; - if (rdev->sdma_fw->size != sdma_req_size) { - printk(KERN_ERR - "cik_sdma: Bogus length %zu in firmware \"%s\"\n", - rdev->sdma_fw->size, fw_name); - err = -EINVAL; + if (err) { + snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name); + err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev); + if (err) + goto out; + if (rdev->sdma_fw->size != sdma_req_size) { + printk(KERN_ERR + "cik_sdma: Bogus length %zu in firmware \"%s\"\n", + rdev->sdma_fw->size, fw_name); + err = -EINVAL; + } + } else { + err = radeon_ucode_validate(rdev->sdma_fw); + if (err) { + printk(KERN_ERR + "cik_fw: validation failed for firmware \"%s\"\n", + fw_name); + goto out; + } else { + new_fw++; + } } /* No SMC, MC ucode on APUs */ if (!(rdev->flags & RADEON_IS_IGP)) { - 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 + "cik_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 + "cik_fw: 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 - "cik_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 - "cik_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 + "cik_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 + "cik_fw: 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 < num_fw) { + printk(KERN_ERR "ci_fw: mixing new and old firmware!\n"); + err = -EINVAL; + } else { + rdev->new_fw = true; + } + out: if (err) { if (err != -EINVAL) @@ -2021,8 +2239,14 @@ out: rdev->me_fw = NULL; release_firmware(rdev->ce_fw); rdev->ce_fw = NULL; + release_firmware(rdev->mec_fw); + rdev->mec_fw = NULL; + release_firmware(rdev->mec2_fw); + rdev->mec2_fw = NULL; release_firmware(rdev->rlc_fw); rdev->rlc_fw = NULL; + release_firmware(rdev->sdma_fw); + rdev->sdma_fw = NULL; release_firmware(rdev->mc_fw); rdev->mc_fw = NULL; release_firmware(rdev->smc_fw); @@ -2291,6 +2515,7 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev) gb_tile_moden = 0; break; } + rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden; WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden); } } else if (num_pipe_configs == 8) { @@ -3258,7 +3483,7 @@ static void cik_gpu_init(struct radeon_device *rdev) u32 mc_shared_chmap, mc_arb_ramcfg; u32 hdp_host_path_cntl; u32 tmp; - int i, j, k; + int i, j; switch (rdev->family) { case CHIP_BONAIRE: @@ -3319,6 +3544,7 @@ static void cik_gpu_init(struct radeon_device *rdev) (rdev->pdev->device == 0x130B) || (rdev->pdev->device == 0x130E) || (rdev->pdev->device == 0x1315) || + (rdev->pdev->device == 0x1318) || (rdev->pdev->device == 0x131B)) { rdev->config.cik.max_cu_per_sh = 4; rdev->config.cik.max_backends_per_se = 1; @@ -3447,12 +3673,11 @@ static void cik_gpu_init(struct radeon_device *rdev) rdev->config.cik.max_sh_per_se, rdev->config.cik.max_backends_per_se); + rdev->config.cik.active_cus = 0; for (i = 0; i < rdev->config.cik.max_shader_engines; i++) { for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) { - for (k = 0; k < rdev->config.cik.max_cu_per_sh; k++) { - rdev->config.cik.active_cus += - hweight32(cik_get_cu_active_bitmap(rdev, i, j)); - } + rdev->config.cik.active_cus += + hweight32(cik_get_cu_active_bitmap(rdev, i, j)); } } @@ -3576,7 +3801,7 @@ int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); radeon_ring_write(ring, ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2)); radeon_ring_write(ring, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev, ring); + radeon_ring_unlock_commit(rdev, ring, false); for (i = 0; i < rdev->usec_timeout; i++) { tmp = RREG32(scratch); @@ -3665,8 +3890,6 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev, radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | DATA_SEL(1) | INT_SEL(2)); radeon_ring_write(ring, fence->seq); radeon_ring_write(ring, 0); - /* HDP flush */ - cik_hdp_flush_cp_ring_emit(rdev, fence->ring); } /** @@ -3695,10 +3918,19 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev, radeon_ring_write(ring, upper_32_bits(addr)); radeon_ring_write(ring, fence->seq); radeon_ring_write(ring, 0); - /* HDP flush */ - cik_hdp_flush_cp_ring_emit(rdev, fence->ring); } +/** + * cik_semaphore_ring_emit - emit a semaphore on the CP ring + * + * @rdev: radeon_device pointer + * @ring: radeon ring buffer object + * @semaphore: radeon semaphore object + * @emit_wait: Is this a sempahore wait? + * + * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP + * from running ahead of semaphore waits. + */ bool cik_semaphore_ring_emit(struct radeon_device *rdev, struct radeon_ring *ring, struct radeon_semaphore *semaphore, @@ -3711,6 +3943,12 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev, radeon_ring_write(ring, lower_32_bits(addr)); radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); + if (emit_wait && ring->idx == RADEON_RING_TYPE_GFX_INDEX) { + /* Prevent the PFP from running ahead of the semaphore wait */ + radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); + radeon_ring_write(ring, 0x0); + } + return true; } @@ -3783,7 +4021,7 @@ int cik_copy_cpdma(struct radeon_device *rdev, return r; } - radeon_ring_unlock_commit(rdev, ring); + radeon_ring_unlock_commit(rdev, ring, false); radeon_semaphore_free(rdev, &sem, *fence); return r; @@ -3882,7 +4120,7 @@ int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2); ib.ptr[2] = 0xDEADBEEF; ib.length_dw = 3; - r = radeon_ib_schedule(rdev, &ib, NULL); + r = radeon_ib_schedule(rdev, &ib, NULL, false); if (r) { radeon_scratch_free(rdev, scratch); radeon_ib_free(rdev, &ib); @@ -3968,7 +4206,6 @@ static void cik_cp_gfx_enable(struct radeon_device *rdev, bool enable) */ static int cik_cp_gfx_load_microcode(struct radeon_device *rdev) { - const __be32 *fw_data; int i; if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw) @@ -3976,26 +4213,70 @@ static int cik_cp_gfx_load_microcode(struct radeon_device *rdev) cik_cp_gfx_enable(rdev, false); - /* PFP */ - fw_data = (const __be32 *)rdev->pfp_fw->data; - WREG32(CP_PFP_UCODE_ADDR, 0); - for (i = 0; i < CIK_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 < CIK_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 < CIK_ME_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 < CIK_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 < CIK_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 < CIK_ME_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); @@ -4060,7 +4341,7 @@ static int cik_cp_gfx_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); return 0; } @@ -4260,7 +4541,6 @@ static void cik_cp_compute_enable(struct radeon_device *rdev, bool enable) */ static int cik_cp_compute_load_microcode(struct radeon_device *rdev) { - const __be32 *fw_data; int i; if (!rdev->mec_fw) @@ -4268,20 +4548,55 @@ static int cik_cp_compute_load_microcode(struct radeon_device *rdev) cik_cp_compute_enable(rdev, false); - /* MEC1 */ - fw_data = (const __be32 *)rdev->mec_fw->data; - WREG32(CP_MEC_ME1_UCODE_ADDR, 0); - for (i = 0; i < CIK_MEC_UCODE_SIZE; i++) - WREG32(CP_MEC_ME1_UCODE_DATA, be32_to_cpup(fw_data++)); - WREG32(CP_MEC_ME1_UCODE_ADDR, 0); + if (rdev->new_fw) { + const struct gfx_firmware_header_v1_0 *mec_hdr = + (const struct gfx_firmware_header_v1_0 *)rdev->mec_fw->data; + const __le32 *fw_data; + u32 fw_size; + + radeon_ucode_print_gfx_hdr(&mec_hdr->header); + + /* MEC1 */ + fw_data = (const __le32 *) + (rdev->mec_fw->data + le32_to_cpu(mec_hdr->header.ucode_array_offset_bytes)); + fw_size = le32_to_cpu(mec_hdr->header.ucode_size_bytes) / 4; + WREG32(CP_MEC_ME1_UCODE_ADDR, 0); + for (i = 0; i < fw_size; i++) + WREG32(CP_MEC_ME1_UCODE_DATA, le32_to_cpup(fw_data++)); + WREG32(CP_MEC_ME1_UCODE_ADDR, 0); - if (rdev->family == CHIP_KAVERI) { /* MEC2 */ + if (rdev->family == CHIP_KAVERI) { + const struct gfx_firmware_header_v1_0 *mec2_hdr = + (const struct gfx_firmware_header_v1_0 *)rdev->mec2_fw->data; + + fw_data = (const __le32 *) + (rdev->mec2_fw->data + + le32_to_cpu(mec2_hdr->header.ucode_array_offset_bytes)); + fw_size = le32_to_cpu(mec2_hdr->header.ucode_size_bytes) / 4; + WREG32(CP_MEC_ME2_UCODE_ADDR, 0); + for (i = 0; i < fw_size; i++) + WREG32(CP_MEC_ME2_UCODE_DATA, le32_to_cpup(fw_data++)); + WREG32(CP_MEC_ME2_UCODE_ADDR, 0); + } + } else { + const __be32 *fw_data; + + /* MEC1 */ fw_data = (const __be32 *)rdev->mec_fw->data; - WREG32(CP_MEC_ME2_UCODE_ADDR, 0); + WREG32(CP_MEC_ME1_UCODE_ADDR, 0); for (i = 0; i < CIK_MEC_UCODE_SIZE; i++) - WREG32(CP_MEC_ME2_UCODE_DATA, be32_to_cpup(fw_data++)); - WREG32(CP_MEC_ME2_UCODE_ADDR, 0); + WREG32(CP_MEC_ME1_UCODE_DATA, be32_to_cpup(fw_data++)); + WREG32(CP_MEC_ME1_UCODE_ADDR, 0); + + if (rdev->family == CHIP_KAVERI) { + /* MEC2 */ + fw_data = (const __be32 *)rdev->mec_fw->data; + WREG32(CP_MEC_ME2_UCODE_ADDR, 0); + for (i = 0; i < CIK_MEC_UCODE_SIZE; i++) + WREG32(CP_MEC_ME2_UCODE_DATA, be32_to_cpup(fw_data++)); + WREG32(CP_MEC_ME2_UCODE_ADDR, 0); + } } return 0; @@ -4374,7 +4689,7 @@ static int cik_mec_init(struct radeon_device *rdev) r = radeon_bo_create(rdev, rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2, PAGE_SIZE, true, - RADEON_GEM_DOMAIN_GTT, NULL, + RADEON_GEM_DOMAIN_GTT, 0, NULL, &rdev->mec.hpd_eop_obj); if (r) { dev_warn(rdev->dev, "(%d) create HDP EOP bo failed\n", r); @@ -4544,7 +4859,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) r = radeon_bo_create(rdev, sizeof(struct bonaire_mqd), PAGE_SIZE, true, - RADEON_GEM_DOMAIN_GTT, NULL, + RADEON_GEM_DOMAIN_GTT, 0, NULL, &rdev->ring[idx].mqd_obj); if (r) { dev_warn(rdev->dev, "(%d) create MQD bo failed\n", r); @@ -5401,7 +5716,6 @@ static int cik_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) | @@ -5435,20 +5749,17 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) WREG32(0x15D8, 0); WREG32(0x15DC, 0); - /* empty context1-15 */ - /* FIXME start with 4G, once using 2 level pt switch to full - * vm size space - */ + /* restore context1-15 */ /* set vm size, must be a multiple of 4 */ WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); 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 */ @@ -5513,6 +5824,17 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) */ static void cik_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); @@ -5641,12 +5963,13 @@ static void cik_vm_decode_fault(struct radeon_device *rdev, void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) { struct radeon_ring *ring = &rdev->ring[ridx]; + int usepfp = (ridx == RADEON_RING_TYPE_GFX_INDEX); if (vm == NULL) return; 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(usepfp) | WRITE_DATA_DST_SEL(0))); if (vm->id < 8) { radeon_ring_write(ring, @@ -5660,14 +5983,14 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) /* update SH_MEM_* regs */ 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(usepfp) | WRITE_DATA_DST_SEL(0))); radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); radeon_ring_write(ring, 0); radeon_ring_write(ring, VMID(vm->id)); radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6)); - radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | + radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | WRITE_DATA_DST_SEL(0))); radeon_ring_write(ring, SH_MEM_BASES >> 2); radeon_ring_write(ring, 0); @@ -5678,7 +6001,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) radeon_ring_write(ring, 0); /* SH_MEM_APE1_LIMIT */ 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(usepfp) | WRITE_DATA_DST_SEL(0))); radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); radeon_ring_write(ring, 0); @@ -5689,14 +6012,14 @@ void cik_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(usepfp) | WRITE_DATA_DST_SEL(0))); radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); radeon_ring_write(ring, 0); radeon_ring_write(ring, 1 << vm->id); /* compute doesn't have PFP */ - if (ridx == RADEON_RING_TYPE_GFX_INDEX) { + if (usepfp) { /* sync PFP to ME, otherwise we might get invalid PFP reads */ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); radeon_ring_write(ring, 0x0); @@ -5864,28 +6187,10 @@ static void cik_rlc_start(struct radeon_device *rdev) static int cik_rlc_resume(struct radeon_device *rdev) { u32 i, size, tmp; - const __be32 *fw_data; if (!rdev->rlc_fw) return -EINVAL; - switch (rdev->family) { - case CHIP_BONAIRE: - case CHIP_HAWAII: - default: - size = BONAIRE_RLC_UCODE_SIZE; - break; - case CHIP_KAVERI: - size = KV_RLC_UCODE_SIZE; - break; - case CHIP_KABINI: - size = KB_RLC_UCODE_SIZE; - break; - case CHIP_MULLINS: - size = ML_RLC_UCODE_SIZE; - break; - } - cik_rlc_stop(rdev); /* disable CG */ @@ -5909,11 +6214,45 @@ static int cik_rlc_resume(struct radeon_device *rdev) WREG32(RLC_MC_CNTL, 0); WREG32(RLC_UCODE_CNTL, 0); - fw_data = (const __be32 *)rdev->rlc_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; + 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); + + size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; + WREG32(RLC_GPM_UCODE_ADDR, 0); + for (i = 0; i < size; i++) + WREG32(RLC_GPM_UCODE_DATA, le32_to_cpup(fw_data++)); + WREG32(RLC_GPM_UCODE_ADDR, 0); + } else { + const __be32 *fw_data; + + switch (rdev->family) { + case CHIP_BONAIRE: + case CHIP_HAWAII: + default: + size = BONAIRE_RLC_UCODE_SIZE; + break; + case CHIP_KAVERI: + size = KV_RLC_UCODE_SIZE; + break; + case CHIP_KABINI: + size = KB_RLC_UCODE_SIZE; + break; + case CHIP_MULLINS: + size = ML_RLC_UCODE_SIZE; + break; + } + + fw_data = (const __be32 *)rdev->rlc_fw->data; + WREG32(RLC_GPM_UCODE_ADDR, 0); + for (i = 0; i < size; i++) + WREG32(RLC_GPM_UCODE_DATA, be32_to_cpup(fw_data++)); WREG32(RLC_GPM_UCODE_ADDR, 0); - for (i = 0; i < size; i++) - WREG32(RLC_GPM_UCODE_DATA, be32_to_cpup(fw_data++)); - WREG32(RLC_GPM_UCODE_ADDR, 0); + } /* XXX - find out what chips support lbpw */ cik_enable_lbpw(rdev, false); @@ -6347,11 +6686,10 @@ static void cik_enable_gds_pg(struct radeon_device *rdev, bool enable) void cik_init_cp_pg_table(struct radeon_device *rdev) { - const __be32 *fw_data; volatile u32 *dst_ptr; int me, i, max_me = 4; u32 bo_offset = 0; - u32 table_offset; + u32 table_offset, table_size; if (rdev->family == CHIP_KAVERI) max_me = 5; @@ -6362,24 +6700,71 @@ void cik_init_cp_pg_table(struct radeon_device *rdev) /* write the cp table buffer */ dst_ptr = rdev->rlc.cp_table_ptr; for (me = 0; me < max_me; me++) { - if (me == 0) { - fw_data = (const __be32 *)rdev->ce_fw->data; - table_offset = CP_ME_TABLE_OFFSET; - } else if (me == 1) { - fw_data = (const __be32 *)rdev->pfp_fw->data; - table_offset = CP_ME_TABLE_OFFSET; - } else if (me == 2) { - fw_data = (const __be32 *)rdev->me_fw->data; - table_offset = CP_ME_TABLE_OFFSET; + if (rdev->new_fw) { + const __le32 *fw_data; + const struct gfx_firmware_header_v1_0 *hdr; + + if (me == 0) { + hdr = (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data; + fw_data = (const __le32 *) + (rdev->ce_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); + table_offset = le32_to_cpu(hdr->jt_offset); + table_size = le32_to_cpu(hdr->jt_size); + } else if (me == 1) { + hdr = (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data; + fw_data = (const __le32 *) + (rdev->pfp_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); + table_offset = le32_to_cpu(hdr->jt_offset); + table_size = le32_to_cpu(hdr->jt_size); + } else if (me == 2) { + hdr = (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data; + fw_data = (const __le32 *) + (rdev->me_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); + table_offset = le32_to_cpu(hdr->jt_offset); + table_size = le32_to_cpu(hdr->jt_size); + } else if (me == 3) { + hdr = (const struct gfx_firmware_header_v1_0 *)rdev->mec_fw->data; + fw_data = (const __le32 *) + (rdev->mec_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); + table_offset = le32_to_cpu(hdr->jt_offset); + table_size = le32_to_cpu(hdr->jt_size); + } else { + hdr = (const struct gfx_firmware_header_v1_0 *)rdev->mec2_fw->data; + fw_data = (const __le32 *) + (rdev->mec2_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); + table_offset = le32_to_cpu(hdr->jt_offset); + table_size = le32_to_cpu(hdr->jt_size); + } + + for (i = 0; i < table_size; i ++) { + dst_ptr[bo_offset + i] = + cpu_to_le32(le32_to_cpu(fw_data[table_offset + i])); + } + bo_offset += table_size; } else { - fw_data = (const __be32 *)rdev->mec_fw->data; - table_offset = CP_MEC_TABLE_OFFSET; - } + const __be32 *fw_data; + table_size = CP_ME_TABLE_SIZE; + + if (me == 0) { + fw_data = (const __be32 *)rdev->ce_fw->data; + table_offset = CP_ME_TABLE_OFFSET; + } else if (me == 1) { + fw_data = (const __be32 *)rdev->pfp_fw->data; + table_offset = CP_ME_TABLE_OFFSET; + } else if (me == 2) { + fw_data = (const __be32 *)rdev->me_fw->data; + table_offset = CP_ME_TABLE_OFFSET; + } else { + fw_data = (const __be32 *)rdev->mec_fw->data; + table_offset = CP_MEC_TABLE_OFFSET; + } - for (i = 0; i < CP_ME_TABLE_SIZE; i ++) { - dst_ptr[bo_offset + i] = cpu_to_le32(be32_to_cpu(fw_data[table_offset + i])); + for (i = 0; i < table_size; i ++) { + dst_ptr[bo_offset + i] = + cpu_to_le32(be32_to_cpu(fw_data[table_offset + i])); + } + bo_offset += table_size; } - bo_offset += CP_ME_TABLE_SIZE; } } @@ -7376,6 +7761,7 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp); + wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask); } @@ -7616,7 +8002,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) { @@ -7898,6 +8285,7 @@ restart_ih: static int cik_startup(struct radeon_device *rdev) { struct radeon_ring *ring; + u32 nop; int r; /* enable pcie gen2/3 link */ @@ -8031,9 +8419,18 @@ static int cik_startup(struct radeon_device *rdev) } cik_irq_set(rdev); + if (rdev->family == CHIP_HAWAII) { + if (rdev->new_fw) + nop = PACKET3(PACKET3_NOP, 0x3FFF); + else + nop = RADEON_CP_PACKET2; + } else { + nop = PACKET3(PACKET3_NOP, 0x3FFF); + } + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - PACKET3(PACKET3_NOP, 0x3FFF)); + nop); if (r) return r; @@ -8041,7 +8438,7 @@ static int cik_startup(struct radeon_device *rdev) /* type-2 packets are deprecated on MEC, use type-3 instead */ ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET, - PACKET3(PACKET3_NOP, 0x3FFF)); + nop); if (r) return r; ring->me = 1; /* first MEC */ @@ -8052,7 +8449,7 @@ static int cik_startup(struct radeon_device *rdev) /* type-2 packets are deprecated on MEC, use type-3 instead */ ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET, - PACKET3(PACKET3_NOP, 0x3FFF)); + nop); if (r) return r; /* dGPU only have 1 MEC */ @@ -9166,6 +9563,9 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) int ret, i; u16 tmp16; + if (pci_is_root_bus(rdev->pdev->bus)) + return; + if (radeon_pcie_gen2 == 0) return; @@ -9392,7 +9792,8 @@ static void cik_program_aspm(struct radeon_device *rdev) if (orig != data) WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data); - if (!disable_clkreq) { + if (!disable_clkreq && + !pci_is_root_bus(rdev->pdev->bus)) { struct pci_dev *root = rdev->pdev->bus->self; u32 lnkcap; |