diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/cik.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 803 | 
1 files changed, 601 insertions, 202 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index c0ea66192fe0..3d546c606b43 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); @@ -3259,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: @@ -3320,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; @@ -3448,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));  		}  	} @@ -3577,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); @@ -3666,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);  }  /** @@ -3696,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, @@ -3712,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;  } @@ -3784,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; @@ -3883,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); @@ -3969,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) @@ -3977,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); @@ -4061,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;  } @@ -4261,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) @@ -4269,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; @@ -4375,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); @@ -4489,7 +4803,7 @@ struct bonaire_mqd   */  static int cik_cp_compute_resume(struct radeon_device *rdev)  { -	int r, i, idx; +	int r, i, j, idx;  	u32 tmp;  	bool use_doorbell = true;  	u64 hqd_gpu_addr; @@ -4545,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); @@ -4608,7 +4922,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)  		mqd->queue_state.cp_hqd_pq_wptr= 0;  		if (RREG32(CP_HQD_ACTIVE) & 1) {  			WREG32(CP_HQD_DEQUEUE_REQUEST, 1); -			for (i = 0; i < rdev->usec_timeout; i++) { +			for (j = 0; j < rdev->usec_timeout; j++) {  				if (!(RREG32(CP_HQD_ACTIVE) & 1))  					break;  				udelay(1); @@ -5402,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) | @@ -5436,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 */ @@ -5514,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); @@ -5642,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, @@ -5661,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); @@ -5679,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); @@ -5690,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); @@ -5865,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 */ @@ -5910,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); -	for (i = 0; i < size; i++) -		WREG32(RLC_GPM_UCODE_DATA, be32_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); +	}  	/* XXX - find out what chips support lbpw */  	cik_enable_lbpw(rdev, false); @@ -6348,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; @@ -6363,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;  	}  } @@ -7367,17 +7751,17 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev)  		wptr = RREG32(IH_RB_WPTR);  	if (wptr & RB_OVERFLOW) { +		wptr &= ~RB_OVERFLOW;  		/* When a ring buffer overflow happen start parsing interrupt  		 * from the last not overwritten vector (wptr + 16). Hopefully  		 * this should allow us to catchup.  		 */ -		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", -			wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); +		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", +			 wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);  		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;  		tmp = RREG32(IH_RB_CNTL);  		tmp |= IH_WPTR_OVERFLOW_CLEAR;  		WREG32(IH_RB_CNTL, tmp); -		wptr &= ~RB_OVERFLOW;  	}  	return (wptr & rdev->ih.ptr_mask);  } @@ -7618,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) { @@ -7866,6 +8251,7 @@ restart_ih:  		/* wptr/rptr are in bytes! */  		rptr += 16;  		rptr &= rdev->ih.ptr_mask; +		WREG32(IH_RB_RPTR, rptr);  	}  	if (queue_hotplug)  		schedule_work(&rdev->hotplug_work); @@ -7874,7 +8260,6 @@ restart_ih:  	if (queue_thermal)  		schedule_work(&rdev->pm.dpm.thermal.work);  	rdev->ih.rptr = rptr; -	WREG32(IH_RB_RPTR, rdev->ih.rptr);  	atomic_set(&rdev->ih.lock, 0);  	/* make sure wptr hasn't changed while processing */ @@ -7900,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 */ @@ -8033,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; @@ -8043,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 */ @@ -8054,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 */ @@ -9168,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; @@ -9394,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;  |