diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-11 21:12:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-11 21:12:22 -0400 |
commit | 6b25e21fa6f26d0f0d45f161d169029411c84286 (patch) | |
tree | fdff805ecd81ec46951f49577efe450ddb7d060a /drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |
parent | a379f71a30dddbd2e7393624e455ce53c87965d1 (diff) | |
parent | 69405d3da98b48633b78a49403e4f9cdb7c6a0f5 (diff) |
Merge tag 'drm-for-v4.9' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"Core:
- Fence destaging work
- DRIVER_LEGACY to split off legacy drm drivers
- drm_mm refactoring
- Splitting drm_crtc.c into chunks and documenting better
- Display info fixes
- rbtree support for prime buffer lookup
- Simple VGA DAC driver
Panel:
- Add Nexus 7 panel
- More simple panels
i915:
- Refactoring GEM naming
- Refactored vma/active tracking
- Lockless request lookups
- Better stolen memory support
- FBC fixes
- SKL watermark fixes
- VGPU improvements
- dma-buf fencing support
- Better DP dongle support
amdgpu:
- Powerplay for Iceland asics
- Improved GPU reset support
- UVD/VEC powergating support for CZ/ST
- Preinitialised VRAM buffer support
- Virtual display support
- Initial SI support
- GTT rework
- PCI shutdown callback support
- HPD IRQ storm fixes
amdkfd:
- bugfixes
tilcdc:
- Atomic modesetting support
mediatek:
- AAL + GAMMA engine support
- Hook up gamma LUT
- Temporal dithering support
imx:
- Pixel clock from devicetree
- drm bridge support for LVDS bridges
- active plane reconfiguration
- VDIC deinterlacer support
- Frame synchronisation unit support
- Color space conversion support
analogix:
- PSR support
- Better panel on/off support
rockchip:
- rk3399 vop/crtc support
- PSR support
vc4:
- Interlaced vblank timing
- 3D rendering CPU overhead reduction
- HDMI output fixes
tda998x:
- HDMI audio ASoC support
sunxi:
- Allwinner A33 support
- better TCON support
msm:
- DT binding cleanups
- Explicit fence-fd support
sti:
- remove sti415/416 support
etnaviv:
- MMUv2 refactoring
- GC3000 support
exynos:
- Refactoring HDMI DCC/PHY
- G2D pm regression fix
- Page fault issues with wait for vblank
There is no nouveau work in this tree, as Ben didn't get a pull
request in, and he was fighting moving to atomic and adding mst
support, so maybe best it waits for a cycle"
* tag 'drm-for-v4.9' of git://people.freedesktop.org/~airlied/linux: (1412 commits)
drm/crtc: constify drm_crtc_index parameter
drm/i915: Fix conflict resolution from backmerge of v4.8-rc8 to drm-next
drm/i915/guc: Unwind GuC workqueue reservation if request construction fails
drm/i915: Reset the breadcrumbs IRQ more carefully
drm/i915: Force relocations via cpu if we run out of idle aperture
drm/i915: Distinguish last emitted request from last submitted request
drm/i915: Allow DP to work w/o EDID
drm/i915: Move long hpd handling into the hotplug work
drm/i915/execlists: Reinitialise context image after GPU hang
drm/i915: Use correct index for backtracking HUNG semaphores
drm/i915: Unalias obj->phys_handle and obj->userptr
drm/i915: Just clear the mmiodebug before a register access
drm/i915/gen9: only add the planes actually affected by ddb changes
drm/i915: Allow PCH DPLL sharing regardless of DPLL_SDVO_HIGH_SPEED
drm/i915/bxt: Fix HDMI DPLL configuration
drm/i915/gen9: fix the watermark res_blocks value
drm/i915/gen9: fix plane_blocks_per_line on watermarks calculations
drm/i915/gen9: minimum scanlines for Y tile is not always 4
drm/i915/gen9: fix the WaWmMemoryReadLatency implementation
drm/i915/kbl: KBL also needs to run the SAGV code
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 477 |
1 files changed, 416 insertions, 61 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 39c01b942ee4..7dbe85d67d26 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -41,16 +41,26 @@ | |||
41 | #include "atom.h" | 41 | #include "atom.h" |
42 | #include "amdgpu_atombios.h" | 42 | #include "amdgpu_atombios.h" |
43 | #include "amd_pcie.h" | 43 | #include "amd_pcie.h" |
44 | #ifdef CONFIG_DRM_AMDGPU_SI | ||
45 | #include "si.h" | ||
46 | #endif | ||
44 | #ifdef CONFIG_DRM_AMDGPU_CIK | 47 | #ifdef CONFIG_DRM_AMDGPU_CIK |
45 | #include "cik.h" | 48 | #include "cik.h" |
46 | #endif | 49 | #endif |
47 | #include "vi.h" | 50 | #include "vi.h" |
48 | #include "bif/bif_4_1_d.h" | 51 | #include "bif/bif_4_1_d.h" |
52 | #include <linux/pci.h> | ||
53 | #include <linux/firmware.h> | ||
49 | 54 | ||
50 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); | 55 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); |
51 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); | 56 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); |
52 | 57 | ||
53 | static const char *amdgpu_asic_name[] = { | 58 | static const char *amdgpu_asic_name[] = { |
59 | "TAHITI", | ||
60 | "PITCAIRN", | ||
61 | "VERDE", | ||
62 | "OLAND", | ||
63 | "HAINAN", | ||
54 | "BONAIRE", | 64 | "BONAIRE", |
55 | "KAVERI", | 65 | "KAVERI", |
56 | "KABINI", | 66 | "KABINI", |
@@ -101,7 +111,7 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, | |||
101 | bool always_indirect) | 111 | bool always_indirect) |
102 | { | 112 | { |
103 | trace_amdgpu_mm_wreg(adev->pdev->device, reg, v); | 113 | trace_amdgpu_mm_wreg(adev->pdev->device, reg, v); |
104 | 114 | ||
105 | if ((reg * 4) < adev->rmmio_size && !always_indirect) | 115 | if ((reg * 4) < adev->rmmio_size && !always_indirect) |
106 | writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); | 116 | writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); |
107 | else { | 117 | else { |
@@ -642,6 +652,46 @@ bool amdgpu_card_posted(struct amdgpu_device *adev) | |||
642 | 652 | ||
643 | } | 653 | } |
644 | 654 | ||
655 | static bool amdgpu_vpost_needed(struct amdgpu_device *adev) | ||
656 | { | ||
657 | if (amdgpu_sriov_vf(adev)) | ||
658 | return false; | ||
659 | |||
660 | if (amdgpu_passthrough(adev)) { | ||
661 | /* for FIJI: In whole GPU pass-through virtualization case | ||
662 | * old smc fw won't clear some registers (e.g. MEM_SIZE, BIOS_SCRATCH) | ||
663 | * so amdgpu_card_posted return false and driver will incorrectly skip vPost. | ||
664 | * but if we force vPost do in pass-through case, the driver reload will hang. | ||
665 | * whether doing vPost depends on amdgpu_card_posted if smc version is above | ||
666 | * 00160e00 for FIJI. | ||
667 | */ | ||
668 | if (adev->asic_type == CHIP_FIJI) { | ||
669 | int err; | ||
670 | uint32_t fw_ver; | ||
671 | err = request_firmware(&adev->pm.fw, "amdgpu/fiji_smc.bin", adev->dev); | ||
672 | /* force vPost if error occured */ | ||
673 | if (err) | ||
674 | return true; | ||
675 | |||
676 | fw_ver = *((uint32_t *)adev->pm.fw->data + 69); | ||
677 | if (fw_ver >= 0x00160e00) | ||
678 | return !amdgpu_card_posted(adev); | ||
679 | } | ||
680 | } else { | ||
681 | /* in bare-metal case, amdgpu_card_posted return false | ||
682 | * after system reboot/boot, and return true if driver | ||
683 | * reloaded. | ||
684 | * we shouldn't do vPost after driver reload otherwise GPU | ||
685 | * could hang. | ||
686 | */ | ||
687 | if (amdgpu_card_posted(adev)) | ||
688 | return false; | ||
689 | } | ||
690 | |||
691 | /* we assume vPost is neede for all other cases */ | ||
692 | return true; | ||
693 | } | ||
694 | |||
645 | /** | 695 | /** |
646 | * amdgpu_dummy_page_init - init dummy page used by the driver | 696 | * amdgpu_dummy_page_init - init dummy page used by the driver |
647 | * | 697 | * |
@@ -1026,7 +1076,7 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
1026 | /* don't suspend or resume card normally */ | 1076 | /* don't suspend or resume card normally */ |
1027 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 1077 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
1028 | 1078 | ||
1029 | amdgpu_resume_kms(dev, true, true); | 1079 | amdgpu_device_resume(dev, true, true); |
1030 | 1080 | ||
1031 | dev->pdev->d3_delay = d3_delay; | 1081 | dev->pdev->d3_delay = d3_delay; |
1032 | 1082 | ||
@@ -1036,7 +1086,7 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
1036 | printk(KERN_INFO "amdgpu: switched off\n"); | 1086 | printk(KERN_INFO "amdgpu: switched off\n"); |
1037 | drm_kms_helper_poll_disable(dev); | 1087 | drm_kms_helper_poll_disable(dev); |
1038 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 1088 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
1039 | amdgpu_suspend_kms(dev, true, true); | 1089 | amdgpu_device_suspend(dev, true, true); |
1040 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; | 1090 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; |
1041 | } | 1091 | } |
1042 | } | 1092 | } |
@@ -1181,10 +1231,38 @@ int amdgpu_ip_block_version_cmp(struct amdgpu_device *adev, | |||
1181 | return 1; | 1231 | return 1; |
1182 | } | 1232 | } |
1183 | 1233 | ||
1234 | static void amdgpu_whether_enable_virtual_display(struct amdgpu_device *adev) | ||
1235 | { | ||
1236 | adev->enable_virtual_display = false; | ||
1237 | |||
1238 | if (amdgpu_virtual_display) { | ||
1239 | struct drm_device *ddev = adev->ddev; | ||
1240 | const char *pci_address_name = pci_name(ddev->pdev); | ||
1241 | char *pciaddstr, *pciaddstr_tmp, *pciaddname; | ||
1242 | |||
1243 | pciaddstr = kstrdup(amdgpu_virtual_display, GFP_KERNEL); | ||
1244 | pciaddstr_tmp = pciaddstr; | ||
1245 | while ((pciaddname = strsep(&pciaddstr_tmp, ";"))) { | ||
1246 | if (!strcmp(pci_address_name, pciaddname)) { | ||
1247 | adev->enable_virtual_display = true; | ||
1248 | break; | ||
1249 | } | ||
1250 | } | ||
1251 | |||
1252 | DRM_INFO("virtual display string:%s, %s:virtual_display:%d\n", | ||
1253 | amdgpu_virtual_display, pci_address_name, | ||
1254 | adev->enable_virtual_display); | ||
1255 | |||
1256 | kfree(pciaddstr); | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1184 | static int amdgpu_early_init(struct amdgpu_device *adev) | 1260 | static int amdgpu_early_init(struct amdgpu_device *adev) |
1185 | { | 1261 | { |
1186 | int i, r; | 1262 | int i, r; |
1187 | 1263 | ||
1264 | amdgpu_whether_enable_virtual_display(adev); | ||
1265 | |||
1188 | switch (adev->asic_type) { | 1266 | switch (adev->asic_type) { |
1189 | case CHIP_TOPAZ: | 1267 | case CHIP_TOPAZ: |
1190 | case CHIP_TONGA: | 1268 | case CHIP_TONGA: |
@@ -1202,6 +1280,18 @@ static int amdgpu_early_init(struct amdgpu_device *adev) | |||
1202 | if (r) | 1280 | if (r) |
1203 | return r; | 1281 | return r; |
1204 | break; | 1282 | break; |
1283 | #ifdef CONFIG_DRM_AMDGPU_SI | ||
1284 | case CHIP_VERDE: | ||
1285 | case CHIP_TAHITI: | ||
1286 | case CHIP_PITCAIRN: | ||
1287 | case CHIP_OLAND: | ||
1288 | case CHIP_HAINAN: | ||
1289 | adev->family = AMDGPU_FAMILY_SI; | ||
1290 | r = si_set_ip_blocks(adev); | ||
1291 | if (r) | ||
1292 | return r; | ||
1293 | break; | ||
1294 | #endif | ||
1205 | #ifdef CONFIG_DRM_AMDGPU_CIK | 1295 | #ifdef CONFIG_DRM_AMDGPU_CIK |
1206 | case CHIP_BONAIRE: | 1296 | case CHIP_BONAIRE: |
1207 | case CHIP_HAWAII: | 1297 | case CHIP_HAWAII: |
@@ -1318,6 +1408,9 @@ static int amdgpu_late_init(struct amdgpu_device *adev) | |||
1318 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1408 | for (i = 0; i < adev->num_ip_blocks; i++) { |
1319 | if (!adev->ip_block_status[i].valid) | 1409 | if (!adev->ip_block_status[i].valid) |
1320 | continue; | 1410 | continue; |
1411 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_UVD || | ||
1412 | adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_VCE) | ||
1413 | continue; | ||
1321 | /* enable clockgating to save power */ | 1414 | /* enable clockgating to save power */ |
1322 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | 1415 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, |
1323 | AMD_CG_STATE_GATE); | 1416 | AMD_CG_STATE_GATE); |
@@ -1331,6 +1424,7 @@ static int amdgpu_late_init(struct amdgpu_device *adev) | |||
1331 | DRM_ERROR("late_init of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r); | 1424 | DRM_ERROR("late_init of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r); |
1332 | return r; | 1425 | return r; |
1333 | } | 1426 | } |
1427 | adev->ip_block_status[i].late_initialized = true; | ||
1334 | } | 1428 | } |
1335 | } | 1429 | } |
1336 | 1430 | ||
@@ -1376,8 +1470,11 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
1376 | } | 1470 | } |
1377 | 1471 | ||
1378 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1472 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
1473 | if (!adev->ip_block_status[i].late_initialized) | ||
1474 | continue; | ||
1379 | if (adev->ip_blocks[i].funcs->late_fini) | 1475 | if (adev->ip_blocks[i].funcs->late_fini) |
1380 | adev->ip_blocks[i].funcs->late_fini((void *)adev); | 1476 | adev->ip_blocks[i].funcs->late_fini((void *)adev); |
1477 | adev->ip_block_status[i].late_initialized = false; | ||
1381 | } | 1478 | } |
1382 | 1479 | ||
1383 | return 0; | 1480 | return 0; |
@@ -1433,13 +1530,10 @@ static int amdgpu_resume(struct amdgpu_device *adev) | |||
1433 | return 0; | 1530 | return 0; |
1434 | } | 1531 | } |
1435 | 1532 | ||
1436 | static bool amdgpu_device_is_virtual(void) | 1533 | static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) |
1437 | { | 1534 | { |
1438 | #ifdef CONFIG_X86 | 1535 | if (amdgpu_atombios_has_gpu_virtualization_table(adev)) |
1439 | return boot_cpu_has(X86_FEATURE_HYPERVISOR); | 1536 | adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; |
1440 | #else | ||
1441 | return false; | ||
1442 | #endif | ||
1443 | } | 1537 | } |
1444 | 1538 | ||
1445 | /** | 1539 | /** |
@@ -1461,6 +1555,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1461 | { | 1555 | { |
1462 | int r, i; | 1556 | int r, i; |
1463 | bool runtime = false; | 1557 | bool runtime = false; |
1558 | u32 max_MBps; | ||
1464 | 1559 | ||
1465 | adev->shutdown = false; | 1560 | adev->shutdown = false; |
1466 | adev->dev = &pdev->dev; | 1561 | adev->dev = &pdev->dev; |
@@ -1484,6 +1579,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1484 | adev->smc_wreg = &amdgpu_invalid_wreg; | 1579 | adev->smc_wreg = &amdgpu_invalid_wreg; |
1485 | adev->pcie_rreg = &amdgpu_invalid_rreg; | 1580 | adev->pcie_rreg = &amdgpu_invalid_rreg; |
1486 | adev->pcie_wreg = &amdgpu_invalid_wreg; | 1581 | adev->pcie_wreg = &amdgpu_invalid_wreg; |
1582 | adev->pciep_rreg = &amdgpu_invalid_rreg; | ||
1583 | adev->pciep_wreg = &amdgpu_invalid_wreg; | ||
1487 | adev->uvd_ctx_rreg = &amdgpu_invalid_rreg; | 1584 | adev->uvd_ctx_rreg = &amdgpu_invalid_rreg; |
1488 | adev->uvd_ctx_wreg = &amdgpu_invalid_wreg; | 1585 | adev->uvd_ctx_wreg = &amdgpu_invalid_wreg; |
1489 | adev->didt_rreg = &amdgpu_invalid_rreg; | 1586 | adev->didt_rreg = &amdgpu_invalid_rreg; |
@@ -1520,9 +1617,22 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1520 | spin_lock_init(&adev->didt_idx_lock); | 1617 | spin_lock_init(&adev->didt_idx_lock); |
1521 | spin_lock_init(&adev->gc_cac_idx_lock); | 1618 | spin_lock_init(&adev->gc_cac_idx_lock); |
1522 | spin_lock_init(&adev->audio_endpt_idx_lock); | 1619 | spin_lock_init(&adev->audio_endpt_idx_lock); |
1620 | spin_lock_init(&adev->mm_stats.lock); | ||
1621 | |||
1622 | INIT_LIST_HEAD(&adev->shadow_list); | ||
1623 | mutex_init(&adev->shadow_list_lock); | ||
1624 | |||
1625 | INIT_LIST_HEAD(&adev->gtt_list); | ||
1626 | spin_lock_init(&adev->gtt_list_lock); | ||
1627 | |||
1628 | if (adev->asic_type >= CHIP_BONAIRE) { | ||
1629 | adev->rmmio_base = pci_resource_start(adev->pdev, 5); | ||
1630 | adev->rmmio_size = pci_resource_len(adev->pdev, 5); | ||
1631 | } else { | ||
1632 | adev->rmmio_base = pci_resource_start(adev->pdev, 2); | ||
1633 | adev->rmmio_size = pci_resource_len(adev->pdev, 2); | ||
1634 | } | ||
1523 | 1635 | ||
1524 | adev->rmmio_base = pci_resource_start(adev->pdev, 5); | ||
1525 | adev->rmmio_size = pci_resource_len(adev->pdev, 5); | ||
1526 | adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size); | 1636 | adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size); |
1527 | if (adev->rmmio == NULL) { | 1637 | if (adev->rmmio == NULL) { |
1528 | return -ENOMEM; | 1638 | return -ENOMEM; |
@@ -1530,8 +1640,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1530 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base); | 1640 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base); |
1531 | DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size); | 1641 | DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size); |
1532 | 1642 | ||
1533 | /* doorbell bar mapping */ | 1643 | if (adev->asic_type >= CHIP_BONAIRE) |
1534 | amdgpu_doorbell_init(adev); | 1644 | /* doorbell bar mapping */ |
1645 | amdgpu_doorbell_init(adev); | ||
1535 | 1646 | ||
1536 | /* io port mapping */ | 1647 | /* io port mapping */ |
1537 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 1648 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
@@ -1579,25 +1690,24 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1579 | goto failed; | 1690 | goto failed; |
1580 | } | 1691 | } |
1581 | 1692 | ||
1582 | /* See if the asic supports SR-IOV */ | 1693 | /* detect if we are with an SRIOV vbios */ |
1583 | adev->virtualization.supports_sr_iov = | 1694 | amdgpu_device_detect_sriov_bios(adev); |
1584 | amdgpu_atombios_has_gpu_virtualization_table(adev); | ||
1585 | |||
1586 | /* Check if we are executing in a virtualized environment */ | ||
1587 | adev->virtualization.is_virtual = amdgpu_device_is_virtual(); | ||
1588 | adev->virtualization.caps = amdgpu_asic_get_virtual_caps(adev); | ||
1589 | 1695 | ||
1590 | /* Post card if necessary */ | 1696 | /* Post card if necessary */ |
1591 | if (!amdgpu_card_posted(adev) || | 1697 | if (amdgpu_vpost_needed(adev)) { |
1592 | (adev->virtualization.is_virtual && | ||
1593 | !(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) { | ||
1594 | if (!adev->bios) { | 1698 | if (!adev->bios) { |
1595 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); | 1699 | dev_err(adev->dev, "no vBIOS found\n"); |
1596 | r = -EINVAL; | 1700 | r = -EINVAL; |
1597 | goto failed; | 1701 | goto failed; |
1598 | } | 1702 | } |
1599 | DRM_INFO("GPU not posted. posting now...\n"); | 1703 | DRM_INFO("GPU posting now...\n"); |
1600 | amdgpu_atom_asic_init(adev->mode_info.atom_context); | 1704 | r = amdgpu_atom_asic_init(adev->mode_info.atom_context); |
1705 | if (r) { | ||
1706 | dev_err(adev->dev, "gpu post error!\n"); | ||
1707 | goto failed; | ||
1708 | } | ||
1709 | } else { | ||
1710 | DRM_INFO("GPU post is not needed\n"); | ||
1601 | } | 1711 | } |
1602 | 1712 | ||
1603 | /* Initialize clocks */ | 1713 | /* Initialize clocks */ |
@@ -1628,6 +1738,14 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1628 | 1738 | ||
1629 | adev->accel_working = true; | 1739 | adev->accel_working = true; |
1630 | 1740 | ||
1741 | /* Initialize the buffer migration limit. */ | ||
1742 | if (amdgpu_moverate >= 0) | ||
1743 | max_MBps = amdgpu_moverate; | ||
1744 | else | ||
1745 | max_MBps = 8; /* Allow 8 MB/s. */ | ||
1746 | /* Get a log2 for easy divisions. */ | ||
1747 | adev->mm_stats.log2_max_MBps = ilog2(max(1u, max_MBps)); | ||
1748 | |||
1631 | amdgpu_fbdev_init(adev); | 1749 | amdgpu_fbdev_init(adev); |
1632 | 1750 | ||
1633 | r = amdgpu_ib_pool_init(adev); | 1751 | r = amdgpu_ib_pool_init(adev); |
@@ -1732,7 +1850,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
1732 | adev->rio_mem = NULL; | 1850 | adev->rio_mem = NULL; |
1733 | iounmap(adev->rmmio); | 1851 | iounmap(adev->rmmio); |
1734 | adev->rmmio = NULL; | 1852 | adev->rmmio = NULL; |
1735 | amdgpu_doorbell_fini(adev); | 1853 | if (adev->asic_type >= CHIP_BONAIRE) |
1854 | amdgpu_doorbell_fini(adev); | ||
1736 | amdgpu_debugfs_regs_cleanup(adev); | 1855 | amdgpu_debugfs_regs_cleanup(adev); |
1737 | amdgpu_debugfs_remove_files(adev); | 1856 | amdgpu_debugfs_remove_files(adev); |
1738 | } | 1857 | } |
@@ -1742,7 +1861,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
1742 | * Suspend & resume. | 1861 | * Suspend & resume. |
1743 | */ | 1862 | */ |
1744 | /** | 1863 | /** |
1745 | * amdgpu_suspend_kms - initiate device suspend | 1864 | * amdgpu_device_suspend - initiate device suspend |
1746 | * | 1865 | * |
1747 | * @pdev: drm dev pointer | 1866 | * @pdev: drm dev pointer |
1748 | * @state: suspend state | 1867 | * @state: suspend state |
@@ -1751,7 +1870,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
1751 | * Returns 0 for success or an error on failure. | 1870 | * Returns 0 for success or an error on failure. |
1752 | * Called at driver suspend. | 1871 | * Called at driver suspend. |
1753 | */ | 1872 | */ |
1754 | int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) | 1873 | int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) |
1755 | { | 1874 | { |
1756 | struct amdgpu_device *adev; | 1875 | struct amdgpu_device *adev; |
1757 | struct drm_crtc *crtc; | 1876 | struct drm_crtc *crtc; |
@@ -1819,6 +1938,10 @@ int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) | |||
1819 | /* Shut down the device */ | 1938 | /* Shut down the device */ |
1820 | pci_disable_device(dev->pdev); | 1939 | pci_disable_device(dev->pdev); |
1821 | pci_set_power_state(dev->pdev, PCI_D3hot); | 1940 | pci_set_power_state(dev->pdev, PCI_D3hot); |
1941 | } else { | ||
1942 | r = amdgpu_asic_reset(adev); | ||
1943 | if (r) | ||
1944 | DRM_ERROR("amdgpu asic reset failed\n"); | ||
1822 | } | 1945 | } |
1823 | 1946 | ||
1824 | if (fbcon) { | 1947 | if (fbcon) { |
@@ -1830,7 +1953,7 @@ int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) | |||
1830 | } | 1953 | } |
1831 | 1954 | ||
1832 | /** | 1955 | /** |
1833 | * amdgpu_resume_kms - initiate device resume | 1956 | * amdgpu_device_resume - initiate device resume |
1834 | * | 1957 | * |
1835 | * @pdev: drm dev pointer | 1958 | * @pdev: drm dev pointer |
1836 | * | 1959 | * |
@@ -1838,7 +1961,7 @@ int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) | |||
1838 | * Returns 0 for success or an error on failure. | 1961 | * Returns 0 for success or an error on failure. |
1839 | * Called at driver resume. | 1962 | * Called at driver resume. |
1840 | */ | 1963 | */ |
1841 | int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon) | 1964 | int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) |
1842 | { | 1965 | { |
1843 | struct drm_connector *connector; | 1966 | struct drm_connector *connector; |
1844 | struct amdgpu_device *adev = dev->dev_private; | 1967 | struct amdgpu_device *adev = dev->dev_private; |
@@ -1848,22 +1971,26 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon) | |||
1848 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 1971 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
1849 | return 0; | 1972 | return 0; |
1850 | 1973 | ||
1851 | if (fbcon) { | 1974 | if (fbcon) |
1852 | console_lock(); | 1975 | console_lock(); |
1853 | } | 1976 | |
1854 | if (resume) { | 1977 | if (resume) { |
1855 | pci_set_power_state(dev->pdev, PCI_D0); | 1978 | pci_set_power_state(dev->pdev, PCI_D0); |
1856 | pci_restore_state(dev->pdev); | 1979 | pci_restore_state(dev->pdev); |
1857 | if (pci_enable_device(dev->pdev)) { | 1980 | r = pci_enable_device(dev->pdev); |
1981 | if (r) { | ||
1858 | if (fbcon) | 1982 | if (fbcon) |
1859 | console_unlock(); | 1983 | console_unlock(); |
1860 | return -1; | 1984 | return r; |
1861 | } | 1985 | } |
1862 | } | 1986 | } |
1863 | 1987 | ||
1864 | /* post card */ | 1988 | /* post card */ |
1865 | if (!amdgpu_card_posted(adev)) | 1989 | if (!amdgpu_card_posted(adev) || !resume) { |
1866 | amdgpu_atom_asic_init(adev->mode_info.atom_context); | 1990 | r = amdgpu_atom_asic_init(adev->mode_info.atom_context); |
1991 | if (r) | ||
1992 | DRM_ERROR("amdgpu asic init failed\n"); | ||
1993 | } | ||
1867 | 1994 | ||
1868 | r = amdgpu_resume(adev); | 1995 | r = amdgpu_resume(adev); |
1869 | if (r) | 1996 | if (r) |
@@ -1937,6 +2064,126 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon) | |||
1937 | return 0; | 2064 | return 0; |
1938 | } | 2065 | } |
1939 | 2066 | ||
2067 | static bool amdgpu_check_soft_reset(struct amdgpu_device *adev) | ||
2068 | { | ||
2069 | int i; | ||
2070 | bool asic_hang = false; | ||
2071 | |||
2072 | for (i = 0; i < adev->num_ip_blocks; i++) { | ||
2073 | if (!adev->ip_block_status[i].valid) | ||
2074 | continue; | ||
2075 | if (adev->ip_blocks[i].funcs->check_soft_reset) | ||
2076 | adev->ip_blocks[i].funcs->check_soft_reset(adev); | ||
2077 | if (adev->ip_block_status[i].hang) { | ||
2078 | DRM_INFO("IP block:%d is hang!\n", i); | ||
2079 | asic_hang = true; | ||
2080 | } | ||
2081 | } | ||
2082 | return asic_hang; | ||
2083 | } | ||
2084 | |||
2085 | static int amdgpu_pre_soft_reset(struct amdgpu_device *adev) | ||
2086 | { | ||
2087 | int i, r = 0; | ||
2088 | |||
2089 | for (i = 0; i < adev->num_ip_blocks; i++) { | ||
2090 | if (!adev->ip_block_status[i].valid) | ||
2091 | continue; | ||
2092 | if (adev->ip_block_status[i].hang && | ||
2093 | adev->ip_blocks[i].funcs->pre_soft_reset) { | ||
2094 | r = adev->ip_blocks[i].funcs->pre_soft_reset(adev); | ||
2095 | if (r) | ||
2096 | return r; | ||
2097 | } | ||
2098 | } | ||
2099 | |||
2100 | return 0; | ||
2101 | } | ||
2102 | |||
2103 | static bool amdgpu_need_full_reset(struct amdgpu_device *adev) | ||
2104 | { | ||
2105 | if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang || | ||
2106 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang || | ||
2107 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang || | ||
2108 | adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) { | ||
2109 | DRM_INFO("Some block need full reset!\n"); | ||
2110 | return true; | ||
2111 | } | ||
2112 | return false; | ||
2113 | } | ||
2114 | |||
2115 | static int amdgpu_soft_reset(struct amdgpu_device *adev) | ||
2116 | { | ||
2117 | int i, r = 0; | ||
2118 | |||
2119 | for (i = 0; i < adev->num_ip_blocks; i++) { | ||
2120 | if (!adev->ip_block_status[i].valid) | ||
2121 | continue; | ||
2122 | if (adev->ip_block_status[i].hang && | ||
2123 | adev->ip_blocks[i].funcs->soft_reset) { | ||
2124 | r = adev->ip_blocks[i].funcs->soft_reset(adev); | ||
2125 | if (r) | ||
2126 | return r; | ||
2127 | } | ||
2128 | } | ||
2129 | |||
2130 | return 0; | ||
2131 | } | ||
2132 | |||
2133 | static int amdgpu_post_soft_reset(struct amdgpu_device *adev) | ||
2134 | { | ||
2135 | int i, r = 0; | ||
2136 | |||
2137 | for (i = 0; i < adev->num_ip_blocks; i++) { | ||
2138 | if (!adev->ip_block_status[i].valid) | ||
2139 | continue; | ||
2140 | if (adev->ip_block_status[i].hang && | ||
2141 | adev->ip_blocks[i].funcs->post_soft_reset) | ||
2142 | r = adev->ip_blocks[i].funcs->post_soft_reset(adev); | ||
2143 | if (r) | ||
2144 | return r; | ||
2145 | } | ||
2146 | |||
2147 | return 0; | ||
2148 | } | ||
2149 | |||
2150 | bool amdgpu_need_backup(struct amdgpu_device *adev) | ||
2151 | { | ||
2152 | if (adev->flags & AMD_IS_APU) | ||
2153 | return false; | ||
2154 | |||
2155 | return amdgpu_lockup_timeout > 0 ? true : false; | ||
2156 | } | ||
2157 | |||
2158 | static int amdgpu_recover_vram_from_shadow(struct amdgpu_device *adev, | ||
2159 | struct amdgpu_ring *ring, | ||
2160 | struct amdgpu_bo *bo, | ||
2161 | struct fence **fence) | ||
2162 | { | ||
2163 | uint32_t domain; | ||
2164 | int r; | ||
2165 | |||
2166 | if (!bo->shadow) | ||
2167 | return 0; | ||
2168 | |||
2169 | r = amdgpu_bo_reserve(bo, false); | ||
2170 | if (r) | ||
2171 | return r; | ||
2172 | domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); | ||
2173 | /* if bo has been evicted, then no need to recover */ | ||
2174 | if (domain == AMDGPU_GEM_DOMAIN_VRAM) { | ||
2175 | r = amdgpu_bo_restore_from_shadow(adev, ring, bo, | ||
2176 | NULL, fence, true); | ||
2177 | if (r) { | ||
2178 | DRM_ERROR("recover page table failed!\n"); | ||
2179 | goto err; | ||
2180 | } | ||
2181 | } | ||
2182 | err: | ||
2183 | amdgpu_bo_unreserve(bo); | ||
2184 | return r; | ||
2185 | } | ||
2186 | |||
1940 | /** | 2187 | /** |
1941 | * amdgpu_gpu_reset - reset the asic | 2188 | * amdgpu_gpu_reset - reset the asic |
1942 | * | 2189 | * |
@@ -1949,6 +2196,12 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) | |||
1949 | { | 2196 | { |
1950 | int i, r; | 2197 | int i, r; |
1951 | int resched; | 2198 | int resched; |
2199 | bool need_full_reset; | ||
2200 | |||
2201 | if (!amdgpu_check_soft_reset(adev)) { | ||
2202 | DRM_INFO("No hardware hang detected. Did some blocks stall?\n"); | ||
2203 | return 0; | ||
2204 | } | ||
1952 | 2205 | ||
1953 | atomic_inc(&adev->gpu_reset_counter); | 2206 | atomic_inc(&adev->gpu_reset_counter); |
1954 | 2207 | ||
@@ -1967,40 +2220,93 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) | |||
1967 | /* after all hw jobs are reset, hw fence is meaningless, so force_completion */ | 2220 | /* after all hw jobs are reset, hw fence is meaningless, so force_completion */ |
1968 | amdgpu_fence_driver_force_completion(adev); | 2221 | amdgpu_fence_driver_force_completion(adev); |
1969 | 2222 | ||
1970 | /* save scratch */ | 2223 | need_full_reset = amdgpu_need_full_reset(adev); |
1971 | amdgpu_atombios_scratch_regs_save(adev); | ||
1972 | r = amdgpu_suspend(adev); | ||
1973 | 2224 | ||
1974 | retry: | 2225 | if (!need_full_reset) { |
1975 | /* Disable fb access */ | 2226 | amdgpu_pre_soft_reset(adev); |
1976 | if (adev->mode_info.num_crtc) { | 2227 | r = amdgpu_soft_reset(adev); |
1977 | struct amdgpu_mode_mc_save save; | 2228 | amdgpu_post_soft_reset(adev); |
1978 | amdgpu_display_stop_mc_access(adev, &save); | 2229 | if (r || amdgpu_check_soft_reset(adev)) { |
1979 | amdgpu_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GMC); | 2230 | DRM_INFO("soft reset failed, will fallback to full reset!\n"); |
2231 | need_full_reset = true; | ||
2232 | } | ||
1980 | } | 2233 | } |
1981 | 2234 | ||
1982 | r = amdgpu_asic_reset(adev); | 2235 | if (need_full_reset) { |
1983 | /* post card */ | 2236 | /* save scratch */ |
1984 | amdgpu_atom_asic_init(adev->mode_info.atom_context); | 2237 | amdgpu_atombios_scratch_regs_save(adev); |
2238 | r = amdgpu_suspend(adev); | ||
1985 | 2239 | ||
1986 | if (!r) { | 2240 | retry: |
1987 | dev_info(adev->dev, "GPU reset succeeded, trying to resume\n"); | 2241 | /* Disable fb access */ |
1988 | r = amdgpu_resume(adev); | 2242 | if (adev->mode_info.num_crtc) { |
2243 | struct amdgpu_mode_mc_save save; | ||
2244 | amdgpu_display_stop_mc_access(adev, &save); | ||
2245 | amdgpu_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GMC); | ||
2246 | } | ||
2247 | |||
2248 | r = amdgpu_asic_reset(adev); | ||
2249 | /* post card */ | ||
2250 | amdgpu_atom_asic_init(adev->mode_info.atom_context); | ||
2251 | |||
2252 | if (!r) { | ||
2253 | dev_info(adev->dev, "GPU reset succeeded, trying to resume\n"); | ||
2254 | r = amdgpu_resume(adev); | ||
2255 | } | ||
2256 | /* restore scratch */ | ||
2257 | amdgpu_atombios_scratch_regs_restore(adev); | ||
1989 | } | 2258 | } |
1990 | /* restore scratch */ | ||
1991 | amdgpu_atombios_scratch_regs_restore(adev); | ||
1992 | if (!r) { | 2259 | if (!r) { |
2260 | amdgpu_irq_gpu_reset_resume_helper(adev); | ||
2261 | if (need_full_reset && amdgpu_need_backup(adev)) { | ||
2262 | r = amdgpu_ttm_recover_gart(adev); | ||
2263 | if (r) | ||
2264 | DRM_ERROR("gart recovery failed!!!\n"); | ||
2265 | } | ||
1993 | r = amdgpu_ib_ring_tests(adev); | 2266 | r = amdgpu_ib_ring_tests(adev); |
1994 | if (r) { | 2267 | if (r) { |
1995 | dev_err(adev->dev, "ib ring test failed (%d).\n", r); | 2268 | dev_err(adev->dev, "ib ring test failed (%d).\n", r); |
1996 | r = amdgpu_suspend(adev); | 2269 | r = amdgpu_suspend(adev); |
2270 | need_full_reset = true; | ||
1997 | goto retry; | 2271 | goto retry; |
1998 | } | 2272 | } |
2273 | /** | ||
2274 | * recovery vm page tables, since we cannot depend on VRAM is | ||
2275 | * consistent after gpu full reset. | ||
2276 | */ | ||
2277 | if (need_full_reset && amdgpu_need_backup(adev)) { | ||
2278 | struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; | ||
2279 | struct amdgpu_bo *bo, *tmp; | ||
2280 | struct fence *fence = NULL, *next = NULL; | ||
2281 | |||
2282 | DRM_INFO("recover vram bo from shadow\n"); | ||
2283 | mutex_lock(&adev->shadow_list_lock); | ||
2284 | list_for_each_entry_safe(bo, tmp, &adev->shadow_list, shadow_list) { | ||
2285 | amdgpu_recover_vram_from_shadow(adev, ring, bo, &next); | ||
2286 | if (fence) { | ||
2287 | r = fence_wait(fence, false); | ||
2288 | if (r) { | ||
2289 | WARN(r, "recovery from shadow isn't comleted\n"); | ||
2290 | break; | ||
2291 | } | ||
2292 | } | ||
1999 | 2293 | ||
2294 | fence_put(fence); | ||
2295 | fence = next; | ||
2296 | } | ||
2297 | mutex_unlock(&adev->shadow_list_lock); | ||
2298 | if (fence) { | ||
2299 | r = fence_wait(fence, false); | ||
2300 | if (r) | ||
2301 | WARN(r, "recovery from shadow isn't comleted\n"); | ||
2302 | } | ||
2303 | fence_put(fence); | ||
2304 | } | ||
2000 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 2305 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
2001 | struct amdgpu_ring *ring = adev->rings[i]; | 2306 | struct amdgpu_ring *ring = adev->rings[i]; |
2002 | if (!ring) | 2307 | if (!ring) |
2003 | continue; | 2308 | continue; |
2309 | |||
2004 | amd_sched_job_recovery(&ring->sched); | 2310 | amd_sched_job_recovery(&ring->sched); |
2005 | kthread_unpark(ring->sched.thread); | 2311 | kthread_unpark(ring->sched.thread); |
2006 | } | 2312 | } |
@@ -2020,7 +2326,6 @@ retry: | |||
2020 | /* bad news, how to tell it to userspace ? */ | 2326 | /* bad news, how to tell it to userspace ? */ |
2021 | dev_info(adev->dev, "GPU reset failed\n"); | 2327 | dev_info(adev->dev, "GPU reset failed\n"); |
2022 | } | 2328 | } |
2023 | amdgpu_irq_gpu_reset_resume_helper(adev); | ||
2024 | 2329 | ||
2025 | return r; | 2330 | return r; |
2026 | } | 2331 | } |
@@ -2178,22 +2483,26 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | |||
2178 | struct amdgpu_device *adev = f->f_inode->i_private; | 2483 | struct amdgpu_device *adev = f->f_inode->i_private; |
2179 | ssize_t result = 0; | 2484 | ssize_t result = 0; |
2180 | int r; | 2485 | int r; |
2181 | bool use_bank; | 2486 | bool pm_pg_lock, use_bank; |
2182 | unsigned instance_bank, sh_bank, se_bank; | 2487 | unsigned instance_bank, sh_bank, se_bank; |
2183 | 2488 | ||
2184 | if (size & 0x3 || *pos & 0x3) | 2489 | if (size & 0x3 || *pos & 0x3) |
2185 | return -EINVAL; | 2490 | return -EINVAL; |
2186 | 2491 | ||
2492 | /* are we reading registers for which a PG lock is necessary? */ | ||
2493 | pm_pg_lock = (*pos >> 23) & 1; | ||
2494 | |||
2187 | if (*pos & (1ULL << 62)) { | 2495 | if (*pos & (1ULL << 62)) { |
2188 | se_bank = (*pos >> 24) & 0x3FF; | 2496 | se_bank = (*pos >> 24) & 0x3FF; |
2189 | sh_bank = (*pos >> 34) & 0x3FF; | 2497 | sh_bank = (*pos >> 34) & 0x3FF; |
2190 | instance_bank = (*pos >> 44) & 0x3FF; | 2498 | instance_bank = (*pos >> 44) & 0x3FF; |
2191 | use_bank = 1; | 2499 | use_bank = 1; |
2192 | *pos &= 0xFFFFFF; | ||
2193 | } else { | 2500 | } else { |
2194 | use_bank = 0; | 2501 | use_bank = 0; |
2195 | } | 2502 | } |
2196 | 2503 | ||
2504 | *pos &= 0x3FFFF; | ||
2505 | |||
2197 | if (use_bank) { | 2506 | if (use_bank) { |
2198 | if (sh_bank >= adev->gfx.config.max_sh_per_se || | 2507 | if (sh_bank >= adev->gfx.config.max_sh_per_se || |
2199 | se_bank >= adev->gfx.config.max_shader_engines) | 2508 | se_bank >= adev->gfx.config.max_shader_engines) |
@@ -2203,6 +2512,9 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | |||
2203 | sh_bank, instance_bank); | 2512 | sh_bank, instance_bank); |
2204 | } | 2513 | } |
2205 | 2514 | ||
2515 | if (pm_pg_lock) | ||
2516 | mutex_lock(&adev->pm.mutex); | ||
2517 | |||
2206 | while (size) { | 2518 | while (size) { |
2207 | uint32_t value; | 2519 | uint32_t value; |
2208 | 2520 | ||
@@ -2228,6 +2540,9 @@ end: | |||
2228 | mutex_unlock(&adev->grbm_idx_mutex); | 2540 | mutex_unlock(&adev->grbm_idx_mutex); |
2229 | } | 2541 | } |
2230 | 2542 | ||
2543 | if (pm_pg_lock) | ||
2544 | mutex_unlock(&adev->pm.mutex); | ||
2545 | |||
2231 | return result; | 2546 | return result; |
2232 | } | 2547 | } |
2233 | 2548 | ||
@@ -2385,7 +2700,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, | |||
2385 | while (size) { | 2700 | while (size) { |
2386 | uint32_t value; | 2701 | uint32_t value; |
2387 | 2702 | ||
2388 | value = RREG32_SMC(*pos >> 2); | 2703 | value = RREG32_SMC(*pos); |
2389 | r = put_user(value, (uint32_t *)buf); | 2704 | r = put_user(value, (uint32_t *)buf); |
2390 | if (r) | 2705 | if (r) |
2391 | return r; | 2706 | return r; |
@@ -2416,7 +2731,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * | |||
2416 | if (r) | 2731 | if (r) |
2417 | return r; | 2732 | return r; |
2418 | 2733 | ||
2419 | WREG32_SMC(*pos >> 2, value); | 2734 | WREG32_SMC(*pos, value); |
2420 | 2735 | ||
2421 | result += 4; | 2736 | result += 4; |
2422 | buf += 4; | 2737 | buf += 4; |
@@ -2438,12 +2753,12 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, | |||
2438 | if (size & 0x3 || *pos & 0x3) | 2753 | if (size & 0x3 || *pos & 0x3) |
2439 | return -EINVAL; | 2754 | return -EINVAL; |
2440 | 2755 | ||
2441 | config = kmalloc(256 * sizeof(*config), GFP_KERNEL); | 2756 | config = kmalloc_array(256, sizeof(*config), GFP_KERNEL); |
2442 | if (!config) | 2757 | if (!config) |
2443 | return -ENOMEM; | 2758 | return -ENOMEM; |
2444 | 2759 | ||
2445 | /* version, increment each time something is added */ | 2760 | /* version, increment each time something is added */ |
2446 | config[no_regs++] = 0; | 2761 | config[no_regs++] = 2; |
2447 | config[no_regs++] = adev->gfx.config.max_shader_engines; | 2762 | config[no_regs++] = adev->gfx.config.max_shader_engines; |
2448 | config[no_regs++] = adev->gfx.config.max_tile_pipes; | 2763 | config[no_regs++] = adev->gfx.config.max_tile_pipes; |
2449 | config[no_regs++] = adev->gfx.config.max_cu_per_sh; | 2764 | config[no_regs++] = adev->gfx.config.max_cu_per_sh; |
@@ -2468,6 +2783,15 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, | |||
2468 | config[no_regs++] = adev->gfx.config.gb_addr_config; | 2783 | config[no_regs++] = adev->gfx.config.gb_addr_config; |
2469 | config[no_regs++] = adev->gfx.config.num_rbs; | 2784 | config[no_regs++] = adev->gfx.config.num_rbs; |
2470 | 2785 | ||
2786 | /* rev==1 */ | ||
2787 | config[no_regs++] = adev->rev_id; | ||
2788 | config[no_regs++] = adev->pg_flags; | ||
2789 | config[no_regs++] = adev->cg_flags; | ||
2790 | |||
2791 | /* rev==2 */ | ||
2792 | config[no_regs++] = adev->family; | ||
2793 | config[no_regs++] = adev->external_rev_id; | ||
2794 | |||
2471 | while (size && (*pos < no_regs * 4)) { | 2795 | while (size && (*pos < no_regs * 4)) { |
2472 | uint32_t value; | 2796 | uint32_t value; |
2473 | 2797 | ||
@@ -2488,6 +2812,29 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, | |||
2488 | return result; | 2812 | return result; |
2489 | } | 2813 | } |
2490 | 2814 | ||
2815 | static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, | ||
2816 | size_t size, loff_t *pos) | ||
2817 | { | ||
2818 | struct amdgpu_device *adev = f->f_inode->i_private; | ||
2819 | int idx, r; | ||
2820 | int32_t value; | ||
2821 | |||
2822 | if (size != 4 || *pos & 0x3) | ||
2823 | return -EINVAL; | ||
2824 | |||
2825 | /* convert offset to sensor number */ | ||
2826 | idx = *pos >> 2; | ||
2827 | |||
2828 | if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor) | ||
2829 | r = adev->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, idx, &value); | ||
2830 | else | ||
2831 | return -EINVAL; | ||
2832 | |||
2833 | if (!r) | ||
2834 | r = put_user(value, (int32_t *)buf); | ||
2835 | |||
2836 | return !r ? 4 : r; | ||
2837 | } | ||
2491 | 2838 | ||
2492 | static const struct file_operations amdgpu_debugfs_regs_fops = { | 2839 | static const struct file_operations amdgpu_debugfs_regs_fops = { |
2493 | .owner = THIS_MODULE, | 2840 | .owner = THIS_MODULE, |
@@ -2520,12 +2867,19 @@ static const struct file_operations amdgpu_debugfs_gca_config_fops = { | |||
2520 | .llseek = default_llseek | 2867 | .llseek = default_llseek |
2521 | }; | 2868 | }; |
2522 | 2869 | ||
2870 | static const struct file_operations amdgpu_debugfs_sensors_fops = { | ||
2871 | .owner = THIS_MODULE, | ||
2872 | .read = amdgpu_debugfs_sensor_read, | ||
2873 | .llseek = default_llseek | ||
2874 | }; | ||
2875 | |||
2523 | static const struct file_operations *debugfs_regs[] = { | 2876 | static const struct file_operations *debugfs_regs[] = { |
2524 | &amdgpu_debugfs_regs_fops, | 2877 | &amdgpu_debugfs_regs_fops, |
2525 | &amdgpu_debugfs_regs_didt_fops, | 2878 | &amdgpu_debugfs_regs_didt_fops, |
2526 | &amdgpu_debugfs_regs_pcie_fops, | 2879 | &amdgpu_debugfs_regs_pcie_fops, |
2527 | &amdgpu_debugfs_regs_smc_fops, | 2880 | &amdgpu_debugfs_regs_smc_fops, |
2528 | &amdgpu_debugfs_gca_config_fops, | 2881 | &amdgpu_debugfs_gca_config_fops, |
2882 | &amdgpu_debugfs_sensors_fops, | ||
2529 | }; | 2883 | }; |
2530 | 2884 | ||
2531 | static const char *debugfs_regs_names[] = { | 2885 | static const char *debugfs_regs_names[] = { |
@@ -2534,6 +2888,7 @@ static const char *debugfs_regs_names[] = { | |||
2534 | "amdgpu_regs_pcie", | 2888 | "amdgpu_regs_pcie", |
2535 | "amdgpu_regs_smc", | 2889 | "amdgpu_regs_smc", |
2536 | "amdgpu_gca_config", | 2890 | "amdgpu_gca_config", |
2891 | "amdgpu_sensors", | ||
2537 | }; | 2892 | }; |
2538 | 2893 | ||
2539 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) | 2894 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) |