Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4639eba authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux

More DPM fixes, r6xx DMA fix for bo moving, UVD fixes,
one major regression fix on bootup on some machine (ttm backoff missing)

* 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux:
  radeon kms: do not flush uninitialized hotplug work
  drm/radeon/dpm/sumo: handle boost states properly when forcing a perf level
  drm/radeon: align VM PTBs (Page Table Blocks) to 32K
  drm/radeon: allow selection of alignment in the sub-allocator
  drm/radeon: never unpin UVD bo v3
  drm/radeon: fix UVD fence emit
  drm/radeon: add fault decode function for CIK
  drm/radeon: add fault decode function for SI (v2)
  drm/radeon: add fault decode function for cayman/TN (v2)
  drm/radeon: use radeon device for request firmware
  drm/radeon: add missing ttm_eu_backoff_reservation to radeon_bo_list_validate
  drm/radeon: use CP DMA on r6xx for bo moves
  drm/radeon: implement bo copy callback using CP DMA (v2)
  drm/radeon: Disable dma rings for bo moves on r6xx
  drm/radeon/dpm: disable gfx PG on PALM
  drm/radeon/hdmi: make sure we have an afmt block assigned
parents ad81f054 a01c34f7
Loading
Loading
Loading
Loading
+38 −21
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
 * Authors: Alex Deucher
 */
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include "drmP.h"
@@ -742,7 +741,6 @@ static int ci_mc_load_microcode(struct radeon_device *rdev)
 */
