diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/cik.c')
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index ed1d91025928..6dacec4e2090 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -22,7 +22,6 @@ | |||
22 | * Authors: Alex Deucher | 22 | * Authors: Alex Deucher |
23 | */ | 23 | */ |
24 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
28 | #include "drmP.h" | 27 | #include "drmP.h" |
@@ -742,7 +741,6 @@ static int ci_mc_load_microcode(struct radeon_device *rdev) | |||
742 | */ | 741 | */ |
743 | static int cik_init_microcode(struct radeon_device *rdev) | 742 | static int cik_init_microcode(struct radeon_device *rdev) |
744 | { | 743 | { |
745 | struct platform_device *pdev; | ||
746 | const char *chip_name; | 744 | const char *chip_name; |
747 | size_t pfp_req_size, me_req_size, ce_req_size, | 745 | size_t pfp_req_size, me_req_size, ce_req_size, |
748 | mec_req_size, rlc_req_size, mc_req_size, | 746 | mec_req_size, rlc_req_size, mc_req_size, |
@@ -752,13 +750,6 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
752 | 750 | ||
753 | DRM_DEBUG("\n"); | 751 | DRM_DEBUG("\n"); |
754 | 752 | ||
755 | pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); | ||
756 | err = IS_ERR(pdev); | ||
757 | if (err) { | ||
758 | printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); | ||
759 | return -EINVAL; | ||
760 | } | ||
761 | |||
762 | switch (rdev->family) { | 753 | switch (rdev->family) { |
763 | case CHIP_BONAIRE: | 754 | case CHIP_BONAIRE: |
764 | chip_name = "BONAIRE"; | 755 | chip_name = "BONAIRE"; |
@@ -794,7 +785,7 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
794 | DRM_INFO("Loading %s Microcode\n", chip_name); | 785 | DRM_INFO("Loading %s Microcode\n", chip_name); |
795 | 786 | ||
796 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); | 787 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); |
797 | err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); | 788 | err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev); |
798 | if (err) | 789 | if (err) |
799 | goto out; | 790 | goto out; |
800 | if (rdev->pfp_fw->size != pfp_req_size) { | 791 | if (rdev->pfp_fw->size != pfp_req_size) { |
@@ -806,7 +797,7 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
806 | } | 797 | } |
807 | 798 | ||
808 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); | 799 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); |
809 | err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); | 800 | err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); |
810 | if (err) | 801 | if (err) |
811 | goto out; | 802 | goto out; |
812 | if (rdev->me_fw->size != me_req_size) { | 803 | if (rdev->me_fw->size != me_req_size) { |
@@ -817,7 +808,7 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
817 | } | 808 | } |
818 | 809 | ||
819 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); | 810 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); |
820 | err = request_firmware(&rdev->ce_fw, fw_name, &pdev->dev); | 811 | err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev); |
821 | if (err) | 812 | if (err) |
822 | goto out; | 813 | goto out; |
823 | if (rdev->ce_fw->size != ce_req_size) { | 814 | if (rdev->ce_fw->size != ce_req_size) { |
@@ -828,7 +819,7 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
828 | } | 819 | } |
829 | 820 | ||
830 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name); | 821 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name); |
831 | err = request_firmware(&rdev->mec_fw, fw_name, &pdev->dev); | 822 | err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev); |
832 | if (err) | 823 | if (err) |
833 | goto out; | 824 | goto out; |
834 | if (rdev->mec_fw->size != mec_req_size) { | 825 | if (rdev->mec_fw->size != mec_req_size) { |
@@ -839,7 +830,7 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
839 | } | 830 | } |
840 | 831 | ||
841 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name); | 832 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name); |
842 | err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); | 833 | err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); |
843 | if (err) | 834 | if (err) |
844 | goto out; | 835 | goto out; |
845 | if (rdev->rlc_fw->size != rlc_req_size) { | 836 | if (rdev->rlc_fw->size != rlc_req_size) { |
@@ -850,7 +841,7 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
850 | } | 841 | } |
851 | 842 | ||
852 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name); | 843 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name); |
853 | err = request_firmware(&rdev->sdma_fw, fw_name, &pdev->dev); | 844 | err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev); |
854 | if (err) | 845 | if (err) |
855 | goto out; | 846 | goto out; |
856 | if (rdev->sdma_fw->size != sdma_req_size) { | 847 | if (rdev->sdma_fw->size != sdma_req_size) { |
@@ -863,7 +854,7 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
863 | /* No MC ucode on APUs */ | 854 | /* No MC ucode on APUs */ |
864 | if (!(rdev->flags & RADEON_IS_IGP)) { | 855 | if (!(rdev->flags & RADEON_IS_IGP)) { |
865 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); | 856 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); |
866 | err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev); | 857 | err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); |
867 | if (err) | 858 | if (err) |
868 | goto out; | 859 | goto out; |
869 | if (rdev->mc_fw->size != mc_req_size) { | 860 | if (rdev->mc_fw->size != mc_req_size) { |
@@ -875,8 +866,6 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
875 | } | 866 | } |
876 | 867 | ||
877 | out: | 868 | out: |
878 | platform_device_unregister(pdev); | ||
879 | |||
880 | if (err) { | 869 | if (err) { |
881 | if (err != -EINVAL) | 870 | if (err != -EINVAL) |
882 | printk(KERN_ERR | 871 | printk(KERN_ERR |
@@ -4453,6 +4442,29 @@ void cik_vm_fini(struct radeon_device *rdev) | |||
4453 | } | 4442 | } |
4454 | 4443 | ||
4455 | /** | 4444 | /** |
4445 | * cik_vm_decode_fault - print human readable fault info | ||
4446 | * | ||
4447 | * @rdev: radeon_device pointer | ||
4448 | * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value | ||
4449 | * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value | ||
4450 | * | ||
4451 | * Print human readable fault information (CIK). | ||
4452 | */ | ||
4453 | static void cik_vm_decode_fault(struct radeon_device *rdev, | ||
4454 | u32 status, u32 addr, u32 mc_client) | ||
4455 | { | ||
4456 | u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; | ||
4457 | u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT; | ||
4458 | u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT; | ||
4459 | char *block = (char *)&mc_client; | ||
4460 | |||
4461 | printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n", | ||
4462 | protections, vmid, addr, | ||
4463 | (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read", | ||
4464 | block, mc_id); | ||
4465 | } | ||
4466 | |||
4467 | /** | ||
4456 | * cik_vm_flush - cik vm flush using the CP | 4468 | * cik_vm_flush - cik vm flush using the CP |
4457 | * | 4469 | * |
4458 | * @rdev: radeon_device pointer | 4470 | * @rdev: radeon_device pointer |
@@ -5507,6 +5519,7 @@ int cik_irq_process(struct radeon_device *rdev) | |||
5507 | u32 ring_index; | 5519 | u32 ring_index; |
5508 | bool queue_hotplug = false; | 5520 | bool queue_hotplug = false; |
5509 | bool queue_reset = false; | 5521 | bool queue_reset = false; |
5522 | u32 addr, status, mc_client; | ||
5510 | 5523 | ||
5511 | if (!rdev->ih.enabled || rdev->shutdown) | 5524 | if (!rdev->ih.enabled || rdev->shutdown) |
5512 | return IRQ_NONE; | 5525 | return IRQ_NONE; |
@@ -5742,11 +5755,15 @@ restart_ih: | |||
5742 | break; | 5755 | break; |
5743 | case 146: | 5756 | case 146: |
5744 | case 147: | 5757 | case 147: |
5758 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); | ||
5759 | status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); | ||
5760 | mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT); | ||
5745 | dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); | 5761 | dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); |
5746 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | 5762 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", |
5747 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR)); | 5763 | addr); |
5748 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | 5764 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", |
5749 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); | 5765 | status); |
5766 | cik_vm_decode_fault(rdev, status, addr, mc_client); | ||
5750 | /* reset addr and status */ | 5767 | /* reset addr and status */ |
5751 | WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); | 5768 | WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); |
5752 | break; | 5769 | break; |
@@ -6961,7 +6978,7 @@ int cik_uvd_resume(struct radeon_device *rdev) | |||
6961 | 6978 | ||
6962 | /* programm the VCPU memory controller bits 0-27 */ | 6979 | /* programm the VCPU memory controller bits 0-27 */ |
6963 | addr = rdev->uvd.gpu_addr >> 3; | 6980 | addr = rdev->uvd.gpu_addr >> 3; |
6964 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; | 6981 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3; |
6965 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); | 6982 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); |
6966 | WREG32(UVD_VCPU_CACHE_SIZE0, size); | 6983 | WREG32(UVD_VCPU_CACHE_SIZE0, size); |
6967 | 6984 | ||