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
This commit is contained in:
commit
d4639ebadb
25 changed files with 745 additions and 183 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -133,6 +133,22 @@
|
|||
#define VM_CONTEXT1_CNTL2 0x1434
|
||||
#define VM_INVALIDATE_REQUEST 0x1478
|
||||
#define VM_INVALIDATE_RESPONSE 0x147c
|
||||
#define VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x14FC
|
||||
#define VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x14DC
|
||||
#define PROTECTIONS_MASK (0xf << 0)
|
||||
#define PROTECTIONS_SHIFT 0
|
||||
/* bit 0: range
|
||||
* bit 2: pde0
|
||||
* bit 3: valid
|
||||
* bit 4: read
|
||||
* bit 5: 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 (0x7 << 25)
|
||||
#define FAULT_VMID_SHIFT 25
|
||||
#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518
|
||||
#define VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR 0x151c
|
||||
#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "atom.h"
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "r100_reg_safe.h"
|
||||
|
@ -989,18 +988,11 @@ void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring)
|
|||
/* Load the microcode for the CP */
|
||||
static int r100_cp_init_microcode(struct radeon_device *rdev)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
const char *fw_name = NULL;
|
||||
int err;
|
||||
|
||||
DRM_DEBUG_KMS("\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;
|
||||
}
|
||||
if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
|
||||
(rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
|
||||
(rdev->family == CHIP_RS200)) {
|
||||
|
@ -1042,8 +1034,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
|
|||
fw_name = FIRMWARE_R520;
|
||||
}
|
||||
|
||||
err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
|
||||
platform_device_unregister(pdev);
|
||||
err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
|
||||
fw_name);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
|
@ -2144,7 +2143,6 @@ void r600_cp_stop(struct radeon_device *rdev)
|
|||
|
||||
int r600_init_microcode(struct radeon_device *rdev)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
const char *chip_name;
|
||||
const char *rlc_chip_name;
|
||||
const char *smc_chip_name = "RV770";
|
||||
|
@ -2154,13 +2152,6 @@ int r600_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_R600:
|
||||
chip_name = "R600";
|
||||
|
@ -2272,7 +2263,7 @@ int r600_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) {
|
||||
|
@ -2284,7 +2275,7 @@ int r600_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) {
|
||||
|
@ -2295,7 +2286,7 @@ int r600_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) {
|
||||
|
@ -2307,7 +2298,7 @@ int r600_init_microcode(struct radeon_device *rdev)
|
|||
|
||||
if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) {
|
||||
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_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) {
|
||||
|
@ -2319,8 +2310,6 @@ int r600_init_microcode(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
out:
|
||||
platform_device_unregister(pdev);
|
||||
|
||||
if (err) {
|
||||
if (err != -EINVAL)
|
||||
printk(KERN_ERR
|
||||
|
@ -3019,7 +3008,7 @@ void r600_uvd_fence_emit(struct radeon_device *rdev,
|
|||
struct radeon_fence *fence)
|
||||
{
|
||||
struct radeon_ring *ring = &rdev->ring[fence->ring];
|
||||
uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr;
|
||||
uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
|
||||
|
||||
radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
|
||||
radeon_ring_write(ring, fence->seq);
|
||||
|
@ -3144,6 +3133,87 @@ int r600_copy_blit(struct radeon_device *rdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* r600_copy_cpdma - copy pages using the CP DMA engine
|
||||
*
|
||||
* @rdev: radeon_device pointer
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @num_gpu_pages: number of GPU pages to xfer
|
||||
* @fence: radeon fence object
|
||||
*
|
||||
* Copy GPU paging using the CP DMA engine (r6xx+).
|
||||
* Used by the radeon ttm implementation to move pages if
|
||||
* registered as the asic copy callback.
|
||||
*/
|
||||
int r600_copy_cpdma(struct radeon_device *rdev,
|
||||
uint64_t src_offset, uint64_t dst_offset,
|
||||
unsigned num_gpu_pages,
|
||||
struct radeon_fence **fence)
|
||||
{
|
||||
struct radeon_semaphore *sem = NULL;
|
||||
int ring_index = rdev->asic->copy.blit_ring_index;
|
||||
struct radeon_ring *ring = &rdev->ring[ring_index];
|
||||
u32 size_in_bytes, cur_size_in_bytes, tmp;
|
||||
int i, num_loops;
|
||||
int r = 0;
|
||||
|
||||
r = radeon_semaphore_create(rdev, &sem);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: moving bo (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
|
||||
num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff);
|
||||
r = radeon_ring_lock(rdev, ring, num_loops * 6 + 21);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: moving bo (%d).\n", r);
|
||||
radeon_semaphore_free(rdev, &sem, NULL);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (radeon_fence_need_sync(*fence, ring->idx)) {
|
||||
radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
|
||||
ring->idx);
|
||||
radeon_fence_note_sync(*fence, ring->idx);
|
||||
} else {
|
||||
radeon_semaphore_free(rdev, &sem, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_loops; i++) {
|
||||
cur_size_in_bytes = size_in_bytes;
|
||||
if (cur_size_in_bytes > 0x1fffff)
|
||||
cur_size_in_bytes = 0x1fffff;
|
||||
size_in_bytes -= cur_size_in_bytes;
|
||||
tmp = upper_32_bits(src_offset) & 0xff;
|
||||
if (size_in_bytes == 0)
|
||||
tmp |= PACKET3_CP_DMA_CP_SYNC;
|
||||
radeon_ring_write(ring, PACKET3(PACKET3_CP_DMA, 4));
|
||||
radeon_ring_write(ring, src_offset & 0xffffffff);
|
||||
radeon_ring_write(ring, tmp);
|
||||
radeon_ring_write(ring, dst_offset & 0xffffffff);
|
||||
radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
|
||||
radeon_ring_write(ring, cur_size_in_bytes);
|
||||
src_offset += cur_size_in_bytes;
|
||||
dst_offset += cur_size_in_bytes;
|
||||
}
|
||||
radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
|
||||
radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
|
||||
radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit);
|
||||
|
||||
r = radeon_fence_emit(rdev, fence, ring->idx);
|
||||
if (r) {
|
||||
radeon_ring_unlock_undo(rdev, ring);
|
||||
return r;
|
||||
}
|
||||
|
||||
radeon_ring_unlock_commit(rdev, ring);
|
||||
radeon_semaphore_free(rdev, &sem, *fence);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* r600_copy_dma - copy pages using the DMA engine
|
||||
*
|
||||
|
|
|
@ -266,6 +266,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
|
|||
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;
|
||||
|
@ -448,6 +451,9 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)
|
|||
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
|
||||
u32 hdmi = HDMI0_ERROR_ACK;
|
||||
|
||||
if (!dig || !dig->afmt)
|
||||
return;
|
||||
|
||||
/* Silent, r600_hdmi_enable will raise WARN for us */
|
||||
if (enable && dig->afmt->enabled)
|
||||
return;
|
||||
|
|
|
@ -602,6 +602,7 @@
|
|||
#define L2_BUSY (1 << 0)
|
||||
|
||||
#define WAIT_UNTIL 0x8040
|
||||
#define WAIT_CP_DMA_IDLE_bit (1 << 8)
|
||||
#define WAIT_2D_IDLE_bit (1 << 14)
|
||||
#define WAIT_3D_IDLE_bit (1 << 15)
|
||||
#define WAIT_2D_IDLECLEAN_bit (1 << 16)
|
||||
|
|
|
@ -455,6 +455,7 @@ struct radeon_sa_manager {
|
|||
uint64_t gpu_addr;
|
||||
void *cpu_ptr;
|
||||
uint32_t domain;
|
||||
uint32_t align;
|
||||
};
|
||||
|
||||
struct radeon_sa_bo;
|
||||
|
@ -783,6 +784,11 @@ struct radeon_mec {
|
|||
/* number of entries in page table */
|
||||
#define RADEON_VM_PTE_COUNT (1 << RADEON_VM_BLOCK_SIZE)
|
||||
|
||||
/* PTBs (Page Table Blocks) need to be aligned to 32K */
|
||||
#define RADEON_VM_PTB_ALIGN_SIZE 32768
|
||||
#define RADEON_VM_PTB_ALIGN_MASK (RADEON_VM_PTB_ALIGN_SIZE - 1)
|
||||
#define RADEON_VM_PTB_ALIGN(a) (((a) + RADEON_VM_PTB_ALIGN_MASK) & ~RADEON_VM_PTB_ALIGN_MASK)
|
||||
|
||||
struct radeon_vm {
|
||||
struct list_head list;
|
||||
struct list_head va;
|
||||
|
@ -1460,6 +1466,8 @@ struct radeon_uvd {
|
|||
struct radeon_bo *vcpu_bo;
|
||||
void *cpu_addr;
|
||||
uint64_t gpu_addr;
|
||||
void *saved_bo;
|
||||
unsigned fw_size;
|
||||
atomic_t handles[RADEON_MAX_UVD_HANDLES];
|
||||
struct drm_file *filp[RADEON_MAX_UVD_HANDLES];
|
||||
struct delayed_work idle_work;
|
||||
|
@ -2054,7 +2062,6 @@ struct radeon_device {
|
|||
const struct firmware *rlc_fw; /* r6/700 RLC firmware */
|
||||
const struct firmware *mc_fw; /* NI MC firmware */
|
||||
const struct firmware *ce_fw; /* SI CE firmware */
|
||||
const struct firmware *uvd_fw; /* UVD firmware */
|
||||
const struct firmware *mec_fw; /* CIK MEC firmware */
|
||||
const struct firmware *sdma_fw; /* CIK SDMA firmware */
|
||||
const struct firmware *smc_fw; /* SMC firmware */
|
||||
|
|
|
@ -1026,8 +1026,8 @@ static struct radeon_asic r600_asic = {
|
|||
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
.dma = &r600_copy_dma,
|
||||
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
|
||||
.copy = &r600_copy_dma,
|
||||
.copy_ring_index = R600_RING_TYPE_DMA_INDEX,
|
||||
.copy = &r600_copy_cpdma,
|
||||
.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
},
|
||||
.surface = {
|
||||
.set_reg = r600_set_surface_reg,
|
||||
|
@ -1119,8 +1119,8 @@ static struct radeon_asic rv6xx_asic = {
|
|||
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
.dma = &r600_copy_dma,
|
||||
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
|
||||
.copy = &r600_copy_dma,
|
||||
.copy_ring_index = R600_RING_TYPE_DMA_INDEX,
|
||||
.copy = &r600_copy_cpdma,
|
||||
.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
},
|
||||
.surface = {
|
||||
.set_reg = r600_set_surface_reg,
|
||||
|
@ -1229,8 +1229,8 @@ static struct radeon_asic rs780_asic = {
|
|||
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
.dma = &r600_copy_dma,
|
||||
.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
|
||||
.copy = &r600_copy_dma,
|
||||
.copy_ring_index = R600_RING_TYPE_DMA_INDEX,
|
||||
.copy = &r600_copy_cpdma,
|
||||
.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
},
|
||||
.surface = {
|
||||
.set_reg = r600_set_surface_reg,
|
||||
|
|
|
@ -340,6 +340,9 @@ int r600_uvd_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
|
|||
int r600_copy_blit(struct radeon_device *rdev,
|
||||
uint64_t src_offset, uint64_t dst_offset,
|
||||
unsigned num_gpu_pages, struct radeon_fence **fence);
|
||||
int r600_copy_cpdma(struct radeon_device *rdev,
|
||||
uint64_t src_offset, uint64_t dst_offset,
|
||||
unsigned num_gpu_pages, struct radeon_fence **fence);
|
||||
int r600_copy_dma(struct radeon_device *rdev,
|
||||
uint64_t src_offset, uint64_t dst_offset,
|
||||
unsigned num_gpu_pages, struct radeon_fence **fence);
|
||||
|
|
|
@ -782,7 +782,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
|
|||
|
||||
} else {
|
||||
/* put fence directly behind firmware */
|
||||
index = ALIGN(rdev->uvd_fw->size, 8);
|
||||
index = ALIGN(rdev->uvd.fw_size, 8);
|
||||
rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index;
|
||||
rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index;
|
||||
}
|
||||
|
|
|
@ -466,7 +466,8 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
|
|||
size += rdev->vm_manager.max_pfn * 8;
|
||||
size *= 2;
|
||||
r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
|
||||
RADEON_GPU_PAGE_ALIGN(size),
|
||||
RADEON_VM_PTB_ALIGN(size),
|
||||
RADEON_VM_PTB_ALIGN_SIZE,
|
||||
RADEON_GEM_DOMAIN_VRAM);
|
||||
if (r) {
|
||||
dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
|
||||
|
@ -620,10 +621,10 @@ int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm)
|
|||
}
|
||||
|
||||
retry:
|
||||
pd_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev));
|
||||
pd_size = RADEON_VM_PTB_ALIGN(radeon_vm_directory_size(rdev));
|
||||
r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager,
|
||||
&vm->page_directory, pd_size,
|
||||
RADEON_GPU_PAGE_SIZE, false);
|
||||
RADEON_VM_PTB_ALIGN_SIZE, false);
|
||||
if (r == -ENOMEM) {
|
||||
r = radeon_vm_evict(rdev, vm);
|
||||
if (r)
|
||||
|
@ -952,8 +953,8 @@ static int radeon_vm_update_pdes(struct radeon_device *rdev,
|
|||
retry:
|
||||
r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager,
|
||||
&vm->page_tables[pt_idx],
|
||||
RADEON_VM_PTE_COUNT * 8,
|
||||
RADEON_GPU_PAGE_SIZE, false);
|
||||
RADEON_VM_PTB_ALIGN(RADEON_VM_PTE_COUNT * 8),
|
||||
RADEON_VM_PTB_ALIGN_SIZE, false);
|
||||
|
||||
if (r == -ENOMEM) {
|
||||
r = radeon_vm_evict(rdev, vm);
|
||||
|
|
|
@ -260,10 +260,6 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
|
|||
{
|
||||
int r = 0;
|
||||
|
||||
INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
|
||||
INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
|
||||
INIT_WORK(&rdev->reset_work, radeon_irq_reset_work_func);
|
||||
|
||||
spin_lock_init(&rdev->irq.lock);
|
||||
r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
|
||||
if (r) {
|
||||
|
@ -285,6 +281,11 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
|
|||
rdev->irq.installed = false;
|
||||
return r;
|
||||
}
|
||||
|
||||
INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
|
||||
INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
|
||||
INIT_WORK(&rdev->reset_work, radeon_irq_reset_work_func);
|
||||
|
||||
DRM_INFO("radeon: irq initialized.\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -304,8 +305,8 @@ void radeon_irq_kms_fini(struct radeon_device *rdev)
|
|||
rdev->irq.installed = false;
|
||||
if (rdev->msi_enabled)
|
||||
pci_disable_msi(rdev->pdev);
|
||||
flush_work(&rdev->hotplug_work);
|
||||
}
|
||||
flush_work(&rdev->hotplug_work);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -377,6 +377,7 @@ int radeon_bo_list_validate(struct ww_acquire_ctx *ticket,
|
|||
domain = lobj->alt_domain;
|
||||
goto retry;
|
||||
}
|
||||
ttm_eu_backoff_reservation(ticket, head);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo)
|
|||
|
||||
extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
|
||||
struct radeon_sa_manager *sa_manager,
|
||||
unsigned size, u32 domain);
|
||||
unsigned size, u32 align, u32 domain);
|
||||
extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
|
||||
struct radeon_sa_manager *sa_manager);
|
||||
extern int radeon_sa_bo_manager_start(struct radeon_device *rdev,
|
||||
|
|
|
@ -224,6 +224,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
|
|||
}
|
||||
r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
|
||||
RADEON_IB_POOL_SIZE*64*1024,
|
||||
RADEON_GPU_PAGE_SIZE,
|
||||
RADEON_GEM_DOMAIN_GTT);
|
||||
if (r) {
|
||||
return r;
|
||||
|
|
|
@ -49,7 +49,7 @@ static void radeon_sa_bo_try_free(struct radeon_sa_manager *sa_manager);
|
|||
|
||||
int radeon_sa_bo_manager_init(struct radeon_device *rdev,
|
||||
struct radeon_sa_manager *sa_manager,
|
||||
unsigned size, u32 domain)
|
||||
unsigned size, u32 align, u32 domain)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
|
@ -57,13 +57,14 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev,
|
|||
sa_manager->bo = NULL;
|
||||
sa_manager->size = size;
|
||||
sa_manager->domain = domain;
|
||||
sa_manager->align = align;
|
||||
sa_manager->hole = &sa_manager->olist;
|
||||
INIT_LIST_HEAD(&sa_manager->olist);
|
||||
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
|
||||
INIT_LIST_HEAD(&sa_manager->flist[i]);
|
||||
}
|
||||
|
||||
r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true,
|
||||
r = radeon_bo_create(rdev, size, align, true,
|
||||
domain, NULL, &sa_manager->bo);
|
||||
if (r) {
|
||||
dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r);
|
||||
|
@ -317,7 +318,7 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
|
|||
unsigned tries[RADEON_NUM_RINGS];
|
||||
int i, r;
|
||||
|
||||
BUG_ON(align > RADEON_GPU_PAGE_SIZE);
|
||||
BUG_ON(align > sa_manager->align);
|
||||
BUG_ON(size > sa_manager->size);
|
||||
|
||||
*sa_bo = kmalloc(sizeof(struct radeon_sa_bo), GFP_KERNEL);
|
||||
|
|
|
@ -56,20 +56,13 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work);
|
|||
|
||||
int radeon_uvd_init(struct radeon_device *rdev)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
const struct firmware *fw;
|
||||
unsigned long bo_size;
|
||||
const char *fw_name;
|
||||
int i, r;
|
||||
|
||||
INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);
|
||||
|
||||
pdev = platform_device_register_simple("radeon_uvd", 0, NULL, 0);
|
||||
r = IS_ERR(pdev);
|
||||
if (r) {
|
||||
dev_err(rdev->dev, "radeon_uvd: Failed to register firmware\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (rdev->family) {
|
||||
case CHIP_RV710:
|
||||
case CHIP_RV730:
|
||||
|
@ -112,17 +105,14 @@ int radeon_uvd_init(struct radeon_device *rdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = request_firmware(&rdev->uvd_fw, fw_name, &pdev->dev);
|
||||
r = request_firmware(&fw, fw_name, rdev->dev);
|
||||
if (r) {
|
||||
dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
|
||||
fw_name);
|
||||
platform_device_unregister(pdev);
|
||||
return r;
|
||||
}
|
||||
|
||||
platform_device_unregister(pdev);
|
||||
|
||||
bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
|
||||
bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) +
|
||||
RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
|
||||
r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
|
||||
RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo);
|
||||
|
@ -131,64 +121,6 @@ int radeon_uvd_init(struct radeon_device *rdev)
|
|||
return r;
|
||||
}
|
||||
|
||||
r = radeon_uvd_resume(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
memset(rdev->uvd.cpu_addr, 0, bo_size);
|
||||
memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
|
||||
|
||||
r = radeon_uvd_suspend(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
|
||||
atomic_set(&rdev->uvd.handles[i], 0);
|
||||
rdev->uvd.filp[i] = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_uvd_fini(struct radeon_device *rdev)
|
||||
{
|
||||
radeon_uvd_suspend(rdev);
|
||||
radeon_bo_unref(&rdev->uvd.vcpu_bo);
|
||||
}
|
||||
|
||||
int radeon_uvd_suspend(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (rdev->uvd.vcpu_bo == NULL)
|
||||
return 0;
|
||||
|
||||
r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
|
||||
if (!r) {
|
||||
radeon_bo_kunmap(rdev->uvd.vcpu_bo);
|
||||
radeon_bo_unpin(rdev->uvd.vcpu_bo);
|
||||
rdev->uvd.cpu_addr = NULL;
|
||||
if (!radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_CPU, NULL)) {
|
||||
radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr);
|
||||
}
|
||||
radeon_bo_unreserve(rdev->uvd.vcpu_bo);
|
||||
|
||||
if (rdev->uvd.cpu_addr) {
|
||||
radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
|
||||
} else {
|
||||
rdev->fence_drv[R600_RING_TYPE_UVD_INDEX].cpu_addr = NULL;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int radeon_uvd_resume(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (rdev->uvd.vcpu_bo == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
|
||||
if (r) {
|
||||
radeon_bo_unref(&rdev->uvd.vcpu_bo);
|
||||
|
@ -196,10 +128,6 @@ int radeon_uvd_resume(struct radeon_device *rdev)
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Have been pin in cpu unmap unpin */
|
||||
radeon_bo_kunmap(rdev->uvd.vcpu_bo);
|
||||
radeon_bo_unpin(rdev->uvd.vcpu_bo);
|
||||
|
||||
r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->uvd.gpu_addr);
|
||||
if (r) {
|
||||
|
@ -217,6 +145,63 @@ int radeon_uvd_resume(struct radeon_device *rdev)
|
|||
|
||||
radeon_bo_unreserve(rdev->uvd.vcpu_bo);
|
||||
|
||||
rdev->uvd.fw_size = fw->size;
|
||||
memset(rdev->uvd.cpu_addr, 0, bo_size);
|
||||
memcpy(rdev->uvd.cpu_addr, fw->data, fw->size);
|
||||
|
||||
release_firmware(fw);
|
||||
|
||||
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
|
||||
atomic_set(&rdev->uvd.handles[i], 0);
|
||||
rdev->uvd.filp[i] = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_uvd_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (rdev->uvd.vcpu_bo == NULL)
|
||||
return;
|
||||
|
||||
r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
|
||||
if (!r) {
|
||||
radeon_bo_kunmap(rdev->uvd.vcpu_bo);
|
||||
radeon_bo_unpin(rdev->uvd.vcpu_bo);
|
||||
radeon_bo_unreserve(rdev->uvd.vcpu_bo);
|
||||
}
|
||||
|
||||
radeon_bo_unref(&rdev->uvd.vcpu_bo);
|
||||
}
|
||||
|
||||
int radeon_uvd_suspend(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned size;
|
||||
|
||||
if (rdev->uvd.vcpu_bo == NULL)
|
||||
return 0;
|
||||
|
||||
size = radeon_bo_size(rdev->uvd.vcpu_bo);
|
||||
rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
|
||||
memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_uvd_resume(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->uvd.vcpu_bo == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (rdev->uvd.saved_bo != NULL) {
|
||||
unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo);
|
||||
memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size);
|
||||
kfree(rdev->uvd.saved_bo);
|
||||
rdev->uvd.saved_bo = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -813,7 +813,7 @@ int rv770_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);
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
@ -1541,7 +1540,6 @@ static int si_mc_load_microcode(struct radeon_device *rdev)
|
|||
|
||||
static int si_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, ce_req_size, rlc_req_size, mc_req_size;
|
||||
|
@ -1551,13 +1549,6 @@ static int si_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_TAHITI:
|
||||
chip_name = "TAHITI";
|
||||
|
@ -1615,7 +1606,7 @@ static int si_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) {
|
||||
|
@ -1627,7 +1618,7 @@ static int si_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) {
|
||||
|
@ -1638,7 +1629,7 @@ static int si_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) {
|
||||
|
@ -1649,7 +1640,7 @@ static int si_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) {
|
||||
|
@ -1660,7 +1651,7 @@ static int si_init_microcode(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -1671,7 +1662,7 @@ static int si_init_microcode(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -1682,8 +1673,6 @@ static int si_init_microcode(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
out:
|
||||
platform_device_unregister(pdev);
|
||||
|
||||
if (err) {
|
||||
if (err != -EINVAL)
|
||||
printk(KERN_ERR
|
||||
|
@ -4400,6 +4389,270 @@ void si_vm_fini(struct radeon_device *rdev)
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* si_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 (SI).
|
||||
*/
|
||||
static void si_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;
|
||||
|
||||
if (rdev->family == CHIP_TAHITI) {
|
||||
switch (mc_id) {
|
||||
case 160:
|
||||
case 144:
|
||||
case 96:
|
||||
case 80:
|
||||
case 224:
|
||||
case 208:
|
||||
case 32:
|
||||
case 16:
|
||||
block = "CB";
|
||||
break;
|
||||
case 161:
|
||||
case 145:
|
||||
case 97:
|
||||
case 81:
|
||||
case 225:
|
||||
case 209:
|
||||
case 33:
|
||||
case 17:
|
||||
block = "CB_FMASK";
|
||||
break;
|
||||
case 162:
|
||||
case 146:
|
||||
case 98:
|
||||
case 82:
|
||||
case 226:
|
||||
case 210:
|
||||
case 34:
|
||||
case 18:
|
||||
block = "CB_CMASK";
|
||||
break;
|
||||
case 163:
|
||||
case 147:
|
||||
case 99:
|
||||
case 83:
|
||||
case 227:
|
||||
case 211:
|
||||
case 35:
|
||||
case 19:
|
||||
block = "CB_IMMED";
|
||||
break;
|
||||
case 164:
|
||||
case 148:
|
||||
case 100:
|
||||
case 84:
|
||||
case 228:
|
||||
case 212:
|
||||
case 36:
|
||||
case 20:
|
||||
block = "DB";
|
||||
break;
|
||||
case 165:
|
||||
case 149:
|
||||
case 101:
|
||||
case 85:
|
||||
case 229:
|
||||
case 213:
|
||||
case 37:
|
||||
case 21:
|
||||
block = "DB_HTILE";
|
||||
break;
|
||||
case 167:
|
||||
case 151:
|
||||
case 103:
|
||||
case 87:
|
||||
case 231:
|
||||
case 215:
|
||||
case 39:
|
||||
case 23:
|
||||
block = "DB_STEN";
|
||||
break;
|
||||
case 72:
|
||||
case 68:
|
||||
case 64:
|
||||
case 8:
|
||||
case 4:
|
||||
case 0:
|
||||
case 136:
|
||||
case 132:
|
||||
case 128:
|
||||
case 200:
|
||||
case 196:
|
||||
case 192:
|
||||
block = "TC";
|
||||
break;
|
||||
case 112:
|
||||
case 48:
|
||||
block = "CP";
|
||||
break;
|
||||
case 49:
|
||||
case 177:
|
||||
case 50:
|
||||
case 178:
|
||||
block = "SH";
|
||||
break;
|
||||
case 53:
|
||||
case 190:
|
||||
block = "VGT";
|
||||
break;
|
||||
case 117:
|
||||
block = "IH";
|
||||
break;
|
||||
case 51:
|
||||
case 115:
|
||||
block = "RLC";
|
||||
break;
|
||||
case 119:
|
||||
case 183:
|
||||
block = "DMA0";
|
||||
break;
|
||||
case 61:
|
||||
block = "DMA1";
|
||||
break;
|
||||
case 248:
|
||||
case 120:
|
||||
block = "HDP";
|
||||
break;
|
||||
default:
|
||||
block = "unknown";
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
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 39:
|
||||
case 23:
|
||||
case 103:
|
||||
case 87:
|
||||
case 167:
|
||||
case 151:
|
||||
case 231:
|
||||
case 215:
|
||||
block = "DB_STEN";
|
||||
break;
|
||||
case 72:
|
||||
case 68:
|
||||
case 8:
|
||||
case 4:
|
||||
case 136:
|
||||
case 132:
|
||||
case 200:
|
||||
case 196:
|
||||
block = "TC";
|
||||
break;
|
||||
case 112:
|
||||
case 48:
|
||||
block = "CP";
|
||||
break;
|
||||
case 49:
|
||||
case 177:
|
||||
case 50:
|
||||
case 178:
|
||||
block = "SH";
|
||||
break;
|
||||
case 53:
|
||||
block = "VGT";
|
||||
break;
|
||||
case 117:
|
||||
block = "IH";
|
||||
break;
|
||||
case 51:
|
||||
case 115:
|
||||
block = "RLC";
|
||||
break;
|
||||
case 119:
|
||||
case 183:
|
||||
block = "DMA0";
|
||||
break;
|
||||
case 61:
|
||||
block = "DMA1";
|
||||
break;
|
||||
case 248:
|
||||
case 120:
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* si_vm_set_page - update the page tables using the CP
|
||||
*
|
||||
|
@ -5766,6 +6019,7 @@ int si_irq_process(struct radeon_device *rdev)
|
|||
u32 ring_index;
|
||||
bool queue_hotplug = false;
|
||||
bool queue_thermal = false;
|
||||
u32 status, addr;
|
||||
|
||||
if (!rdev->ih.enabled || rdev->shutdown)
|
||||
return IRQ_NONE;
|
||||
|
@ -6001,11 +6255,14 @@ int si_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);
|
||||
si_vm_decode_fault(rdev, status, addr);
|
||||
/* reset addr and status */
|
||||
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
|
||||
break;
|
||||
|
|
|
@ -367,6 +367,20 @@
|
|||
|
||||
#define VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x14FC
|
||||
#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_INVALIDATE_REQUEST 0x1478
|
||||
#define VM_INVALIDATE_RESPONSE 0x147c
|
||||
|
|
|
@ -1732,7 +1732,13 @@ int sumo_dpm_init(struct radeon_device *rdev)
|
|||
pi->enable_sclk_ds = true;
|
||||
pi->enable_dynamic_m3_arbiter = false;
|
||||
pi->enable_dynamic_patch_ps = true;
|
||||
pi->enable_gfx_power_gating = true;
|
||||
/* Some PALM chips don't seem to properly ungate gfx when UVD is in use;
|
||||
* for now just disable gfx PG.
|
||||
*/
|
||||
if (rdev->family == CHIP_PALM)
|
||||
pi->enable_gfx_power_gating = false;
|
||||
else
|
||||
pi->enable_gfx_power_gating = true;
|
||||
pi->enable_gfx_clock_gating = true;
|
||||
pi->enable_mg_clock_gating = true;
|
||||
pi->enable_auto_thermal_throttling = true;
|
||||
|
@ -1845,6 +1851,8 @@ int sumo_dpm_force_performance_level(struct radeon_device *rdev,
|
|||
return 0;
|
||||
|
||||
if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
|
||||
if (pi->enable_boost)
|
||||
sumo_enable_boost(rdev, rps, false);
|
||||
sumo_power_level_enable(rdev, ps->num_levels - 1, true);
|
||||
sumo_set_forced_level(rdev, ps->num_levels - 1);
|
||||
sumo_set_forced_mode_enabled(rdev);
|
||||
|
@ -1855,6 +1863,8 @@ int sumo_dpm_force_performance_level(struct radeon_device *rdev,
|
|||
sumo_set_forced_mode_enabled(rdev);
|
||||
sumo_set_forced_mode(rdev, false);
|
||||
} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
|
||||
if (pi->enable_boost)
|
||||
sumo_enable_boost(rdev, rps, false);
|
||||
sumo_power_level_enable(rdev, 0, true);
|
||||
sumo_set_forced_level(rdev, 0);
|
||||
sumo_set_forced_mode_enabled(rdev);
|
||||
|
@ -1868,6 +1878,8 @@ int sumo_dpm_force_performance_level(struct radeon_device *rdev,
|
|||
for (i = 0; i < ps->num_levels; i++) {
|
||||
sumo_power_level_enable(rdev, i, true);
|
||||
}
|
||||
if (pi->enable_boost)
|
||||
sumo_enable_boost(rdev, rps, true);
|
||||
}
|
||||
|
||||
rdev->pm.dpm.forced_level = level;
|
||||
|
|
Loading…
Reference in a new issue