static int cik_init_microcode(struct radeon_device *rdev)
{
	struct platform_device *pdev;
	const char *chip_name;
	size_t pfp_req_size, me_req_size, ce_req_size,
		mec_req_size, rlc_req_size, mc_req_size,
@@ -752,13 +750,6 @@ static int cik_init_microcode(struct radeon_device *rdev)

	DRM_DEBUG("\n");

	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
	err = IS_ERR(pdev);
	if (err) {
		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
		return -EINVAL;
	}

	switch (rdev->family) {
	case CHIP_BONAIRE:
		chip_name = "BONAIRE";
@@ -794,7 +785,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
	DRM_INFO("Loading %s Microcode\n", chip_name);

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
	err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->pfp_fw->size != pfp_req_size) {
@@ -806,7 +797,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
	err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->me_fw->size != me_req_size) {
@@ -817,7 +808,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
	err = request_firmware(&rdev->ce_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->ce_fw->size != ce_req_size) {
@@ -828,7 +819,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name);
	err = request_firmware(&rdev->mec_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->mec_fw->size != mec_req_size) {
@@ -839,7 +830,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name);
	err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->rlc_fw->size != rlc_req_size) {
@@ -850,7 +841,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name);
	err = request_firmware(&rdev->sdma_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->sdma_fw->size != sdma_req_size) {
@@ -863,7 +854,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
	/* No MC ucode on APUs */
	if (!(rdev->flags & RADEON_IS_IGP)) {
		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
		err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
		if (err)
			goto out;
		if (rdev->mc_fw->size != mc_req_size) {
@@ -875,8 +866,6 @@ static int cik_init_microcode(struct radeon_device *rdev)
	}

out:
	platform_device_unregister(pdev);

	if (err) {
		if (err != -EINVAL)
			printk(KERN_ERR
@@ -4452,6 +4441,29 @@ void cik_vm_fini(struct radeon_device *rdev)
{
}

/**
 * cik_vm_decode_fault - print human readable fault info
 *
 * @rdev: radeon_device pointer
 * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
 * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
 *
 * Print human readable fault information (CIK).
 */
static void cik_vm_decode_fault(struct radeon_device *rdev,
				u32 status, u32 addr, u32 mc_client)
{
	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
	char *block = (char *)&mc_client;

	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
	       protections, vmid, addr,
	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
	       block, mc_id);
}

/**
 * cik_vm_flush - cik vm flush using the CP
 *
@@ -5507,6 +5519,7 @@ int cik_irq_process(struct radeon_device *rdev)
	u32 ring_index;
	bool queue_hotplug = false;
	bool queue_reset = false;
	u32 addr, status, mc_client;

	if (!rdev->ih.enabled || rdev->shutdown)
		return IRQ_NONE;
@@ -5742,11 +5755,15 @@ int cik_irq_process(struct radeon_device *rdev)
			break;
		case 146:
		case 147:
			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
			mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT);
			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
				RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
				addr);
			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
				RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
				status);
			cik_vm_decode_fault(rdev, status, addr, mc_client);
			/* reset addr and status */
			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
			break;
@@ -6961,7 +6978,7 @@ int cik_uvd_resume(struct radeon_device *rdev)

	/* programm the VCPU memory controller bits 0-27 */
	addr = rdev->uvd.gpu_addr >> 3;
	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3;
	WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
	WREG32(UVD_VCPU_CACHE_SIZE0, size);

+16 −0
Original line number Diff line number Diff line
@@ -136,6 +136,22 @@
#define VM_INVALIDATE_RESPONSE				0x147c

#define	VM_CONTEXT1_PROTECTION_FAULT_STATUS		0x14DC
#define		PROTECTIONS_MASK			(0xf << 0)
#define		PROTECTIONS_SHIFT			0
		/* bit 0: range
		 * bit 1: pde0
		 * bit 2: valid
		 * bit 3: read
		 * bit 4: write
		 */
#define		MEMORY_CLIENT_ID_MASK			(0xff << 12)
#define		MEMORY_CLIENT_ID_SHIFT			12
#define		MEMORY_CLIENT_RW_MASK			(1 << 24)
#define		MEMORY_CLIENT_RW_SHIFT			24
#define		FAULT_VMID_MASK				(0xf << 25)
#define		FAULT_VMID_SHIFT			25

#define	VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT		0x14E4

#define	VM_CONTEXT1_PROTECTION_FAULT_ADDR		0x14FC

+8 −2
Original line number Diff line number Diff line
@@ -139,6 +139,8 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
void evergreen_program_aspm(struct radeon_device *rdev);
extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
				     int ring, u32 cp_int_cntl);
extern void cayman_vm_decode_fault(struct radeon_device *rdev,
				   u32 status, u32 addr);

static const u32 evergreen_golden_registers[] =
{
@@ -4586,6 +4588,7 @@ int evergreen_irq_process(struct radeon_device *rdev)
	bool queue_hotplug = false;
	bool queue_hdmi = false;
	bool queue_thermal = false;
	u32 status, addr;

	if (!rdev->ih.enabled || rdev->shutdown)
		return IRQ_NONE;
@@ -4872,11 +4875,14 @@ int evergreen_irq_process(struct radeon_device *rdev)
			break;
		case 146:
		case 147:
			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
				RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
				addr);
			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
				RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
				status);
			cayman_vm_decode_fault(rdev, status, addr);
			/* reset addr and status */
			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
			break;
+6 −0
Original line number Diff line number Diff line
@@ -177,6 +177,9 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
	uint32_t offset;
	ssize_t err;

	if (!dig || !dig->afmt)
		return;

	/* Silent, r600_hdmi_enable will raise WARN for us */
	if (!dig->afmt->enabled)
		return;
@@ -280,6 +283,9 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;

	if (!dig || !dig->afmt)
		return;

	/* Silent, r600_hdmi_enable will raise WARN for us */
	if (enable && dig->afmt->enabled)
		return;
+166 −16
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
 * Authors: Alex Deucher
 */
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <drm/drmP.h>
@@ -684,7 +683,6 @@ int ni_mc_load_microcode(struct radeon_device *rdev)

int ni_init_microcode(struct radeon_device *rdev)
{
	struct platform_device *pdev;
	const char *chip_name;
	const char *rlc_chip_name;
	size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
@@ -694,13 +692,6 @@ int ni_init_microcode(struct radeon_device *rdev)

	DRM_DEBUG("\n");

	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
	err = IS_ERR(pdev);
	if (err) {
		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
		return -EINVAL;
	}

	switch (rdev->family) {
	case CHIP_BARTS:
		chip_name = "BARTS";
@@ -753,7 +744,7 @@ int ni_init_microcode(struct radeon_device *rdev)
	DRM_INFO("Loading %s Microcode\n", chip_name);

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
	err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->pfp_fw->size != pfp_req_size) {
@@ -765,7 +756,7 @@ int ni_init_microcode(struct radeon_device *rdev)
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
	err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->me_fw->size != me_req_size) {
@@ -776,7 +767,7 @@ int ni_init_microcode(struct radeon_device *rdev)
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
	err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
	err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
	if (err)
		goto out;
	if (rdev->rlc_fw->size != rlc_req_size) {
@@ -789,7 +780,7 @@ int ni_init_microcode(struct radeon_device *rdev)
	/* no MC ucode on TN */
	if (!(rdev->flags & RADEON_IS_IGP)) {
		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
		err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
		if (err)
			goto out;
		if (rdev->mc_fw->size != mc_req_size) {
@@ -802,7 +793,7 @@ int ni_init_microcode(struct radeon_device *rdev)

	if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
		err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev);
		err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
		if (err)
			goto out;
		if (rdev->smc_fw->size != smc_req_size) {
@@ -814,8 +805,6 @@ int ni_init_microcode(struct radeon_device *rdev)
	}

out:
	platform_device_unregister(pdev);

	if (err) {
		if (err != -EINVAL)
			printk(KERN_ERR
@@ -2461,6 +2450,167 @@ void cayman_vm_fini(struct radeon_device *rdev)
{
}

/**
 * cayman_vm_decode_fault - print human readable fault info
 *
 * @rdev: radeon_device pointer
 * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
 * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
 *
 * Print human readable fault information (cayman/TN).
 */
void cayman_vm_decode_fault(struct radeon_device *rdev,
			    u32 status, u32 addr)
{
	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
	char *block;

	switch (mc_id) {
	case 32:
	case 16:
	case 96:
	case 80:
	case 160:
	case 144:
	case 224:
	case 208:
		block = "CB";
		break;
	case 33:
	case 17:
	case 97:
	case 81:
	case 161:
	case 145:
	case 225:
	case 209:
		block = "CB_FMASK";
		break;
	case 34:
	case 18:
	case 98:
	case 82:
	case 162:
	case 146:
	case 226:
	case 210:
		block = "CB_CMASK";
		break;
	case 35:
	case 19:
	case 99:
	case 83:
	case 163:
	case 147:
	case 227:
	case 211:
		block = "CB_IMMED";
		break;
	case 36:
	case 20:
	case 100:
	case 84:
	case 164:
	case 148:
	case 228:
	case 212:
		block = "DB";
		break;
	case 37:
	case 21:
	case 101:
	case 85:
	case 165:
	case 149:
	case 229:
	case 213:
		block = "DB_HTILE";
		break;
	case 38:
	case 22:
	case 102:
	case 86:
	case 166:
	case 150:
	case 230:
	case 214:
		block = "SX";
		break;
	case 39:
	case 23:
	case 103:
	case 87:
	case 167:
	case 151:
	case 231:
	case 215:
		block = "DB_STEN";
		break;
	case 40:
	case 24:
	case 104:
	case 88:
	case 232:
	case 216:
	case 168:
	case 152:
		block = "TC_TFETCH";
		break;
	case 41:
	case 25:
	case 105:
	case 89:
	case 233:
	case 217:
	case 169:
	case 153:
		block = "TC_VFETCH";
		break;
	case 42:
	case 26:
	case 106:
	case 90:
	case 234:
	case 218:
	case 170:
	case 154:
		block = "VC";
		break;
	case 112:
		block = "CP";
		break;
	case 113:
	case 114:
		block = "SH";
		break;
	case 115:
		block = "VGT";
		break;
	case 178:
		block = "IH";
		break;
	case 51:
		block = "RLC";
		break;
	case 55:
		block = "DMA";
		break;
	case 56:
		block = "HDP";
		break;
	default:
		block = "unknown";
		break;
	}

	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
	       protections, vmid, addr,
	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
	       block, mc_id);
}

#define R600_ENTRY_VALID   (1 << 0)
#define R600_PTE_SYSTEM    (1 << 1)
#define R600_PTE_SNOOPED   (1 << 2)
Loading