|
@@ -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 @@ restart_ih:
|
|
|
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);
|
|
|
|