Skip to content

Commit

Permalink
Merge branch 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
Dave Airlie committed Jul 16, 2013
2 parents ad81f05 + a01c34f commit d4639eb
Show file tree
Hide file tree
Showing 25 changed files with 733 additions and 171 deletions.
59 changes: 38 additions & 21 deletions drivers/gpu/drm/radeon/cik.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand All @@ -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";
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
16 changes: 16 additions & 0 deletions drivers/gpu/drm/radeon/cikd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 8 additions & 2 deletions drivers/gpu/drm/radeon/evergreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] =
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/radeon/evergreen_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit d4639eb

Please sign in to comment.