aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-08-24 22:59:50 -0400
committerDave Airlie <airlied@redhat.com>2016-08-24 22:59:50 -0400
commite9c3ddee6a08c5b25cdb06b524320a5a98250513 (patch)
tree41cc2cc030ef965c1d34b336c994a3ac9c00c13e
parent51d6120792ab5f46d6f5f7f37b65d05cc1afc019 (diff)
parent7b4d3e297e8a7d3b82e68231ff077e891c370349 (diff)
Merge branch 'drm-next-4.9' of git://people.freedesktop.org/~agd5f/linux into drm-next
First drm-next pull for radeon and amdgpu for 4.9. Highlights: - powerplay support for iceland asics - improved GPU reset (both full asic and per block) - UVD and VCE powergating for CZ and ST - VCE clockgating for CZ and ST - Support for pre-initialized (e.g., zeroed) vram buffers - ttm cleanups - virtual display support - core and radeon/amdgpu support for page_flip_target - lots of bug fixes and clean ups * 'drm-next-4.9' of git://people.freedesktop.org/~agd5f/linux: (171 commits) drm/amdgpu: use memcpy_toio for VCE firmware upload drm/amdgpu: use memcpy_to/fromio for UVD fw upload drm/amd/powerplay: delete useless code in iceland_hwmgr.c. drm/radeon: switch UVD code to use UVD_NO_OP for padding drm/amdgpu: switch UVD code to use UVD_NO_OP for padding drm/radeon: add support for UVD_NO_OP register drm/amdgpu: add support for UVD_NO_OP register drm/amdgpu: fix VCE ib alignment value drm/amdgpu: fix IB alignment for UVD drm/amd/amdgpu: Print ring name in amdgpu_ib_schedule() drm/radeon: remove dead code, si_mc_load_microcode (v2) drm/radeon/cik: remove dead code (v2) drm/amd/powerplay: avoid NULL dereference, cz_hwmgr.c drm/amd/powerplay: avoid NULL pointer dereference drm/amdgpu/gmc8: remove dead code (v2) drm/amdgpu/gmc7: remove dead code (v2) drm/amdgpu: Fix indentation in dce_v8_0_audio_write_sad_regs() drm/amdgpu: Use correct mask in dce_v8_0_afmt_setmode() and fix comment typos. drm/amdgpu: cleanup amdgpu_vm_bo_update params drm/amdgpu: stop adding dummy entry in amdgpu_ttm_placement_init ...
-rw-r--r--drivers/gpu/drm/Kconfig3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Kconfig2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/ObjectID.h7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h94
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c27
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c91
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c95
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c266
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c101
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c27
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c423
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.h32
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c58
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c27
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_test.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c112
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h80
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c58
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c454
-rw-r--r--drivers/gpu/drm/amd/amdgpu/atombios_dp.c22
-rw-r--r--drivers/gpu/drm/amd/amdgpu/ci_dpm.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik.c417
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik_sdma.c113
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cz_dpm.c47
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c68
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c59
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c85
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c806
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.h31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c628
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c76
-rw-r--r--drivers/gpu/drm/amd/amdgpu/kv_dpm.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c113
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c195
-rw-r--r--drivers/gpu/drm/amd/amdgpu/tonga_ih.c49
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c121
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v2_0.c160
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v3_0.c293
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vi.c438
-rw-r--r--drivers/gpu/drm/amd/include/amd_shared.h6
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_4_2_d.h1
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_5_0_d.h1
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c5
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/Makefile6
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c58
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c3
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c7
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c64
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_clockpowergating.c119
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_clockpowergating.h38
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_dyn_defaults.h41
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c5692
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.h424
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.c490
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.h74
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.c595
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.h58
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c32
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c24
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h11
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c498
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h22
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h4
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h112
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu71.h510
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu71_discrete.h631
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/Makefile3
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c713
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.h64
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c4
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c4
-rw-r--r--drivers/gpu/drm/drm_crtc.c66
-rw-r--r--drivers/gpu/drm/drm_ioctl.c8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c6
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c4
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c8
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c21
-rw-r--r--drivers/gpu/drm/radeon/cik.c12
-rw-r--r--drivers/gpu/drm/radeon/cikd.h1
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c5
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h1
-rw-r--r--drivers/gpu/drm/radeon/ni.c2
-rw-r--r--drivers/gpu/drm/radeon/nid.h1
-rw-r--r--drivers/gpu/drm/radeon/r600.c2
-rw-r--r--drivers/gpu/drm/radeon/r600d.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c89
-rw-r--r--drivers/gpu/drm/radeon/radeon_dp_auxch.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_uvd.c7
-rw-r--r--drivers/gpu/drm/radeon/rv515.c3
-rw-r--r--drivers/gpu/drm/radeon/rv770.c2
-rw-r--r--drivers/gpu/drm/radeon/rv770d.h1
-rw-r--r--drivers/gpu/drm/radeon/si.c12
-rw-r--r--drivers/gpu/drm/radeon/sid.h1
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c7
-rw-r--r--drivers/gpu/drm/ttm/ttm_memory.c6
-rw-r--r--include/drm/drm_crtc.h18
-rw-r--r--include/drm/ttm/ttm_bo_driver.h7
-rw-r--r--include/drm/ttm/ttm_memory.h1
-rw-r--r--include/uapi/drm/amdgpu_drm.h6
-rw-r--r--include/uapi/drm/drm.h1
-rw-r--r--include/uapi/drm/drm_mode.h39
127 files changed, 14468 insertions, 2022 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index fe1e86ea6d27..cbb64d9a82f8 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -163,9 +163,6 @@ config DRM_AMDGPU
163 If M is selected, the module will be called amdgpu. 163 If M is selected, the module will be called amdgpu.
164 164
165source "drivers/gpu/drm/amd/amdgpu/Kconfig" 165source "drivers/gpu/drm/amd/amdgpu/Kconfig"
166source "drivers/gpu/drm/amd/powerplay/Kconfig"
167
168source "drivers/gpu/drm/amd/acp/Kconfig"
169 166
170source "drivers/gpu/drm/nouveau/Kconfig" 167source "drivers/gpu/drm/nouveau/Kconfig"
171 168
diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 7335c0420c70..f3cb69de0c44 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -25,3 +25,5 @@ config DRM_AMDGPU_GART_DEBUGFS
25 Selecting this option creates a debugfs file to inspect the mapped 25 Selecting this option creates a debugfs file to inspect the mapped
26 pages. Uses more memory for housekeeping, enable only for debugging. 26 pages. Uses more memory for housekeeping, enable only for debugging.
27 27
28source "drivers/gpu/drm/amd/powerplay/Kconfig"
29source "drivers/gpu/drm/amd/acp/Kconfig"
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index c7fcdcedaadb..21dd7c00da15 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -58,7 +58,8 @@ amdgpu-y += \
58# add DCE block 58# add DCE block
59amdgpu-y += \ 59amdgpu-y += \
60 dce_v10_0.o \ 60 dce_v10_0.o \
61 dce_v11_0.o 61 dce_v11_0.o \
62 dce_virtual.o
62 63
63# add GFX block 64# add GFX block
64amdgpu-y += \ 65amdgpu-y += \
diff --git a/drivers/gpu/drm/amd/amdgpu/ObjectID.h b/drivers/gpu/drm/amd/amdgpu/ObjectID.h
index 06192698bd96..b8d66670bb17 100644
--- a/drivers/gpu/drm/amd/amdgpu/ObjectID.h
+++ b/drivers/gpu/drm/amd/amdgpu/ObjectID.h
@@ -90,6 +90,7 @@
90#define ENCODER_OBJECT_ID_INTERNAL_VCE 0x24 90#define ENCODER_OBJECT_ID_INTERNAL_VCE 0x24
91#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 0x25 91#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 0x25
92#define ENCODER_OBJECT_ID_INTERNAL_AMCLK 0x27 92#define ENCODER_OBJECT_ID_INTERNAL_AMCLK 0x27
93#define ENCODER_OBJECT_ID_VIRTUAL 0x28
93 94
94#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF 95#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF
95 96
@@ -119,6 +120,7 @@
119#define CONNECTOR_OBJECT_ID_eDP 0x14 120#define CONNECTOR_OBJECT_ID_eDP 0x14
120#define CONNECTOR_OBJECT_ID_MXM 0x15 121#define CONNECTOR_OBJECT_ID_MXM 0x15
121#define CONNECTOR_OBJECT_ID_LVDS_eDP 0x16 122#define CONNECTOR_OBJECT_ID_LVDS_eDP 0x16
123#define CONNECTOR_OBJECT_ID_VIRTUAL 0x17
122 124
123/* deleted */ 125/* deleted */
124 126
@@ -147,6 +149,7 @@
147#define GRAPH_OBJECT_ENUM_ID5 0x05 149#define GRAPH_OBJECT_ENUM_ID5 0x05
148#define GRAPH_OBJECT_ENUM_ID6 0x06 150#define GRAPH_OBJECT_ENUM_ID6 0x06
149#define GRAPH_OBJECT_ENUM_ID7 0x07 151#define GRAPH_OBJECT_ENUM_ID7 0x07
152#define GRAPH_OBJECT_ENUM_VIRTUAL 0x08
150 153
151/****************************************************/ 154/****************************************************/
152/* Graphics Object ID Bit definition */ 155/* Graphics Object ID Bit definition */
@@ -408,6 +411,10 @@
408 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ 411 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
409 ENCODER_OBJECT_ID_HDMI_ANX9805 << OBJECT_ID_SHIFT) 412 ENCODER_OBJECT_ID_HDMI_ANX9805 << OBJECT_ID_SHIFT)
410 413
414#define ENCODER_VIRTUAL_ENUM_VIRTUAL ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
415 GRAPH_OBJECT_ENUM_VIRTUAL << ENUM_ID_SHIFT |\
416 ENCODER_OBJECT_ID_VIRTUAL << OBJECT_ID_SHIFT)
417
411/****************************************************/ 418/****************************************************/
412/* Connector Object ID definition - Shared with BIOS */ 419/* Connector Object ID definition - Shared with BIOS */
413/****************************************************/ 420/****************************************************/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 8ebc5f1eb4c0..3cc2629eb158 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -51,6 +51,7 @@
51#include "amdgpu_ih.h" 51#include "amdgpu_ih.h"
52#include "amdgpu_irq.h" 52#include "amdgpu_irq.h"
53#include "amdgpu_ucode.h" 53#include "amdgpu_ucode.h"
54#include "amdgpu_ttm.h"
54#include "amdgpu_gds.h" 55#include "amdgpu_gds.h"
55#include "amd_powerplay.h" 56#include "amd_powerplay.h"
56#include "amdgpu_acp.h" 57#include "amdgpu_acp.h"
@@ -91,6 +92,8 @@ extern unsigned amdgpu_pcie_lane_cap;
91extern unsigned amdgpu_cg_mask; 92extern unsigned amdgpu_cg_mask;
92extern unsigned amdgpu_pg_mask; 93extern unsigned amdgpu_pg_mask;
93extern char *amdgpu_disable_cu; 94extern char *amdgpu_disable_cu;
95extern int amdgpu_sclk_deep_sleep_en;
96extern char *amdgpu_virtual_display;
94 97
95#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 98#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
96#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ 99#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -248,10 +251,9 @@ struct amdgpu_vm_pte_funcs {
248 uint64_t pe, uint64_t src, 251 uint64_t pe, uint64_t src,
249 unsigned count); 252 unsigned count);
250 /* write pte one entry at a time with addr mapping */ 253 /* write pte one entry at a time with addr mapping */
251 void (*write_pte)(struct amdgpu_ib *ib, 254 void (*write_pte)(struct amdgpu_ib *ib, uint64_t pe,
252 const dma_addr_t *pages_addr, uint64_t pe, 255 uint64_t value, unsigned count,
253 uint64_t addr, unsigned count, 256 uint32_t incr);
254 uint32_t incr, uint32_t flags);
255 /* for linear pte/pde updates without addr mapping */ 257 /* for linear pte/pde updates without addr mapping */
256 void (*set_pte_pde)(struct amdgpu_ib *ib, 258 void (*set_pte_pde)(struct amdgpu_ib *ib,
257 uint64_t pe, 259 uint64_t pe,
@@ -396,46 +398,9 @@ int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
396unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); 398unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring);
397 399
398/* 400/*
399 * TTM. 401 * BO.
400 */ 402 */
401 403
402#define AMDGPU_TTM_LRU_SIZE 20
403
404struct amdgpu_mman_lru {
405 struct list_head *lru[TTM_NUM_MEM_TYPES];
406 struct list_head *swap_lru;
407};
408
409struct amdgpu_mman {
410 struct ttm_bo_global_ref bo_global_ref;
411 struct drm_global_reference mem_global_ref;
412 struct ttm_bo_device bdev;
413 bool mem_global_referenced;
414 bool initialized;
415
416#if defined(CONFIG_DEBUG_FS)
417 struct dentry *vram;
418 struct dentry *gtt;
419#endif
420
421 /* buffer handling */
422 const struct amdgpu_buffer_funcs *buffer_funcs;
423 struct amdgpu_ring *buffer_funcs_ring;
424 /* Scheduler entity for buffer moves */
425 struct amd_sched_entity entity;
426
427 /* custom LRU management */
428 struct amdgpu_mman_lru log2_size[AMDGPU_TTM_LRU_SIZE];
429};
430
431int amdgpu_copy_buffer(struct amdgpu_ring *ring,
432 uint64_t src_offset,
433 uint64_t dst_offset,
434 uint32_t byte_count,
435 struct reservation_object *resv,
436 struct fence **fence);
437int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
438
439struct amdgpu_bo_list_entry { 404struct amdgpu_bo_list_entry {
440 struct amdgpu_bo *robj; 405 struct amdgpu_bo *robj;
441 struct ttm_validate_buffer tv; 406 struct ttm_validate_buffer tv;
@@ -498,10 +463,12 @@ struct amdgpu_bo {
498 struct amdgpu_device *adev; 463 struct amdgpu_device *adev;
499 struct drm_gem_object gem_base; 464 struct drm_gem_object gem_base;
500 struct amdgpu_bo *parent; 465 struct amdgpu_bo *parent;
466 struct amdgpu_bo *shadow;
501 467
502 struct ttm_bo_kmap_obj dma_buf_vmap; 468 struct ttm_bo_kmap_obj dma_buf_vmap;
503 struct amdgpu_mn *mn; 469 struct amdgpu_mn *mn;
504 struct list_head mn_list; 470 struct list_head mn_list;
471 struct list_head shadow_list;
505}; 472};
506#define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, gem_base) 473#define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, gem_base)
507 474
@@ -677,6 +644,8 @@ struct amdgpu_mc {
677 uint32_t fw_version; 644 uint32_t fw_version;
678 struct amdgpu_irq_src vm_fault; 645 struct amdgpu_irq_src vm_fault;
679 uint32_t vram_type; 646 uint32_t vram_type;
647 uint32_t srbm_soft_reset;
648 struct amdgpu_mode_mc_save save;
680}; 649};
681 650
682/* 651/*
@@ -721,10 +690,11 @@ void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
721 */ 690 */
722 691
723struct amdgpu_flip_work { 692struct amdgpu_flip_work {
724 struct work_struct flip_work; 693 struct delayed_work flip_work;
725 struct work_struct unpin_work; 694 struct work_struct unpin_work;
726 struct amdgpu_device *adev; 695 struct amdgpu_device *adev;
727 int crtc_id; 696 int crtc_id;
697 u32 target_vblank;
728 uint64_t base; 698 uint64_t base;
729 struct drm_pending_vblank_event *event; 699 struct drm_pending_vblank_event *event;
730 struct amdgpu_bo *old_rbo; 700 struct amdgpu_bo *old_rbo;
@@ -815,13 +785,17 @@ struct amdgpu_ring {
815/* maximum number of VMIDs */ 785/* maximum number of VMIDs */
816#define AMDGPU_NUM_VM 16 786#define AMDGPU_NUM_VM 16
817 787
788/* Maximum number of PTEs the hardware can write with one command */
789#define AMDGPU_VM_MAX_UPDATE_SIZE 0x3FFFF
790
818/* number of entries in page table */ 791/* number of entries in page table */
819#define AMDGPU_VM_PTE_COUNT (1 << amdgpu_vm_block_size) 792#define AMDGPU_VM_PTE_COUNT (1 << amdgpu_vm_block_size)
820 793
821/* PTBs (Page Table Blocks) need to be aligned to 32K */ 794/* PTBs (Page Table Blocks) need to be aligned to 32K */
822#define AMDGPU_VM_PTB_ALIGN_SIZE 32768 795#define AMDGPU_VM_PTB_ALIGN_SIZE 32768
823#define AMDGPU_VM_PTB_ALIGN_MASK (AMDGPU_VM_PTB_ALIGN_SIZE - 1) 796
824#define AMDGPU_VM_PTB_ALIGN(a) (((a) + AMDGPU_VM_PTB_ALIGN_MASK) & ~AMDGPU_VM_PTB_ALIGN_MASK) 797/* LOG2 number of continuous pages for the fragment field */
798#define AMDGPU_LOG2_PAGES_PER_FRAG 4
825 799
826#define AMDGPU_PTE_VALID (1 << 0) 800#define AMDGPU_PTE_VALID (1 << 0)
827#define AMDGPU_PTE_SYSTEM (1 << 1) 801#define AMDGPU_PTE_SYSTEM (1 << 1)
@@ -833,10 +807,7 @@ struct amdgpu_ring {
833#define AMDGPU_PTE_READABLE (1 << 5) 807#define AMDGPU_PTE_READABLE (1 << 5)
834#define AMDGPU_PTE_WRITEABLE (1 << 6) 808#define AMDGPU_PTE_WRITEABLE (1 << 6)
835 809
836/* PTE (Page Table Entry) fragment field for different page sizes */ 810#define AMDGPU_PTE_FRAG(x) ((x & 0x1f) << 7)
837#define AMDGPU_PTE_FRAG_4KB (0 << 7)
838#define AMDGPU_PTE_FRAG_64KB (4 << 7)
839#define AMDGPU_LOG2_PAGES_PER_FRAG 4
840 811
841/* How to programm VM fault handling */ 812/* How to programm VM fault handling */
842#define AMDGPU_VM_FAULT_STOP_NEVER 0 813#define AMDGPU_VM_FAULT_STOP_NEVER 0
@@ -846,6 +817,7 @@ struct amdgpu_ring {
846struct amdgpu_vm_pt { 817struct amdgpu_vm_pt {
847 struct amdgpu_bo_list_entry entry; 818 struct amdgpu_bo_list_entry entry;
848 uint64_t addr; 819 uint64_t addr;
820 uint64_t shadow_addr;
849}; 821};
850 822
851struct amdgpu_vm { 823struct amdgpu_vm {
@@ -948,7 +920,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
948 struct amdgpu_job *job); 920 struct amdgpu_job *job);
949int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job); 921int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job);
950void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); 922void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id);
951uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr);
952int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, 923int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
953 struct amdgpu_vm *vm); 924 struct amdgpu_vm *vm);
954int amdgpu_vm_clear_freed(struct amdgpu_device *adev, 925int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
@@ -957,7 +928,7 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, struct amdgpu_vm *vm,
957 struct amdgpu_sync *sync); 928 struct amdgpu_sync *sync);
958int amdgpu_vm_bo_update(struct amdgpu_device *adev, 929int amdgpu_vm_bo_update(struct amdgpu_device *adev,
959 struct amdgpu_bo_va *bo_va, 930 struct amdgpu_bo_va *bo_va,
960 struct ttm_mem_reg *mem); 931 bool clear);
961void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, 932void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
962 struct amdgpu_bo *bo); 933 struct amdgpu_bo *bo);
963struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, 934struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
@@ -1195,6 +1166,10 @@ struct amdgpu_gfx {
1195 unsigned ce_ram_size; 1166 unsigned ce_ram_size;
1196 struct amdgpu_cu_info cu_info; 1167 struct amdgpu_cu_info cu_info;
1197 const struct amdgpu_gfx_funcs *funcs; 1168 const struct amdgpu_gfx_funcs *funcs;
1169
1170 /* reset mask */
1171 uint32_t grbm_soft_reset;
1172 uint32_t srbm_soft_reset;
1198}; 1173};
1199 1174
1200int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, 1175int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
@@ -1683,6 +1658,7 @@ struct amdgpu_uvd {
1683 bool address_64_bit; 1658 bool address_64_bit;
1684 bool use_ctx_buf; 1659 bool use_ctx_buf;
1685 struct amd_sched_entity entity; 1660 struct amd_sched_entity entity;
1661 uint32_t srbm_soft_reset;
1686}; 1662};
1687 1663
1688/* 1664/*
@@ -1709,6 +1685,7 @@ struct amdgpu_vce {
1709 struct amdgpu_irq_src irq; 1685 struct amdgpu_irq_src irq;
1710 unsigned harvest_config; 1686 unsigned harvest_config;
1711 struct amd_sched_entity entity; 1687 struct amd_sched_entity entity;
1688 uint32_t srbm_soft_reset;
1712}; 1689};
1713 1690
1714/* 1691/*
@@ -1729,6 +1706,7 @@ struct amdgpu_sdma {
1729 struct amdgpu_irq_src trap_irq; 1706 struct amdgpu_irq_src trap_irq;
1730 struct amdgpu_irq_src illegal_inst_irq; 1707 struct amdgpu_irq_src illegal_inst_irq;
1731 int num_instances; 1708 int num_instances;
1709 uint32_t srbm_soft_reset;
1732}; 1710};
1733 1711
1734/* 1712/*
@@ -1956,6 +1934,7 @@ struct amdgpu_ip_block_status {
1956 bool valid; 1934 bool valid;
1957 bool sw; 1935 bool sw;
1958 bool hw; 1936 bool hw;
1937 bool hang;
1959}; 1938};
1960 1939
1961struct amdgpu_device { 1940struct amdgpu_device {
@@ -2055,6 +2034,7 @@ struct amdgpu_device {
2055 atomic_t gpu_reset_counter; 2034 atomic_t gpu_reset_counter;
2056 2035
2057 /* display */ 2036 /* display */
2037 bool enable_virtual_display;
2058 struct amdgpu_mode_info mode_info; 2038 struct amdgpu_mode_info mode_info;
2059 struct work_struct hotplug_work; 2039 struct work_struct hotplug_work;
2060 struct amdgpu_irq_src crtc_irq; 2040 struct amdgpu_irq_src crtc_irq;
@@ -2117,6 +2097,10 @@ struct amdgpu_device {
2117 struct kfd_dev *kfd; 2097 struct kfd_dev *kfd;
2118 2098
2119 struct amdgpu_virtualization virtualization; 2099 struct amdgpu_virtualization virtualization;
2100
2101 /* link all shadow bo */
2102 struct list_head shadow_list;
2103 struct mutex shadow_list_lock;
2120}; 2104};
2121 2105
2122bool amdgpu_device_is_px(struct drm_device *dev); 2106bool amdgpu_device_is_px(struct drm_device *dev);
@@ -2192,6 +2176,9 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
2192#define REG_GET_FIELD(value, reg, field) \ 2176#define REG_GET_FIELD(value, reg, field) \
2193 (((value) & REG_FIELD_MASK(reg, field)) >> REG_FIELD_SHIFT(reg, field)) 2177 (((value) & REG_FIELD_MASK(reg, field)) >> REG_FIELD_SHIFT(reg, field))
2194 2178
2179#define WREG32_FIELD(reg, field, val) \
2180 WREG32(mm##reg, (RREG32(mm##reg) & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field))
2181
2195/* 2182/*
2196 * BIOS helpers. 2183 * BIOS helpers.
2197 */ 2184 */
@@ -2242,7 +2229,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
2242#define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid)) 2229#define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid))
2243#define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags)) 2230#define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags))
2244#define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count))) 2231#define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count)))
2245#define amdgpu_vm_write_pte(adev, ib, pa, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pa), (pe), (addr), (count), (incr), (flags))) 2232#define amdgpu_vm_write_pte(adev, ib, pe, value, count, incr) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (value), (count), (incr)))
2246#define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags))) 2233#define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags)))
2247#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib))) 2234#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
2248#define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r)) 2235#define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r))
@@ -2387,6 +2374,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
2387 2374
2388/* Common functions */ 2375/* Common functions */
2389int amdgpu_gpu_reset(struct amdgpu_device *adev); 2376int amdgpu_gpu_reset(struct amdgpu_device *adev);
2377bool amdgpu_need_backup(struct amdgpu_device *adev);
2390void amdgpu_pci_config_reset(struct amdgpu_device *adev); 2378void amdgpu_pci_config_reset(struct amdgpu_device *adev);
2391bool amdgpu_card_posted(struct amdgpu_device *adev); 2379bool amdgpu_card_posted(struct amdgpu_device *adev);
2392void amdgpu_update_display_priority(struct amdgpu_device *adev); 2380void amdgpu_update_display_priority(struct amdgpu_device *adev);
@@ -2412,6 +2400,8 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
2412void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base); 2400void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base);
2413void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc); 2401void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
2414void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size); 2402void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
2403u64 amdgpu_ttm_get_gtt_mem_size(struct amdgpu_device *adev);
2404int amdgpu_ttm_global_init(struct amdgpu_device *adev);
2415void amdgpu_program_register_sequence(struct amdgpu_device *adev, 2405void amdgpu_program_register_sequence(struct amdgpu_device *adev,
2416 const u32 *registers, 2406 const u32 *registers,
2417 const u32 array_size); 2407 const u32 array_size);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
index 983175363b06..1b621160b52e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -259,6 +259,33 @@ static const int object_connector_convert[] = {
259 DRM_MODE_CONNECTOR_Unknown 259 DRM_MODE_CONNECTOR_Unknown
260}; 260};
261 261
262bool amdgpu_atombios_has_dce_engine_info(struct amdgpu_device *adev)
263{
264 struct amdgpu_mode_info *mode_info = &adev->mode_info;
265 struct atom_context *ctx = mode_info->atom_context;
266 int index = GetIndexIntoMasterTable(DATA, Object_Header);
267 u16 size, data_offset;
268 u8 frev, crev;
269 ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
270 ATOM_OBJECT_HEADER *obj_header;
271
272 if (!amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
273 return false;
274
275 if (crev < 2)
276 return false;
277
278 obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);
279 path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
280 (ctx->bios + data_offset +
281 le16_to_cpu(obj_header->usDisplayPathTableOffset));
282
283 if (path_obj->ucNumOfDispPath)
284 return true;
285 else
286 return false;
287}
288
262bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev) 289bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev)
263{ 290{
264 struct amdgpu_mode_info *mode_info = &adev->mode_info; 291 struct amdgpu_mode_info *mode_info = &adev->mode_info;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
index 8c2e69661799..15dd43ec38bb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
@@ -140,6 +140,8 @@ struct amdgpu_i2c_bus_rec amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device *
140 uint8_t id); 140 uint8_t id);
141void amdgpu_atombios_i2c_init(struct amdgpu_device *adev); 141void amdgpu_atombios_i2c_init(struct amdgpu_device *adev);
142 142
143bool amdgpu_atombios_has_dce_engine_info(struct amdgpu_device *adev);
144
143bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev); 145bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device *adev);
144 146
145int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev); 147int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
index 33e47a43ae32..345305235349 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
@@ -39,7 +39,8 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
39 start_jiffies = jiffies; 39 start_jiffies = jiffies;
40 for (i = 0; i < n; i++) { 40 for (i = 0; i < n; i++) {
41 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; 41 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
42 r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence); 42 r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
43 false);
43 if (r) 44 if (r)
44 goto exit_do_move; 45 goto exit_do_move;
45 r = fence_wait(fence, false); 46 r = fence_wait(fence, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index ff0b55a65ca3..319a5e1d9389 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -1504,6 +1504,86 @@ static const struct drm_connector_funcs amdgpu_connector_edp_funcs = {
1504 .force = amdgpu_connector_dvi_force, 1504 .force = amdgpu_connector_dvi_force,
1505}; 1505};
1506 1506
1507static struct drm_encoder *
1508amdgpu_connector_virtual_encoder(struct drm_connector *connector)
1509{
1510 int enc_id = connector->encoder_ids[0];
1511 struct drm_encoder *encoder;
1512 int i;
1513 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1514 if (connector->encoder_ids[i] == 0)
1515 break;
1516
1517 encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
1518 if (!encoder)
1519 continue;
1520
1521 if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
1522 return encoder;
1523 }
1524
1525 /* pick the first one */
1526 if (enc_id)
1527 return drm_encoder_find(connector->dev, enc_id);
1528 return NULL;
1529}
1530
1531static int amdgpu_connector_virtual_get_modes(struct drm_connector *connector)
1532{
1533 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
1534
1535 if (encoder) {
1536 amdgpu_connector_add_common_modes(encoder, connector);
1537 }
1538
1539 return 0;
1540}
1541
1542static int amdgpu_connector_virtual_mode_valid(struct drm_connector *connector,
1543 struct drm_display_mode *mode)
1544{
1545 return MODE_OK;
1546}
1547
1548int amdgpu_connector_virtual_dpms(struct drm_connector *connector, int mode)
1549{
1550 return 0;
1551}
1552
1553static enum drm_connector_status
1554
1555amdgpu_connector_virtual_detect(struct drm_connector *connector, bool force)
1556{
1557 return connector_status_connected;
1558}
1559
1560int amdgpu_connector_virtual_set_property(struct drm_connector *connector,
1561 struct drm_property *property,
1562 uint64_t val)
1563{
1564 return 0;
1565}
1566
1567static void amdgpu_connector_virtual_force(struct drm_connector *connector)
1568{
1569 return;
1570}
1571
1572static const struct drm_connector_helper_funcs amdgpu_connector_virtual_helper_funcs = {
1573 .get_modes = amdgpu_connector_virtual_get_modes,
1574 .mode_valid = amdgpu_connector_virtual_mode_valid,
1575 .best_encoder = amdgpu_connector_virtual_encoder,
1576};
1577
1578static const struct drm_connector_funcs amdgpu_connector_virtual_funcs = {
1579 .dpms = amdgpu_connector_virtual_dpms,
1580 .detect = amdgpu_connector_virtual_detect,
1581 .fill_modes = drm_helper_probe_single_connector_modes,
1582 .set_property = amdgpu_connector_virtual_set_property,
1583 .destroy = amdgpu_connector_destroy,
1584 .force = amdgpu_connector_virtual_force,
1585};
1586
1507void 1587void
1508amdgpu_connector_add(struct amdgpu_device *adev, 1588amdgpu_connector_add(struct amdgpu_device *adev,
1509 uint32_t connector_id, 1589 uint32_t connector_id,
@@ -1888,6 +1968,17 @@ amdgpu_connector_add(struct amdgpu_device *adev,
1888 connector->interlace_allowed = false; 1968 connector->interlace_allowed = false;
1889 connector->doublescan_allowed = false; 1969 connector->doublescan_allowed = false;
1890 break; 1970 break;
1971 case DRM_MODE_CONNECTOR_VIRTUAL:
1972 amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);
1973 if (!amdgpu_dig_connector)
1974 goto failed;
1975 amdgpu_connector->con_priv = amdgpu_dig_connector;
1976 drm_connector_init(dev, &amdgpu_connector->base, &amdgpu_connector_virtual_funcs, connector_type);
1977 drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_virtual_helper_funcs);
1978 subpixel_order = SubPixelHorizontalRGB;
1979 connector->interlace_allowed = false;
1980 connector->doublescan_allowed = false;
1981 break;
1891 } 1982 }
1892 } 1983 }
1893 1984
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 0307ff5887c5..d80e5d3a4add 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -287,18 +287,56 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
287 return max(bytes_moved_threshold, 1024*1024ull); 287 return max(bytes_moved_threshold, 1024*1024ull);
288} 288}
289 289
290static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
291 struct amdgpu_bo *bo)
292{
293 u64 initial_bytes_moved;
294 uint32_t domain;
295 int r;
296
297 if (bo->pin_count)
298 return 0;
299
300 /* Avoid moving this one if we have moved too many buffers
301 * for this IB already.
302 *
303 * Note that this allows moving at least one buffer of
304 * any size, because it doesn't take the current "bo"
305 * into account. We don't want to disallow buffer moves
306 * completely.
307 */
308 if (p->bytes_moved <= p->bytes_moved_threshold)
309 domain = bo->prefered_domains;
310 else
311 domain = bo->allowed_domains;
312
313retry:
314 amdgpu_ttm_placement_from_domain(bo, domain);
315 initial_bytes_moved = atomic64_read(&bo->adev->num_bytes_moved);
316 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
317 p->bytes_moved += atomic64_read(&bo->adev->num_bytes_moved) -
318 initial_bytes_moved;
319
320 if (unlikely(r)) {
321 if (r != -ERESTARTSYS && domain != bo->allowed_domains) {
322 domain = bo->allowed_domains;
323 goto retry;
324 }
325 }
326
327 return r;
328}
329
290int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, 330int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
291 struct list_head *validated) 331 struct list_head *validated)
292{ 332{
293 struct amdgpu_bo_list_entry *lobj; 333 struct amdgpu_bo_list_entry *lobj;
294 u64 initial_bytes_moved;
295 int r; 334 int r;
296 335
297 list_for_each_entry(lobj, validated, tv.head) { 336 list_for_each_entry(lobj, validated, tv.head) {
298 struct amdgpu_bo *bo = lobj->robj; 337 struct amdgpu_bo *bo = lobj->robj;
299 bool binding_userptr = false; 338 bool binding_userptr = false;
300 struct mm_struct *usermm; 339 struct mm_struct *usermm;
301 uint32_t domain;
302 340
303 usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm); 341 usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
304 if (usermm && usermm != current->mm) 342 if (usermm && usermm != current->mm)
@@ -313,35 +351,13 @@ int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
313 binding_userptr = true; 351 binding_userptr = true;
314 } 352 }
315 353
316 if (bo->pin_count) 354 r = amdgpu_cs_bo_validate(p, bo);
317 continue; 355 if (r)
318
319 /* Avoid moving this one if we have moved too many buffers
320 * for this IB already.
321 *
322 * Note that this allows moving at least one buffer of
323 * any size, because it doesn't take the current "bo"
324 * into account. We don't want to disallow buffer moves
325 * completely.
326 */
327 if (p->bytes_moved <= p->bytes_moved_threshold)
328 domain = bo->prefered_domains;
329 else
330 domain = bo->allowed_domains;
331
332 retry:
333 amdgpu_ttm_placement_from_domain(bo, domain);
334 initial_bytes_moved = atomic64_read(&bo->adev->num_bytes_moved);
335 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
336 p->bytes_moved += atomic64_read(&bo->adev->num_bytes_moved) -
337 initial_bytes_moved;
338
339 if (unlikely(r)) {
340 if (r != -ERESTARTSYS && domain != bo->allowed_domains) {
341 domain = bo->allowed_domains;
342 goto retry;
343 }
344 return r; 356 return r;
357 if (bo->shadow) {
358 r = amdgpu_cs_bo_validate(p, bo);
359 if (r)
360 return r;
345 } 361 }
346 362
347 if (binding_userptr) { 363 if (binding_userptr) {
@@ -386,8 +402,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
386 402
387 r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, 403 r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true,
388 &duplicates); 404 &duplicates);
389 if (unlikely(r != 0)) 405 if (unlikely(r != 0)) {
406 DRM_ERROR("ttm_eu_reserve_buffers failed.\n");
390 goto error_free_pages; 407 goto error_free_pages;
408 }
391 409
392 /* Without a BO list we don't have userptr BOs */ 410 /* Without a BO list we don't have userptr BOs */
393 if (!p->bo_list) 411 if (!p->bo_list)
@@ -427,9 +445,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
427 /* Unreserve everything again. */ 445 /* Unreserve everything again. */
428 ttm_eu_backoff_reservation(&p->ticket, &p->validated); 446 ttm_eu_backoff_reservation(&p->ticket, &p->validated);
429 447
430 /* We tried to often, just abort */ 448 /* We tried too many times, just abort */
431 if (!--tries) { 449 if (!--tries) {
432 r = -EDEADLK; 450 r = -EDEADLK;
451 DRM_ERROR("deadlock in %s\n", __func__);
433 goto error_free_pages; 452 goto error_free_pages;
434 } 453 }
435 454
@@ -441,11 +460,13 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
441 sizeof(struct page*)); 460 sizeof(struct page*));
442 if (!e->user_pages) { 461 if (!e->user_pages) {
443 r = -ENOMEM; 462 r = -ENOMEM;
463 DRM_ERROR("calloc failure in %s\n", __func__);
444 goto error_free_pages; 464 goto error_free_pages;
445 } 465 }
446 466
447 r = amdgpu_ttm_tt_get_user_pages(ttm, e->user_pages); 467 r = amdgpu_ttm_tt_get_user_pages(ttm, e->user_pages);
448 if (r) { 468 if (r) {
469 DRM_ERROR("amdgpu_ttm_tt_get_user_pages failed.\n");
449 drm_free_large(e->user_pages); 470 drm_free_large(e->user_pages);
450 e->user_pages = NULL; 471 e->user_pages = NULL;
451 goto error_free_pages; 472 goto error_free_pages;
@@ -462,12 +483,16 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
462 p->bytes_moved = 0; 483 p->bytes_moved = 0;
463 484
464 r = amdgpu_cs_list_validate(p, &duplicates); 485 r = amdgpu_cs_list_validate(p, &duplicates);
465 if (r) 486 if (r) {
487 DRM_ERROR("amdgpu_cs_list_validate(duplicates) failed.\n");
466 goto error_validate; 488 goto error_validate;
489 }
467 490
468 r = amdgpu_cs_list_validate(p, &p->validated); 491 r = amdgpu_cs_list_validate(p, &p->validated);
469 if (r) 492 if (r) {
493 DRM_ERROR("amdgpu_cs_list_validate(validated) failed.\n");
470 goto error_validate; 494 goto error_validate;
495 }
471 496
472 fpriv->vm.last_eviction_counter = 497 fpriv->vm.last_eviction_counter =
473 atomic64_read(&p->adev->num_evictions); 498 atomic64_read(&p->adev->num_evictions);
@@ -617,7 +642,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
617 if (bo_va == NULL) 642 if (bo_va == NULL)
618 continue; 643 continue;
619 644
620 r = amdgpu_vm_bo_update(adev, bo_va, &bo->tbo.mem); 645 r = amdgpu_vm_bo_update(adev, bo_va, false);
621 if (r) 646 if (r)
622 return r; 647 return r;
623 648
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index df7ab2458e50..c38dc47cd767 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -46,6 +46,7 @@
46#endif 46#endif
47#include "vi.h" 47#include "vi.h"
48#include "bif/bif_4_1_d.h" 48#include "bif/bif_4_1_d.h"
49#include <linux/pci.h>
49 50
50static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); 51static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
51static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); 52static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev);
@@ -1181,10 +1182,38 @@ int amdgpu_ip_block_version_cmp(struct amdgpu_device *adev,
1181 return 1; 1182 return 1;
1182} 1183}
1183 1184
1185static void amdgpu_whether_enable_virtual_display(struct amdgpu_device *adev)
1186{
1187 adev->enable_virtual_display = false;
1188
1189 if (amdgpu_virtual_display) {
1190 struct drm_device *ddev = adev->ddev;
1191 const char *pci_address_name = pci_name(ddev->pdev);
1192 char *pciaddstr, *pciaddstr_tmp, *pciaddname;
1193
1194 pciaddstr = kstrdup(amdgpu_virtual_display, GFP_KERNEL);
1195 pciaddstr_tmp = pciaddstr;
1196 while ((pciaddname = strsep(&pciaddstr_tmp, ";"))) {
1197 if (!strcmp(pci_address_name, pciaddname)) {
1198 adev->enable_virtual_display = true;
1199 break;
1200 }
1201 }
1202
1203 DRM_INFO("virtual display string:%s, %s:virtual_display:%d\n",
1204 amdgpu_virtual_display, pci_address_name,
1205 adev->enable_virtual_display);
1206
1207 kfree(pciaddstr);
1208 }
1209}
1210
1184static int amdgpu_early_init(struct amdgpu_device *adev) 1211static int amdgpu_early_init(struct amdgpu_device *adev)
1185{ 1212{
1186 int i, r; 1213 int i, r;
1187 1214
1215 amdgpu_whether_enable_virtual_display(adev);
1216
1188 switch (adev->asic_type) { 1217 switch (adev->asic_type) {
1189 case CHIP_TOPAZ: 1218 case CHIP_TOPAZ:
1190 case CHIP_TONGA: 1219 case CHIP_TONGA:
@@ -1521,6 +1550,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
1521 spin_lock_init(&adev->gc_cac_idx_lock); 1550 spin_lock_init(&adev->gc_cac_idx_lock);
1522 spin_lock_init(&adev->audio_endpt_idx_lock); 1551 spin_lock_init(&adev->audio_endpt_idx_lock);
1523 1552
1553 INIT_LIST_HEAD(&adev->shadow_list);
1554 mutex_init(&adev->shadow_list_lock);
1555
1524 adev->rmmio_base = pci_resource_start(adev->pdev, 5); 1556 adev->rmmio_base = pci_resource_start(adev->pdev, 5);
1525 adev->rmmio_size = pci_resource_len(adev->pdev, 5); 1557 adev->rmmio_size = pci_resource_len(adev->pdev, 5);
1526 adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size); 1558 adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size);
@@ -1937,6 +1969,126 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
1937 return 0; 1969 return 0;
1938} 1970}
1939 1971
1972static bool amdgpu_check_soft_reset(struct amdgpu_device *adev)
1973{
1974 int i;
1975 bool asic_hang = false;
1976
1977 for (i = 0; i < adev->num_ip_blocks; i++) {
1978 if (!adev->ip_block_status[i].valid)
1979 continue;
1980 if (adev->ip_blocks[i].funcs->check_soft_reset)
1981 adev->ip_blocks[i].funcs->check_soft_reset(adev);
1982 if (adev->ip_block_status[i].hang) {
1983 DRM_INFO("IP block:%d is hang!\n", i);
1984 asic_hang = true;
1985 }
1986 }
1987 return asic_hang;
1988}
1989
1990int amdgpu_pre_soft_reset(struct amdgpu_device *adev)
1991{
1992 int i, r = 0;
1993
1994 for (i = 0; i < adev->num_ip_blocks; i++) {
1995 if (!adev->ip_block_status[i].valid)
1996 continue;
1997 if (adev->ip_block_status[i].hang &&
1998 adev->ip_blocks[i].funcs->pre_soft_reset) {
1999 r = adev->ip_blocks[i].funcs->pre_soft_reset(adev);
2000 if (r)
2001 return r;
2002 }
2003 }
2004
2005 return 0;
2006}
2007
2008static bool amdgpu_need_full_reset(struct amdgpu_device *adev)
2009{
2010 if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang ||
2011 adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang ||
2012 adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang ||
2013 adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) {
2014 DRM_INFO("Some block need full reset!\n");
2015 return true;
2016 }
2017 return false;
2018}
2019
2020static int amdgpu_soft_reset(struct amdgpu_device *adev)
2021{
2022 int i, r = 0;
2023
2024 for (i = 0; i < adev->num_ip_blocks; i++) {
2025 if (!adev->ip_block_status[i].valid)
2026 continue;
2027 if (adev->ip_block_status[i].hang &&
2028 adev->ip_blocks[i].funcs->soft_reset) {
2029 r = adev->ip_blocks[i].funcs->soft_reset(adev);
2030 if (r)
2031 return r;
2032 }
2033 }
2034
2035 return 0;
2036}
2037
2038static int amdgpu_post_soft_reset(struct amdgpu_device *adev)
2039{
2040 int i, r = 0;
2041
2042 for (i = 0; i < adev->num_ip_blocks; i++) {
2043 if (!adev->ip_block_status[i].valid)
2044 continue;
2045 if (adev->ip_block_status[i].hang &&
2046 adev->ip_blocks[i].funcs->post_soft_reset)
2047 r = adev->ip_blocks[i].funcs->post_soft_reset(adev);
2048 if (r)
2049 return r;
2050 }
2051
2052 return 0;
2053}
2054
2055bool amdgpu_need_backup(struct amdgpu_device *adev)
2056{
2057 if (adev->flags & AMD_IS_APU)
2058 return false;
2059
2060 return amdgpu_lockup_timeout > 0 ? true : false;
2061}
2062
2063static int amdgpu_recover_vram_from_shadow(struct amdgpu_device *adev,
2064 struct amdgpu_ring *ring,
2065 struct amdgpu_bo *bo,
2066 struct fence **fence)
2067{
2068 uint32_t domain;
2069 int r;
2070
2071 if (!bo->shadow)
2072 return 0;
2073
2074 r = amdgpu_bo_reserve(bo, false);
2075 if (r)
2076 return r;
2077 domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
2078 /* if bo has been evicted, then no need to recover */
2079 if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
2080 r = amdgpu_bo_restore_from_shadow(adev, ring, bo,
2081 NULL, fence, true);
2082 if (r) {
2083 DRM_ERROR("recover page table failed!\n");
2084 goto err;
2085 }
2086 }
2087err:
2088 amdgpu_bo_unreserve(bo);
2089 return r;
2090}
2091
1940/** 2092/**
1941 * amdgpu_gpu_reset - reset the asic 2093 * amdgpu_gpu_reset - reset the asic
1942 * 2094 *
@@ -1949,6 +2101,12 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
1949{ 2101{
1950 int i, r; 2102 int i, r;
1951 int resched; 2103 int resched;
2104 bool need_full_reset;
2105
2106 if (!amdgpu_check_soft_reset(adev)) {
2107 DRM_INFO("No hardware hang detected. Did some blocks stall?\n");
2108 return 0;
2109 }
1952 2110
1953 atomic_inc(&adev->gpu_reset_counter); 2111 atomic_inc(&adev->gpu_reset_counter);
1954 2112
@@ -1967,40 +2125,88 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
1967 /* after all hw jobs are reset, hw fence is meaningless, so force_completion */ 2125 /* after all hw jobs are reset, hw fence is meaningless, so force_completion */
1968 amdgpu_fence_driver_force_completion(adev); 2126 amdgpu_fence_driver_force_completion(adev);
1969 2127
1970 /* save scratch */ 2128 need_full_reset = amdgpu_need_full_reset(adev);
1971 amdgpu_atombios_scratch_regs_save(adev);
1972 r = amdgpu_suspend(adev);
1973 2129
1974retry: 2130 if (!need_full_reset) {
1975 /* Disable fb access */ 2131 amdgpu_pre_soft_reset(adev);
1976 if (adev->mode_info.num_crtc) { 2132 r = amdgpu_soft_reset(adev);
1977 struct amdgpu_mode_mc_save save; 2133 amdgpu_post_soft_reset(adev);
1978 amdgpu_display_stop_mc_access(adev, &save); 2134 if (r || amdgpu_check_soft_reset(adev)) {
1979 amdgpu_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GMC); 2135 DRM_INFO("soft reset failed, will fallback to full reset!\n");
2136 need_full_reset = true;
2137 }
1980 } 2138 }
1981 2139
1982 r = amdgpu_asic_reset(adev); 2140 if (need_full_reset) {
1983 /* post card */ 2141 /* save scratch */
1984 amdgpu_atom_asic_init(adev->mode_info.atom_context); 2142 amdgpu_atombios_scratch_regs_save(adev);
2143 r = amdgpu_suspend(adev);
1985 2144
1986 if (!r) { 2145retry:
1987 dev_info(adev->dev, "GPU reset succeeded, trying to resume\n"); 2146 /* Disable fb access */
1988 r = amdgpu_resume(adev); 2147 if (adev->mode_info.num_crtc) {
2148 struct amdgpu_mode_mc_save save;
2149 amdgpu_display_stop_mc_access(adev, &save);
2150 amdgpu_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GMC);
2151 }
2152
2153 r = amdgpu_asic_reset(adev);
2154 /* post card */
2155 amdgpu_atom_asic_init(adev->mode_info.atom_context);
2156
2157 if (!r) {
2158 dev_info(adev->dev, "GPU reset succeeded, trying to resume\n");
2159 r = amdgpu_resume(adev);
2160 }
2161 /* restore scratch */
2162 amdgpu_atombios_scratch_regs_restore(adev);
1989 } 2163 }
1990 /* restore scratch */
1991 amdgpu_atombios_scratch_regs_restore(adev);
1992 if (!r) { 2164 if (!r) {
2165 amdgpu_irq_gpu_reset_resume_helper(adev);
1993 r = amdgpu_ib_ring_tests(adev); 2166 r = amdgpu_ib_ring_tests(adev);
1994 if (r) { 2167 if (r) {
1995 dev_err(adev->dev, "ib ring test failed (%d).\n", r); 2168 dev_err(adev->dev, "ib ring test failed (%d).\n", r);
1996 r = amdgpu_suspend(adev); 2169 r = amdgpu_suspend(adev);
2170 need_full_reset = true;
1997 goto retry; 2171 goto retry;
1998 } 2172 }
2173 /**
2174 * recovery vm page tables, since we cannot depend on VRAM is
2175 * consistent after gpu full reset.
2176 */
2177 if (need_full_reset && amdgpu_need_backup(adev)) {
2178 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
2179 struct amdgpu_bo *bo, *tmp;
2180 struct fence *fence = NULL, *next = NULL;
2181
2182 DRM_INFO("recover vram bo from shadow\n");
2183 mutex_lock(&adev->shadow_list_lock);
2184 list_for_each_entry_safe(bo, tmp, &adev->shadow_list, shadow_list) {
2185 amdgpu_recover_vram_from_shadow(adev, ring, bo, &next);
2186 if (fence) {
2187 r = fence_wait(fence, false);
2188 if (r) {
2189 WARN(r, "recovery from shadow isn't comleted\n");
2190 break;
2191 }
2192 }
1999 2193
2194 fence_put(fence);
2195 fence = next;
2196 }
2197 mutex_unlock(&adev->shadow_list_lock);
2198 if (fence) {
2199 r = fence_wait(fence, false);
2200 if (r)
2201 WARN(r, "recovery from shadow isn't comleted\n");
2202 }
2203 fence_put(fence);
2204 }
2000 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { 2205 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
2001 struct amdgpu_ring *ring = adev->rings[i]; 2206 struct amdgpu_ring *ring = adev->rings[i];
2002 if (!ring) 2207 if (!ring)
2003 continue; 2208 continue;
2209
2004 amd_sched_job_recovery(&ring->sched); 2210 amd_sched_job_recovery(&ring->sched);
2005 kthread_unpark(ring->sched.thread); 2211 kthread_unpark(ring->sched.thread);
2006 } 2212 }
@@ -2020,7 +2226,6 @@ retry:
2020 /* bad news, how to tell it to userspace ? */ 2226 /* bad news, how to tell it to userspace ? */
2021 dev_info(adev->dev, "GPU reset failed\n"); 2227 dev_info(adev->dev, "GPU reset failed\n");
2022 } 2228 }
2023 amdgpu_irq_gpu_reset_resume_helper(adev);
2024 2229
2025 return r; 2230 return r;
2026} 2231}
@@ -2178,22 +2383,26 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
2178 struct amdgpu_device *adev = f->f_inode->i_private; 2383 struct amdgpu_device *adev = f->f_inode->i_private;
2179 ssize_t result = 0; 2384 ssize_t result = 0;
2180 int r; 2385 int r;
2181 bool use_bank; 2386 bool pm_pg_lock, use_bank;
2182 unsigned instance_bank, sh_bank, se_bank; 2387 unsigned instance_bank, sh_bank, se_bank;
2183 2388
2184 if (size & 0x3 || *pos & 0x3) 2389 if (size & 0x3 || *pos & 0x3)
2185 return -EINVAL; 2390 return -EINVAL;
2186 2391
2392 /* are we reading registers for which a PG lock is necessary? */
2393 pm_pg_lock = (*pos >> 23) & 1;
2394
2187 if (*pos & (1ULL << 62)) { 2395 if (*pos & (1ULL << 62)) {
2188 se_bank = (*pos >> 24) & 0x3FF; 2396 se_bank = (*pos >> 24) & 0x3FF;
2189 sh_bank = (*pos >> 34) & 0x3FF; 2397 sh_bank = (*pos >> 34) & 0x3FF;
2190 instance_bank = (*pos >> 44) & 0x3FF; 2398 instance_bank = (*pos >> 44) & 0x3FF;
2191 use_bank = 1; 2399 use_bank = 1;
2192 *pos &= 0xFFFFFF;
2193 } else { 2400 } else {
2194 use_bank = 0; 2401 use_bank = 0;
2195 } 2402 }
2196 2403
2404 *pos &= 0x3FFFF;
2405
2197 if (use_bank) { 2406 if (use_bank) {
2198 if (sh_bank >= adev->gfx.config.max_sh_per_se || 2407 if (sh_bank >= adev->gfx.config.max_sh_per_se ||
2199 se_bank >= adev->gfx.config.max_shader_engines) 2408 se_bank >= adev->gfx.config.max_shader_engines)
@@ -2203,6 +2412,9 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
2203 sh_bank, instance_bank); 2412 sh_bank, instance_bank);
2204 } 2413 }
2205 2414
2415 if (pm_pg_lock)
2416 mutex_lock(&adev->pm.mutex);
2417
2206 while (size) { 2418 while (size) {
2207 uint32_t value; 2419 uint32_t value;
2208 2420
@@ -2228,6 +2440,9 @@ end:
2228 mutex_unlock(&adev->grbm_idx_mutex); 2440 mutex_unlock(&adev->grbm_idx_mutex);
2229 } 2441 }
2230 2442
2443 if (pm_pg_lock)
2444 mutex_unlock(&adev->pm.mutex);
2445
2231 return result; 2446 return result;
2232} 2447}
2233 2448
@@ -2443,7 +2658,7 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
2443 return -ENOMEM; 2658 return -ENOMEM;
2444 2659
2445 /* version, increment each time something is added */ 2660 /* version, increment each time something is added */
2446 config[no_regs++] = 0; 2661 config[no_regs++] = 2;
2447 config[no_regs++] = adev->gfx.config.max_shader_engines; 2662 config[no_regs++] = adev->gfx.config.max_shader_engines;
2448 config[no_regs++] = adev->gfx.config.max_tile_pipes; 2663 config[no_regs++] = adev->gfx.config.max_tile_pipes;
2449 config[no_regs++] = adev->gfx.config.max_cu_per_sh; 2664 config[no_regs++] = adev->gfx.config.max_cu_per_sh;
@@ -2468,6 +2683,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; 2683 config[no_regs++] = adev->gfx.config.gb_addr_config;
2469 config[no_regs++] = adev->gfx.config.num_rbs; 2684 config[no_regs++] = adev->gfx.config.num_rbs;
2470 2685
2686 /* rev==1 */
2687 config[no_regs++] = adev->rev_id;
2688 config[no_regs++] = adev->pg_flags;
2689 config[no_regs++] = adev->cg_flags;
2690
2691 /* rev==2 */
2692 config[no_regs++] = adev->family;
2693 config[no_regs++] = adev->external_rev_id;
2694
2471 while (size && (*pos < no_regs * 4)) { 2695 while (size && (*pos < no_regs * 4)) {
2472 uint32_t value; 2696 uint32_t value;
2473 2697
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 76f96028313d..9af8d3c7ae8b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -41,7 +41,7 @@ static void amdgpu_flip_callback(struct fence *f, struct fence_cb *cb)
41 container_of(cb, struct amdgpu_flip_work, cb); 41 container_of(cb, struct amdgpu_flip_work, cb);
42 42
43 fence_put(f); 43 fence_put(f);
44 schedule_work(&work->flip_work); 44 schedule_work(&work->flip_work.work);
45} 45}
46 46
47static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work, 47static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
@@ -63,16 +63,17 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
63 63
64static void amdgpu_flip_work_func(struct work_struct *__work) 64static void amdgpu_flip_work_func(struct work_struct *__work)
65{ 65{
66 struct delayed_work *delayed_work =
67 container_of(__work, struct delayed_work, work);
66 struct amdgpu_flip_work *work = 68 struct amdgpu_flip_work *work =
67 container_of(__work, struct amdgpu_flip_work, flip_work); 69 container_of(delayed_work, struct amdgpu_flip_work, flip_work);
68 struct amdgpu_device *adev = work->adev; 70 struct amdgpu_device *adev = work->adev;
69 struct amdgpu_crtc *amdgpuCrtc = adev->mode_info.crtcs[work->crtc_id]; 71 struct amdgpu_crtc *amdgpuCrtc = adev->mode_info.crtcs[work->crtc_id];
70 72
71 struct drm_crtc *crtc = &amdgpuCrtc->base; 73 struct drm_crtc *crtc = &amdgpuCrtc->base;
72 unsigned long flags; 74 unsigned long flags;
73 unsigned i, repcnt = 4; 75 unsigned i;
74 int vpos, hpos, stat, min_udelay = 0; 76 int vpos, hpos;
75 struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
76 77
77 if (amdgpu_flip_handle_fence(work, &work->excl)) 78 if (amdgpu_flip_handle_fence(work, &work->excl))
78 return; 79 return;
@@ -81,55 +82,23 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
81 if (amdgpu_flip_handle_fence(work, &work->shared[i])) 82 if (amdgpu_flip_handle_fence(work, &work->shared[i]))
82 return; 83 return;
83 84
84 /* We borrow the event spin lock for protecting flip_status */ 85 /* Wait until we're out of the vertical blank period before the one
85 spin_lock_irqsave(&crtc->dev->event_lock, flags); 86 * targeted by the flip
86
87 /* If this happens to execute within the "virtually extended" vblank
88 * interval before the start of the real vblank interval then it needs
89 * to delay programming the mmio flip until the real vblank is entered.
90 * This prevents completing a flip too early due to the way we fudge
91 * our vblank counter and vblank timestamps in order to work around the
92 * problem that the hw fires vblank interrupts before actual start of
93 * vblank (when line buffer refilling is done for a frame). It
94 * complements the fudging logic in amdgpu_get_crtc_scanoutpos() for
95 * timestamping and amdgpu_get_vblank_counter_kms() for vblank counts.
96 *
97 * In practice this won't execute very often unless on very fast
98 * machines because the time window for this to happen is very small.
99 */ 87 */
100 while (amdgpuCrtc->enabled && --repcnt) { 88 if (amdgpuCrtc->enabled &&
101 /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank 89 (amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id, 0,
102 * start in hpos, and to the "fudged earlier" vblank start in 90 &vpos, &hpos, NULL, NULL,
103 * vpos. 91 &crtc->hwmode)
104 */ 92 & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) ==
105 stat = amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id, 93 (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) &&
106 GET_DISTANCE_TO_VBLANKSTART, 94 (int)(work->target_vblank -
107 &vpos, &hpos, NULL, NULL, 95 amdgpu_get_vblank_counter_kms(adev->ddev, amdgpuCrtc->crtc_id)) > 0) {
108 &crtc->hwmode); 96 schedule_delayed_work(&work->flip_work, usecs_to_jiffies(1000));
109 97 return;
110 if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
111 (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) ||
112 !(vpos >= 0 && hpos <= 0))
113 break;
114
115 /* Sleep at least until estimated real start of hw vblank */
116 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
117 if (min_udelay > vblank->framedur_ns / 2000) {
118 /* Don't wait ridiculously long - something is wrong */
119 repcnt = 0;
120 break;
121 }
122 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
123 usleep_range(min_udelay, 2 * min_udelay);
124 spin_lock_irqsave(&crtc->dev->event_lock, flags);
125 } 98 }
126 99
127 if (!repcnt) 100 /* We borrow the event spin lock for protecting flip_status */
128 DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, " 101 spin_lock_irqsave(&crtc->dev->event_lock, flags);
129 "framedur %d, linedur %d, stat %d, vpos %d, "
130 "hpos %d\n", work->crtc_id, min_udelay,
131 vblank->framedur_ns / 1000,
132 vblank->linedur_ns / 1000, stat, vpos, hpos);
133 102
134 /* Do the flip (mmio) */ 103 /* Do the flip (mmio) */
135 adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base, work->async); 104 adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base, work->async);
@@ -169,10 +138,10 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)
169 kfree(work); 138 kfree(work);
170} 139}
171 140
172int amdgpu_crtc_page_flip(struct drm_crtc *crtc, 141int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
173 struct drm_framebuffer *fb, 142 struct drm_framebuffer *fb,
174 struct drm_pending_vblank_event *event, 143 struct drm_pending_vblank_event *event,
175 uint32_t page_flip_flags) 144 uint32_t page_flip_flags, uint32_t target)
176{ 145{
177 struct drm_device *dev = crtc->dev; 146 struct drm_device *dev = crtc->dev;
178 struct amdgpu_device *adev = dev->dev_private; 147 struct amdgpu_device *adev = dev->dev_private;
@@ -191,7 +160,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
191 if (work == NULL) 160 if (work == NULL)
192 return -ENOMEM; 161 return -ENOMEM;
193 162
194 INIT_WORK(&work->flip_work, amdgpu_flip_work_func); 163 INIT_DELAYED_WORK(&work->flip_work, amdgpu_flip_work_func);
195 INIT_WORK(&work->unpin_work, amdgpu_unpin_work_func); 164 INIT_WORK(&work->unpin_work, amdgpu_unpin_work_func);
196 165
197 work->event = event; 166 work->event = event;
@@ -237,12 +206,8 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
237 amdgpu_bo_unreserve(new_rbo); 206 amdgpu_bo_unreserve(new_rbo);
238 207
239 work->base = base; 208 work->base = base;
240 209 work->target_vblank = target - drm_crtc_vblank_count(crtc) +
241 r = drm_crtc_vblank_get(crtc); 210 amdgpu_get_vblank_counter_kms(dev, work->crtc_id);
242 if (r) {
243 DRM_ERROR("failed to get vblank before flip\n");
244 goto pflip_cleanup;
245 }
246 211
247 /* we borrow the event spin lock for protecting flip_wrok */ 212 /* we borrow the event spin lock for protecting flip_wrok */
248 spin_lock_irqsave(&crtc->dev->event_lock, flags); 213 spin_lock_irqsave(&crtc->dev->event_lock, flags);
@@ -250,7 +215,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
250 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); 215 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
251 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 216 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
252 r = -EBUSY; 217 r = -EBUSY;
253 goto vblank_cleanup; 218 goto pflip_cleanup;
254 } 219 }
255 220
256 amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING; 221 amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING;
@@ -262,12 +227,9 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
262 /* update crtc fb */ 227 /* update crtc fb */
263 crtc->primary->fb = fb; 228 crtc->primary->fb = fb;
264 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 229 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
265 amdgpu_flip_work_func(&work->flip_work); 230 amdgpu_flip_work_func(&work->flip_work.work);
266 return 0; 231 return 0;
267 232
268vblank_cleanup:
269 drm_crtc_vblank_put(crtc);
270
271pflip_cleanup: 233pflip_cleanup:
272 if (unlikely(amdgpu_bo_reserve(new_rbo, false) != 0)) { 234 if (unlikely(amdgpu_bo_reserve(new_rbo, false) != 0)) {
273 DRM_ERROR("failed to reserve new rbo in error path\n"); 235 DRM_ERROR("failed to reserve new rbo in error path\n");
@@ -335,7 +297,7 @@ int amdgpu_crtc_set_config(struct drm_mode_set *set)
335 return ret; 297 return ret;
336} 298}
337 299
338static const char *encoder_names[38] = { 300static const char *encoder_names[41] = {
339 "NONE", 301 "NONE",
340 "INTERNAL_LVDS", 302 "INTERNAL_LVDS",
341 "INTERNAL_TMDS1", 303 "INTERNAL_TMDS1",
@@ -374,6 +336,9 @@ static const char *encoder_names[38] = {
374 "TRAVIS", 336 "TRAVIS",
375 "INTERNAL_VCE", 337 "INTERNAL_VCE",
376 "INTERNAL_UNIPHY3", 338 "INTERNAL_UNIPHY3",
339 "HDMI_ANX9805",
340 "INTERNAL_AMCLK",
341 "VIRTUAL",
377}; 342};
378 343
379static const char *hpd_names[6] = { 344static const char *hpd_names[6] = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 11263c5b9967..7c911d0be2b3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -53,9 +53,11 @@
53 * - 3.2.0 - GFX8: Uses EOP_TC_WB_ACTION_EN, so UMDs don't have to do the same 53 * - 3.2.0 - GFX8: Uses EOP_TC_WB_ACTION_EN, so UMDs don't have to do the same
54 * at the end of IBs. 54 * at the end of IBs.
55 * - 3.3.0 - Add VM support for UVD on supported hardware. 55 * - 3.3.0 - Add VM support for UVD on supported hardware.
56 * - 3.4.0 - Add AMDGPU_INFO_NUM_EVICTIONS.
57 * - 3.5.0 - Add support for new UVD_NO_OP register.
56 */ 58 */
57#define KMS_DRIVER_MAJOR 3 59#define KMS_DRIVER_MAJOR 3
58#define KMS_DRIVER_MINOR 3 60#define KMS_DRIVER_MINOR 5
59#define KMS_DRIVER_PATCHLEVEL 0 61#define KMS_DRIVER_PATCHLEVEL 0
60 62
61int amdgpu_vram_limit = 0; 63int amdgpu_vram_limit = 0;
@@ -84,11 +86,13 @@ int amdgpu_sched_jobs = 32;
84int amdgpu_sched_hw_submission = 2; 86int amdgpu_sched_hw_submission = 2;
85int amdgpu_powerplay = -1; 87int amdgpu_powerplay = -1;
86int amdgpu_powercontainment = 1; 88int amdgpu_powercontainment = 1;
89int amdgpu_sclk_deep_sleep_en = 1;
87unsigned amdgpu_pcie_gen_cap = 0; 90unsigned amdgpu_pcie_gen_cap = 0;
88unsigned amdgpu_pcie_lane_cap = 0; 91unsigned amdgpu_pcie_lane_cap = 0;
89unsigned amdgpu_cg_mask = 0xffffffff; 92unsigned amdgpu_cg_mask = 0xffffffff;
90unsigned amdgpu_pg_mask = 0xffffffff; 93unsigned amdgpu_pg_mask = 0xffffffff;
91char *amdgpu_disable_cu = NULL; 94char *amdgpu_disable_cu = NULL;
95char *amdgpu_virtual_display = NULL;
92 96
93MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); 97MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
94module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); 98module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
@@ -170,6 +174,9 @@ MODULE_PARM_DESC(powercontainment, "Power Containment (1 = enable (default), 0 =
170module_param_named(powercontainment, amdgpu_powercontainment, int, 0444); 174module_param_named(powercontainment, amdgpu_powercontainment, int, 0444);
171#endif 175#endif
172 176
177MODULE_PARM_DESC(sclkdeepsleep, "SCLK Deep Sleep (1 = enable (default), 0 = disable)");
178module_param_named(sclkdeepsleep, amdgpu_sclk_deep_sleep_en, int, 0444);
179
173MODULE_PARM_DESC(pcie_gen_cap, "PCIE Gen Caps (0: autodetect (default))"); 180MODULE_PARM_DESC(pcie_gen_cap, "PCIE Gen Caps (0: autodetect (default))");
174module_param_named(pcie_gen_cap, amdgpu_pcie_gen_cap, uint, 0444); 181module_param_named(pcie_gen_cap, amdgpu_pcie_gen_cap, uint, 0444);
175 182
@@ -185,6 +192,9 @@ module_param_named(pg_mask, amdgpu_pg_mask, uint, 0444);
185MODULE_PARM_DESC(disable_cu, "Disable CUs (se.sh.cu,...)"); 192MODULE_PARM_DESC(disable_cu, "Disable CUs (se.sh.cu,...)");
186module_param_named(disable_cu, amdgpu_disable_cu, charp, 0444); 193module_param_named(disable_cu, amdgpu_disable_cu, charp, 0444);
187 194
195MODULE_PARM_DESC(virtual_display, "Enable virtual display feature (the virtual_display will be set like xxxx:xx:xx.x;xxxx:xx:xx.x)");
196module_param_named(virtual_display, amdgpu_virtual_display, charp, 0444);
197
188static const struct pci_device_id pciidlist[] = { 198static const struct pci_device_id pciidlist[] = {
189#ifdef CONFIG_DRM_AMDGPU_CIK 199#ifdef CONFIG_DRM_AMDGPU_CIK
190 /* Kaveri */ 200 /* Kaveri */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h
index 503d54098128..e73728d90388 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h
@@ -31,14 +31,6 @@
31#define AMDGPU_GWS_SHIFT PAGE_SHIFT 31#define AMDGPU_GWS_SHIFT PAGE_SHIFT
32#define AMDGPU_OA_SHIFT PAGE_SHIFT 32#define AMDGPU_OA_SHIFT PAGE_SHIFT
33 33
34#define AMDGPU_PL_GDS TTM_PL_PRIV0
35#define AMDGPU_PL_GWS TTM_PL_PRIV1
36#define AMDGPU_PL_OA TTM_PL_PRIV2
37
38#define AMDGPU_PL_FLAG_GDS TTM_PL_FLAG_PRIV0
39#define AMDGPU_PL_FLAG_GWS TTM_PL_FLAG_PRIV1
40#define AMDGPU_PL_FLAG_OA TTM_PL_FLAG_PRIV2
41
42struct amdgpu_ring; 34struct amdgpu_ring;
43struct amdgpu_bo; 35struct amdgpu_bo;
44 36
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c
index 31a676376d73..c93a92a840ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c
@@ -186,10 +186,8 @@ struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev,
186 "AMDGPU i2c hw bus %s", name); 186 "AMDGPU i2c hw bus %s", name);
187 i2c->adapter.algo = &amdgpu_atombios_i2c_algo; 187 i2c->adapter.algo = &amdgpu_atombios_i2c_algo;
188 ret = i2c_add_adapter(&i2c->adapter); 188 ret = i2c_add_adapter(&i2c->adapter);
189 if (ret) { 189 if (ret)
190 DRM_ERROR("Failed to register hw i2c %s\n", name);
191 goto out_free; 190 goto out_free;
192 }
193 } else { 191 } else {
194 /* set the amdgpu bit adapter */ 192 /* set the amdgpu bit adapter */
195 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), 193 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index a31d7ef3032c..f5810f700668 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -142,7 +142,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
142 } 142 }
143 143
144 if (!ring->ready) { 144 if (!ring->ready) {
145 dev_err(adev->dev, "couldn't schedule ib\n"); 145 dev_err(adev->dev, "couldn't schedule ib on ring <%s>\n", ring->name);
146 return -EINVAL; 146 return -EINVAL;
147 } 147 }
148 148
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
index 534fc04e80fd..5ebb3f43feb6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
@@ -40,32 +40,15 @@ static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev)
40 40
41 /* Allocate ring buffer */ 41 /* Allocate ring buffer */
42 if (adev->irq.ih.ring_obj == NULL) { 42 if (adev->irq.ih.ring_obj == NULL) {
43 r = amdgpu_bo_create(adev, adev->irq.ih.ring_size, 43 r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size,
44 PAGE_SIZE, true, 44 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
45 AMDGPU_GEM_DOMAIN_GTT, 0, 45 &adev->irq.ih.ring_obj,
46 NULL, NULL, &adev->irq.ih.ring_obj); 46 &adev->irq.ih.gpu_addr,
47 (void **)&adev->irq.ih.ring);
47 if (r) { 48 if (r) {
48 DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r); 49 DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r);
49 return r; 50 return r;
50 } 51 }
51 r = amdgpu_bo_reserve(adev->irq.ih.ring_obj, false);
52 if (unlikely(r != 0))
53 return r;
54 r = amdgpu_bo_pin(adev->irq.ih.ring_obj,
55 AMDGPU_GEM_DOMAIN_GTT,
56 &adev->irq.ih.gpu_addr);
57 if (r) {
58 amdgpu_bo_unreserve(adev->irq.ih.ring_obj);
59 DRM_ERROR("amdgpu: failed to pin ih ring buffer (%d).\n", r);
60 return r;
61 }
62 r = amdgpu_bo_kmap(adev->irq.ih.ring_obj,
63 (void **)&adev->irq.ih.ring);
64 amdgpu_bo_unreserve(adev->irq.ih.ring_obj);
65 if (r) {
66 DRM_ERROR("amdgpu: failed to map ih ring buffer (%d).\n", r);
67 return r;
68 }
69 } 52 }
70 return 0; 53 return 0;
71} 54}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
index 7ef09352e534..f016464035b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
@@ -70,6 +70,7 @@ struct amdgpu_irq {
70 /* gen irq stuff */ 70 /* gen irq stuff */
71 struct irq_domain *domain; /* GPU irq controller domain */ 71 struct irq_domain *domain; /* GPU irq controller domain */
72 unsigned virq[AMDGPU_MAX_IRQ_SRC_ID]; 72 unsigned virq[AMDGPU_MAX_IRQ_SRC_ID];
73 uint32_t srbm_soft_reset;
73}; 74};
74 75
75void amdgpu_irq_preinstall(struct drm_device *dev); 76void amdgpu_irq_preinstall(struct drm_device *dev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index d942654a1de0..b78e74048f3d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -292,14 +292,14 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
292 type = AMD_IP_BLOCK_TYPE_UVD; 292 type = AMD_IP_BLOCK_TYPE_UVD;
293 ring_mask = adev->uvd.ring.ready ? 1 : 0; 293 ring_mask = adev->uvd.ring.ready ? 1 : 0;
294 ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 294 ib_start_alignment = AMDGPU_GPU_PAGE_SIZE;
295 ib_size_alignment = 8; 295 ib_size_alignment = 16;
296 break; 296 break;
297 case AMDGPU_HW_IP_VCE: 297 case AMDGPU_HW_IP_VCE:
298 type = AMD_IP_BLOCK_TYPE_VCE; 298 type = AMD_IP_BLOCK_TYPE_VCE;
299 for (i = 0; i < AMDGPU_MAX_VCE_RINGS; i++) 299 for (i = 0; i < AMDGPU_MAX_VCE_RINGS; i++)
300 ring_mask |= ((adev->vce.ring[i].ready ? 1 : 0) << i); 300 ring_mask |= ((adev->vce.ring[i].ready ? 1 : 0) << i);
301 ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 301 ib_start_alignment = AMDGPU_GPU_PAGE_SIZE;
302 ib_size_alignment = 8; 302 ib_size_alignment = 1;
303 break; 303 break;
304 default: 304 default:
305 return -EINVAL; 305 return -EINVAL;
@@ -373,6 +373,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
373 case AMDGPU_INFO_NUM_BYTES_MOVED: 373 case AMDGPU_INFO_NUM_BYTES_MOVED:
374 ui64 = atomic64_read(&adev->num_bytes_moved); 374 ui64 = atomic64_read(&adev->num_bytes_moved);
375 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 375 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
376 case AMDGPU_INFO_NUM_EVICTIONS:
377 ui64 = atomic64_read(&adev->num_evictions);
378 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
376 case AMDGPU_INFO_VRAM_USAGE: 379 case AMDGPU_INFO_VRAM_USAGE:
377 ui64 = atomic64_read(&adev->vram_usage); 380 ui64 = atomic64_read(&adev->vram_usage);
378 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 381 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 6b1d7d306564..7b0eff7d060b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -39,6 +39,8 @@
39#include <drm/drm_plane_helper.h> 39#include <drm/drm_plane_helper.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/i2c-algo-bit.h> 41#include <linux/i2c-algo-bit.h>
42#include <linux/hrtimer.h>
43#include "amdgpu_irq.h"
42 44
43struct amdgpu_bo; 45struct amdgpu_bo;
44struct amdgpu_device; 46struct amdgpu_device;
@@ -339,6 +341,8 @@ struct amdgpu_mode_info {
339 int num_dig; /* number of dig blocks */ 341 int num_dig; /* number of dig blocks */
340 int disp_priority; 342 int disp_priority;
341 const struct amdgpu_display_funcs *funcs; 343 const struct amdgpu_display_funcs *funcs;
344 struct hrtimer vblank_timer;
345 enum amdgpu_interrupt_state vsync_timer_enabled;
342}; 346};
343 347
344#define AMDGPU_MAX_BL_LEVEL 0xFF 348#define AMDGPU_MAX_BL_LEVEL 0xFF
@@ -587,10 +591,10 @@ int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tile
587void amdgpu_print_display_setup(struct drm_device *dev); 591void amdgpu_print_display_setup(struct drm_device *dev);
588int amdgpu_modeset_create_props(struct amdgpu_device *adev); 592int amdgpu_modeset_create_props(struct amdgpu_device *adev);
589int amdgpu_crtc_set_config(struct drm_mode_set *set); 593int amdgpu_crtc_set_config(struct drm_mode_set *set);
590int amdgpu_crtc_page_flip(struct drm_crtc *crtc, 594int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
591 struct drm_framebuffer *fb, 595 struct drm_framebuffer *fb,
592 struct drm_pending_vblank_event *event, 596 struct drm_pending_vblank_event *event,
593 uint32_t page_flip_flags); 597 uint32_t page_flip_flags, uint32_t target);
594extern const struct drm_mode_config_funcs amdgpu_mode_funcs; 598extern const struct drm_mode_config_funcs amdgpu_mode_funcs;
595 599
596#endif 600#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 6f0873c75a25..b17734e0ecc8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -44,14 +44,13 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev);
44static u64 amdgpu_get_vis_part_size(struct amdgpu_device *adev, 44static u64 amdgpu_get_vis_part_size(struct amdgpu_device *adev,
45 struct ttm_mem_reg *mem) 45 struct ttm_mem_reg *mem)
46{ 46{
47 u64 ret = 0; 47 if (mem->start << PAGE_SHIFT >= adev->mc.visible_vram_size)
48 if (mem->start << PAGE_SHIFT < adev->mc.visible_vram_size) { 48 return 0;
49 ret = (u64)((mem->start << PAGE_SHIFT) + mem->size) > 49
50 adev->mc.visible_vram_size ? 50 return ((mem->start << PAGE_SHIFT) + mem->size) >
51 adev->mc.visible_vram_size - (mem->start << PAGE_SHIFT) : 51 adev->mc.visible_vram_size ?
52 mem->size; 52 adev->mc.visible_vram_size - (mem->start << PAGE_SHIFT) :
53 } 53 mem->size;
54 return ret;
55} 54}
56 55
57static void amdgpu_update_memory_usage(struct amdgpu_device *adev, 56static void amdgpu_update_memory_usage(struct amdgpu_device *adev,
@@ -99,6 +98,11 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
99 98
100 drm_gem_object_release(&bo->gem_base); 99 drm_gem_object_release(&bo->gem_base);
101 amdgpu_bo_unref(&bo->parent); 100 amdgpu_bo_unref(&bo->parent);
101 if (!list_empty(&bo->shadow_list)) {
102 mutex_lock(&bo->adev->shadow_list_lock);
103 list_del_init(&bo->shadow_list);
104 mutex_unlock(&bo->adev->shadow_list_lock);
105 }
102 kfree(bo->metadata); 106 kfree(bo->metadata);
103 kfree(bo); 107 kfree(bo);
104} 108}
@@ -112,84 +116,93 @@ bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo)
112 116
113static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, 117static void amdgpu_ttm_placement_init(struct amdgpu_device *adev,
114 struct ttm_placement *placement, 118 struct ttm_placement *placement,
115 struct ttm_place *placements, 119 struct ttm_place *places,
116 u32 domain, u64 flags) 120 u32 domain, u64 flags)
117{ 121{
118 u32 c = 0, i; 122 u32 c = 0;
119
120 placement->placement = placements;
121 placement->busy_placement = placements;
122 123
123 if (domain & AMDGPU_GEM_DOMAIN_VRAM) { 124 if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
125 unsigned visible_pfn = adev->mc.visible_vram_size >> PAGE_SHIFT;
126
124 if (flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS && 127 if (flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS &&
125 adev->mc.visible_vram_size < adev->mc.real_vram_size) { 128 !(flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) &&
126 placements[c].fpfn = 129 adev->mc.visible_vram_size < adev->mc.real_vram_size) {
127 adev->mc.visible_vram_size >> PAGE_SHIFT; 130 places[c].fpfn = visible_pfn;
128 placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | 131 places[c].lpfn = 0;
129 TTM_PL_FLAG_VRAM | TTM_PL_FLAG_TOPDOWN; 132 places[c].flags = TTM_PL_FLAG_WC |
133 TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM |
134 TTM_PL_FLAG_TOPDOWN;
135 c++;
130 } 136 }
131 placements[c].fpfn = 0; 137
132 placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | 138 places[c].fpfn = 0;
139 places[c].lpfn = 0;
140 places[c].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
133 TTM_PL_FLAG_VRAM; 141 TTM_PL_FLAG_VRAM;
134 if (!(flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) 142 if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
135 placements[c - 1].flags |= TTM_PL_FLAG_TOPDOWN; 143 places[c].lpfn = visible_pfn;
144 else
145 places[c].flags |= TTM_PL_FLAG_TOPDOWN;
146 c++;
136 } 147 }
137 148
138 if (domain & AMDGPU_GEM_DOMAIN_GTT) { 149 if (domain & AMDGPU_GEM_DOMAIN_GTT) {
139 if (flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) { 150 places[c].fpfn = 0;
140 placements[c].fpfn = 0; 151 places[c].lpfn = 0;
141 placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT | 152 places[c].flags = TTM_PL_FLAG_TT;
153 if (flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC)
154 places[c].flags |= TTM_PL_FLAG_WC |
142 TTM_PL_FLAG_UNCACHED; 155 TTM_PL_FLAG_UNCACHED;
143 } else { 156 else
144 placements[c].fpfn = 0; 157 places[c].flags |= TTM_PL_FLAG_CACHED;
145 placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT; 158 c++;
146 }
147 } 159 }
148 160
149 if (domain & AMDGPU_GEM_DOMAIN_CPU) { 161 if (domain & AMDGPU_GEM_DOMAIN_CPU) {
150 if (flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) { 162 places[c].fpfn = 0;
151 placements[c].fpfn = 0; 163 places[c].lpfn = 0;
152 placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_SYSTEM | 164 places[c].flags = TTM_PL_FLAG_SYSTEM;
165 if (flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC)
166 places[c].flags |= TTM_PL_FLAG_WC |
153 TTM_PL_FLAG_UNCACHED; 167 TTM_PL_FLAG_UNCACHED;
154 } else { 168 else
155 placements[c].fpfn = 0; 169 places[c].flags |= TTM_PL_FLAG_CACHED;
156 placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM; 170 c++;
157 }
158 } 171 }
159 172
160 if (domain & AMDGPU_GEM_DOMAIN_GDS) { 173 if (domain & AMDGPU_GEM_DOMAIN_GDS) {
161 placements[c].fpfn = 0; 174 places[c].fpfn = 0;
162 placements[c++].flags = TTM_PL_FLAG_UNCACHED | 175 places[c].lpfn = 0;
163 AMDGPU_PL_FLAG_GDS; 176 places[c].flags = TTM_PL_FLAG_UNCACHED | AMDGPU_PL_FLAG_GDS;
177 c++;
164 } 178 }
179
165 if (domain & AMDGPU_GEM_DOMAIN_GWS) { 180 if (domain & AMDGPU_GEM_DOMAIN_GWS) {
166 placements[c].fpfn = 0; 181 places[c].fpfn = 0;
167 placements[c++].flags = TTM_PL_FLAG_UNCACHED | 182 places[c].lpfn = 0;
168 AMDGPU_PL_FLAG_GWS; 183 places[c].flags = TTM_PL_FLAG_UNCACHED | AMDGPU_PL_FLAG_GWS;
184 c++;
169 } 185 }
186
170 if (domain & AMDGPU_GEM_DOMAIN_OA) { 187 if (domain & AMDGPU_GEM_DOMAIN_OA) {
171 placements[c].fpfn = 0; 188 places[c].fpfn = 0;
172 placements[c++].flags = TTM_PL_FLAG_UNCACHED | 189 places[c].lpfn = 0;
173 AMDGPU_PL_FLAG_OA; 190 places[c].flags = TTM_PL_FLAG_UNCACHED | AMDGPU_PL_FLAG_OA;
191 c++;
174 } 192 }
175 193
176 if (!c) { 194 if (!c) {
177 placements[c].fpfn = 0; 195 places[c].fpfn = 0;
178 placements[c++].flags = TTM_PL_MASK_CACHING | 196 places[c].lpfn = 0;
179 TTM_PL_FLAG_SYSTEM; 197 places[c].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
198 c++;
180 } 199 }
200
181 placement->num_placement = c; 201 placement->num_placement = c;
182 placement->num_busy_placement = c; 202 placement->placement = places;
183 203
184 for (i = 0; i < c; i++) { 204 placement->num_busy_placement = c;
185 if ((flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && 205 placement->busy_placement = places;
186 (placements[i].flags & TTM_PL_FLAG_VRAM) &&
187 !placements[i].fpfn)
188 placements[i].lpfn =
189 adev->mc.visible_vram_size >> PAGE_SHIFT;
190 else
191 placements[i].lpfn = 0;
192 }
193} 206}
194 207
195void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain) 208void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain)
@@ -211,6 +224,69 @@ static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo,
211 bo->placement.busy_placement = bo->placements; 224 bo->placement.busy_placement = bo->placements;
212} 225}
213 226
227/**
228 * amdgpu_bo_create_kernel - create BO for kernel use
229 *
230 * @adev: amdgpu device object
231 * @size: size for the new BO
232 * @align: alignment for the new BO
233 * @domain: where to place it
234 * @bo_ptr: resulting BO
235 * @gpu_addr: GPU addr of the pinned BO
236 * @cpu_addr: optional CPU address mapping
237 *
238 * Allocates and pins a BO for kernel internal use.
239 *
240 * Returns 0 on success, negative error code otherwise.
241 */
242int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
243 unsigned long size, int align,
244 u32 domain, struct amdgpu_bo **bo_ptr,
245 u64 *gpu_addr, void **cpu_addr)
246{
247 int r;
248
249 r = amdgpu_bo_create(adev, size, align, true, domain,
250 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
251 NULL, NULL, bo_ptr);
252 if (r) {
253 dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r);
254 return r;
255 }
256
257 r = amdgpu_bo_reserve(*bo_ptr, false);
258 if (r) {
259 dev_err(adev->dev, "(%d) failed to reserve kernel bo\n", r);
260 goto error_free;
261 }
262
263 r = amdgpu_bo_pin(*bo_ptr, domain, gpu_addr);
264 if (r) {
265 dev_err(adev->dev, "(%d) kernel bo pin failed\n", r);
266 goto error_unreserve;
267 }
268
269 if (cpu_addr) {
270 r = amdgpu_bo_kmap(*bo_ptr, cpu_addr);
271 if (r) {
272 dev_err(adev->dev, "(%d) kernel bo map failed\n", r);
273 goto error_unreserve;
274 }
275 }
276
277 amdgpu_bo_unreserve(*bo_ptr);
278
279 return 0;
280
281error_unreserve:
282 amdgpu_bo_unreserve(*bo_ptr);
283
284error_free:
285 amdgpu_bo_unref(bo_ptr);
286
287 return r;
288}
289
214int amdgpu_bo_create_restricted(struct amdgpu_device *adev, 290int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
215 unsigned long size, int byte_align, 291 unsigned long size, int byte_align,
216 bool kernel, u32 domain, u64 flags, 292 bool kernel, u32 domain, u64 flags,
@@ -250,6 +326,7 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
250 } 326 }
251 bo->adev = adev; 327 bo->adev = adev;
252 INIT_LIST_HEAD(&bo->list); 328 INIT_LIST_HEAD(&bo->list);
329 INIT_LIST_HEAD(&bo->shadow_list);
253 INIT_LIST_HEAD(&bo->va); 330 INIT_LIST_HEAD(&bo->va);
254 bo->prefered_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM | 331 bo->prefered_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM |
255 AMDGPU_GEM_DOMAIN_GTT | 332 AMDGPU_GEM_DOMAIN_GTT |
@@ -277,11 +354,79 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
277 if (unlikely(r != 0)) { 354 if (unlikely(r != 0)) {
278 return r; 355 return r;
279 } 356 }
357
358 if (flags & AMDGPU_GEM_CREATE_VRAM_CLEARED &&
359 bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) {
360 struct fence *fence;
361
362 if (adev->mman.buffer_funcs_ring == NULL ||
363 !adev->mman.buffer_funcs_ring->ready) {
364 r = -EBUSY;
365 goto fail_free;
366 }
367
368 r = amdgpu_bo_reserve(bo, false);
369 if (unlikely(r != 0))
370 goto fail_free;
371
372 amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);
373 r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
374 if (unlikely(r != 0))
375 goto fail_unreserve;
376
377 amdgpu_fill_buffer(bo, 0, bo->tbo.resv, &fence);
378 amdgpu_bo_fence(bo, fence, false);
379 amdgpu_bo_unreserve(bo);
380 fence_put(bo->tbo.moving);
381 bo->tbo.moving = fence_get(fence);
382 fence_put(fence);
383 }
280 *bo_ptr = bo; 384 *bo_ptr = bo;
281 385
282 trace_amdgpu_bo_create(bo); 386 trace_amdgpu_bo_create(bo);
283 387
284 return 0; 388 return 0;
389
390fail_unreserve:
391 amdgpu_bo_unreserve(bo);
392fail_free:
393 amdgpu_bo_unref(&bo);
394 return r;
395}
396
397static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
398 unsigned long size, int byte_align,
399 struct amdgpu_bo *bo)
400{
401 struct ttm_placement placement = {0};
402 struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
403 int r;
404
405 if (bo->shadow)
406 return 0;
407
408 bo->flags |= AMDGPU_GEM_CREATE_SHADOW;
409 memset(&placements, 0,
410 (AMDGPU_GEM_DOMAIN_MAX + 1) * sizeof(struct ttm_place));
411
412 amdgpu_ttm_placement_init(adev, &placement,
413 placements, AMDGPU_GEM_DOMAIN_GTT,
414 AMDGPU_GEM_CREATE_CPU_GTT_USWC);
415
416 r = amdgpu_bo_create_restricted(adev, size, byte_align, true,
417 AMDGPU_GEM_DOMAIN_GTT,
418 AMDGPU_GEM_CREATE_CPU_GTT_USWC,
419 NULL, &placement,
420 bo->tbo.resv,
421 &bo->shadow);
422 if (!r) {
423 bo->shadow->parent = amdgpu_bo_ref(bo);
424 mutex_lock(&adev->shadow_list_lock);
425 list_add_tail(&bo->shadow_list, &adev->shadow_list);
426 mutex_unlock(&adev->shadow_list_lock);
427 }
428
429 return r;
285} 430}
286 431
287int amdgpu_bo_create(struct amdgpu_device *adev, 432int amdgpu_bo_create(struct amdgpu_device *adev,
@@ -293,6 +438,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
293{ 438{
294 struct ttm_placement placement = {0}; 439 struct ttm_placement placement = {0};
295 struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1]; 440 struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
441 int r;
296 442
297 memset(&placements, 0, 443 memset(&placements, 0,
298 (AMDGPU_GEM_DOMAIN_MAX + 1) * sizeof(struct ttm_place)); 444 (AMDGPU_GEM_DOMAIN_MAX + 1) * sizeof(struct ttm_place));
@@ -300,9 +446,83 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
300 amdgpu_ttm_placement_init(adev, &placement, 446 amdgpu_ttm_placement_init(adev, &placement,
301 placements, domain, flags); 447 placements, domain, flags);
302 448
303 return amdgpu_bo_create_restricted(adev, size, byte_align, kernel, 449 r = amdgpu_bo_create_restricted(adev, size, byte_align, kernel,
304 domain, flags, sg, &placement, 450 domain, flags, sg, &placement,
305 resv, bo_ptr); 451 resv, bo_ptr);
452 if (r)
453 return r;
454
455 if (amdgpu_need_backup(adev) && (flags & AMDGPU_GEM_CREATE_SHADOW)) {
456 r = amdgpu_bo_create_shadow(adev, size, byte_align, (*bo_ptr));
457 if (r)
458 amdgpu_bo_unref(bo_ptr);
459 }
460
461 return r;
462}
463
464int amdgpu_bo_backup_to_shadow(struct amdgpu_device *adev,
465 struct amdgpu_ring *ring,
466 struct amdgpu_bo *bo,
467 struct reservation_object *resv,
468 struct fence **fence,
469 bool direct)
470
471{
472 struct amdgpu_bo *shadow = bo->shadow;
473 uint64_t bo_addr, shadow_addr;
474 int r;
475
476 if (!shadow)
477 return -EINVAL;
478
479 bo_addr = amdgpu_bo_gpu_offset(bo);
480 shadow_addr = amdgpu_bo_gpu_offset(bo->shadow);
481
482 r = reservation_object_reserve_shared(bo->tbo.resv);
483 if (r)
484 goto err;
485
486 r = amdgpu_copy_buffer(ring, bo_addr, shadow_addr,
487 amdgpu_bo_size(bo), resv, fence,
488 direct);
489 if (!r)
490 amdgpu_bo_fence(bo, *fence, true);
491
492err:
493 return r;
494}
495
496int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev,
497 struct amdgpu_ring *ring,
498 struct amdgpu_bo *bo,
499 struct reservation_object *resv,
500 struct fence **fence,
501 bool direct)
502
503{
504 struct amdgpu_bo *shadow = bo->shadow;
505 uint64_t bo_addr, shadow_addr;
506 int r;
507
508 if (!shadow)
509 return -EINVAL;
510
511 bo_addr = amdgpu_bo_gpu_offset(bo);
512 shadow_addr = amdgpu_bo_gpu_offset(bo->shadow);
513
514 r = reservation_object_reserve_shared(bo->tbo.resv);
515 if (r)
516 goto err;
517
518 r = amdgpu_copy_buffer(ring, shadow_addr, bo_addr,
519 amdgpu_bo_size(bo), resv, fence,
520 direct);
521 if (!r)
522 amdgpu_bo_fence(bo, *fence, true);
523
524err:
525 return r;
306} 526}
307 527
308int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) 528int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr)
@@ -380,16 +600,17 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
380 return -EINVAL; 600 return -EINVAL;
381 601
382 if (bo->pin_count) { 602 if (bo->pin_count) {
603 uint32_t mem_type = bo->tbo.mem.mem_type;
604
605 if (domain != amdgpu_mem_type_to_domain(mem_type))
606 return -EINVAL;
607
383 bo->pin_count++; 608 bo->pin_count++;
384 if (gpu_addr) 609 if (gpu_addr)
385 *gpu_addr = amdgpu_bo_gpu_offset(bo); 610 *gpu_addr = amdgpu_bo_gpu_offset(bo);
386 611
387 if (max_offset != 0) { 612 if (max_offset != 0) {
388 u64 domain_start; 613 u64 domain_start = bo->tbo.bdev->man[mem_type].gpu_offset;
389 if (domain == AMDGPU_GEM_DOMAIN_VRAM)
390 domain_start = bo->adev->mc.vram_start;
391 else
392 domain_start = bo->adev->mc.gtt_start;
393 WARN_ON_ONCE(max_offset < 614 WARN_ON_ONCE(max_offset <
394 (amdgpu_bo_gpu_offset(bo) - domain_start)); 615 (amdgpu_bo_gpu_offset(bo) - domain_start));
395 } 616 }
@@ -401,7 +622,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
401 /* force to pin into visible video ram */ 622 /* force to pin into visible video ram */
402 if ((bo->placements[i].flags & TTM_PL_FLAG_VRAM) && 623 if ((bo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
403 !(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) && 624 !(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) &&
404 (!max_offset || max_offset > bo->adev->mc.visible_vram_size)) { 625 (!max_offset || max_offset >
626 bo->adev->mc.visible_vram_size)) {
405 if (WARN_ON_ONCE(min_offset > 627 if (WARN_ON_ONCE(min_offset >
406 bo->adev->mc.visible_vram_size)) 628 bo->adev->mc.visible_vram_size))
407 return -EINVAL; 629 return -EINVAL;
@@ -420,19 +642,23 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
420 } 642 }
421 643
422 r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); 644 r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
423 if (likely(r == 0)) { 645 if (unlikely(r)) {
424 bo->pin_count = 1;
425 if (gpu_addr != NULL)
426 *gpu_addr = amdgpu_bo_gpu_offset(bo);
427 if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
428 bo->adev->vram_pin_size += amdgpu_bo_size(bo);
429 if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
430 bo->adev->invisible_pin_size += amdgpu_bo_size(bo);
431 } else
432 bo->adev->gart_pin_size += amdgpu_bo_size(bo);
433 } else {
434 dev_err(bo->adev->dev, "%p pin failed\n", bo); 646 dev_err(bo->adev->dev, "%p pin failed\n", bo);
647 goto error;
648 }
649
650 bo->pin_count = 1;
651 if (gpu_addr != NULL)
652 *gpu_addr = amdgpu_bo_gpu_offset(bo);
653 if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
654 bo->adev->vram_pin_size += amdgpu_bo_size(bo);
655 if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
656 bo->adev->invisible_pin_size += amdgpu_bo_size(bo);
657 } else if (domain == AMDGPU_GEM_DOMAIN_GTT) {
658 bo->adev->gart_pin_size += amdgpu_bo_size(bo);
435 } 659 }
660
661error:
436 return r; 662 return r;
437} 663}
438 664
@@ -457,16 +683,20 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo)
457 bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; 683 bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
458 } 684 }
459 r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); 685 r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
460 if (likely(r == 0)) { 686 if (unlikely(r)) {
461 if (bo->tbo.mem.mem_type == TTM_PL_VRAM) {
462 bo->adev->vram_pin_size -= amdgpu_bo_size(bo);
463 if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
464 bo->adev->invisible_pin_size -= amdgpu_bo_size(bo);
465 } else
466 bo->adev->gart_pin_size -= amdgpu_bo_size(bo);
467 } else {
468 dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo); 687 dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo);
688 goto error;
689 }
690
691 if (bo->tbo.mem.mem_type == TTM_PL_VRAM) {
692 bo->adev->vram_pin_size -= amdgpu_bo_size(bo);
693 if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
694 bo->adev->invisible_pin_size -= amdgpu_bo_size(bo);
695 } else {
696 bo->adev->gart_pin_size -= amdgpu_bo_size(bo);
469 } 697 }
698
699error:
470 return r; 700 return r;
471} 701}
472 702
@@ -637,7 +867,8 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
637 for (i = 0; i < abo->placement.num_placement; i++) { 867 for (i = 0; i < abo->placement.num_placement; i++) {
638 /* Force into visible VRAM */ 868 /* Force into visible VRAM */
639 if ((abo->placements[i].flags & TTM_PL_FLAG_VRAM) && 869 if ((abo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
640 (!abo->placements[i].lpfn || abo->placements[i].lpfn > lpfn)) 870 (!abo->placements[i].lpfn ||
871 abo->placements[i].lpfn > lpfn))
641 abo->placements[i].lpfn = lpfn; 872 abo->placements[i].lpfn = lpfn;
642 } 873 }
643 r = ttm_bo_validate(bo, &abo->placement, false, false); 874 r = ttm_bo_validate(bo, &abo->placement, false, false);
@@ -674,3 +905,21 @@ void amdgpu_bo_fence(struct amdgpu_bo *bo, struct fence *fence,
674 else 905 else
675 reservation_object_add_excl_fence(resv, fence); 906 reservation_object_add_excl_fence(resv, fence);
676} 907}
908
909/**
910 * amdgpu_bo_gpu_offset - return GPU offset of bo
911 * @bo: amdgpu object for which we query the offset
912 *
913 * Returns current GPU offset of the object.
914 *
915 * Note: object should either be pinned or reserved when calling this
916 * function, it might be useful to add check for this for debugging.
917 */
918u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
919{
920 WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
921 WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
922 !bo->pin_count);
923
924 return bo->tbo.offset;
925}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index bdb01d932548..b6a27390ef88 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -85,21 +85,6 @@ static inline void amdgpu_bo_unreserve(struct amdgpu_bo *bo)
85 ttm_bo_unreserve(&bo->tbo); 85 ttm_bo_unreserve(&bo->tbo);
86} 86}
87 87
88/**
89 * amdgpu_bo_gpu_offset - return GPU offset of bo
90 * @bo: amdgpu object for which we query the offset
91 *
92 * Returns current GPU offset of the object.
93 *
94 * Note: object should either be pinned or reserved when calling this
95 * function, it might be useful to add check for this for debugging.
96 */
97static inline u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
98{
99 WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
100 return bo->tbo.offset;
101}
102
103static inline unsigned long amdgpu_bo_size(struct amdgpu_bo *bo) 88static inline unsigned long amdgpu_bo_size(struct amdgpu_bo *bo)
104{ 89{
105 return bo->tbo.num_pages << PAGE_SHIFT; 90 return bo->tbo.num_pages << PAGE_SHIFT;
@@ -139,6 +124,10 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
139 struct ttm_placement *placement, 124 struct ttm_placement *placement,
140 struct reservation_object *resv, 125 struct reservation_object *resv,
141 struct amdgpu_bo **bo_ptr); 126 struct amdgpu_bo **bo_ptr);
127int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
128 unsigned long size, int align,
129 u32 domain, struct amdgpu_bo **bo_ptr,
130 u64 *gpu_addr, void **cpu_addr);
142int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr); 131int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr);
143void amdgpu_bo_kunmap(struct amdgpu_bo *bo); 132void amdgpu_bo_kunmap(struct amdgpu_bo *bo);
144struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo); 133struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo);
@@ -165,6 +154,19 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
165int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); 154int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
166void amdgpu_bo_fence(struct amdgpu_bo *bo, struct fence *fence, 155void amdgpu_bo_fence(struct amdgpu_bo *bo, struct fence *fence,
167 bool shared); 156 bool shared);
157u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo);
158int amdgpu_bo_backup_to_shadow(struct amdgpu_device *adev,
159 struct amdgpu_ring *ring,
160 struct amdgpu_bo *bo,
161 struct reservation_object *resv,
162 struct fence **fence, bool direct);
163int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev,
164 struct amdgpu_ring *ring,
165 struct amdgpu_bo *bo,
166 struct reservation_object *resv,
167 struct fence **fence,
168 bool direct);
169
168 170
169/* 171/*
170 * sub allocation 172 * sub allocation
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 5cc7052e391d..d4ec3cb187a5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1103,54 +1103,46 @@ force:
1103 1103
1104void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) 1104void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
1105{ 1105{
1106 if (adev->pp_enabled) 1106 if (adev->pp_enabled || adev->pm.funcs->powergate_uvd) {
1107 /* enable/disable UVD */
1108 mutex_lock(&adev->pm.mutex);
1107 amdgpu_dpm_powergate_uvd(adev, !enable); 1109 amdgpu_dpm_powergate_uvd(adev, !enable);
1108 else { 1110 mutex_unlock(&adev->pm.mutex);
1109 if (adev->pm.funcs->powergate_uvd) { 1111 } else {
1112 if (enable) {
1110 mutex_lock(&adev->pm.mutex); 1113 mutex_lock(&adev->pm.mutex);
1111 /* enable/disable UVD */ 1114 adev->pm.dpm.uvd_active = true;
1112 amdgpu_dpm_powergate_uvd(adev, !enable); 1115 adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
1113 mutex_unlock(&adev->pm.mutex); 1116 mutex_unlock(&adev->pm.mutex);
1114 } else { 1117 } else {
1115 if (enable) { 1118 mutex_lock(&adev->pm.mutex);
1116 mutex_lock(&adev->pm.mutex); 1119 adev->pm.dpm.uvd_active = false;
1117 adev->pm.dpm.uvd_active = true; 1120 mutex_unlock(&adev->pm.mutex);
1118 adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
1119 mutex_unlock(&adev->pm.mutex);
1120 } else {
1121 mutex_lock(&adev->pm.mutex);
1122 adev->pm.dpm.uvd_active = false;
1123 mutex_unlock(&adev->pm.mutex);
1124 }
1125 amdgpu_pm_compute_clocks(adev);
1126 } 1121 }
1127 1122 amdgpu_pm_compute_clocks(adev);
1128 } 1123 }
1129} 1124}
1130 1125
1131void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) 1126void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
1132{ 1127{
1133 if (adev->pp_enabled) 1128 if (adev->pp_enabled || adev->pm.funcs->powergate_vce) {
1129 /* enable/disable VCE */
1130 mutex_lock(&adev->pm.mutex);
1134 amdgpu_dpm_powergate_vce(adev, !enable); 1131 amdgpu_dpm_powergate_vce(adev, !enable);
1135 else { 1132 mutex_unlock(&adev->pm.mutex);
1136 if (adev->pm.funcs->powergate_vce) { 1133 } else {
1134 if (enable) {
1137 mutex_lock(&adev->pm.mutex); 1135 mutex_lock(&adev->pm.mutex);
1138 amdgpu_dpm_powergate_vce(adev, !enable); 1136 adev->pm.dpm.vce_active = true;
1137 /* XXX select vce level based on ring/task */
1138 adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
1139 mutex_unlock(&adev->pm.mutex); 1139 mutex_unlock(&adev->pm.mutex);
1140 } else { 1140 } else {
1141 if (enable) { 1141 mutex_lock(&adev->pm.mutex);
1142 mutex_lock(&adev->pm.mutex); 1142 adev->pm.dpm.vce_active = false;
1143 adev->pm.dpm.vce_active = true; 1143 mutex_unlock(&adev->pm.mutex);
1144 /* XXX select vce level based on ring/task */
1145 adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
1146 mutex_unlock(&adev->pm.mutex);
1147 } else {
1148 mutex_lock(&adev->pm.mutex);
1149 adev->pm.dpm.vce_active = false;
1150 mutex_unlock(&adev->pm.mutex);
1151 }
1152 amdgpu_pm_compute_clocks(adev);
1153 } 1144 }
1145 amdgpu_pm_compute_clocks(adev);
1154 } 1146 }
1155} 1147}
1156 1148
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
index c5738a22b690..545074479e1f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
@@ -52,7 +52,9 @@ static int amdgpu_powerplay_init(struct amdgpu_device *adev)
52 pp_init->chip_family = adev->family; 52 pp_init->chip_family = adev->family;
53 pp_init->chip_id = adev->asic_type; 53 pp_init->chip_id = adev->asic_type;
54 pp_init->device = amdgpu_cgs_create_device(adev); 54 pp_init->device = amdgpu_cgs_create_device(adev);
55 pp_init->powercontainment_enabled = amdgpu_powercontainment; 55 pp_init->rev_id = adev->pdev->revision;
56 pp_init->sub_sys_id = adev->pdev->subsystem_device;
57 pp_init->sub_vendor_id = adev->pdev->subsystem_vendor;
56 58
57 ret = amd_powerplay_init(pp_init, amd_pp); 59 ret = amd_powerplay_init(pp_init, amd_pp);
58 kfree(pp_init); 60 kfree(pp_init);
@@ -106,11 +108,10 @@ static int amdgpu_pp_early_init(void *handle)
106 break; 108 break;
107 case CHIP_TONGA: 109 case CHIP_TONGA:
108 case CHIP_FIJI: 110 case CHIP_FIJI:
109 adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true; 111 case CHIP_TOPAZ:
110 break;
111 case CHIP_CARRIZO: 112 case CHIP_CARRIZO:
112 case CHIP_STONEY: 113 case CHIP_STONEY:
113 adev->pp_enabled = (amdgpu_powerplay > 0) ? true : false; 114 adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true;
114 break; 115 break;
115 /* These chips don't have powerplay implemenations */ 116 /* These chips don't have powerplay implemenations */
116 case CHIP_BONAIRE: 117 case CHIP_BONAIRE:
@@ -118,7 +119,6 @@ static int amdgpu_pp_early_init(void *handle)
118 case CHIP_KABINI: 119 case CHIP_KABINI:
119 case CHIP_MULLINS: 120 case CHIP_MULLINS:
120 case CHIP_KAVERI: 121 case CHIP_KAVERI:
121 case CHIP_TOPAZ:
122 default: 122 default:
123 adev->pp_enabled = false; 123 adev->pp_enabled = false;
124 break; 124 break;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 85aeb0a804bb..242ba04bfde6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -222,33 +222,16 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
222 222
223 /* Allocate ring buffer */ 223 /* Allocate ring buffer */
224 if (ring->ring_obj == NULL) { 224 if (ring->ring_obj == NULL) {
225 r = amdgpu_bo_create(adev, ring->ring_size, PAGE_SIZE, true, 225 r = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE,
226 AMDGPU_GEM_DOMAIN_GTT, 0, 226 AMDGPU_GEM_DOMAIN_GTT,
227 NULL, NULL, &ring->ring_obj); 227 &ring->ring_obj,
228 &ring->gpu_addr,
229 (void **)&ring->ring);
228 if (r) { 230 if (r) {
229 dev_err(adev->dev, "(%d) ring create failed\n", r); 231 dev_err(adev->dev, "(%d) ring create failed\n", r);
230 return r; 232 return r;
231 } 233 }
232 r = amdgpu_bo_reserve(ring->ring_obj, false);
233 if (unlikely(r != 0))
234 return r;
235 r = amdgpu_bo_pin(ring->ring_obj, AMDGPU_GEM_DOMAIN_GTT,
236 &ring->gpu_addr);
237 if (r) {
238 amdgpu_bo_unreserve(ring->ring_obj);
239 dev_err(adev->dev, "(%d) ring pin failed\n", r);
240 return r;
241 }
242 r = amdgpu_bo_kmap(ring->ring_obj,
243 (void **)&ring->ring);
244
245 memset((void *)ring->ring, 0, ring->ring_size); 234 memset((void *)ring->ring, 0, ring->ring_size);
246
247 amdgpu_bo_unreserve(ring->ring_obj);
248 if (r) {
249 dev_err(adev->dev, "(%d) ring map failed\n", r);
250 return r;
251 }
252 } 235 }
253 ring->ptr_mask = (ring->ring_size / 4) - 1; 236 ring->ptr_mask = (ring->ring_size / 4) - 1;
254 ring->max_dw = max_dw; 237 ring->max_dw = max_dw;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
index 05a53f4fc334..b827c75e95de 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
@@ -111,7 +111,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
111 amdgpu_bo_kunmap(gtt_obj[i]); 111 amdgpu_bo_kunmap(gtt_obj[i]);
112 112
113 r = amdgpu_copy_buffer(ring, gtt_addr, vram_addr, 113 r = amdgpu_copy_buffer(ring, gtt_addr, vram_addr,
114 size, NULL, &fence); 114 size, NULL, &fence, false);
115 115
116 if (r) { 116 if (r) {
117 DRM_ERROR("Failed GTT->VRAM copy %d\n", i); 117 DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
@@ -156,7 +156,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
156 amdgpu_bo_kunmap(vram_obj); 156 amdgpu_bo_kunmap(vram_obj);
157 157
158 r = amdgpu_copy_buffer(ring, vram_addr, gtt_addr, 158 r = amdgpu_copy_buffer(ring, vram_addr, gtt_addr,
159 size, NULL, &fence); 159 size, NULL, &fence, false);
160 160
161 if (r) { 161 if (r) {
162 DRM_ERROR("Failed VRAM->GTT copy %d\n", i); 162 DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 9b61c8ba7aaf..5447973483ec 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -34,6 +34,7 @@
34#include <ttm/ttm_placement.h> 34#include <ttm/ttm_placement.h>
35#include <ttm/ttm_module.h> 35#include <ttm/ttm_module.h>
36#include <ttm/ttm_page_alloc.h> 36#include <ttm/ttm_page_alloc.h>
37#include <ttm/ttm_memory.h>
37#include <drm/drmP.h> 38#include <drm/drmP.h>
38#include <drm/amdgpu_drm.h> 39#include <drm/amdgpu_drm.h>
39#include <linux/seq_file.h> 40#include <linux/seq_file.h>
@@ -74,7 +75,7 @@ static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref)
74 ttm_mem_global_release(ref->object); 75 ttm_mem_global_release(ref->object);
75} 76}
76 77
77static int amdgpu_ttm_global_init(struct amdgpu_device *adev) 78int amdgpu_ttm_global_init(struct amdgpu_device *adev)
78{ 79{
79 struct drm_global_reference *global_ref; 80 struct drm_global_reference *global_ref;
80 struct amdgpu_ring *ring; 81 struct amdgpu_ring *ring;
@@ -256,10 +257,8 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
256 257
257 switch (old_mem->mem_type) { 258 switch (old_mem->mem_type) {
258 case TTM_PL_VRAM: 259 case TTM_PL_VRAM:
259 old_start += adev->mc.vram_start;
260 break;
261 case TTM_PL_TT: 260 case TTM_PL_TT:
262 old_start += adev->mc.gtt_start; 261 old_start += bo->bdev->man[old_mem->mem_type].gpu_offset;
263 break; 262 break;
264 default: 263 default:
265 DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); 264 DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
@@ -267,10 +266,8 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
267 } 266 }
268 switch (new_mem->mem_type) { 267 switch (new_mem->mem_type) {
269 case TTM_PL_VRAM: 268 case TTM_PL_VRAM:
270 new_start += adev->mc.vram_start;
271 break;
272 case TTM_PL_TT: 269 case TTM_PL_TT:
273 new_start += adev->mc.gtt_start; 270 new_start += bo->bdev->man[new_mem->mem_type].gpu_offset;
274 break; 271 break;
275 default: 272 default:
276 DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); 273 DRM_ERROR("Unknown placement %d\n", old_mem->mem_type);
@@ -285,7 +282,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
285 282
286 r = amdgpu_copy_buffer(ring, old_start, new_start, 283 r = amdgpu_copy_buffer(ring, old_start, new_start,
287 new_mem->num_pages * PAGE_SIZE, /* bytes */ 284 new_mem->num_pages * PAGE_SIZE, /* bytes */
288 bo->resv, &fence); 285 bo->resv, &fence, false);
289 if (r) 286 if (r)
290 return r; 287 return r;
291 288
@@ -335,7 +332,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo,
335 if (unlikely(r)) { 332 if (unlikely(r)) {
336 goto out_cleanup; 333 goto out_cleanup;
337 } 334 }
338 r = ttm_bo_move_ttm(bo, true, interruptible, no_wait_gpu, new_mem); 335 r = ttm_bo_move_ttm(bo, interruptible, no_wait_gpu, new_mem);
339out_cleanup: 336out_cleanup:
340 ttm_bo_mem_put(bo, &tmp_mem); 337 ttm_bo_mem_put(bo, &tmp_mem);
341 return r; 338 return r;
@@ -368,7 +365,7 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo,
368 if (unlikely(r)) { 365 if (unlikely(r)) {
369 return r; 366 return r;
370 } 367 }
371 r = ttm_bo_move_ttm(bo, true, interruptible, no_wait_gpu, &tmp_mem); 368 r = ttm_bo_move_ttm(bo, interruptible, no_wait_gpu, &tmp_mem);
372 if (unlikely(r)) { 369 if (unlikely(r)) {
373 goto out_cleanup; 370 goto out_cleanup;
374 } 371 }
@@ -435,8 +432,7 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo,
435 432
436 if (r) { 433 if (r) {
437memcpy: 434memcpy:
438 r = ttm_bo_move_memcpy(bo, evict, interruptible, 435 r = ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu, new_mem);
439 no_wait_gpu, new_mem);
440 if (r) { 436 if (r) {
441 return r; 437 return r;
442 } 438 }
@@ -950,6 +946,8 @@ static struct list_head *amdgpu_ttm_lru_tail(struct ttm_buffer_object *tbo)
950 struct list_head *res = lru->lru[tbo->mem.mem_type]; 946 struct list_head *res = lru->lru[tbo->mem.mem_type];
951 947
952 lru->lru[tbo->mem.mem_type] = &tbo->lru; 948 lru->lru[tbo->mem.mem_type] = &tbo->lru;
949 while ((++lru)->lru[tbo->mem.mem_type] == res)
950 lru->lru[tbo->mem.mem_type] = &tbo->lru;
953 951
954 return res; 952 return res;
955} 953}
@@ -960,6 +958,8 @@ static struct list_head *amdgpu_ttm_swap_lru_tail(struct ttm_buffer_object *tbo)
960 struct list_head *res = lru->swap_lru; 958 struct list_head *res = lru->swap_lru;
961 959
962 lru->swap_lru = &tbo->swap; 960 lru->swap_lru = &tbo->swap;
961 while ((++lru)->swap_lru == res)
962 lru->swap_lru = &tbo->swap;
963 963
964 return res; 964 return res;
965} 965}
@@ -987,10 +987,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
987 unsigned i, j; 987 unsigned i, j;
988 int r; 988 int r;
989 989
990 r = amdgpu_ttm_global_init(adev);
991 if (r) {
992 return r;
993 }
994 /* No others user of address space so set it to 0 */ 990 /* No others user of address space so set it to 0 */
995 r = ttm_bo_device_init(&adev->mman.bdev, 991 r = ttm_bo_device_init(&adev->mman.bdev,
996 adev->mman.bo_global_ref.ref.object, 992 adev->mman.bo_global_ref.ref.object,
@@ -1011,6 +1007,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1011 lru->swap_lru = &adev->mman.bdev.glob->swap_lru; 1007 lru->swap_lru = &adev->mman.bdev.glob->swap_lru;
1012 } 1008 }
1013 1009
1010 for (j = 0; j < TTM_NUM_MEM_TYPES; ++j)
1011 adev->mman.guard.lru[j] = NULL;
1012 adev->mman.guard.swap_lru = NULL;
1013
1014 adev->mman.initialized = true; 1014 adev->mman.initialized = true;
1015 r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, 1015 r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM,
1016 adev->mc.real_vram_size >> PAGE_SHIFT); 1016 adev->mc.real_vram_size >> PAGE_SHIFT);
@@ -1151,7 +1151,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
1151 uint64_t dst_offset, 1151 uint64_t dst_offset,
1152 uint32_t byte_count, 1152 uint32_t byte_count,
1153 struct reservation_object *resv, 1153 struct reservation_object *resv,
1154 struct fence **fence) 1154 struct fence **fence, bool direct_submit)
1155{ 1155{
1156 struct amdgpu_device *adev = ring->adev; 1156 struct amdgpu_device *adev = ring->adev;
1157 struct amdgpu_job *job; 1157 struct amdgpu_job *job;
@@ -1195,8 +1195,79 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
1195 1195
1196 amdgpu_ring_pad_ib(ring, &job->ibs[0]); 1196 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
1197 WARN_ON(job->ibs[0].length_dw > num_dw); 1197 WARN_ON(job->ibs[0].length_dw > num_dw);
1198 if (direct_submit) {
1199 r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs,
1200 NULL, NULL, fence);
1201 job->fence = fence_get(*fence);
1202 if (r)
1203 DRM_ERROR("Error scheduling IBs (%d)\n", r);
1204 amdgpu_job_free(job);
1205 } else {
1206 r = amdgpu_job_submit(job, ring, &adev->mman.entity,
1207 AMDGPU_FENCE_OWNER_UNDEFINED, fence);
1208 if (r)
1209 goto error_free;
1210 }
1211
1212 return r;
1213
1214error_free:
1215 amdgpu_job_free(job);
1216 return r;
1217}
1218
1219int amdgpu_fill_buffer(struct amdgpu_bo *bo,
1220 uint32_t src_data,
1221 struct reservation_object *resv,
1222 struct fence **fence)
1223{
1224 struct amdgpu_device *adev = bo->adev;
1225 struct amdgpu_job *job;
1226 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
1227
1228 uint32_t max_bytes, byte_count;
1229 uint64_t dst_offset;
1230 unsigned int num_loops, num_dw;
1231 unsigned int i;
1232 int r;
1233
1234 byte_count = bo->tbo.num_pages << PAGE_SHIFT;
1235 max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
1236 num_loops = DIV_ROUND_UP(byte_count, max_bytes);
1237 num_dw = num_loops * adev->mman.buffer_funcs->fill_num_dw;
1238
1239 /* for IB padding */
1240 while (num_dw & 0x7)
1241 num_dw++;
1242
1243 r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job);
1244 if (r)
1245 return r;
1246
1247 if (resv) {
1248 r = amdgpu_sync_resv(adev, &job->sync, resv,
1249 AMDGPU_FENCE_OWNER_UNDEFINED);
1250 if (r) {
1251 DRM_ERROR("sync failed (%d).\n", r);
1252 goto error_free;
1253 }
1254 }
1255
1256 dst_offset = bo->tbo.mem.start << PAGE_SHIFT;
1257 for (i = 0; i < num_loops; i++) {
1258 uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
1259
1260 amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data,
1261 dst_offset, cur_size_in_bytes);
1262
1263 dst_offset += cur_size_in_bytes;
1264 byte_count -= cur_size_in_bytes;
1265 }
1266
1267 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
1268 WARN_ON(job->ibs[0].length_dw > num_dw);
1198 r = amdgpu_job_submit(job, ring, &adev->mman.entity, 1269 r = amdgpu_job_submit(job, ring, &adev->mman.entity,
1199 AMDGPU_FENCE_OWNER_UNDEFINED, fence); 1270 AMDGPU_FENCE_OWNER_UNDEFINED, fence);
1200 if (r) 1271 if (r)
1201 goto error_free; 1272 goto error_free;
1202 1273
@@ -1387,3 +1458,8 @@ static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev)
1387 1458
1388#endif 1459#endif
1389} 1460}
1461
1462u64 amdgpu_ttm_get_gtt_mem_size(struct amdgpu_device *adev)
1463{
1464 return ttm_get_kernel_zone_memory_size(adev->mman.mem_global_ref.object);
1465}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
new file mode 100644
index 000000000000..72f6bfc15d8f
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#ifndef __AMDGPU_TTM_H__
25#define __AMDGPU_TTM_H__
26
27#include "gpu_scheduler.h"
28
29#define AMDGPU_PL_GDS TTM_PL_PRIV0
30#define AMDGPU_PL_GWS TTM_PL_PRIV1
31#define AMDGPU_PL_OA TTM_PL_PRIV2
32
33#define AMDGPU_PL_FLAG_GDS TTM_PL_FLAG_PRIV0
34#define AMDGPU_PL_FLAG_GWS TTM_PL_FLAG_PRIV1
35#define AMDGPU_PL_FLAG_OA TTM_PL_FLAG_PRIV2
36
37#define AMDGPU_TTM_LRU_SIZE 20
38
39struct amdgpu_mman_lru {
40 struct list_head *lru[TTM_NUM_MEM_TYPES];
41 struct list_head *swap_lru;
42};
43
44struct amdgpu_mman {
45 struct ttm_bo_global_ref bo_global_ref;
46 struct drm_global_reference mem_global_ref;
47 struct ttm_bo_device bdev;
48 bool mem_global_referenced;
49 bool initialized;
50
51#if defined(CONFIG_DEBUG_FS)
52 struct dentry *vram;
53 struct dentry *gtt;
54#endif
55
56 /* buffer handling */
57 const struct amdgpu_buffer_funcs *buffer_funcs;
58 struct amdgpu_ring *buffer_funcs_ring;
59 /* Scheduler entity for buffer moves */
60 struct amd_sched_entity entity;
61
62 /* custom LRU management */
63 struct amdgpu_mman_lru log2_size[AMDGPU_TTM_LRU_SIZE];
64 /* guard for log2_size array, don't add anything in between */
65 struct amdgpu_mman_lru guard;
66};
67
68int amdgpu_copy_buffer(struct amdgpu_ring *ring,
69 uint64_t src_offset,
70 uint64_t dst_offset,
71 uint32_t byte_count,
72 struct reservation_object *resv,
73 struct fence **fence, bool direct_submit);
74int amdgpu_fill_buffer(struct amdgpu_bo *bo,
75 uint32_t src_data,
76 struct reservation_object *resv,
77 struct fence **fence);
78
79int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
80#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index b11f4e8868d7..cc766cc53a87 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -201,39 +201,14 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
201 bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) 201 bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8)
202 + AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE 202 + AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE
203 + AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles; 203 + AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles;
204 r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true, 204 r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
205 AMDGPU_GEM_DOMAIN_VRAM, 205 AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.vcpu_bo,
206 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, 206 &adev->uvd.gpu_addr, &adev->uvd.cpu_addr);
207 NULL, NULL, &adev->uvd.vcpu_bo);
208 if (r) { 207 if (r) {
209 dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r); 208 dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r);
210 return r; 209 return r;
211 } 210 }
212 211
213 r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false);
214 if (r) {
215 amdgpu_bo_unref(&adev->uvd.vcpu_bo);
216 dev_err(adev->dev, "(%d) failed to reserve UVD bo\n", r);
217 return r;
218 }
219
220 r = amdgpu_bo_pin(adev->uvd.vcpu_bo, AMDGPU_GEM_DOMAIN_VRAM,
221 &adev->uvd.gpu_addr);
222 if (r) {
223 amdgpu_bo_unreserve(adev->uvd.vcpu_bo);
224 amdgpu_bo_unref(&adev->uvd.vcpu_bo);
225 dev_err(adev->dev, "(%d) UVD bo pin failed\n", r);
226 return r;
227 }
228
229 r = amdgpu_bo_kmap(adev->uvd.vcpu_bo, &adev->uvd.cpu_addr);
230 if (r) {
231 dev_err(adev->dev, "(%d) UVD map failed\n", r);
232 return r;
233 }
234
235 amdgpu_bo_unreserve(adev->uvd.vcpu_bo);
236
237 ring = &adev->uvd.ring; 212 ring = &adev->uvd.ring;
238 rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; 213 rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
239 r = amd_sched_entity_init(&ring->sched, &adev->uvd.entity, 214 r = amd_sched_entity_init(&ring->sched, &adev->uvd.entity,
@@ -323,7 +298,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
323 if (!adev->uvd.saved_bo) 298 if (!adev->uvd.saved_bo)
324 return -ENOMEM; 299 return -ENOMEM;
325 300
326 memcpy(adev->uvd.saved_bo, ptr, size); 301 memcpy_fromio(adev->uvd.saved_bo, ptr, size);
327 302
328 return 0; 303 return 0;
329} 304}
@@ -340,7 +315,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
340 ptr = adev->uvd.cpu_addr; 315 ptr = adev->uvd.cpu_addr;
341 316
342 if (adev->uvd.saved_bo != NULL) { 317 if (adev->uvd.saved_bo != NULL) {
343 memcpy(ptr, adev->uvd.saved_bo, size); 318 memcpy_toio(ptr, adev->uvd.saved_bo, size);
344 kfree(adev->uvd.saved_bo); 319 kfree(adev->uvd.saved_bo);
345 adev->uvd.saved_bo = NULL; 320 adev->uvd.saved_bo = NULL;
346 } else { 321 } else {
@@ -349,11 +324,11 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
349 324
350 hdr = (const struct common_firmware_header *)adev->uvd.fw->data; 325 hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
351 offset = le32_to_cpu(hdr->ucode_array_offset_bytes); 326 offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
352 memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset, 327 memcpy_toio(adev->uvd.cpu_addr, adev->uvd.fw->data + offset,
353 (adev->uvd.fw->size) - offset); 328 le32_to_cpu(hdr->ucode_size_bytes));
354 size -= le32_to_cpu(hdr->ucode_size_bytes); 329 size -= le32_to_cpu(hdr->ucode_size_bytes);
355 ptr += le32_to_cpu(hdr->ucode_size_bytes); 330 ptr += le32_to_cpu(hdr->ucode_size_bytes);
356 memset(ptr, 0, size); 331 memset_io(ptr, 0, size);
357 } 332 }
358 333
359 return 0; 334 return 0;
@@ -843,6 +818,7 @@ static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx,
843 return r; 818 return r;
844 break; 819 break;
845 case mmUVD_ENGINE_CNTL: 820 case mmUVD_ENGINE_CNTL:
821 case mmUVD_NO_OP:
846 break; 822 break;
847 default: 823 default:
848 DRM_ERROR("Invalid reg 0x%X!\n", reg); 824 DRM_ERROR("Invalid reg 0x%X!\n", reg);
@@ -981,8 +957,10 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
981 ib->ptr[3] = addr >> 32; 957 ib->ptr[3] = addr >> 32;
982 ib->ptr[4] = PACKET0(mmUVD_GPCOM_VCPU_CMD, 0); 958 ib->ptr[4] = PACKET0(mmUVD_GPCOM_VCPU_CMD, 0);
983 ib->ptr[5] = 0; 959 ib->ptr[5] = 0;
984 for (i = 6; i < 16; ++i) 960 for (i = 6; i < 16; i += 2) {
985 ib->ptr[i] = PACKET2(0); 961 ib->ptr[i] = PACKET0(mmUVD_NO_OP, 0);
962 ib->ptr[i+1] = 0;
963 }
986 ib->length_dw = 16; 964 ib->length_dw = 16;
987 965
988 if (direct) { 966 if (direct) {
@@ -1114,15 +1092,9 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work)
1114{ 1092{
1115 struct amdgpu_device *adev = 1093 struct amdgpu_device *adev =
1116 container_of(work, struct amdgpu_device, uvd.idle_work.work); 1094 container_of(work, struct amdgpu_device, uvd.idle_work.work);
1117 unsigned i, fences, handles = 0; 1095 unsigned fences = amdgpu_fence_count_emitted(&adev->uvd.ring);
1118
1119 fences = amdgpu_fence_count_emitted(&adev->uvd.ring);
1120
1121 for (i = 0; i < adev->uvd.max_handles; ++i)
1122 if (atomic_read(&adev->uvd.handles[i]))
1123 ++handles;
1124 1096
1125 if (fences == 0 && handles == 0) { 1097 if (fences == 0) {
1126 if (adev->pm.dpm_enabled) { 1098 if (adev->pm.dpm_enabled) {
1127 amdgpu_dpm_enable_uvd(adev, false); 1099 amdgpu_dpm_enable_uvd(adev, false);
1128 } else { 1100 } else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 05865ce35351..da52af2a935a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -282,8 +282,8 @@ int amdgpu_vce_resume(struct amdgpu_device *adev)
282 282
283 hdr = (const struct common_firmware_header *)adev->vce.fw->data; 283 hdr = (const struct common_firmware_header *)adev->vce.fw->data;
284 offset = le32_to_cpu(hdr->ucode_array_offset_bytes); 284 offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
285 memcpy(cpu_addr, (adev->vce.fw->data) + offset, 285 memcpy_toio(cpu_addr, adev->vce.fw->data + offset,
286 (adev->vce.fw->size) - offset); 286 adev->vce.fw->size - offset);
287 287
288 amdgpu_bo_kunmap(adev->vce.vcpu_bo); 288 amdgpu_bo_kunmap(adev->vce.vcpu_bo);
289 289
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 8e642fc48df4..bf56f1814437 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -51,19 +51,22 @@
51 * SI supports 16. 51 * SI supports 16.
52 */ 52 */
53 53
54/* Special value that no flush is necessary */
55#define AMDGPU_VM_NO_FLUSH (~0ll)
56
57/* Local structure. Encapsulate some VM table update parameters to reduce 54/* Local structure. Encapsulate some VM table update parameters to reduce
58 * the number of function parameters 55 * the number of function parameters
59 */ 56 */
60struct amdgpu_vm_update_params { 57struct amdgpu_pte_update_params {
58 /* amdgpu device we do this update for */
59 struct amdgpu_device *adev;
61 /* address where to copy page table entries from */ 60 /* address where to copy page table entries from */
62 uint64_t src; 61 uint64_t src;
63 /* DMA addresses to use for mapping */
64 dma_addr_t *pages_addr;
65 /* indirect buffer to fill with commands */ 62 /* indirect buffer to fill with commands */
66 struct amdgpu_ib *ib; 63 struct amdgpu_ib *ib;
64 /* Function which actually does the update */
65 void (*func)(struct amdgpu_pte_update_params *params, uint64_t pe,
66 uint64_t addr, unsigned count, uint32_t incr,
67 uint32_t flags);
68 /* indicate update pt or its shadow */
69 bool shadow;
67}; 70};
68 71
69/** 72/**
@@ -467,10 +470,9 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
467} 470}
468 471
469/** 472/**
470 * amdgpu_vm_update_pages - helper to call the right asic function 473 * amdgpu_vm_do_set_ptes - helper to call the right asic function
471 * 474 *
472 * @adev: amdgpu_device pointer 475 * @params: see amdgpu_pte_update_params definition
473 * @vm_update_params: see amdgpu_vm_update_params definition
474 * @pe: addr of the page entry 476 * @pe: addr of the page entry
475 * @addr: dst addr to write into pe 477 * @addr: dst addr to write into pe
476 * @count: number of page entries to update 478 * @count: number of page entries to update
@@ -480,35 +482,47 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
480 * Traces the parameters and calls the right asic functions 482 * Traces the parameters and calls the right asic functions
481 * to setup the page table using the DMA. 483 * to setup the page table using the DMA.
482 */ 484 */
483static void amdgpu_vm_update_pages(struct amdgpu_device *adev, 485static void amdgpu_vm_do_set_ptes(struct amdgpu_pte_update_params *params,
484 struct amdgpu_vm_update_params 486 uint64_t pe, uint64_t addr,
485 *vm_update_params, 487 unsigned count, uint32_t incr,
486 uint64_t pe, uint64_t addr, 488 uint32_t flags)
487 unsigned count, uint32_t incr,
488 uint32_t flags)
489{ 489{
490 trace_amdgpu_vm_set_page(pe, addr, count, incr, flags); 490 trace_amdgpu_vm_set_page(pe, addr, count, incr, flags);
491 491
492 if (vm_update_params->src) { 492 if (count < 3) {
493 amdgpu_vm_copy_pte(adev, vm_update_params->ib, 493 amdgpu_vm_write_pte(params->adev, params->ib, pe,
494 pe, (vm_update_params->src + (addr >> 12) * 8), count); 494 addr | flags, count, incr);
495
496 } else if (vm_update_params->pages_addr) {
497 amdgpu_vm_write_pte(adev, vm_update_params->ib,
498 vm_update_params->pages_addr,
499 pe, addr, count, incr, flags);
500
501 } else if (count < 3) {
502 amdgpu_vm_write_pte(adev, vm_update_params->ib, NULL, pe, addr,
503 count, incr, flags);
504 495
505 } else { 496 } else {
506 amdgpu_vm_set_pte_pde(adev, vm_update_params->ib, pe, addr, 497 amdgpu_vm_set_pte_pde(params->adev, params->ib, pe, addr,
507 count, incr, flags); 498 count, incr, flags);
508 } 499 }
509} 500}
510 501
511/** 502/**
503 * amdgpu_vm_do_copy_ptes - copy the PTEs from the GART
504 *
505 * @params: see amdgpu_pte_update_params definition
506 * @pe: addr of the page entry
507 * @addr: dst addr to write into pe
508 * @count: number of page entries to update
509 * @incr: increase next addr by incr bytes
510 * @flags: hw access flags
511 *
512 * Traces the parameters and calls the DMA function to copy the PTEs.
513 */
514static void amdgpu_vm_do_copy_ptes(struct amdgpu_pte_update_params *params,
515 uint64_t pe, uint64_t addr,
516 unsigned count, uint32_t incr,
517 uint32_t flags)
518{
519 trace_amdgpu_vm_set_page(pe, addr, count, incr, flags);
520
521 amdgpu_vm_copy_pte(params->adev, params->ib, pe,
522 (params->src + (addr >> 12) * 8), count);
523}
524
525/**
512 * amdgpu_vm_clear_bo - initially clear the page dir/table 526 * amdgpu_vm_clear_bo - initially clear the page dir/table
513 * 527 *
514 * @adev: amdgpu_device pointer 528 * @adev: amdgpu_device pointer
@@ -523,12 +537,11 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
523 struct amdgpu_ring *ring; 537 struct amdgpu_ring *ring;
524 struct fence *fence = NULL; 538 struct fence *fence = NULL;
525 struct amdgpu_job *job; 539 struct amdgpu_job *job;
526 struct amdgpu_vm_update_params vm_update_params; 540 struct amdgpu_pte_update_params params;
527 unsigned entries; 541 unsigned entries;
528 uint64_t addr; 542 uint64_t addr;
529 int r; 543 int r;
530 544
531 memset(&vm_update_params, 0, sizeof(vm_update_params));
532 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); 545 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched);
533 546
534 r = reservation_object_reserve_shared(bo->tbo.resv); 547 r = reservation_object_reserve_shared(bo->tbo.resv);
@@ -546,9 +559,10 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
546 if (r) 559 if (r)
547 goto error; 560 goto error;
548 561
549 vm_update_params.ib = &job->ibs[0]; 562 memset(&params, 0, sizeof(params));
550 amdgpu_vm_update_pages(adev, &vm_update_params, addr, 0, entries, 563 params.adev = adev;
551 0, 0); 564 params.ib = &job->ibs[0];
565 amdgpu_vm_do_set_ptes(&params, addr, 0, entries, 0, 0);
552 amdgpu_ring_pad_ib(ring, &job->ibs[0]); 566 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
553 567
554 WARN_ON(job->ibs[0].length_dw > 64); 568 WARN_ON(job->ibs[0].length_dw > 64);
@@ -577,55 +591,41 @@ error:
577 * Look up the physical address of the page that the pte resolves 591 * Look up the physical address of the page that the pte resolves
578 * to and return the pointer for the page table entry. 592 * to and return the pointer for the page table entry.
579 */ 593 */
580uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr) 594static uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr)
581{ 595{
582 uint64_t result; 596 uint64_t result;
583 597
584 if (pages_addr) { 598 /* page table offset */
585 /* page table offset */ 599 result = pages_addr[addr >> PAGE_SHIFT];
586 result = pages_addr[addr >> PAGE_SHIFT];
587
588 /* in case cpu page size != gpu page size*/
589 result |= addr & (~PAGE_MASK);
590 600
591 } else { 601 /* in case cpu page size != gpu page size*/
592 /* No mapping required */ 602 result |= addr & (~PAGE_MASK);
593 result = addr;
594 }
595 603
596 result &= 0xFFFFFFFFFFFFF000ULL; 604 result &= 0xFFFFFFFFFFFFF000ULL;
597 605
598 return result; 606 return result;
599} 607}
600 608
601/** 609static int amdgpu_vm_update_pd_or_shadow(struct amdgpu_device *adev,
602 * amdgpu_vm_update_pdes - make sure that page directory is valid 610 struct amdgpu_vm *vm,
603 * 611 bool shadow)
604 * @adev: amdgpu_device pointer
605 * @vm: requested vm
606 * @start: start of GPU address range
607 * @end: end of GPU address range
608 *
609 * Allocates new page tables if necessary
610 * and updates the page directory.
611 * Returns 0 for success, error for failure.
612 */
613int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
614 struct amdgpu_vm *vm)
615{ 612{
616 struct amdgpu_ring *ring; 613 struct amdgpu_ring *ring;
617 struct amdgpu_bo *pd = vm->page_directory; 614 struct amdgpu_bo *pd = shadow ? vm->page_directory->shadow :
618 uint64_t pd_addr = amdgpu_bo_gpu_offset(pd); 615 vm->page_directory;
616 uint64_t pd_addr;
619 uint32_t incr = AMDGPU_VM_PTE_COUNT * 8; 617 uint32_t incr = AMDGPU_VM_PTE_COUNT * 8;
620 uint64_t last_pde = ~0, last_pt = ~0; 618 uint64_t last_pde = ~0, last_pt = ~0;
621 unsigned count = 0, pt_idx, ndw; 619 unsigned count = 0, pt_idx, ndw;
622 struct amdgpu_job *job; 620 struct amdgpu_job *job;
623 struct amdgpu_vm_update_params vm_update_params; 621 struct amdgpu_pte_update_params params;
624 struct fence *fence = NULL; 622 struct fence *fence = NULL;
625 623
626 int r; 624 int r;
627 625
628 memset(&vm_update_params, 0, sizeof(vm_update_params)); 626 if (!pd)
627 return 0;
628 pd_addr = amdgpu_bo_gpu_offset(pd);
629 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); 629 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched);
630 630
631 /* padding, etc. */ 631 /* padding, etc. */
@@ -638,7 +638,9 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
638 if (r) 638 if (r)
639 return r; 639 return r;
640 640
641 vm_update_params.ib = &job->ibs[0]; 641 memset(&params, 0, sizeof(params));
642 params.adev = adev;
643 params.ib = &job->ibs[0];
642 644
643 /* walk over the address space and update the page directory */ 645 /* walk over the address space and update the page directory */
644 for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) { 646 for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) {
@@ -649,19 +651,25 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
649 continue; 651 continue;
650 652
651 pt = amdgpu_bo_gpu_offset(bo); 653 pt = amdgpu_bo_gpu_offset(bo);
652 if (vm->page_tables[pt_idx].addr == pt) 654 if (!shadow) {
653 continue; 655 if (vm->page_tables[pt_idx].addr == pt)
654 vm->page_tables[pt_idx].addr = pt; 656 continue;
657 vm->page_tables[pt_idx].addr = pt;
658 } else {
659 if (vm->page_tables[pt_idx].shadow_addr == pt)
660 continue;
661 vm->page_tables[pt_idx].shadow_addr = pt;
662 }
655 663
656 pde = pd_addr + pt_idx * 8; 664 pde = pd_addr + pt_idx * 8;
657 if (((last_pde + 8 * count) != pde) || 665 if (((last_pde + 8 * count) != pde) ||
658 ((last_pt + incr * count) != pt)) { 666 ((last_pt + incr * count) != pt) ||
667 (count == AMDGPU_VM_MAX_UPDATE_SIZE)) {
659 668
660 if (count) { 669 if (count) {
661 amdgpu_vm_update_pages(adev, &vm_update_params, 670 amdgpu_vm_do_set_ptes(&params, last_pde,
662 last_pde, last_pt, 671 last_pt, count, incr,
663 count, incr, 672 AMDGPU_PTE_VALID);
664 AMDGPU_PTE_VALID);
665 } 673 }
666 674
667 count = 1; 675 count = 1;
@@ -673,15 +681,14 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
673 } 681 }
674 682
675 if (count) 683 if (count)
676 amdgpu_vm_update_pages(adev, &vm_update_params, 684 amdgpu_vm_do_set_ptes(&params, last_pde, last_pt,
677 last_pde, last_pt, 685 count, incr, AMDGPU_PTE_VALID);
678 count, incr, AMDGPU_PTE_VALID);
679 686
680 if (vm_update_params.ib->length_dw != 0) { 687 if (params.ib->length_dw != 0) {
681 amdgpu_ring_pad_ib(ring, vm_update_params.ib); 688 amdgpu_ring_pad_ib(ring, params.ib);
682 amdgpu_sync_resv(adev, &job->sync, pd->tbo.resv, 689 amdgpu_sync_resv(adev, &job->sync, pd->tbo.resv,
683 AMDGPU_FENCE_OWNER_VM); 690 AMDGPU_FENCE_OWNER_VM);
684 WARN_ON(vm_update_params.ib->length_dw > ndw); 691 WARN_ON(params.ib->length_dw > ndw);
685 r = amdgpu_job_submit(job, ring, &vm->entity, 692 r = amdgpu_job_submit(job, ring, &vm->entity,
686 AMDGPU_FENCE_OWNER_VM, &fence); 693 AMDGPU_FENCE_OWNER_VM, &fence);
687 if (r) 694 if (r)
@@ -703,92 +710,33 @@ error_free:
703 return r; 710 return r;
704} 711}
705 712
706/** 713/*
707 * amdgpu_vm_frag_ptes - add fragment information to PTEs 714 * amdgpu_vm_update_pdes - make sure that page directory is valid
708 * 715 *
709 * @adev: amdgpu_device pointer 716 * @adev: amdgpu_device pointer
710 * @vm_update_params: see amdgpu_vm_update_params definition 717 * @vm: requested vm
711 * @pe_start: first PTE to handle 718 * @start: start of GPU address range
712 * @pe_end: last PTE to handle 719 * @end: end of GPU address range
713 * @addr: addr those PTEs should point to 720 *
714 * @flags: hw mapping flags 721 * Allocates new page tables if necessary
722 * and updates the page directory.
723 * Returns 0 for success, error for failure.
715 */ 724 */
716static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, 725int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
717 struct amdgpu_vm_update_params 726 struct amdgpu_vm *vm)
718 *vm_update_params,
719 uint64_t pe_start, uint64_t pe_end,
720 uint64_t addr, uint32_t flags)
721{ 727{
722 /** 728 int r;
723 * The MC L1 TLB supports variable sized pages, based on a fragment
724 * field in the PTE. When this field is set to a non-zero value, page
725 * granularity is increased from 4KB to (1 << (12 + frag)). The PTE
726 * flags are considered valid for all PTEs within the fragment range
727 * and corresponding mappings are assumed to be physically contiguous.
728 *
729 * The L1 TLB can store a single PTE for the whole fragment,
730 * significantly increasing the space available for translation
731 * caching. This leads to large improvements in throughput when the
732 * TLB is under pressure.
733 *
734 * The L2 TLB distributes small and large fragments into two
735 * asymmetric partitions. The large fragment cache is significantly
736 * larger. Thus, we try to use large fragments wherever possible.
737 * Userspace can support this by aligning virtual base address and
738 * allocation size to the fragment size.
739 */
740
741 /* SI and newer are optimized for 64KB */
742 uint64_t frag_flags = AMDGPU_PTE_FRAG_64KB;
743 uint64_t frag_align = 0x80;
744
745 uint64_t frag_start = ALIGN(pe_start, frag_align);
746 uint64_t frag_end = pe_end & ~(frag_align - 1);
747
748 unsigned count;
749
750 /* Abort early if there isn't anything to do */
751 if (pe_start == pe_end)
752 return;
753
754 /* system pages are non continuously */
755 if (vm_update_params->src || vm_update_params->pages_addr ||
756 !(flags & AMDGPU_PTE_VALID) || (frag_start >= frag_end)) {
757
758 count = (pe_end - pe_start) / 8;
759 amdgpu_vm_update_pages(adev, vm_update_params, pe_start,
760 addr, count, AMDGPU_GPU_PAGE_SIZE,
761 flags);
762 return;
763 }
764
765 /* handle the 4K area at the beginning */
766 if (pe_start != frag_start) {
767 count = (frag_start - pe_start) / 8;
768 amdgpu_vm_update_pages(adev, vm_update_params, pe_start, addr,
769 count, AMDGPU_GPU_PAGE_SIZE, flags);
770 addr += AMDGPU_GPU_PAGE_SIZE * count;
771 }
772
773 /* handle the area in the middle */
774 count = (frag_end - frag_start) / 8;
775 amdgpu_vm_update_pages(adev, vm_update_params, frag_start, addr, count,
776 AMDGPU_GPU_PAGE_SIZE, flags | frag_flags);
777 729
778 /* handle the 4K area at the end */ 730 r = amdgpu_vm_update_pd_or_shadow(adev, vm, true);
779 if (frag_end != pe_end) { 731 if (r)
780 addr += AMDGPU_GPU_PAGE_SIZE * count; 732 return r;
781 count = (pe_end - frag_end) / 8; 733 return amdgpu_vm_update_pd_or_shadow(adev, vm, false);
782 amdgpu_vm_update_pages(adev, vm_update_params, frag_end, addr,
783 count, AMDGPU_GPU_PAGE_SIZE, flags);
784 }
785} 734}
786 735
787/** 736/**
788 * amdgpu_vm_update_ptes - make sure that page tables are valid 737 * amdgpu_vm_update_ptes - make sure that page tables are valid
789 * 738 *
790 * @adev: amdgpu_device pointer 739 * @params: see amdgpu_pte_update_params definition
791 * @vm_update_params: see amdgpu_vm_update_params definition
792 * @vm: requested vm 740 * @vm: requested vm
793 * @start: start of GPU address range 741 * @start: start of GPU address range
794 * @end: end of GPU address range 742 * @end: end of GPU address range
@@ -797,16 +745,14 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev,
797 * 745 *
798 * Update the page tables in the range @start - @end. 746 * Update the page tables in the range @start - @end.
799 */ 747 */
800static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, 748static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
801 struct amdgpu_vm_update_params
802 *vm_update_params,
803 struct amdgpu_vm *vm, 749 struct amdgpu_vm *vm,
804 uint64_t start, uint64_t end, 750 uint64_t start, uint64_t end,
805 uint64_t dst, uint32_t flags) 751 uint64_t dst, uint32_t flags)
806{ 752{
807 const uint64_t mask = AMDGPU_VM_PTE_COUNT - 1; 753 const uint64_t mask = AMDGPU_VM_PTE_COUNT - 1;
808 754
809 uint64_t cur_pe_start, cur_pe_end, cur_dst; 755 uint64_t cur_pe_start, cur_nptes, cur_dst;
810 uint64_t addr; /* next GPU address to be updated */ 756 uint64_t addr; /* next GPU address to be updated */
811 uint64_t pt_idx; 757 uint64_t pt_idx;
812 struct amdgpu_bo *pt; 758 struct amdgpu_bo *pt;
@@ -817,7 +763,11 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
817 addr = start; 763 addr = start;
818 pt_idx = addr >> amdgpu_vm_block_size; 764 pt_idx = addr >> amdgpu_vm_block_size;
819 pt = vm->page_tables[pt_idx].entry.robj; 765 pt = vm->page_tables[pt_idx].entry.robj;
820 766 if (params->shadow) {
767 if (!pt->shadow)
768 return;
769 pt = vm->page_tables[pt_idx].entry.robj->shadow;
770 }
821 if ((addr & ~mask) == (end & ~mask)) 771 if ((addr & ~mask) == (end & ~mask))
822 nptes = end - addr; 772 nptes = end - addr;
823 else 773 else
@@ -825,7 +775,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
825 775
826 cur_pe_start = amdgpu_bo_gpu_offset(pt); 776 cur_pe_start = amdgpu_bo_gpu_offset(pt);
827 cur_pe_start += (addr & mask) * 8; 777 cur_pe_start += (addr & mask) * 8;
828 cur_pe_end = cur_pe_start + 8 * nptes; 778 cur_nptes = nptes;
829 cur_dst = dst; 779 cur_dst = dst;
830 780
831 /* for next ptb*/ 781 /* for next ptb*/
@@ -836,6 +786,11 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
836 while (addr < end) { 786 while (addr < end) {
837 pt_idx = addr >> amdgpu_vm_block_size; 787 pt_idx = addr >> amdgpu_vm_block_size;
838 pt = vm->page_tables[pt_idx].entry.robj; 788 pt = vm->page_tables[pt_idx].entry.robj;
789 if (params->shadow) {
790 if (!pt->shadow)
791 return;
792 pt = vm->page_tables[pt_idx].entry.robj->shadow;
793 }
839 794
840 if ((addr & ~mask) == (end & ~mask)) 795 if ((addr & ~mask) == (end & ~mask))
841 nptes = end - addr; 796 nptes = end - addr;
@@ -845,19 +800,19 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
845 next_pe_start = amdgpu_bo_gpu_offset(pt); 800 next_pe_start = amdgpu_bo_gpu_offset(pt);
846 next_pe_start += (addr & mask) * 8; 801 next_pe_start += (addr & mask) * 8;
847 802
848 if (cur_pe_end == next_pe_start) { 803 if ((cur_pe_start + 8 * cur_nptes) == next_pe_start &&
804 ((cur_nptes + nptes) <= AMDGPU_VM_MAX_UPDATE_SIZE)) {
849 /* The next ptb is consecutive to current ptb. 805 /* The next ptb is consecutive to current ptb.
850 * Don't call amdgpu_vm_frag_ptes now. 806 * Don't call the update function now.
851 * Will update two ptbs together in future. 807 * Will update two ptbs together in future.
852 */ 808 */
853 cur_pe_end += 8 * nptes; 809 cur_nptes += nptes;
854 } else { 810 } else {
855 amdgpu_vm_frag_ptes(adev, vm_update_params, 811 params->func(params, cur_pe_start, cur_dst, cur_nptes,
856 cur_pe_start, cur_pe_end, 812 AMDGPU_GPU_PAGE_SIZE, flags);
857 cur_dst, flags);
858 813
859 cur_pe_start = next_pe_start; 814 cur_pe_start = next_pe_start;
860 cur_pe_end = next_pe_start + 8 * nptes; 815 cur_nptes = nptes;
861 cur_dst = dst; 816 cur_dst = dst;
862 } 817 }
863 818
@@ -866,8 +821,79 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
866 dst += nptes * AMDGPU_GPU_PAGE_SIZE; 821 dst += nptes * AMDGPU_GPU_PAGE_SIZE;
867 } 822 }
868 823
869 amdgpu_vm_frag_ptes(adev, vm_update_params, cur_pe_start, 824 params->func(params, cur_pe_start, cur_dst, cur_nptes,
870 cur_pe_end, cur_dst, flags); 825 AMDGPU_GPU_PAGE_SIZE, flags);
826}
827
828/*
829 * amdgpu_vm_frag_ptes - add fragment information to PTEs
830 *
831 * @params: see amdgpu_pte_update_params definition
832 * @vm: requested vm
833 * @start: first PTE to handle
834 * @end: last PTE to handle
835 * @dst: addr those PTEs should point to
836 * @flags: hw mapping flags
837 */
838static void amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params,
839 struct amdgpu_vm *vm,
840 uint64_t start, uint64_t end,
841 uint64_t dst, uint32_t flags)
842{
843 /**
844 * The MC L1 TLB supports variable sized pages, based on a fragment
845 * field in the PTE. When this field is set to a non-zero value, page
846 * granularity is increased from 4KB to (1 << (12 + frag)). The PTE
847 * flags are considered valid for all PTEs within the fragment range
848 * and corresponding mappings are assumed to be physically contiguous.
849 *
850 * The L1 TLB can store a single PTE for the whole fragment,
851 * significantly increasing the space available for translation
852 * caching. This leads to large improvements in throughput when the
853 * TLB is under pressure.
854 *
855 * The L2 TLB distributes small and large fragments into two
856 * asymmetric partitions. The large fragment cache is significantly
857 * larger. Thus, we try to use large fragments wherever possible.
858 * Userspace can support this by aligning virtual base address and
859 * allocation size to the fragment size.
860 */
861
862 const uint64_t frag_align = 1 << AMDGPU_LOG2_PAGES_PER_FRAG;
863
864 uint64_t frag_start = ALIGN(start, frag_align);
865 uint64_t frag_end = end & ~(frag_align - 1);
866
867 uint32_t frag;
868
869 /* system pages are non continuously */
870 if (params->src || !(flags & AMDGPU_PTE_VALID) ||
871 (frag_start >= frag_end)) {
872
873 amdgpu_vm_update_ptes(params, vm, start, end, dst, flags);
874 return;
875 }
876
877 /* use more than 64KB fragment size if possible */
878 frag = lower_32_bits(frag_start | frag_end);
879 frag = likely(frag) ? __ffs(frag) : 31;
880
881 /* handle the 4K area at the beginning */
882 if (start != frag_start) {
883 amdgpu_vm_update_ptes(params, vm, start, frag_start,
884 dst, flags);
885 dst += (frag_start - start) * AMDGPU_GPU_PAGE_SIZE;
886 }
887
888 /* handle the area in the middle */
889 amdgpu_vm_update_ptes(params, vm, frag_start, frag_end, dst,
890 flags | AMDGPU_PTE_FRAG(frag));
891
892 /* handle the 4K area at the end */
893 if (frag_end != end) {
894 dst += (frag_end - frag_start) * AMDGPU_GPU_PAGE_SIZE;
895 amdgpu_vm_update_ptes(params, vm, frag_end, end, dst, flags);
896 }
871} 897}
872 898
873/** 899/**
@@ -900,14 +926,19 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
900 void *owner = AMDGPU_FENCE_OWNER_VM; 926 void *owner = AMDGPU_FENCE_OWNER_VM;
901 unsigned nptes, ncmds, ndw; 927 unsigned nptes, ncmds, ndw;
902 struct amdgpu_job *job; 928 struct amdgpu_job *job;
903 struct amdgpu_vm_update_params vm_update_params; 929 struct amdgpu_pte_update_params params;
904 struct fence *f = NULL; 930 struct fence *f = NULL;
905 int r; 931 int r;
906 932
933 memset(&params, 0, sizeof(params));
934 params.adev = adev;
935 params.src = src;
936
907 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); 937 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched);
908 memset(&vm_update_params, 0, sizeof(vm_update_params)); 938
909 vm_update_params.src = src; 939 memset(&params, 0, sizeof(params));
910 vm_update_params.pages_addr = pages_addr; 940 params.adev = adev;
941 params.src = src;
911 942
912 /* sync to everything on unmapping */ 943 /* sync to everything on unmapping */
913 if (!(flags & AMDGPU_PTE_VALID)) 944 if (!(flags & AMDGPU_PTE_VALID))
@@ -924,30 +955,52 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
924 /* padding, etc. */ 955 /* padding, etc. */
925 ndw = 64; 956 ndw = 64;
926 957
927 if (vm_update_params.src) { 958 if (src) {
928 /* only copy commands needed */ 959 /* only copy commands needed */
929 ndw += ncmds * 7; 960 ndw += ncmds * 7;
930 961
931 } else if (vm_update_params.pages_addr) { 962 params.func = amdgpu_vm_do_copy_ptes;
932 /* header for write data commands */ 963
933 ndw += ncmds * 4; 964 } else if (pages_addr) {
965 /* copy commands needed */
966 ndw += ncmds * 7;
934 967
935 /* body of write data command */ 968 /* and also PTEs */
936 ndw += nptes * 2; 969 ndw += nptes * 2;
937 970
971 params.func = amdgpu_vm_do_copy_ptes;
972
938 } else { 973 } else {
939 /* set page commands needed */ 974 /* set page commands needed */
940 ndw += ncmds * 10; 975 ndw += ncmds * 10;
941 976
942 /* two extra commands for begin/end of fragment */ 977 /* two extra commands for begin/end of fragment */
943 ndw += 2 * 10; 978 ndw += 2 * 10;
979
980 params.func = amdgpu_vm_do_set_ptes;
944 } 981 }
945 982
946 r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job); 983 r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job);
947 if (r) 984 if (r)
948 return r; 985 return r;
949 986
950 vm_update_params.ib = &job->ibs[0]; 987 params.ib = &job->ibs[0];
988
989 if (!src && pages_addr) {
990 uint64_t *pte;
991 unsigned i;
992
993 /* Put the PTEs at the end of the IB. */
994 i = ndw - nptes * 2;
995 pte= (uint64_t *)&(job->ibs->ptr[i]);
996 params.src = job->ibs->gpu_addr + i * 4;
997
998 for (i = 0; i < nptes; ++i) {
999 pte[i] = amdgpu_vm_map_gart(pages_addr, addr + i *
1000 AMDGPU_GPU_PAGE_SIZE);
1001 pte[i] |= flags;
1002 }
1003 }
951 1004
952 r = amdgpu_sync_fence(adev, &job->sync, exclusive); 1005 r = amdgpu_sync_fence(adev, &job->sync, exclusive);
953 if (r) 1006 if (r)
@@ -962,11 +1015,13 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
962 if (r) 1015 if (r)
963 goto error_free; 1016 goto error_free;
964 1017
965 amdgpu_vm_update_ptes(adev, &vm_update_params, vm, start, 1018 params.shadow = true;
966 last + 1, addr, flags); 1019 amdgpu_vm_frag_ptes(&params, vm, start, last + 1, addr, flags);
1020 params.shadow = false;
1021 amdgpu_vm_frag_ptes(&params, vm, start, last + 1, addr, flags);
967 1022
968 amdgpu_ring_pad_ib(ring, vm_update_params.ib); 1023 amdgpu_ring_pad_ib(ring, params.ib);
969 WARN_ON(vm_update_params.ib->length_dw > ndw); 1024 WARN_ON(params.ib->length_dw > ndw);
970 r = amdgpu_job_submit(job, ring, &vm->entity, 1025 r = amdgpu_job_submit(job, ring, &vm->entity,
971 AMDGPU_FENCE_OWNER_VM, &f); 1026 AMDGPU_FENCE_OWNER_VM, &f);
972 if (r) 1027 if (r)
@@ -1062,28 +1117,32 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
1062 * 1117 *
1063 * @adev: amdgpu_device pointer 1118 * @adev: amdgpu_device pointer
1064 * @bo_va: requested BO and VM object 1119 * @bo_va: requested BO and VM object
1065 * @mem: ttm mem 1120 * @clear: if true clear the entries
1066 * 1121 *
1067 * Fill in the page table entries for @bo_va. 1122 * Fill in the page table entries for @bo_va.
1068 * Returns 0 for success, -EINVAL for failure. 1123 * Returns 0 for success, -EINVAL for failure.
1069 *
1070 * Object have to be reserved and mutex must be locked!
1071 */ 1124 */
1072int amdgpu_vm_bo_update(struct amdgpu_device *adev, 1125int amdgpu_vm_bo_update(struct amdgpu_device *adev,
1073 struct amdgpu_bo_va *bo_va, 1126 struct amdgpu_bo_va *bo_va,
1074 struct ttm_mem_reg *mem) 1127 bool clear)
1075{ 1128{
1076 struct amdgpu_vm *vm = bo_va->vm; 1129 struct amdgpu_vm *vm = bo_va->vm;
1077 struct amdgpu_bo_va_mapping *mapping; 1130 struct amdgpu_bo_va_mapping *mapping;
1078 dma_addr_t *pages_addr = NULL; 1131 dma_addr_t *pages_addr = NULL;
1079 uint32_t gtt_flags, flags; 1132 uint32_t gtt_flags, flags;
1133 struct ttm_mem_reg *mem;
1080 struct fence *exclusive; 1134 struct fence *exclusive;
1081 uint64_t addr; 1135 uint64_t addr;
1082 int r; 1136 int r;
1083 1137
1084 if (mem) { 1138 if (clear) {
1139 mem = NULL;
1140 addr = 0;
1141 exclusive = NULL;
1142 } else {
1085 struct ttm_dma_tt *ttm; 1143 struct ttm_dma_tt *ttm;
1086 1144
1145 mem = &bo_va->bo->tbo.mem;
1087 addr = (u64)mem->start << PAGE_SHIFT; 1146 addr = (u64)mem->start << PAGE_SHIFT;
1088 switch (mem->mem_type) { 1147 switch (mem->mem_type) {
1089 case TTM_PL_TT: 1148 case TTM_PL_TT:
@@ -1101,9 +1160,6 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
1101 } 1160 }
1102 1161
1103 exclusive = reservation_object_get_excl(bo_va->bo->tbo.resv); 1162 exclusive = reservation_object_get_excl(bo_va->bo->tbo.resv);
1104 } else {
1105 addr = 0;
1106 exclusive = NULL;
1107 } 1163 }
1108 1164
1109 flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem); 1165 flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem);
@@ -1134,7 +1190,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
1134 spin_lock(&vm->status_lock); 1190 spin_lock(&vm->status_lock);
1135 list_splice_init(&bo_va->invalids, &bo_va->valids); 1191 list_splice_init(&bo_va->invalids, &bo_va->valids);
1136 list_del_init(&bo_va->vm_status); 1192 list_del_init(&bo_va->vm_status);
1137 if (!mem) 1193 if (clear)
1138 list_add(&bo_va->vm_status, &vm->cleared); 1194 list_add(&bo_va->vm_status, &vm->cleared);
1139 spin_unlock(&vm->status_lock); 1195 spin_unlock(&vm->status_lock);
1140 1196
@@ -1197,7 +1253,7 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
1197 struct amdgpu_bo_va, vm_status); 1253 struct amdgpu_bo_va, vm_status);
1198 spin_unlock(&vm->status_lock); 1254 spin_unlock(&vm->status_lock);
1199 1255
1200 r = amdgpu_vm_bo_update(adev, bo_va, NULL); 1256 r = amdgpu_vm_bo_update(adev, bo_va, true);
1201 if (r) 1257 if (r)
1202 return r; 1258 return r;
1203 1259
@@ -1342,7 +1398,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
1342 r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8, 1398 r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8,
1343 AMDGPU_GPU_PAGE_SIZE, true, 1399 AMDGPU_GPU_PAGE_SIZE, true,
1344 AMDGPU_GEM_DOMAIN_VRAM, 1400 AMDGPU_GEM_DOMAIN_VRAM,
1345 AMDGPU_GEM_CREATE_NO_CPU_ACCESS, 1401 AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
1402 AMDGPU_GEM_CREATE_SHADOW,
1346 NULL, resv, &pt); 1403 NULL, resv, &pt);
1347 if (r) 1404 if (r)
1348 goto error_free; 1405 goto error_free;
@@ -1541,7 +1598,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
1541 1598
1542 r = amdgpu_bo_create(adev, pd_size, align, true, 1599 r = amdgpu_bo_create(adev, pd_size, align, true,
1543 AMDGPU_GEM_DOMAIN_VRAM, 1600 AMDGPU_GEM_DOMAIN_VRAM,
1544 AMDGPU_GEM_CREATE_NO_CPU_ACCESS, 1601 AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
1602 AMDGPU_GEM_CREATE_SHADOW,
1545 NULL, NULL, &vm->page_directory); 1603 NULL, NULL, &vm->page_directory);
1546 if (r) 1604 if (r)
1547 goto error_free_sched_entity; 1605 goto error_free_sched_entity;
@@ -1597,10 +1655,16 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
1597 kfree(mapping); 1655 kfree(mapping);
1598 } 1656 }
1599 1657
1600 for (i = 0; i < amdgpu_vm_num_pdes(adev); i++) 1658 for (i = 0; i < amdgpu_vm_num_pdes(adev); i++) {
1659 if (vm->page_tables[i].entry.robj &&
1660 vm->page_tables[i].entry.robj->shadow)
1661 amdgpu_bo_unref(&vm->page_tables[i].entry.robj->shadow);
1601 amdgpu_bo_unref(&vm->page_tables[i].entry.robj); 1662 amdgpu_bo_unref(&vm->page_tables[i].entry.robj);
1663 }
1602 drm_free_large(vm->page_tables); 1664 drm_free_large(vm->page_tables);
1603 1665
1666 if (vm->page_directory->shadow)
1667 amdgpu_bo_unref(&vm->page_directory->shadow);
1604 amdgpu_bo_unref(&vm->page_directory); 1668 amdgpu_bo_unref(&vm->page_directory);
1605 fence_put(vm->page_directory_fence); 1669 fence_put(vm->page_directory_fence);
1606} 1670}
diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
index 7f85c2c1d681..f81068ba4cc6 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
@@ -88,7 +88,6 @@ static int amdgpu_atombios_dp_process_aux_ch(struct amdgpu_i2c_chan *chan,
88 88
89 /* timeout */ 89 /* timeout */
90 if (args.v2.ucReplyStatus == 1) { 90 if (args.v2.ucReplyStatus == 1) {
91 DRM_DEBUG_KMS("dp_aux_ch timeout\n");
92 r = -ETIMEDOUT; 91 r = -ETIMEDOUT;
93 goto done; 92 goto done;
94 } 93 }
@@ -339,22 +338,21 @@ int amdgpu_atombios_dp_get_dpcd(struct amdgpu_connector *amdgpu_connector)
339{ 338{
340 struct amdgpu_connector_atom_dig *dig_connector = amdgpu_connector->con_priv; 339 struct amdgpu_connector_atom_dig *dig_connector = amdgpu_connector->con_priv;
341 u8 msg[DP_DPCD_SIZE]; 340 u8 msg[DP_DPCD_SIZE];
342 int ret, i; 341 int ret;
343 342
344 for (i = 0; i < 7; i++) { 343 ret = drm_dp_dpcd_read(&amdgpu_connector->ddc_bus->aux, DP_DPCD_REV,
345 ret = drm_dp_dpcd_read(&amdgpu_connector->ddc_bus->aux, DP_DPCD_REV, msg, 344 msg, DP_DPCD_SIZE);
346 DP_DPCD_SIZE); 345 if (ret == DP_DPCD_SIZE) {
347 if (ret == DP_DPCD_SIZE) { 346 memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
348 memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
349 347
350 DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd), 348 DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd),
351 dig_connector->dpcd); 349 dig_connector->dpcd);
352 350
353 amdgpu_atombios_dp_probe_oui(amdgpu_connector); 351 amdgpu_atombios_dp_probe_oui(amdgpu_connector);
354 352
355 return 0; 353 return 0;
356 }
357 } 354 }
355
358 dig_connector->dpcd[0] = 0; 356 dig_connector->dpcd[0] = 0;
359 return -EINVAL; 357 return -EINVAL;
360} 358}
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
index a5c94b482459..a0d63a293bb0 100644
--- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
@@ -5874,7 +5874,10 @@ static int ci_dpm_init(struct amdgpu_device *adev)
5874 pi->pcie_dpm_key_disabled = 0; 5874 pi->pcie_dpm_key_disabled = 0;
5875 pi->thermal_sclk_dpm_enabled = 0; 5875 pi->thermal_sclk_dpm_enabled = 0;
5876 5876
5877 pi->caps_sclk_ds = true; 5877 if (amdgpu_sclk_deep_sleep_en)
5878 pi->caps_sclk_ds = true;
5879 else
5880 pi->caps_sclk_ds = false;
5878 5881
5879 pi->mclk_strobe_mode_threshold = 40000; 5882 pi->mclk_strobe_mode_threshold = 40000;
5880 pi->mclk_stutter_mode_threshold = 40000; 5883 pi->mclk_stutter_mode_threshold = 40000;
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 4efc901f658c..825de800b798 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -67,6 +67,7 @@
67 67
68#include "amdgpu_amdkfd.h" 68#include "amdgpu_amdkfd.h"
69#include "amdgpu_powerplay.h" 69#include "amdgpu_powerplay.h"
70#include "dce_virtual.h"
70 71
71/* 72/*
72 * Indirect registers accessor 73 * Indirect registers accessor
@@ -1708,6 +1709,74 @@ static const struct amdgpu_ip_block_version bonaire_ip_blocks[] =
1708 }, 1709 },
1709}; 1710};
1710 1711
1712static const struct amdgpu_ip_block_version bonaire_ip_blocks_vd[] =
1713{
1714 /* ORDER MATTERS! */
1715 {
1716 .type = AMD_IP_BLOCK_TYPE_COMMON,
1717 .major = 1,
1718 .minor = 0,
1719 .rev = 0,
1720 .funcs = &cik_common_ip_funcs,
1721 },
1722 {
1723 .type = AMD_IP_BLOCK_TYPE_GMC,
1724 .major = 7,
1725 .minor = 0,
1726 .rev = 0,
1727 .funcs = &gmc_v7_0_ip_funcs,
1728 },
1729 {
1730 .type = AMD_IP_BLOCK_TYPE_IH,
1731 .major = 2,
1732 .minor = 0,
1733 .rev = 0,
1734 .funcs = &cik_ih_ip_funcs,
1735 },
1736 {
1737 .type = AMD_IP_BLOCK_TYPE_SMC,
1738 .major = 7,
1739 .minor = 0,
1740 .rev = 0,
1741 .funcs = &amdgpu_pp_ip_funcs,
1742 },
1743 {
1744 .type = AMD_IP_BLOCK_TYPE_DCE,
1745 .major = 8,
1746 .minor = 2,
1747 .rev = 0,
1748 .funcs = &dce_virtual_ip_funcs,
1749 },
1750 {
1751 .type = AMD_IP_BLOCK_TYPE_GFX,
1752 .major = 7,
1753 .minor = 2,
1754 .rev = 0,
1755 .funcs = &gfx_v7_0_ip_funcs,
1756 },
1757 {
1758 .type = AMD_IP_BLOCK_TYPE_SDMA,
1759 .major = 2,
1760 .minor = 0,
1761 .rev = 0,
1762 .funcs = &cik_sdma_ip_funcs,
1763 },
1764 {
1765 .type = AMD_IP_BLOCK_TYPE_UVD,
1766 .major = 4,
1767 .minor = 2,
1768 .rev = 0,
1769 .funcs = &uvd_v4_2_ip_funcs,
1770 },
1771 {
1772 .type = AMD_IP_BLOCK_TYPE_VCE,
1773 .major = 2,
1774 .minor = 0,
1775 .rev = 0,
1776 .funcs = &vce_v2_0_ip_funcs,
1777 },
1778};
1779
1711static const struct amdgpu_ip_block_version hawaii_ip_blocks[] = 1780static const struct amdgpu_ip_block_version hawaii_ip_blocks[] =
1712{ 1781{
1713 /* ORDER MATTERS! */ 1782 /* ORDER MATTERS! */
@@ -1776,6 +1845,74 @@ static const struct amdgpu_ip_block_version hawaii_ip_blocks[] =
1776 }, 1845 },
1777}; 1846};
1778 1847
1848static const struct amdgpu_ip_block_version hawaii_ip_blocks_vd[] =
1849{
1850 /* ORDER MATTERS! */
1851 {
1852 .type = AMD_IP_BLOCK_TYPE_COMMON,
1853 .major = 1,
1854 .minor = 0,
1855 .rev = 0,
1856 .funcs = &cik_common_ip_funcs,
1857 },
1858 {
1859 .type = AMD_IP_BLOCK_TYPE_GMC,
1860 .major = 7,
1861 .minor = 0,
1862 .rev = 0,
1863 .funcs = &gmc_v7_0_ip_funcs,
1864 },
1865 {
1866 .type = AMD_IP_BLOCK_TYPE_IH,
1867 .major = 2,
1868 .minor = 0,
1869 .rev = 0,
1870 .funcs = &cik_ih_ip_funcs,
1871 },
1872 {
1873 .type = AMD_IP_BLOCK_TYPE_SMC,
1874 .major = 7,
1875 .minor = 0,
1876 .rev = 0,
1877 .funcs = &amdgpu_pp_ip_funcs,
1878 },
1879 {
1880 .type = AMD_IP_BLOCK_TYPE_DCE,
1881 .major = 8,
1882 .minor = 5,
1883 .rev = 0,
1884 .funcs = &dce_virtual_ip_funcs,
1885 },
1886 {
1887 .type = AMD_IP_BLOCK_TYPE_GFX,
1888 .major = 7,
1889 .minor = 3,
1890 .rev = 0,
1891 .funcs = &gfx_v7_0_ip_funcs,
1892 },
1893 {
1894 .type = AMD_IP_BLOCK_TYPE_SDMA,
1895 .major = 2,
1896 .minor = 0,
1897 .rev = 0,
1898 .funcs = &cik_sdma_ip_funcs,
1899 },
1900 {
1901 .type = AMD_IP_BLOCK_TYPE_UVD,
1902 .major = 4,
1903 .minor = 2,
1904 .rev = 0,
1905 .funcs = &uvd_v4_2_ip_funcs,
1906 },
1907 {
1908 .type = AMD_IP_BLOCK_TYPE_VCE,
1909 .major = 2,
1910 .minor = 0,
1911 .rev = 0,
1912 .funcs = &vce_v2_0_ip_funcs,
1913 },
1914};
1915
1779static const struct amdgpu_ip_block_version kabini_ip_blocks[] = 1916static const struct amdgpu_ip_block_version kabini_ip_blocks[] =
1780{ 1917{
1781 /* ORDER MATTERS! */ 1918 /* ORDER MATTERS! */
@@ -1844,6 +1981,74 @@ static const struct amdgpu_ip_block_version kabini_ip_blocks[] =
1844 }, 1981 },
1845}; 1982};
1846 1983
1984static const struct amdgpu_ip_block_version kabini_ip_blocks_vd[] =
1985{
1986 /* ORDER MATTERS! */
1987 {
1988 .type = AMD_IP_BLOCK_TYPE_COMMON,
1989 .major = 1,
1990 .minor = 0,
1991 .rev = 0,
1992 .funcs = &cik_common_ip_funcs,
1993 },
1994 {
1995 .type = AMD_IP_BLOCK_TYPE_GMC,
1996 .major = 7,
1997 .minor = 0,
1998 .rev = 0,
1999 .funcs = &gmc_v7_0_ip_funcs,
2000 },
2001 {
2002 .type = AMD_IP_BLOCK_TYPE_IH,
2003 .major = 2,
2004 .minor = 0,
2005 .rev = 0,
2006 .funcs = &cik_ih_ip_funcs,
2007 },
2008 {
2009 .type = AMD_IP_BLOCK_TYPE_SMC,
2010 .major = 7,
2011 .minor = 0,
2012 .rev = 0,
2013 .funcs = &amdgpu_pp_ip_funcs,
2014 },
2015 {
2016 .type = AMD_IP_BLOCK_TYPE_DCE,
2017 .major = 8,
2018 .minor = 3,
2019 .rev = 0,
2020 .funcs = &dce_virtual_ip_funcs,
2021 },
2022 {
2023 .type = AMD_IP_BLOCK_TYPE_GFX,
2024 .major = 7,
2025 .minor = 2,
2026 .rev = 0,
2027 .funcs = &gfx_v7_0_ip_funcs,
2028 },
2029 {
2030 .type = AMD_IP_BLOCK_TYPE_SDMA,
2031 .major = 2,
2032 .minor = 0,
2033 .rev = 0,
2034 .funcs = &cik_sdma_ip_funcs,
2035 },
2036 {
2037 .type = AMD_IP_BLOCK_TYPE_UVD,
2038 .major = 4,
2039 .minor = 2,
2040 .rev = 0,
2041 .funcs = &uvd_v4_2_ip_funcs,
2042 },
2043 {
2044 .type = AMD_IP_BLOCK_TYPE_VCE,
2045 .major = 2,
2046 .minor = 0,
2047 .rev = 0,
2048 .funcs = &vce_v2_0_ip_funcs,
2049 },
2050};
2051
1847static const struct amdgpu_ip_block_version mullins_ip_blocks[] = 2052static const struct amdgpu_ip_block_version mullins_ip_blocks[] =
1848{ 2053{
1849 /* ORDER MATTERS! */ 2054 /* ORDER MATTERS! */
@@ -1912,6 +2117,74 @@ static const struct amdgpu_ip_block_version mullins_ip_blocks[] =
1912 }, 2117 },
1913}; 2118};
1914 2119
2120static const struct amdgpu_ip_block_version mullins_ip_blocks_vd[] =
2121{
2122 /* ORDER MATTERS! */
2123 {
2124 .type = AMD_IP_BLOCK_TYPE_COMMON,
2125 .major = 1,
2126 .minor = 0,
2127 .rev = 0,
2128 .funcs = &cik_common_ip_funcs,
2129 },
2130 {
2131 .type = AMD_IP_BLOCK_TYPE_GMC,
2132 .major = 7,
2133 .minor = 0,
2134 .rev = 0,
2135 .funcs = &gmc_v7_0_ip_funcs,
2136 },
2137 {
2138 .type = AMD_IP_BLOCK_TYPE_IH,
2139 .major = 2,
2140 .minor = 0,
2141 .rev = 0,
2142 .funcs = &cik_ih_ip_funcs,
2143 },
2144 {
2145 .type = AMD_IP_BLOCK_TYPE_SMC,
2146 .major = 7,
2147 .minor = 0,
2148 .rev = 0,
2149 .funcs = &amdgpu_pp_ip_funcs,
2150 },
2151 {
2152 .type = AMD_IP_BLOCK_TYPE_DCE,
2153 .major = 8,
2154 .minor = 3,
2155 .rev = 0,
2156 .funcs = &dce_virtual_ip_funcs,
2157 },
2158 {
2159 .type = AMD_IP_BLOCK_TYPE_GFX,
2160 .major = 7,
2161 .minor = 2,
2162 .rev = 0,
2163 .funcs = &gfx_v7_0_ip_funcs,
2164 },
2165 {
2166 .type = AMD_IP_BLOCK_TYPE_SDMA,
2167 .major = 2,
2168 .minor = 0,
2169 .rev = 0,
2170 .funcs = &cik_sdma_ip_funcs,
2171 },
2172 {
2173 .type = AMD_IP_BLOCK_TYPE_UVD,
2174 .major = 4,
2175 .minor = 2,
2176 .rev = 0,
2177 .funcs = &uvd_v4_2_ip_funcs,
2178 },
2179 {
2180 .type = AMD_IP_BLOCK_TYPE_VCE,
2181 .major = 2,
2182 .minor = 0,
2183 .rev = 0,
2184 .funcs = &vce_v2_0_ip_funcs,
2185 },
2186};
2187
1915static const struct amdgpu_ip_block_version kaveri_ip_blocks[] = 2188static const struct amdgpu_ip_block_version kaveri_ip_blocks[] =
1916{ 2189{
1917 /* ORDER MATTERS! */ 2190 /* ORDER MATTERS! */
@@ -1980,32 +2253,128 @@ static const struct amdgpu_ip_block_version kaveri_ip_blocks[] =
1980 }, 2253 },
1981}; 2254};
1982 2255
2256static const struct amdgpu_ip_block_version kaveri_ip_blocks_vd[] =
2257{
2258 /* ORDER MATTERS! */
2259 {
2260 .type = AMD_IP_BLOCK_TYPE_COMMON,
2261 .major = 1,
2262 .minor = 0,
2263 .rev = 0,
2264 .funcs = &cik_common_ip_funcs,
2265 },
2266 {
2267 .type = AMD_IP_BLOCK_TYPE_GMC,
2268 .major = 7,
2269 .minor = 0,
2270 .rev = 0,
2271 .funcs = &gmc_v7_0_ip_funcs,
2272 },
2273 {
2274 .type = AMD_IP_BLOCK_TYPE_IH,
2275 .major = 2,
2276 .minor = 0,
2277 .rev = 0,
2278 .funcs = &cik_ih_ip_funcs,
2279 },
2280 {
2281 .type = AMD_IP_BLOCK_TYPE_SMC,
2282 .major = 7,
2283 .minor = 0,
2284 .rev = 0,
2285 .funcs = &amdgpu_pp_ip_funcs,
2286 },
2287 {
2288 .type = AMD_IP_BLOCK_TYPE_DCE,
2289 .major = 8,
2290 .minor = 1,
2291 .rev = 0,
2292 .funcs = &dce_virtual_ip_funcs,
2293 },
2294 {
2295 .type = AMD_IP_BLOCK_TYPE_GFX,
2296 .major = 7,
2297 .minor = 1,
2298 .rev = 0,
2299 .funcs = &gfx_v7_0_ip_funcs,
2300 },
2301 {
2302 .type = AMD_IP_BLOCK_TYPE_SDMA,
2303 .major = 2,
2304 .minor = 0,
2305 .rev = 0,
2306 .funcs = &cik_sdma_ip_funcs,
2307 },
2308 {
2309 .type = AMD_IP_BLOCK_TYPE_UVD,
2310 .major = 4,
2311 .minor = 2,
2312 .rev = 0,
2313 .funcs = &uvd_v4_2_ip_funcs,
2314 },
2315 {
2316 .type = AMD_IP_BLOCK_TYPE_VCE,
2317 .major = 2,
2318 .minor = 0,
2319 .rev = 0,
2320 .funcs = &vce_v2_0_ip_funcs,
2321 },
2322};
2323
1983int cik_set_ip_blocks(struct amdgpu_device *adev) 2324int cik_set_ip_blocks(struct amdgpu_device *adev)
1984{ 2325{
1985 switch (adev->asic_type) { 2326 if (adev->enable_virtual_display) {
1986 case CHIP_BONAIRE: 2327 switch (adev->asic_type) {
1987 adev->ip_blocks = bonaire_ip_blocks; 2328 case CHIP_BONAIRE:
1988 adev->num_ip_blocks = ARRAY_SIZE(bonaire_ip_blocks); 2329 adev->ip_blocks = bonaire_ip_blocks_vd;
1989 break; 2330 adev->num_ip_blocks = ARRAY_SIZE(bonaire_ip_blocks_vd);
1990 case CHIP_HAWAII: 2331 break;
1991 adev->ip_blocks = hawaii_ip_blocks; 2332 case CHIP_HAWAII:
1992 adev->num_ip_blocks = ARRAY_SIZE(hawaii_ip_blocks); 2333 adev->ip_blocks = hawaii_ip_blocks_vd;
1993 break; 2334 adev->num_ip_blocks = ARRAY_SIZE(hawaii_ip_blocks_vd);
1994 case CHIP_KAVERI: 2335 break;
1995 adev->ip_blocks = kaveri_ip_blocks; 2336 case CHIP_KAVERI:
1996 adev->num_ip_blocks = ARRAY_SIZE(kaveri_ip_blocks); 2337 adev->ip_blocks = kaveri_ip_blocks_vd;
1997 break; 2338 adev->num_ip_blocks = ARRAY_SIZE(kaveri_ip_blocks_vd);
1998 case CHIP_KABINI: 2339 break;
1999 adev->ip_blocks = kabini_ip_blocks; 2340 case CHIP_KABINI:
2000 adev->num_ip_blocks = ARRAY_SIZE(kabini_ip_blocks); 2341 adev->ip_blocks = kabini_ip_blocks_vd;
2001 break; 2342 adev->num_ip_blocks = ARRAY_SIZE(kabini_ip_blocks_vd);
2002 case CHIP_MULLINS: 2343 break;
2003 adev->ip_blocks = mullins_ip_blocks; 2344 case CHIP_MULLINS:
2004 adev->num_ip_blocks = ARRAY_SIZE(mullins_ip_blocks); 2345 adev->ip_blocks = mullins_ip_blocks_vd;
2005 break; 2346 adev->num_ip_blocks = ARRAY_SIZE(mullins_ip_blocks_vd);
2006 default: 2347 break;
2007 /* FIXME: not supported yet */ 2348 default:
2008 return -EINVAL; 2349 /* FIXME: not supported yet */
2350 return -EINVAL;
2351 }
2352 } else {
2353 switch (adev->asic_type) {
2354 case CHIP_BONAIRE:
2355 adev->ip_blocks = bonaire_ip_blocks;
2356 adev->num_ip_blocks = ARRAY_SIZE(bonaire_ip_blocks);
2357 break;
2358 case CHIP_HAWAII:
2359 adev->ip_blocks = hawaii_ip_blocks;
2360 adev->num_ip_blocks = ARRAY_SIZE(hawaii_ip_blocks);
2361 break;
2362 case CHIP_KAVERI:
2363 adev->ip_blocks = kaveri_ip_blocks;
2364 adev->num_ip_blocks = ARRAY_SIZE(kaveri_ip_blocks);
2365 break;
2366 case CHIP_KABINI:
2367 adev->ip_blocks = kabini_ip_blocks;
2368 adev->num_ip_blocks = ARRAY_SIZE(kabini_ip_blocks);
2369 break;
2370 case CHIP_MULLINS:
2371 adev->ip_blocks = mullins_ip_blocks;
2372 adev->num_ip_blocks = ARRAY_SIZE(mullins_ip_blocks);
2373 break;
2374 default:
2375 /* FIXME: not supported yet */
2376 return -EINVAL;
2377 }
2009 } 2378 }
2010 2379
2011 return 0; 2380 return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index ee6466912497..e71cd12104b3 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -694,24 +694,16 @@ static void cik_sdma_vm_copy_pte(struct amdgpu_ib *ib,
694 uint64_t pe, uint64_t src, 694 uint64_t pe, uint64_t src,
695 unsigned count) 695 unsigned count)
696{ 696{
697 while (count) { 697 unsigned bytes = count * 8;
698 unsigned bytes = count * 8; 698
699 if (bytes > 0x1FFFF8) 699 ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_COPY,
700 bytes = 0x1FFFF8; 700 SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
701 701 ib->ptr[ib->length_dw++] = bytes;
702 ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_COPY, 702 ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
703 SDMA_WRITE_SUB_OPCODE_LINEAR, 0); 703 ib->ptr[ib->length_dw++] = lower_32_bits(src);
704 ib->ptr[ib->length_dw++] = bytes; 704 ib->ptr[ib->length_dw++] = upper_32_bits(src);
705 ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */ 705 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
706 ib->ptr[ib->length_dw++] = lower_32_bits(src); 706 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
707 ib->ptr[ib->length_dw++] = upper_32_bits(src);
708 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
709 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
710
711 pe += bytes;
712 src += bytes;
713 count -= bytes / 8;
714 }
715} 707}
716 708
717/** 709/**
@@ -719,39 +711,27 @@ static void cik_sdma_vm_copy_pte(struct amdgpu_ib *ib,
719 * 711 *
720 * @ib: indirect buffer to fill with commands 712 * @ib: indirect buffer to fill with commands
721 * @pe: addr of the page entry 713 * @pe: addr of the page entry
722 * @addr: dst addr to write into pe 714 * @value: dst addr to write into pe
723 * @count: number of page entries to update 715 * @count: number of page entries to update
724 * @incr: increase next addr by incr bytes 716 * @incr: increase next addr by incr bytes
725 * @flags: access flags
726 * 717 *
727 * Update PTEs by writing them manually using sDMA (CIK). 718 * Update PTEs by writing them manually using sDMA (CIK).
728 */ 719 */
729static void cik_sdma_vm_write_pte(struct amdgpu_ib *ib, 720static void cik_sdma_vm_write_pte(struct amdgpu_ib *ib, uint64_t pe,
730 const dma_addr_t *pages_addr, uint64_t pe, 721 uint64_t value, unsigned count,
731 uint64_t addr, unsigned count, 722 uint32_t incr)
732 uint32_t incr, uint32_t flags)
733{ 723{
734 uint64_t value; 724 unsigned ndw = count * 2;
735 unsigned ndw; 725
736 726 ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
737 while (count) { 727 SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
738 ndw = count * 2; 728 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
739 if (ndw > 0xFFFFE) 729 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
740 ndw = 0xFFFFE; 730 ib->ptr[ib->length_dw++] = ndw;
741 731 for (; ndw > 0; ndw -= 2) {
742 /* for non-physically contiguous pages (system) */ 732 ib->ptr[ib->length_dw++] = lower_32_bits(value);
743 ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_WRITE, 733 ib->ptr[ib->length_dw++] = upper_32_bits(value);
744 SDMA_WRITE_SUB_OPCODE_LINEAR, 0); 734 value += incr;
745 ib->ptr[ib->length_dw++] = pe;
746 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
747 ib->ptr[ib->length_dw++] = ndw;
748 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
749 value = amdgpu_vm_map_gart(pages_addr, addr);
750 addr += incr;
751 value |= flags;
752 ib->ptr[ib->length_dw++] = value;
753 ib->ptr[ib->length_dw++] = upper_32_bits(value);
754 }
755 } 735 }
756} 736}
757 737
@@ -767,40 +747,21 @@ static void cik_sdma_vm_write_pte(struct amdgpu_ib *ib,
767 * 747 *
768 * Update the page tables using sDMA (CIK). 748 * Update the page tables using sDMA (CIK).
769 */ 749 */
770static void cik_sdma_vm_set_pte_pde(struct amdgpu_ib *ib, 750static void cik_sdma_vm_set_pte_pde(struct amdgpu_ib *ib, uint64_t pe,
771 uint64_t pe,
772 uint64_t addr, unsigned count, 751 uint64_t addr, unsigned count,
773 uint32_t incr, uint32_t flags) 752 uint32_t incr, uint32_t flags)
774{ 753{
775 uint64_t value; 754 /* for physically contiguous pages (vram) */
776 unsigned ndw; 755 ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0);
777 756 ib->ptr[ib->length_dw++] = lower_32_bits(pe); /* dst addr */
778 while (count) { 757 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
779 ndw = count; 758 ib->ptr[ib->length_dw++] = flags; /* mask */
780 if (ndw > 0x7FFFF) 759 ib->ptr[ib->length_dw++] = 0;
781 ndw = 0x7FFFF; 760 ib->ptr[ib->length_dw++] = lower_32_bits(addr); /* value */
782 761 ib->ptr[ib->length_dw++] = upper_32_bits(addr);
783 if (flags & AMDGPU_PTE_VALID) 762 ib->ptr[ib->length_dw++] = incr; /* increment size */
784 value = addr; 763 ib->ptr[ib->length_dw++] = 0;
785 else 764 ib->ptr[ib->length_dw++] = count; /* number of entries */
786 value = 0;
787
788 /* for physically contiguous pages (vram) */
789 ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0);
790 ib->ptr[ib->length_dw++] = pe; /* dst addr */
791 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
792 ib->ptr[ib->length_dw++] = flags; /* mask */
793 ib->ptr[ib->length_dw++] = 0;
794 ib->ptr[ib->length_dw++] = value; /* value */
795 ib->ptr[ib->length_dw++] = upper_32_bits(value);
796 ib->ptr[ib->length_dw++] = incr; /* increment size */
797 ib->ptr[ib->length_dw++] = 0;
798 ib->ptr[ib->length_dw++] = ndw; /* number of entries */
799
800 pe += ndw * 8;
801 addr += ndw * incr;
802 count -= ndw;
803 }
804} 765}
805 766
806/** 767/**
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c
index 2a11413ed54a..794c5f36ca68 100644
--- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c
@@ -435,7 +435,11 @@ static int cz_dpm_init(struct amdgpu_device *adev)
435 pi->caps_td_ramping = true; 435 pi->caps_td_ramping = true;
436 pi->caps_tcp_ramping = true; 436 pi->caps_tcp_ramping = true;
437 } 437 }
438 pi->caps_sclk_ds = true; 438 if (amdgpu_sclk_deep_sleep_en)
439 pi->caps_sclk_ds = true;
440 else
441 pi->caps_sclk_ds = false;
442
439 pi->voting_clients = 0x00c00033; 443 pi->voting_clients = 0x00c00033;
440 pi->auto_thermal_throttling_enabled = true; 444 pi->auto_thermal_throttling_enabled = true;
441 pi->bapm_enabled = false; 445 pi->bapm_enabled = false;
@@ -2108,29 +2112,58 @@ static void cz_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate)
2108 /* disable clockgating so we can properly shut down the block */ 2112 /* disable clockgating so we can properly shut down the block */
2109 ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD, 2113 ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
2110 AMD_CG_STATE_UNGATE); 2114 AMD_CG_STATE_UNGATE);
2115 if (ret) {
2116 DRM_ERROR("UVD DPM Power Gating failed to set clockgating state\n");
2117 return;
2118 }
2119
2111 /* shutdown the UVD block */ 2120 /* shutdown the UVD block */
2112 ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD, 2121 ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
2113 AMD_PG_STATE_GATE); 2122 AMD_PG_STATE_GATE);
2114 /* XXX: check for errors */ 2123
2124 if (ret) {
2125 DRM_ERROR("UVD DPM Power Gating failed to set powergating state\n");
2126 return;
2127 }
2115 } 2128 }
2116 cz_update_uvd_dpm(adev, gate); 2129 cz_update_uvd_dpm(adev, gate);
2117 if (pi->caps_uvd_pg) 2130 if (pi->caps_uvd_pg) {
2118 /* power off the UVD block */ 2131 /* power off the UVD block */
2119 cz_send_msg_to_smc(adev, PPSMC_MSG_UVDPowerOFF); 2132 ret = cz_send_msg_to_smc(adev, PPSMC_MSG_UVDPowerOFF);
2133 if (ret) {
2134 DRM_ERROR("UVD DPM Power Gating failed to send SMU PowerOFF message\n");
2135 return;
2136 }
2137 }
2120 } else { 2138 } else {
2121 if (pi->caps_uvd_pg) { 2139 if (pi->caps_uvd_pg) {
2122 /* power on the UVD block */ 2140 /* power on the UVD block */
2123 if (pi->uvd_dynamic_pg) 2141 if (pi->uvd_dynamic_pg)
2124 cz_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_UVDPowerON, 1); 2142 ret = cz_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_UVDPowerON, 1);
2125 else 2143 else
2126 cz_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_UVDPowerON, 0); 2144 ret = cz_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_UVDPowerON, 0);
2145
2146 if (ret) {
2147 DRM_ERROR("UVD DPM Power Gating Failed to send SMU PowerON message\n");
2148 return;
2149 }
2150
2127 /* re-init the UVD block */ 2151 /* re-init the UVD block */
2128 ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD, 2152 ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
2129 AMD_PG_STATE_UNGATE); 2153 AMD_PG_STATE_UNGATE);
2154
2155 if (ret) {
2156 DRM_ERROR("UVD DPM Power Gating Failed to set powergating state\n");
2157 return;
2158 }
2159
2130 /* enable clockgating. hw will dynamically gate/ungate clocks on the fly */ 2160 /* enable clockgating. hw will dynamically gate/ungate clocks on the fly */
2131 ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD, 2161 ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
2132 AMD_CG_STATE_GATE); 2162 AMD_CG_STATE_GATE);
2133 /* XXX: check for errors */ 2163 if (ret) {
2164 DRM_ERROR("UVD DPM Power Gating Failed to set clockgating state\n");
2165 return;
2166 }
2134 } 2167 }
2135 cz_update_uvd_dpm(adev, gate); 2168 cz_update_uvd_dpm(adev, gate);
2136 } 2169 }
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 741da36cd8b6..bc5bb4eb9625 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -646,8 +646,8 @@ static void dce_v10_0_resume_mc_access(struct amdgpu_device *adev,
646 646
647 if (save->crtc_enabled[i]) { 647 if (save->crtc_enabled[i]) {
648 tmp = RREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i]); 648 tmp = RREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i]);
649 if (REG_GET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE) != 3) { 649 if (REG_GET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE) != 0) {
650 tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE, 3); 650 tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE, 0);
651 WREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i], tmp); 651 WREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i], tmp);
652 } 652 }
653 tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]); 653 tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
@@ -712,6 +712,45 @@ static void dce_v10_0_set_vga_render_state(struct amdgpu_device *adev,
712 WREG32(mmVGA_RENDER_CONTROL, tmp); 712 WREG32(mmVGA_RENDER_CONTROL, tmp);
713} 713}
714 714
715static int dce_v10_0_get_num_crtc(struct amdgpu_device *adev)
716{
717 int num_crtc = 0;
718
719 switch (adev->asic_type) {
720 case CHIP_FIJI:
721 case CHIP_TONGA:
722 num_crtc = 6;
723 break;
724 default:
725 num_crtc = 0;
726 }
727 return num_crtc;
728}
729
730void dce_v10_0_disable_dce(struct amdgpu_device *adev)
731{
732 /*Disable VGA render and enabled crtc, if has DCE engine*/
733 if (amdgpu_atombios_has_dce_engine_info(adev)) {
734 u32 tmp;
735 int crtc_enabled, i;
736
737 dce_v10_0_set_vga_render_state(adev, false);
738
739 /*Disable crtc*/
740 for (i = 0; i < dce_v10_0_get_num_crtc(adev); i++) {
741 crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
742 CRTC_CONTROL, CRTC_MASTER_EN);
743 if (crtc_enabled) {
744 WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
745 tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
746 tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
747 WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
748 WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
749 }
750 }
751 }
752}
753
715static void dce_v10_0_program_fmt(struct drm_encoder *encoder) 754static void dce_v10_0_program_fmt(struct drm_encoder *encoder)
716{ 755{
717 struct drm_device *dev = encoder->dev; 756 struct drm_device *dev = encoder->dev;
@@ -2277,8 +2316,8 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
2277 WREG32(mmVIEWPORT_SIZE + amdgpu_crtc->crtc_offset, 2316 WREG32(mmVIEWPORT_SIZE + amdgpu_crtc->crtc_offset,
2278 (viewport_w << 16) | viewport_h); 2317 (viewport_w << 16) | viewport_h);
2279 2318
2280 /* set pageflip to happen only at start of vblank interval (front porch) */ 2319 /* set pageflip to happen anywhere in vblank interval */
2281 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 3); 2320 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
2282 2321
2283 if (!atomic && fb && fb != crtc->primary->fb) { 2322 if (!atomic && fb && fb != crtc->primary->fb) {
2284 amdgpu_fb = to_amdgpu_framebuffer(fb); 2323 amdgpu_fb = to_amdgpu_framebuffer(fb);
@@ -2700,7 +2739,7 @@ static const struct drm_crtc_funcs dce_v10_0_crtc_funcs = {
2700 .gamma_set = dce_v10_0_crtc_gamma_set, 2739 .gamma_set = dce_v10_0_crtc_gamma_set,
2701 .set_config = amdgpu_crtc_set_config, 2740 .set_config = amdgpu_crtc_set_config,
2702 .destroy = dce_v10_0_crtc_destroy, 2741 .destroy = dce_v10_0_crtc_destroy,
2703 .page_flip = amdgpu_crtc_page_flip, 2742 .page_flip_target = amdgpu_crtc_page_flip_target,
2704}; 2743};
2705 2744
2706static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) 2745static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode)
@@ -2964,10 +3003,11 @@ static int dce_v10_0_early_init(void *handle)
2964 dce_v10_0_set_display_funcs(adev); 3003 dce_v10_0_set_display_funcs(adev);
2965 dce_v10_0_set_irq_funcs(adev); 3004 dce_v10_0_set_irq_funcs(adev);
2966 3005
3006 adev->mode_info.num_crtc = dce_v10_0_get_num_crtc(adev);
3007
2967 switch (adev->asic_type) { 3008 switch (adev->asic_type) {
2968 case CHIP_FIJI: 3009 case CHIP_FIJI:
2969 case CHIP_TONGA: 3010 case CHIP_TONGA:
2970 adev->mode_info.num_crtc = 6; /* XXX 7??? */
2971 adev->mode_info.num_hpd = 6; 3011 adev->mode_info.num_hpd = 6;
2972 adev->mode_info.num_dig = 7; 3012 adev->mode_info.num_dig = 7;
2973 break; 3013 break;
@@ -3143,11 +3183,26 @@ static int dce_v10_0_wait_for_idle(void *handle)
3143 return 0; 3183 return 0;
3144} 3184}
3145 3185
3186static int dce_v10_0_check_soft_reset(void *handle)
3187{
3188 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
3189
3190 if (dce_v10_0_is_display_hung(adev))
3191 adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = true;
3192 else
3193 adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = false;
3194
3195 return 0;
3196}
3197
3146static int dce_v10_0_soft_reset(void *handle) 3198static int dce_v10_0_soft_reset(void *handle)
3147{ 3199{
3148 u32 srbm_soft_reset = 0, tmp; 3200 u32 srbm_soft_reset = 0, tmp;
3149 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 3201 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
3150 3202
3203 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang)
3204 return 0;
3205
3151 if (dce_v10_0_is_display_hung(adev)) 3206 if (dce_v10_0_is_display_hung(adev))
3152 srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK; 3207 srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;
3153 3208
@@ -3514,6 +3569,7 @@ const struct amd_ip_funcs dce_v10_0_ip_funcs = {
3514 .resume = dce_v10_0_resume, 3569 .resume = dce_v10_0_resume,
3515 .is_idle = dce_v10_0_is_idle, 3570 .is_idle = dce_v10_0_is_idle,
3516 .wait_for_idle = dce_v10_0_wait_for_idle, 3571 .wait_for_idle = dce_v10_0_wait_for_idle,
3572 .check_soft_reset = dce_v10_0_check_soft_reset,
3517 .soft_reset = dce_v10_0_soft_reset, 3573 .soft_reset = dce_v10_0_soft_reset,
3518 .set_clockgating_state = dce_v10_0_set_clockgating_state, 3574 .set_clockgating_state = dce_v10_0_set_clockgating_state,
3519 .set_powergating_state = dce_v10_0_set_powergating_state, 3575 .set_powergating_state = dce_v10_0_set_powergating_state,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
index 1bfa48ddd8a6..e3dc04d293e4 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.h
@@ -26,4 +26,6 @@
26 26
27extern const struct amd_ip_funcs dce_v10_0_ip_funcs; 27extern const struct amd_ip_funcs dce_v10_0_ip_funcs;
28 28
29void dce_v10_0_disable_dce(struct amdgpu_device *adev);
30
29#endif 31#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 2282eb60aba6..b93eba077950 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -673,6 +673,53 @@ static void dce_v11_0_set_vga_render_state(struct amdgpu_device *adev,
673 WREG32(mmVGA_RENDER_CONTROL, tmp); 673 WREG32(mmVGA_RENDER_CONTROL, tmp);
674} 674}
675 675
676static int dce_v11_0_get_num_crtc (struct amdgpu_device *adev)
677{
678 int num_crtc = 0;
679
680 switch (adev->asic_type) {
681 case CHIP_CARRIZO:
682 num_crtc = 3;
683 break;
684 case CHIP_STONEY:
685 num_crtc = 2;
686 break;
687 case CHIP_POLARIS10:
688 num_crtc = 6;
689 break;
690 case CHIP_POLARIS11:
691 num_crtc = 5;
692 break;
693 default:
694 num_crtc = 0;
695 }
696 return num_crtc;
697}
698
699void dce_v11_0_disable_dce(struct amdgpu_device *adev)
700{
701 /*Disable VGA render and enabled crtc, if has DCE engine*/
702 if (amdgpu_atombios_has_dce_engine_info(adev)) {
703 u32 tmp;
704 int crtc_enabled, i;
705
706 dce_v11_0_set_vga_render_state(adev, false);
707
708 /*Disable crtc*/
709 for (i = 0; i < dce_v11_0_get_num_crtc(adev); i++) {
710 crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
711 CRTC_CONTROL, CRTC_MASTER_EN);
712 if (crtc_enabled) {
713 WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
714 tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
715 tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
716 WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
717 WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
718 }
719 }
720 }
721}
722
676static void dce_v11_0_program_fmt(struct drm_encoder *encoder) 723static void dce_v11_0_program_fmt(struct drm_encoder *encoder)
677{ 724{
678 struct drm_device *dev = encoder->dev; 725 struct drm_device *dev = encoder->dev;
@@ -2252,8 +2299,8 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc,
2252 WREG32(mmVIEWPORT_SIZE + amdgpu_crtc->crtc_offset, 2299 WREG32(mmVIEWPORT_SIZE + amdgpu_crtc->crtc_offset,
2253 (viewport_w << 16) | viewport_h); 2300 (viewport_w << 16) | viewport_h);
2254 2301
2255 /* set pageflip to happen only at start of vblank interval (front porch) */ 2302 /* set pageflip to happen anywhere in vblank interval */
2256 WREG32(mmCRTC_MASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 3); 2303 WREG32(mmCRTC_MASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
2257 2304
2258 if (!atomic && fb && fb != crtc->primary->fb) { 2305 if (!atomic && fb && fb != crtc->primary->fb) {
2259 amdgpu_fb = to_amdgpu_framebuffer(fb); 2306 amdgpu_fb = to_amdgpu_framebuffer(fb);
@@ -2710,7 +2757,7 @@ static const struct drm_crtc_funcs dce_v11_0_crtc_funcs = {
2710 .gamma_set = dce_v11_0_crtc_gamma_set, 2757 .gamma_set = dce_v11_0_crtc_gamma_set,
2711 .set_config = amdgpu_crtc_set_config, 2758 .set_config = amdgpu_crtc_set_config,
2712 .destroy = dce_v11_0_crtc_destroy, 2759 .destroy = dce_v11_0_crtc_destroy,
2713 .page_flip = amdgpu_crtc_page_flip, 2760 .page_flip_target = amdgpu_crtc_page_flip_target,
2714}; 2761};
2715 2762
2716static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode) 2763static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode)
@@ -3001,24 +3048,22 @@ static int dce_v11_0_early_init(void *handle)
3001 dce_v11_0_set_display_funcs(adev); 3048 dce_v11_0_set_display_funcs(adev);
3002 dce_v11_0_set_irq_funcs(adev); 3049 dce_v11_0_set_irq_funcs(adev);
3003 3050
3051 adev->mode_info.num_crtc = dce_v11_0_get_num_crtc(adev);
3052
3004 switch (adev->asic_type) { 3053 switch (adev->asic_type) {
3005 case CHIP_CARRIZO: 3054 case CHIP_CARRIZO:
3006 adev->mode_info.num_crtc = 3;
3007 adev->mode_info.num_hpd = 6; 3055 adev->mode_info.num_hpd = 6;
3008 adev->mode_info.num_dig = 9; 3056 adev->mode_info.num_dig = 9;
3009 break; 3057 break;
3010 case CHIP_STONEY: 3058 case CHIP_STONEY:
3011 adev->mode_info.num_crtc = 2;
3012 adev->mode_info.num_hpd = 6; 3059 adev->mode_info.num_hpd = 6;
3013 adev->mode_info.num_dig = 9; 3060 adev->mode_info.num_dig = 9;
3014 break; 3061 break;
3015 case CHIP_POLARIS10: 3062 case CHIP_POLARIS10:
3016 adev->mode_info.num_crtc = 6;
3017 adev->mode_info.num_hpd = 6; 3063 adev->mode_info.num_hpd = 6;
3018 adev->mode_info.num_dig = 6; 3064 adev->mode_info.num_dig = 6;
3019 break; 3065 break;
3020 case CHIP_POLARIS11: 3066 case CHIP_POLARIS11:
3021 adev->mode_info.num_crtc = 5;
3022 adev->mode_info.num_hpd = 5; 3067 adev->mode_info.num_hpd = 5;
3023 adev->mode_info.num_dig = 5; 3068 adev->mode_info.num_dig = 5;
3024 break; 3069 break;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
index 84e4618f5253..1f58a65ba2ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.h
@@ -26,4 +26,6 @@
26 26
27extern const struct amd_ip_funcs dce_v11_0_ip_funcs; 27extern const struct amd_ip_funcs dce_v11_0_ip_funcs;
28 28
29void dce_v11_0_disable_dce(struct amdgpu_device *adev);
30
29#endif 31#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 8b7ad345771f..abd5213dfe18 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -604,6 +604,52 @@ static void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,
604 WREG32(mmVGA_RENDER_CONTROL, tmp); 604 WREG32(mmVGA_RENDER_CONTROL, tmp);
605} 605}
606 606
607static int dce_v8_0_get_num_crtc(struct amdgpu_device *adev)
608{
609 int num_crtc = 0;
610
611 switch (adev->asic_type) {
612 case CHIP_BONAIRE:
613 case CHIP_HAWAII:
614 num_crtc = 6;
615 break;
616 case CHIP_KAVERI:
617 num_crtc = 4;
618 break;
619 case CHIP_KABINI:
620 case CHIP_MULLINS:
621 num_crtc = 2;
622 break;
623 default:
624 num_crtc = 0;
625 }
626 return num_crtc;
627}
628
629void dce_v8_0_disable_dce(struct amdgpu_device *adev)
630{
631 /*Disable VGA render and enabled crtc, if has DCE engine*/
632 if (amdgpu_atombios_has_dce_engine_info(adev)) {
633 u32 tmp;
634 int crtc_enabled, i;
635
636 dce_v8_0_set_vga_render_state(adev, false);
637
638 /*Disable crtc*/
639 for (i = 0; i < dce_v8_0_get_num_crtc(adev); i++) {
640 crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
641 CRTC_CONTROL, CRTC_MASTER_EN);
642 if (crtc_enabled) {
643 WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
644 tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
645 tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
646 WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
647 WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
648 }
649 }
650 }
651}
652
607static void dce_v8_0_program_fmt(struct drm_encoder *encoder) 653static void dce_v8_0_program_fmt(struct drm_encoder *encoder)
608{ 654{
609 struct drm_device *dev = encoder->dev; 655 struct drm_device *dev = encoder->dev;
@@ -1501,13 +1547,13 @@ static void dce_v8_0_audio_write_sad_regs(struct drm_encoder *encoder)
1501 1547
1502 if (sad->format == eld_reg_to_type[i][1]) { 1548 if (sad->format == eld_reg_to_type[i][1]) {
1503 if (sad->channels > max_channels) { 1549 if (sad->channels > max_channels) {
1504 value = (sad->channels << 1550 value = (sad->channels <<
1505 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__MAX_CHANNELS__SHIFT) | 1551 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__MAX_CHANNELS__SHIFT) |
1506 (sad->byte2 << 1552 (sad->byte2 <<
1507 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__DESCRIPTOR_BYTE_2__SHIFT) | 1553 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__DESCRIPTOR_BYTE_2__SHIFT) |
1508 (sad->freq << 1554 (sad->freq <<
1509 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__SUPPORTED_FREQUENCIES__SHIFT); 1555 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__SUPPORTED_FREQUENCIES__SHIFT);
1510 max_channels = sad->channels; 1556 max_channels = sad->channels;
1511 } 1557 }
1512 1558
1513 if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) 1559 if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM)
@@ -1613,7 +1659,7 @@ static void dce_v8_0_afmt_update_ACR(struct drm_encoder *encoder, uint32_t clock
1613 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv; 1659 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
1614 uint32_t offset = dig->afmt->offset; 1660 uint32_t offset = dig->afmt->offset;
1615 1661
1616 WREG32(mmHDMI_ACR_32_0 + offset, (acr.cts_32khz << HDMI_ACR_44_0__HDMI_ACR_CTS_44__SHIFT)); 1662 WREG32(mmHDMI_ACR_32_0 + offset, (acr.cts_32khz << HDMI_ACR_32_0__HDMI_ACR_CTS_32__SHIFT));
1617 WREG32(mmHDMI_ACR_32_1 + offset, acr.n_32khz); 1663 WREG32(mmHDMI_ACR_32_1 + offset, acr.n_32khz);
1618 1664
1619 WREG32(mmHDMI_ACR_44_0 + offset, (acr.cts_44_1khz << HDMI_ACR_44_0__HDMI_ACR_CTS_44__SHIFT)); 1665 WREG32(mmHDMI_ACR_44_0 + offset, (acr.cts_44_1khz << HDMI_ACR_44_0__HDMI_ACR_CTS_44__SHIFT));
@@ -1693,6 +1739,7 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,
1693 /* Silent, r600_hdmi_enable will raise WARN for us */ 1739 /* Silent, r600_hdmi_enable will raise WARN for us */
1694 if (!dig->afmt->enabled) 1740 if (!dig->afmt->enabled)
1695 return; 1741 return;
1742
1696 offset = dig->afmt->offset; 1743 offset = dig->afmt->offset;
1697 1744
1698 /* hdmi deep color mode general control packets setup, if bpc > 8 */ 1745 /* hdmi deep color mode general control packets setup, if bpc > 8 */
@@ -1817,7 +1864,7 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,
1817 1864
1818 WREG32_OR(mmHDMI_INFOFRAME_CONTROL0 + offset, 1865 WREG32_OR(mmHDMI_INFOFRAME_CONTROL0 + offset,
1819 HDMI_INFOFRAME_CONTROL0__HDMI_AVI_INFO_SEND_MASK | /* enable AVI info frames */ 1866 HDMI_INFOFRAME_CONTROL0__HDMI_AVI_INFO_SEND_MASK | /* enable AVI info frames */
1820 HDMI_INFOFRAME_CONTROL0__HDMI_AVI_INFO_SEND_MASK); /* required for audio info values to be updated */ 1867 HDMI_INFOFRAME_CONTROL0__HDMI_AVI_INFO_CONT_MASK); /* required for audio info values to be updated */
1821 1868
1822 WREG32_P(mmHDMI_INFOFRAME_CONTROL1 + offset, 1869 WREG32_P(mmHDMI_INFOFRAME_CONTROL1 + offset,
1823 (2 << HDMI_INFOFRAME_CONTROL1__HDMI_AVI_INFO_LINE__SHIFT), /* anything other than 0 */ 1870 (2 << HDMI_INFOFRAME_CONTROL1__HDMI_AVI_INFO_LINE__SHIFT), /* anything other than 0 */
@@ -1826,13 +1873,12 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,
1826 WREG32_OR(mmAFMT_AUDIO_PACKET_CONTROL + offset, 1873 WREG32_OR(mmAFMT_AUDIO_PACKET_CONTROL + offset,
1827 AFMT_AUDIO_PACKET_CONTROL__AFMT_AUDIO_SAMPLE_SEND_MASK); /* send audio packets */ 1874 AFMT_AUDIO_PACKET_CONTROL__AFMT_AUDIO_SAMPLE_SEND_MASK); /* send audio packets */
1828 1875
1829 /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
1830 WREG32(mmAFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF); 1876 WREG32(mmAFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF);
1831 WREG32(mmAFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); 1877 WREG32(mmAFMT_RAMP_CONTROL1 + offset, 0x007FFFFF);
1832 WREG32(mmAFMT_RAMP_CONTROL2 + offset, 0x00000001); 1878 WREG32(mmAFMT_RAMP_CONTROL2 + offset, 0x00000001);
1833 WREG32(mmAFMT_RAMP_CONTROL3 + offset, 0x00000001); 1879 WREG32(mmAFMT_RAMP_CONTROL3 + offset, 0x00000001);
1834 1880
1835 /* enable audio after to setting up hw */ 1881 /* enable audio after setting up hw */
1836 dce_v8_0_audio_enable(adev, dig->afmt->pin, true); 1882 dce_v8_0_audio_enable(adev, dig->afmt->pin, true);
1837} 1883}
1838 1884
@@ -2000,7 +2046,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
2000 case DRM_FORMAT_XRGB4444: 2046 case DRM_FORMAT_XRGB4444:
2001 case DRM_FORMAT_ARGB4444: 2047 case DRM_FORMAT_ARGB4444:
2002 fb_format = ((GRPH_DEPTH_16BPP << GRPH_CONTROL__GRPH_DEPTH__SHIFT) | 2048 fb_format = ((GRPH_DEPTH_16BPP << GRPH_CONTROL__GRPH_DEPTH__SHIFT) |
2003 (GRPH_FORMAT_ARGB1555 << GRPH_CONTROL__GRPH_FORMAT__SHIFT)); 2049 (GRPH_FORMAT_ARGB4444 << GRPH_CONTROL__GRPH_FORMAT__SHIFT));
2004#ifdef __BIG_ENDIAN 2050#ifdef __BIG_ENDIAN
2005 fb_swap = (GRPH_ENDIAN_8IN16 << GRPH_SWAP_CNTL__GRPH_ENDIAN_SWAP__SHIFT); 2051 fb_swap = (GRPH_ENDIAN_8IN16 << GRPH_SWAP_CNTL__GRPH_ENDIAN_SWAP__SHIFT);
2006#endif 2052#endif
@@ -2139,8 +2185,8 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
2139 WREG32(mmVIEWPORT_SIZE + amdgpu_crtc->crtc_offset, 2185 WREG32(mmVIEWPORT_SIZE + amdgpu_crtc->crtc_offset,
2140 (viewport_w << 16) | viewport_h); 2186 (viewport_w << 16) | viewport_h);
2141 2187
2142 /* set pageflip to happen only at start of vblank interval (front porch) */ 2188 /* set pageflip to happen anywhere in vblank interval */
2143 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 3); 2189 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
2144 2190
2145 if (!atomic && fb && fb != crtc->primary->fb) { 2191 if (!atomic && fb && fb != crtc->primary->fb) {
2146 amdgpu_fb = to_amdgpu_framebuffer(fb); 2192 amdgpu_fb = to_amdgpu_framebuffer(fb);
@@ -2554,7 +2600,7 @@ static const struct drm_crtc_funcs dce_v8_0_crtc_funcs = {
2554 .gamma_set = dce_v8_0_crtc_gamma_set, 2600 .gamma_set = dce_v8_0_crtc_gamma_set,
2555 .set_config = amdgpu_crtc_set_config, 2601 .set_config = amdgpu_crtc_set_config,
2556 .destroy = dce_v8_0_crtc_destroy, 2602 .destroy = dce_v8_0_crtc_destroy,
2557 .page_flip = amdgpu_crtc_page_flip, 2603 .page_flip_target = amdgpu_crtc_page_flip_target,
2558}; 2604};
2559 2605
2560static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode) 2606static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode)
@@ -2655,7 +2701,7 @@ static void dce_v8_0_crtc_disable(struct drm_crtc *crtc)
2655 case ATOM_PPLL2: 2701 case ATOM_PPLL2:
2656 /* disable the ppll */ 2702 /* disable the ppll */
2657 amdgpu_atombios_crtc_program_pll(crtc, amdgpu_crtc->crtc_id, amdgpu_crtc->pll_id, 2703 amdgpu_atombios_crtc_program_pll(crtc, amdgpu_crtc->crtc_id, amdgpu_crtc->pll_id,
2658 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); 2704 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
2659 break; 2705 break;
2660 case ATOM_PPLL0: 2706 case ATOM_PPLL0:
2661 /* disable the ppll */ 2707 /* disable the ppll */
@@ -2805,21 +2851,20 @@ static int dce_v8_0_early_init(void *handle)
2805 dce_v8_0_set_display_funcs(adev); 2851 dce_v8_0_set_display_funcs(adev);
2806 dce_v8_0_set_irq_funcs(adev); 2852 dce_v8_0_set_irq_funcs(adev);
2807 2853
2854 adev->mode_info.num_crtc = dce_v8_0_get_num_crtc(adev);
2855
2808 switch (adev->asic_type) { 2856 switch (adev->asic_type) {
2809 case CHIP_BONAIRE: 2857 case CHIP_BONAIRE:
2810 case CHIP_HAWAII: 2858 case CHIP_HAWAII:
2811 adev->mode_info.num_crtc = 6;
2812 adev->mode_info.num_hpd = 6; 2859 adev->mode_info.num_hpd = 6;
2813 adev->mode_info.num_dig = 6; 2860 adev->mode_info.num_dig = 6;
2814 break; 2861 break;
2815 case CHIP_KAVERI: 2862 case CHIP_KAVERI:
2816 adev->mode_info.num_crtc = 4;
2817 adev->mode_info.num_hpd = 6; 2863 adev->mode_info.num_hpd = 6;
2818 adev->mode_info.num_dig = 7; 2864 adev->mode_info.num_dig = 7;
2819 break; 2865 break;
2820 case CHIP_KABINI: 2866 case CHIP_KABINI:
2821 case CHIP_MULLINS: 2867 case CHIP_MULLINS:
2822 adev->mode_info.num_crtc = 2;
2823 adev->mode_info.num_hpd = 6; 2868 adev->mode_info.num_hpd = 6;
2824 adev->mode_info.num_dig = 6; /* ? */ 2869 adev->mode_info.num_dig = 6; /* ? */
2825 break; 2870 break;
@@ -3238,7 +3283,6 @@ static int dce_v8_0_crtc_irq(struct amdgpu_device *adev,
3238 drm_handle_vblank(adev->ddev, crtc); 3283 drm_handle_vblank(adev->ddev, crtc);
3239 } 3284 }
3240 DRM_DEBUG("IH: D%d vblank\n", crtc + 1); 3285 DRM_DEBUG("IH: D%d vblank\n", crtc + 1);
3241
3242 break; 3286 break;
3243 case 1: /* vline */ 3287 case 1: /* vline */
3244 if (disp_int & interrupt_status_offsets[crtc].vline) 3288 if (disp_int & interrupt_status_offsets[crtc].vline)
@@ -3247,7 +3291,6 @@ static int dce_v8_0_crtc_irq(struct amdgpu_device *adev,
3247 DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 3291 DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
3248 3292
3249 DRM_DEBUG("IH: D%d vline\n", crtc + 1); 3293 DRM_DEBUG("IH: D%d vline\n", crtc + 1);
3250
3251 break; 3294 break;
3252 default: 3295 default:
3253 DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data); 3296 DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
index 77016852b252..7d0770c3a49b 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.h
@@ -26,4 +26,6 @@
26 26
27extern const struct amd_ip_funcs dce_v8_0_ip_funcs; 27extern const struct amd_ip_funcs dce_v8_0_ip_funcs;
28 28
29void dce_v8_0_disable_dce(struct amdgpu_device *adev);
30
29#endif 31#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
new file mode 100644
index 000000000000..00663a7b4053
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -0,0 +1,806 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#include "drmP.h"
24#include "amdgpu.h"
25#include "amdgpu_pm.h"
26#include "amdgpu_i2c.h"
27#include "atom.h"
28#include "amdgpu_pll.h"
29#include "amdgpu_connectors.h"
30#ifdef CONFIG_DRM_AMDGPU_CIK
31#include "dce_v8_0.h"
32#endif
33#include "dce_v10_0.h"
34#include "dce_v11_0.h"
35#include "dce_virtual.h"
36
37static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
38static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
39static int dce_virtual_pageflip_irq(struct amdgpu_device *adev,
40 struct amdgpu_irq_src *source,
41 struct amdgpu_iv_entry *entry);
42
43/**
44 * dce_virtual_vblank_wait - vblank wait asic callback.
45 *
46 * @adev: amdgpu_device pointer
47 * @crtc: crtc to wait for vblank on
48 *
49 * Wait for vblank on the requested crtc (evergreen+).
50 */
51static void dce_virtual_vblank_wait(struct amdgpu_device *adev, int crtc)
52{
53 return;
54}
55
56static u32 dce_virtual_vblank_get_counter(struct amdgpu_device *adev, int crtc)
57{
58 return 0;
59}
60
61static void dce_virtual_page_flip(struct amdgpu_device *adev,
62 int crtc_id, u64 crtc_base, bool async)
63{
64 return;
65}
66
67static int dce_virtual_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
68 u32 *vbl, u32 *position)
69{
70 *vbl = 0;
71 *position = 0;
72
73 return -EINVAL;
74}
75
76static bool dce_virtual_hpd_sense(struct amdgpu_device *adev,
77 enum amdgpu_hpd_id hpd)
78{
79 return true;
80}
81
82static void dce_virtual_hpd_set_polarity(struct amdgpu_device *adev,
83 enum amdgpu_hpd_id hpd)
84{
85 return;
86}
87
88static u32 dce_virtual_hpd_get_gpio_reg(struct amdgpu_device *adev)
89{
90 return 0;
91}
92
93static bool dce_virtual_is_display_hung(struct amdgpu_device *adev)
94{
95 return false;
96}
97
98void dce_virtual_stop_mc_access(struct amdgpu_device *adev,
99 struct amdgpu_mode_mc_save *save)
100{
101 switch (adev->asic_type) {
102 case CHIP_BONAIRE:
103 case CHIP_HAWAII:
104 case CHIP_KAVERI:
105 case CHIP_KABINI:
106 case CHIP_MULLINS:
107#ifdef CONFIG_DRM_AMDGPU_CIK
108 dce_v8_0_disable_dce(adev);
109#endif
110 break;
111 case CHIP_FIJI:
112 case CHIP_TONGA:
113 dce_v10_0_disable_dce(adev);
114 break;
115 case CHIP_CARRIZO:
116 case CHIP_STONEY:
117 case CHIP_POLARIS11:
118 case CHIP_POLARIS10:
119 dce_v11_0_disable_dce(adev);
120 break;
121 case CHIP_TOPAZ:
122 /* no DCE */
123 return;
124 default:
125 DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);
126 }
127
128 return;
129}
130void dce_virtual_resume_mc_access(struct amdgpu_device *adev,
131 struct amdgpu_mode_mc_save *save)
132{
133 return;
134}
135
136void dce_virtual_set_vga_render_state(struct amdgpu_device *adev,
137 bool render)
138{
139 return;
140}
141
142/**
143 * dce_virtual_bandwidth_update - program display watermarks
144 *
145 * @adev: amdgpu_device pointer
146 *
147 * Calculate and program the display watermarks and line
148 * buffer allocation (CIK).
149 */
150static void dce_virtual_bandwidth_update(struct amdgpu_device *adev)
151{
152 return;
153}
154
155static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
156 u16 *green, u16 *blue, uint32_t size)
157{
158 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
159 int i;
160
161 /* userspace palettes are always correct as is */
162 for (i = 0; i < size; i++) {
163 amdgpu_crtc->lut_r[i] = red[i] >> 6;
164 amdgpu_crtc->lut_g[i] = green[i] >> 6;
165 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
166 }
167
168 return 0;
169}
170
171static void dce_virtual_crtc_destroy(struct drm_crtc *crtc)
172{
173 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
174
175 drm_crtc_cleanup(crtc);
176 kfree(amdgpu_crtc);
177}
178
179static const struct drm_crtc_funcs dce_virtual_crtc_funcs = {
180 .cursor_set2 = NULL,
181 .cursor_move = NULL,
182 .gamma_set = dce_virtual_crtc_gamma_set,
183 .set_config = amdgpu_crtc_set_config,
184 .destroy = dce_virtual_crtc_destroy,
185 .page_flip_target = amdgpu_crtc_page_flip_target,
186};
187
188static void dce_virtual_crtc_dpms(struct drm_crtc *crtc, int mode)
189{
190 struct drm_device *dev = crtc->dev;
191 struct amdgpu_device *adev = dev->dev_private;
192 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
193 unsigned type;
194
195 switch (mode) {
196 case DRM_MODE_DPMS_ON:
197 amdgpu_crtc->enabled = true;
198 /* Make sure VBLANK and PFLIP interrupts are still enabled */
199 type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);
200 amdgpu_irq_update(adev, &adev->crtc_irq, type);
201 amdgpu_irq_update(adev, &adev->pageflip_irq, type);
202 drm_vblank_on(dev, amdgpu_crtc->crtc_id);
203 break;
204 case DRM_MODE_DPMS_STANDBY:
205 case DRM_MODE_DPMS_SUSPEND:
206 case DRM_MODE_DPMS_OFF:
207 drm_vblank_off(dev, amdgpu_crtc->crtc_id);
208 amdgpu_crtc->enabled = false;
209 break;
210 }
211}
212
213
214static void dce_virtual_crtc_prepare(struct drm_crtc *crtc)
215{
216 dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
217}
218
219static void dce_virtual_crtc_commit(struct drm_crtc *crtc)
220{
221 dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
222}
223
224static void dce_virtual_crtc_disable(struct drm_crtc *crtc)
225{
226 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
227
228 dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
229 if (crtc->primary->fb) {
230 int r;
231 struct amdgpu_framebuffer *amdgpu_fb;
232 struct amdgpu_bo *rbo;
233
234 amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb);
235 rbo = gem_to_amdgpu_bo(amdgpu_fb->obj);
236 r = amdgpu_bo_reserve(rbo, false);
237 if (unlikely(r))
238 DRM_ERROR("failed to reserve rbo before unpin\n");
239 else {
240 amdgpu_bo_unpin(rbo);
241 amdgpu_bo_unreserve(rbo);
242 }
243 }
244
245 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
246 amdgpu_crtc->encoder = NULL;
247 amdgpu_crtc->connector = NULL;
248}
249
250static int dce_virtual_crtc_mode_set(struct drm_crtc *crtc,
251 struct drm_display_mode *mode,
252 struct drm_display_mode *adjusted_mode,
253 int x, int y, struct drm_framebuffer *old_fb)
254{
255 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
256
257 /* update the hw version fpr dpm */
258 amdgpu_crtc->hw_mode = *adjusted_mode;
259
260 return 0;
261}
262
263static bool dce_virtual_crtc_mode_fixup(struct drm_crtc *crtc,
264 const struct drm_display_mode *mode,
265 struct drm_display_mode *adjusted_mode)
266{
267 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
268 struct drm_device *dev = crtc->dev;
269 struct drm_encoder *encoder;
270
271 /* assign the encoder to the amdgpu crtc to avoid repeated lookups later */
272 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
273 if (encoder->crtc == crtc) {
274 amdgpu_crtc->encoder = encoder;
275 amdgpu_crtc->connector = amdgpu_get_connector_for_encoder(encoder);
276 break;
277 }
278 }
279 if ((amdgpu_crtc->encoder == NULL) || (amdgpu_crtc->connector == NULL)) {
280 amdgpu_crtc->encoder = NULL;
281 amdgpu_crtc->connector = NULL;
282 return false;
283 }
284
285 return true;
286}
287
288
289static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y,
290 struct drm_framebuffer *old_fb)
291{
292 return 0;
293}
294
295static void dce_virtual_crtc_load_lut(struct drm_crtc *crtc)
296{
297 return;
298}
299
300static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc,
301 struct drm_framebuffer *fb,
302 int x, int y, enum mode_set_atomic state)
303{
304 return 0;
305}
306
307static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = {
308 .dpms = dce_virtual_crtc_dpms,
309 .mode_fixup = dce_virtual_crtc_mode_fixup,
310 .mode_set = dce_virtual_crtc_mode_set,
311 .mode_set_base = dce_virtual_crtc_set_base,
312 .mode_set_base_atomic = dce_virtual_crtc_set_base_atomic,
313 .prepare = dce_virtual_crtc_prepare,
314 .commit = dce_virtual_crtc_commit,
315 .load_lut = dce_virtual_crtc_load_lut,
316 .disable = dce_virtual_crtc_disable,
317};
318
319static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
320{
321 struct amdgpu_crtc *amdgpu_crtc;
322 int i;
323
324 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
325 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
326 if (amdgpu_crtc == NULL)
327 return -ENOMEM;
328
329 drm_crtc_init(adev->ddev, &amdgpu_crtc->base, &dce_virtual_crtc_funcs);
330
331 drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256);
332 amdgpu_crtc->crtc_id = index;
333 adev->mode_info.crtcs[index] = amdgpu_crtc;
334
335 for (i = 0; i < 256; i++) {
336 amdgpu_crtc->lut_r[i] = i << 2;
337 amdgpu_crtc->lut_g[i] = i << 2;
338 amdgpu_crtc->lut_b[i] = i << 2;
339 }
340
341 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
342 amdgpu_crtc->encoder = NULL;
343 amdgpu_crtc->connector = NULL;
344 drm_crtc_helper_add(&amdgpu_crtc->base, &dce_virtual_crtc_helper_funcs);
345
346 return 0;
347}
348
349static int dce_virtual_early_init(void *handle)
350{
351 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
352
353 adev->mode_info.vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE;
354 dce_virtual_set_display_funcs(adev);
355 dce_virtual_set_irq_funcs(adev);
356
357 adev->mode_info.num_crtc = 1;
358 adev->mode_info.num_hpd = 1;
359 adev->mode_info.num_dig = 1;
360 return 0;
361}
362
363static bool dce_virtual_get_connector_info(struct amdgpu_device *adev)
364{
365 struct amdgpu_i2c_bus_rec ddc_bus;
366 struct amdgpu_router router;
367 struct amdgpu_hpd hpd;
368
369 /* look up gpio for ddc, hpd */
370 ddc_bus.valid = false;
371 hpd.hpd = AMDGPU_HPD_NONE;
372 /* needed for aux chan transactions */
373 ddc_bus.hpd = hpd.hpd;
374
375 memset(&router, 0, sizeof(router));
376 router.ddc_valid = false;
377 router.cd_valid = false;
378 amdgpu_display_add_connector(adev,
379 0,
380 ATOM_DEVICE_CRT1_SUPPORT,
381 DRM_MODE_CONNECTOR_VIRTUAL, &ddc_bus,
382 CONNECTOR_OBJECT_ID_VIRTUAL,
383 &hpd,
384 &router);
385
386 amdgpu_display_add_encoder(adev, ENCODER_VIRTUAL_ENUM_VIRTUAL,
387 ATOM_DEVICE_CRT1_SUPPORT,
388 0);
389
390 amdgpu_link_encoder_connector(adev->ddev);
391
392 return true;
393}
394
395static int dce_virtual_sw_init(void *handle)
396{
397 int r, i;
398 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
399
400 r = amdgpu_irq_add_id(adev, 229, &adev->crtc_irq);
401 if (r)
402 return r;
403
404 adev->ddev->max_vblank_count = 0;
405
406 adev->ddev->mode_config.funcs = &amdgpu_mode_funcs;
407
408 adev->ddev->mode_config.max_width = 16384;
409 adev->ddev->mode_config.max_height = 16384;
410
411 adev->ddev->mode_config.preferred_depth = 24;
412 adev->ddev->mode_config.prefer_shadow = 1;
413
414 adev->ddev->mode_config.fb_base = adev->mc.aper_base;
415
416 r = amdgpu_modeset_create_props(adev);
417 if (r)
418 return r;
419
420 adev->ddev->mode_config.max_width = 16384;
421 adev->ddev->mode_config.max_height = 16384;
422
423 /* allocate crtcs */
424 for (i = 0; i < adev->mode_info.num_crtc; i++) {
425 r = dce_virtual_crtc_init(adev, i);
426 if (r)
427 return r;
428 }
429
430 dce_virtual_get_connector_info(adev);
431 amdgpu_print_display_setup(adev->ddev);
432
433 drm_kms_helper_poll_init(adev->ddev);
434
435 adev->mode_info.mode_config_initialized = true;
436 return 0;
437}
438
439static int dce_virtual_sw_fini(void *handle)
440{
441 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
442
443 kfree(adev->mode_info.bios_hardcoded_edid);
444
445 drm_kms_helper_poll_fini(adev->ddev);
446
447 drm_mode_config_cleanup(adev->ddev);
448 adev->mode_info.mode_config_initialized = false;
449 return 0;
450}
451
452static int dce_virtual_hw_init(void *handle)
453{
454 return 0;
455}
456
457static int dce_virtual_hw_fini(void *handle)
458{
459 return 0;
460}
461
462static int dce_virtual_suspend(void *handle)
463{
464 return dce_virtual_hw_fini(handle);
465}
466
467static int dce_virtual_resume(void *handle)
468{
469 int ret;
470
471 ret = dce_virtual_hw_init(handle);
472
473 return ret;
474}
475
476static bool dce_virtual_is_idle(void *handle)
477{
478 return true;
479}
480
481static int dce_virtual_wait_for_idle(void *handle)
482{
483 return 0;
484}
485
486static int dce_virtual_soft_reset(void *handle)
487{
488 return 0;
489}
490
491static int dce_virtual_set_clockgating_state(void *handle,
492 enum amd_clockgating_state state)
493{
494 return 0;
495}
496
497static int dce_virtual_set_powergating_state(void *handle,
498 enum amd_powergating_state state)
499{
500 return 0;
501}
502
503const struct amd_ip_funcs dce_virtual_ip_funcs = {
504 .name = "dce_virtual",
505 .early_init = dce_virtual_early_init,
506 .late_init = NULL,
507 .sw_init = dce_virtual_sw_init,
508 .sw_fini = dce_virtual_sw_fini,
509 .hw_init = dce_virtual_hw_init,
510 .hw_fini = dce_virtual_hw_fini,
511 .suspend = dce_virtual_suspend,
512 .resume = dce_virtual_resume,
513 .is_idle = dce_virtual_is_idle,
514 .wait_for_idle = dce_virtual_wait_for_idle,
515 .soft_reset = dce_virtual_soft_reset,
516 .set_clockgating_state = dce_virtual_set_clockgating_state,
517 .set_powergating_state = dce_virtual_set_powergating_state,
518};
519
520/* these are handled by the primary encoders */
521static void dce_virtual_encoder_prepare(struct drm_encoder *encoder)
522{
523 return;
524}
525
526static void dce_virtual_encoder_commit(struct drm_encoder *encoder)
527{
528 return;
529}
530
531static void
532dce_virtual_encoder_mode_set(struct drm_encoder *encoder,
533 struct drm_display_mode *mode,
534 struct drm_display_mode *adjusted_mode)
535{
536 return;
537}
538
539static void dce_virtual_encoder_disable(struct drm_encoder *encoder)
540{
541 return;
542}
543
544static void
545dce_virtual_encoder_dpms(struct drm_encoder *encoder, int mode)
546{
547 return;
548}
549
550static bool dce_virtual_encoder_mode_fixup(struct drm_encoder *encoder,
551 const struct drm_display_mode *mode,
552 struct drm_display_mode *adjusted_mode)
553{
554
555 /* set the active encoder to connector routing */
556 amdgpu_encoder_set_active_device(encoder);
557
558 return true;
559}
560
561static const struct drm_encoder_helper_funcs dce_virtual_encoder_helper_funcs = {
562 .dpms = dce_virtual_encoder_dpms,
563 .mode_fixup = dce_virtual_encoder_mode_fixup,
564 .prepare = dce_virtual_encoder_prepare,
565 .mode_set = dce_virtual_encoder_mode_set,
566 .commit = dce_virtual_encoder_commit,
567 .disable = dce_virtual_encoder_disable,
568};
569
570static void dce_virtual_encoder_destroy(struct drm_encoder *encoder)
571{
572 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
573
574 kfree(amdgpu_encoder->enc_priv);
575 drm_encoder_cleanup(encoder);
576 kfree(amdgpu_encoder);
577}
578
579static const struct drm_encoder_funcs dce_virtual_encoder_funcs = {
580 .destroy = dce_virtual_encoder_destroy,
581};
582
583static void dce_virtual_encoder_add(struct amdgpu_device *adev,
584 uint32_t encoder_enum,
585 uint32_t supported_device,
586 u16 caps)
587{
588 struct drm_device *dev = adev->ddev;
589 struct drm_encoder *encoder;
590 struct amdgpu_encoder *amdgpu_encoder;
591
592 /* see if we already added it */
593 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
594 amdgpu_encoder = to_amdgpu_encoder(encoder);
595 if (amdgpu_encoder->encoder_enum == encoder_enum) {
596 amdgpu_encoder->devices |= supported_device;
597 return;
598 }
599
600 }
601
602 /* add a new one */
603 amdgpu_encoder = kzalloc(sizeof(struct amdgpu_encoder), GFP_KERNEL);
604 if (!amdgpu_encoder)
605 return;
606
607 encoder = &amdgpu_encoder->base;
608 encoder->possible_crtcs = 0x1;
609 amdgpu_encoder->enc_priv = NULL;
610 amdgpu_encoder->encoder_enum = encoder_enum;
611 amdgpu_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
612 amdgpu_encoder->devices = supported_device;
613 amdgpu_encoder->rmx_type = RMX_OFF;
614 amdgpu_encoder->underscan_type = UNDERSCAN_OFF;
615 amdgpu_encoder->is_ext_encoder = false;
616 amdgpu_encoder->caps = caps;
617
618 drm_encoder_init(dev, encoder, &dce_virtual_encoder_funcs,
619 DRM_MODE_ENCODER_VIRTUAL, NULL);
620 drm_encoder_helper_add(encoder, &dce_virtual_encoder_helper_funcs);
621 DRM_INFO("[FM]encoder: %d is VIRTUAL\n", amdgpu_encoder->encoder_id);
622}
623
624static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
625 .set_vga_render_state = &dce_virtual_set_vga_render_state,
626 .bandwidth_update = &dce_virtual_bandwidth_update,
627 .vblank_get_counter = &dce_virtual_vblank_get_counter,
628 .vblank_wait = &dce_virtual_vblank_wait,
629 .is_display_hung = &dce_virtual_is_display_hung,
630 .backlight_set_level = NULL,
631 .backlight_get_level = NULL,
632 .hpd_sense = &dce_virtual_hpd_sense,
633 .hpd_set_polarity = &dce_virtual_hpd_set_polarity,
634 .hpd_get_gpio_reg = &dce_virtual_hpd_get_gpio_reg,
635 .page_flip = &dce_virtual_page_flip,
636 .page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
637 .add_encoder = &dce_virtual_encoder_add,
638 .add_connector = &amdgpu_connector_add,
639 .stop_mc_access = &dce_virtual_stop_mc_access,
640 .resume_mc_access = &dce_virtual_resume_mc_access,
641};
642
643static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
644{
645 if (adev->mode_info.funcs == NULL)
646 adev->mode_info.funcs = &dce_virtual_display_funcs;
647}
648
649static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer)
650{
651 struct amdgpu_mode_info *mode_info = container_of(vblank_timer, struct amdgpu_mode_info ,vblank_timer);
652 struct amdgpu_device *adev = container_of(mode_info, struct amdgpu_device ,mode_info);
653 unsigned crtc = 0;
654 drm_handle_vblank(adev->ddev, crtc);
655 dce_virtual_pageflip_irq(adev, NULL, NULL);
656 hrtimer_start(vblank_timer, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD), HRTIMER_MODE_REL);
657 return HRTIMER_NORESTART;
658}
659
660static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
661 int crtc,
662 enum amdgpu_interrupt_state state)
663{
664 if (crtc >= adev->mode_info.num_crtc) {
665 DRM_DEBUG("invalid crtc %d\n", crtc);
666 return;
667 }
668
669 if (state && !adev->mode_info.vsync_timer_enabled) {
670 DRM_DEBUG("Enable software vsync timer\n");
671 hrtimer_init(&adev->mode_info.vblank_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
672 hrtimer_set_expires(&adev->mode_info.vblank_timer, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD));
673 adev->mode_info.vblank_timer.function = dce_virtual_vblank_timer_handle;
674 hrtimer_start(&adev->mode_info.vblank_timer, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD), HRTIMER_MODE_REL);
675 } else if (!state && adev->mode_info.vsync_timer_enabled) {
676 DRM_DEBUG("Disable software vsync timer\n");
677 hrtimer_cancel(&adev->mode_info.vblank_timer);
678 }
679
680 adev->mode_info.vsync_timer_enabled = state;
681 DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc, state);
682}
683
684
685static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev,
686 struct amdgpu_irq_src *source,
687 unsigned type,
688 enum amdgpu_interrupt_state state)
689{
690 switch (type) {
691 case AMDGPU_CRTC_IRQ_VBLANK1:
692 dce_virtual_set_crtc_vblank_interrupt_state(adev, 0, state);
693 break;
694 default:
695 break;
696 }
697 return 0;
698}
699
700static void dce_virtual_crtc_vblank_int_ack(struct amdgpu_device *adev,
701 int crtc)
702{
703 if (crtc >= adev->mode_info.num_crtc) {
704 DRM_DEBUG("invalid crtc %d\n", crtc);
705 return;
706 }
707}
708
709static int dce_virtual_crtc_irq(struct amdgpu_device *adev,
710 struct amdgpu_irq_src *source,
711 struct amdgpu_iv_entry *entry)
712{
713 unsigned crtc = 0;
714 unsigned irq_type = AMDGPU_CRTC_IRQ_VBLANK1;
715
716 dce_virtual_crtc_vblank_int_ack(adev, crtc);
717
718 if (amdgpu_irq_enabled(adev, source, irq_type)) {
719 drm_handle_vblank(adev->ddev, crtc);
720 }
721 dce_virtual_pageflip_irq(adev, NULL, NULL);
722 DRM_DEBUG("IH: D%d vblank\n", crtc + 1);
723 return 0;
724}
725
726static int dce_virtual_set_pageflip_irq_state(struct amdgpu_device *adev,
727 struct amdgpu_irq_src *src,
728 unsigned type,
729 enum amdgpu_interrupt_state state)
730{
731 if (type >= adev->mode_info.num_crtc) {
732 DRM_ERROR("invalid pageflip crtc %d\n", type);
733 return -EINVAL;
734 }
735 DRM_DEBUG("[FM]set pageflip irq type %d state %d\n", type, state);
736
737 return 0;
738}
739
740static int dce_virtual_pageflip_irq(struct amdgpu_device *adev,
741 struct amdgpu_irq_src *source,
742 struct amdgpu_iv_entry *entry)
743{
744 unsigned long flags;
745 unsigned crtc_id = 0;
746 struct amdgpu_crtc *amdgpu_crtc;
747 struct amdgpu_flip_work *works;
748
749 crtc_id = 0;
750 amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
751
752 if (crtc_id >= adev->mode_info.num_crtc) {
753 DRM_ERROR("invalid pageflip crtc %d\n", crtc_id);
754 return -EINVAL;
755 }
756
757 /* IRQ could occur when in initial stage */
758 if (amdgpu_crtc == NULL)
759 return 0;
760
761 spin_lock_irqsave(&adev->ddev->event_lock, flags);
762 works = amdgpu_crtc->pflip_works;
763 if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) {
764 DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != "
765 "AMDGPU_FLIP_SUBMITTED(%d)\n",
766 amdgpu_crtc->pflip_status,
767 AMDGPU_FLIP_SUBMITTED);
768 spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
769 return 0;
770 }
771
772 /* page flip completed. clean up */
773 amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE;
774 amdgpu_crtc->pflip_works = NULL;
775
776 /* wakeup usersapce */
777 if (works->event)
778 drm_crtc_send_vblank_event(&amdgpu_crtc->base, works->event);
779
780 spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
781
782 drm_crtc_vblank_put(&amdgpu_crtc->base);
783 schedule_work(&works->unpin_work);
784
785 return 0;
786}
787
788static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = {
789 .set = dce_virtual_set_crtc_irq_state,
790 .process = dce_virtual_crtc_irq,
791};
792
793static const struct amdgpu_irq_src_funcs dce_virtual_pageflip_irq_funcs = {
794 .set = dce_virtual_set_pageflip_irq_state,
795 .process = dce_virtual_pageflip_irq,
796};
797
798static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
799{
800 adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
801 adev->crtc_irq.funcs = &dce_virtual_crtc_irq_funcs;
802
803 adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
804 adev->pageflip_irq.funcs = &dce_virtual_pageflip_irq_funcs;
805}
806
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.h b/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
new file mode 100644
index 000000000000..e239243f6ebc
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#ifndef __DCE_VIRTUAL_H__
25#define __DCE_VIRTUAL_H__
26
27extern const struct amd_ip_funcs dce_virtual_ip_funcs;
28#define DCE_VIRTUAL_VBLANK_PERIOD 16666666
29
30#endif
31
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index d869d058ef24..f4fbec3e224e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -4465,24 +4465,21 @@ static int gfx_v7_0_sw_init(void *handle)
4465 } 4465 }
4466 4466
4467 /* reserve GDS, GWS and OA resource for gfx */ 4467 /* reserve GDS, GWS and OA resource for gfx */
4468 r = amdgpu_bo_create(adev, adev->gds.mem.gfx_partition_size, 4468 r = amdgpu_bo_create_kernel(adev, adev->gds.mem.gfx_partition_size,
4469 PAGE_SIZE, true, 4469 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GDS,
4470 AMDGPU_GEM_DOMAIN_GDS, 0, 4470 &adev->gds.gds_gfx_bo, NULL, NULL);
4471 NULL, NULL, &adev->gds.gds_gfx_bo);
4472 if (r) 4471 if (r)
4473 return r; 4472 return r;
4474 4473
4475 r = amdgpu_bo_create(adev, adev->gds.gws.gfx_partition_size, 4474 r = amdgpu_bo_create_kernel(adev, adev->gds.gws.gfx_partition_size,
4476 PAGE_SIZE, true, 4475 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GWS,
4477 AMDGPU_GEM_DOMAIN_GWS, 0, 4476 &adev->gds.gws_gfx_bo, NULL, NULL);
4478 NULL, NULL, &adev->gds.gws_gfx_bo);
4479 if (r) 4477 if (r)
4480 return r; 4478 return r;
4481 4479
4482 r = amdgpu_bo_create(adev, adev->gds.oa.gfx_partition_size, 4480 r = amdgpu_bo_create_kernel(adev, adev->gds.oa.gfx_partition_size,
4483 PAGE_SIZE, true, 4481 PAGE_SIZE, AMDGPU_GEM_DOMAIN_OA,
4484 AMDGPU_GEM_DOMAIN_OA, 0, 4482 &adev->gds.oa_gfx_bo, NULL, NULL);
4485 NULL, NULL, &adev->gds.oa_gfx_bo);
4486 if (r) 4483 if (r)
4487 return r; 4484 return r;
4488 4485
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index b8184617ca25..c6a63c2f91e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -703,7 +703,10 @@ static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
703 polaris10_golden_common_all, 703 polaris10_golden_common_all,
704 (const u32)ARRAY_SIZE(polaris10_golden_common_all)); 704 (const u32)ARRAY_SIZE(polaris10_golden_common_all));
705 WREG32_SMC(ixCG_ACLK_CNTL, 0x0000001C); 705 WREG32_SMC(ixCG_ACLK_CNTL, 0x0000001C);
706 if (adev->pdev->revision == 0xc7) { 706 if (adev->pdev->revision == 0xc7 &&
707 ((adev->pdev->subsystem_device == 0xb37 && adev->pdev->subsystem_vendor == 0x1002) ||
708 (adev->pdev->subsystem_device == 0x4a8 && adev->pdev->subsystem_vendor == 0x1043) ||
709 (adev->pdev->subsystem_device == 0x9480 && adev->pdev->subsystem_vendor == 0x1682))) {
707 amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1E, 0xDD); 710 amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1E, 0xDD);
708 amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1F, 0xD0); 711 amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1F, 0xD0);
709 } 712 }
@@ -1233,10 +1236,9 @@ static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev)
1233 if (adev->gfx.rlc.clear_state_obj) { 1236 if (adev->gfx.rlc.clear_state_obj) {
1234 r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); 1237 r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
1235 if (unlikely(r != 0)) 1238 if (unlikely(r != 0))
1236 dev_warn(adev->dev, "(%d) reserve RLC c bo failed\n", r); 1239 dev_warn(adev->dev, "(%d) reserve RLC cbs bo failed\n", r);
1237 amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); 1240 amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
1238 amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); 1241 amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
1239
1240 amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj); 1242 amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
1241 adev->gfx.rlc.clear_state_obj = NULL; 1243 adev->gfx.rlc.clear_state_obj = NULL;
1242 } 1244 }
@@ -1248,7 +1250,6 @@ static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev)
1248 dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r); 1250 dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
1249 amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj); 1251 amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj);
1250 amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); 1252 amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
1251
1252 amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj); 1253 amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj);
1253 adev->gfx.rlc.cp_table_obj = NULL; 1254 adev->gfx.rlc.cp_table_obj = NULL;
1254 } 1255 }
@@ -1290,14 +1291,14 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
1290 &adev->gfx.rlc.clear_state_gpu_addr); 1291 &adev->gfx.rlc.clear_state_gpu_addr);
1291 if (r) { 1292 if (r) {
1292 amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); 1293 amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
1293 dev_warn(adev->dev, "(%d) pin RLC c bo failed\n", r); 1294 dev_warn(adev->dev, "(%d) pin RLC cbs bo failed\n", r);
1294 gfx_v8_0_rlc_fini(adev); 1295 gfx_v8_0_rlc_fini(adev);
1295 return r; 1296 return r;
1296 } 1297 }
1297 1298
1298 r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr); 1299 r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr);
1299 if (r) { 1300 if (r) {
1300 dev_warn(adev->dev, "(%d) map RLC c bo failed\n", r); 1301 dev_warn(adev->dev, "(%d) map RLC cbs bo failed\n", r);
1301 gfx_v8_0_rlc_fini(adev); 1302 gfx_v8_0_rlc_fini(adev);
1302 return r; 1303 return r;
1303 } 1304 }
@@ -1332,7 +1333,7 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
1332 &adev->gfx.rlc.cp_table_gpu_addr); 1333 &adev->gfx.rlc.cp_table_gpu_addr);
1333 if (r) { 1334 if (r) {
1334 amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); 1335 amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
1335 dev_warn(adev->dev, "(%d) pin RLC cp_table bo failed\n", r); 1336 dev_warn(adev->dev, "(%d) pin RLC cp table bo failed\n", r);
1336 return r; 1337 return r;
1337 } 1338 }
1338 r = amdgpu_bo_kmap(adev->gfx.rlc.cp_table_obj, (void **)&adev->gfx.rlc.cp_table_ptr); 1339 r = amdgpu_bo_kmap(adev->gfx.rlc.cp_table_obj, (void **)&adev->gfx.rlc.cp_table_ptr);
@@ -1345,7 +1346,6 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
1345 1346
1346 amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj); 1347 amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj);
1347 amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); 1348 amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
1348
1349 } 1349 }
1350 1350
1351 return 0; 1351 return 0;
@@ -1361,7 +1361,6 @@ static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
1361 dev_warn(adev->dev, "(%d) reserve HPD EOP bo failed\n", r); 1361 dev_warn(adev->dev, "(%d) reserve HPD EOP bo failed\n", r);
1362 amdgpu_bo_unpin(adev->gfx.mec.hpd_eop_obj); 1362 amdgpu_bo_unpin(adev->gfx.mec.hpd_eop_obj);
1363 amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj); 1363 amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
1364
1365 amdgpu_bo_unref(&adev->gfx.mec.hpd_eop_obj); 1364 amdgpu_bo_unref(&adev->gfx.mec.hpd_eop_obj);
1366 adev->gfx.mec.hpd_eop_obj = NULL; 1365 adev->gfx.mec.hpd_eop_obj = NULL;
1367 } 1366 }
@@ -2082,24 +2081,21 @@ static int gfx_v8_0_sw_init(void *handle)
2082 } 2081 }
2083 2082
2084 /* reserve GDS, GWS and OA resource for gfx */ 2083 /* reserve GDS, GWS and OA resource for gfx */
2085 r = amdgpu_bo_create(adev, adev->gds.mem.gfx_partition_size, 2084 r = amdgpu_bo_create_kernel(adev, adev->gds.mem.gfx_partition_size,
2086 PAGE_SIZE, true, 2085 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GDS,
2087 AMDGPU_GEM_DOMAIN_GDS, 0, NULL, 2086 &adev->gds.gds_gfx_bo, NULL, NULL);
2088 NULL, &adev->gds.gds_gfx_bo);
2089 if (r) 2087 if (r)
2090 return r; 2088 return r;
2091 2089
2092 r = amdgpu_bo_create(adev, adev->gds.gws.gfx_partition_size, 2090 r = amdgpu_bo_create_kernel(adev, adev->gds.gws.gfx_partition_size,
2093 PAGE_SIZE, true, 2091 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GWS,
2094 AMDGPU_GEM_DOMAIN_GWS, 0, NULL, 2092 &adev->gds.gws_gfx_bo, NULL, NULL);
2095 NULL, &adev->gds.gws_gfx_bo);
2096 if (r) 2093 if (r)
2097 return r; 2094 return r;
2098 2095
2099 r = amdgpu_bo_create(adev, adev->gds.oa.gfx_partition_size, 2096 r = amdgpu_bo_create_kernel(adev, adev->gds.oa.gfx_partition_size,
2100 PAGE_SIZE, true, 2097 PAGE_SIZE, AMDGPU_GEM_DOMAIN_OA,
2101 AMDGPU_GEM_DOMAIN_OA, 0, NULL, 2098 &adev->gds.oa_gfx_bo, NULL, NULL);
2102 NULL, &adev->gds.oa_gfx_bo);
2103 if (r) 2099 if (r)
2104 return r; 2100 return r;
2105 2101
@@ -2127,9 +2123,7 @@ static int gfx_v8_0_sw_fini(void *handle)
2127 amdgpu_ring_fini(&adev->gfx.compute_ring[i]); 2123 amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
2128 2124
2129 gfx_v8_0_mec_fini(adev); 2125 gfx_v8_0_mec_fini(adev);
2130
2131 gfx_v8_0_rlc_fini(adev); 2126 gfx_v8_0_rlc_fini(adev);
2132
2133 gfx_v8_0_free_microcode(adev); 2127 gfx_v8_0_free_microcode(adev);
2134 2128
2135 return 0; 2129 return 0;
@@ -3465,19 +3459,16 @@ static void gfx_v8_0_select_se_sh(struct amdgpu_device *adev,
3465 else 3459 else
3466 data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_INDEX, instance); 3460 data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_INDEX, instance);
3467 3461
3468 if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) { 3462 if (se_num == 0xffffffff)
3469 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1);
3470 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_BROADCAST_WRITES, 1); 3463 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_BROADCAST_WRITES, 1);
3471 } else if (se_num == 0xffffffff) { 3464 else
3472 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_INDEX, sh_num);
3473 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_BROADCAST_WRITES, 1);
3474 } else if (sh_num == 0xffffffff) {
3475 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1);
3476 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num); 3465 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num);
3477 } else { 3466
3467 if (sh_num == 0xffffffff)
3468 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1);
3469 else
3478 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_INDEX, sh_num); 3470 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_INDEX, sh_num);
3479 data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num); 3471
3480 }
3481 WREG32(mmGRBM_GFX_INDEX, data); 3472 WREG32(mmGRBM_GFX_INDEX, data);
3482} 3473}
3483 3474
@@ -3490,11 +3481,10 @@ static u32 gfx_v8_0_get_rb_active_bitmap(struct amdgpu_device *adev)
3490{ 3481{
3491 u32 data, mask; 3482 u32 data, mask;
3492 3483
3493 data = RREG32(mmCC_RB_BACKEND_DISABLE); 3484 data = RREG32(mmCC_RB_BACKEND_DISABLE) |
3494 data |= RREG32(mmGC_USER_RB_BACKEND_DISABLE); 3485 RREG32(mmGC_USER_RB_BACKEND_DISABLE);
3495 3486
3496 data &= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK; 3487 data = REG_GET_FIELD(data, GC_USER_RB_BACKEND_DISABLE, BACKEND_DISABLE);
3497 data >>= GC_USER_RB_BACKEND_DISABLE__BACKEND_DISABLE__SHIFT;
3498 3488
3499 mask = gfx_v8_0_create_bitmask(adev->gfx.config.max_backends_per_se / 3489 mask = gfx_v8_0_create_bitmask(adev->gfx.config.max_backends_per_se /
3500 adev->gfx.config.max_sh_per_se); 3490 adev->gfx.config.max_sh_per_se);
@@ -3576,16 +3566,12 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev)
3576 u32 tmp; 3566 u32 tmp;
3577 int i; 3567 int i;
3578 3568
3579 tmp = RREG32(mmGRBM_CNTL); 3569 WREG32_FIELD(GRBM_CNTL, READ_TIMEOUT, 0xFF);
3580 tmp = REG_SET_FIELD(tmp, GRBM_CNTL, READ_TIMEOUT, 0xff);
3581 WREG32(mmGRBM_CNTL, tmp);
3582
3583 WREG32(mmGB_ADDR_CONFIG, adev->gfx.config.gb_addr_config); 3570 WREG32(mmGB_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
3584 WREG32(mmHDP_ADDR_CONFIG, adev->gfx.config.gb_addr_config); 3571 WREG32(mmHDP_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
3585 WREG32(mmDMIF_ADDR_CALC, adev->gfx.config.gb_addr_config); 3572 WREG32(mmDMIF_ADDR_CALC, adev->gfx.config.gb_addr_config);
3586 3573
3587 gfx_v8_0_tiling_mode_table_init(adev); 3574 gfx_v8_0_tiling_mode_table_init(adev);
3588
3589 gfx_v8_0_setup_rb(adev); 3575 gfx_v8_0_setup_rb(adev);
3590 gfx_v8_0_get_cu_info(adev); 3576 gfx_v8_0_get_cu_info(adev);
3591 3577
@@ -3769,9 +3755,7 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev)
3769 sizeof(indirect_start_offsets)/sizeof(int)); 3755 sizeof(indirect_start_offsets)/sizeof(int));
3770 3756
3771 /* save and restore list */ 3757 /* save and restore list */
3772 temp = RREG32(mmRLC_SRM_CNTL); 3758 WREG32_FIELD(RLC_SRM_CNTL, AUTO_INCR_ADDR, 1);
3773 temp |= RLC_SRM_CNTL__AUTO_INCR_ADDR_MASK;
3774 WREG32(mmRLC_SRM_CNTL, temp);
3775 3759
3776 WREG32(mmRLC_SRM_ARAM_ADDR, 0); 3760 WREG32(mmRLC_SRM_ARAM_ADDR, 0);
3777 for (i = 0; i < adev->gfx.rlc.reg_list_size_bytes >> 2; i++) 3761 for (i = 0; i < adev->gfx.rlc.reg_list_size_bytes >> 2; i++)
@@ -3808,11 +3792,7 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev)
3808 3792
3809static void gfx_v8_0_enable_save_restore_machine(struct amdgpu_device *adev) 3793static void gfx_v8_0_enable_save_restore_machine(struct amdgpu_device *adev)
3810{ 3794{
3811 uint32_t data; 3795 WREG32_FIELD(RLC_SRM_CNTL, SRM_ENABLE, 1);
3812
3813 data = RREG32(mmRLC_SRM_CNTL);
3814 data |= RLC_SRM_CNTL__SRM_ENABLE_MASK;
3815 WREG32(mmRLC_SRM_CNTL, data);
3816} 3796}
3817 3797
3818static void gfx_v8_0_init_power_gating(struct amdgpu_device *adev) 3798static void gfx_v8_0_init_power_gating(struct amdgpu_device *adev)
@@ -3822,75 +3802,34 @@ static void gfx_v8_0_init_power_gating(struct amdgpu_device *adev)
3822 if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | 3802 if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG |
3823 AMD_PG_SUPPORT_GFX_SMG | 3803 AMD_PG_SUPPORT_GFX_SMG |
3824 AMD_PG_SUPPORT_GFX_DMG)) { 3804 AMD_PG_SUPPORT_GFX_DMG)) {
3825 data = RREG32(mmCP_RB_WPTR_POLL_CNTL); 3805 WREG32_FIELD(CP_RB_WPTR_POLL_CNTL, IDLE_POLL_COUNT, 0x60);
3826 data &= ~CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT_MASK;
3827 data |= (0x60 << CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT__SHIFT);
3828 WREG32(mmCP_RB_WPTR_POLL_CNTL, data);
3829
3830 data = 0;
3831 data |= (0x10 << RLC_PG_DELAY__POWER_UP_DELAY__SHIFT);
3832 data |= (0x10 << RLC_PG_DELAY__POWER_DOWN_DELAY__SHIFT);
3833 data |= (0x10 << RLC_PG_DELAY__CMD_PROPAGATE_DELAY__SHIFT);
3834 data |= (0x10 << RLC_PG_DELAY__MEM_SLEEP_DELAY__SHIFT);
3835 WREG32(mmRLC_PG_DELAY, data);
3836 3806
3837 data = RREG32(mmRLC_PG_DELAY_2); 3807 data = REG_SET_FIELD(0, RLC_PG_DELAY, POWER_UP_DELAY, 0x10);
3838 data &= ~RLC_PG_DELAY_2__SERDES_CMD_DELAY_MASK; 3808 data = REG_SET_FIELD(data, RLC_PG_DELAY, POWER_DOWN_DELAY, 0x10);
3839 data |= (0x3 << RLC_PG_DELAY_2__SERDES_CMD_DELAY__SHIFT); 3809 data = REG_SET_FIELD(data, RLC_PG_DELAY, CMD_PROPAGATE_DELAY, 0x10);
3840 WREG32(mmRLC_PG_DELAY_2, data); 3810 data = REG_SET_FIELD(data, RLC_PG_DELAY, MEM_SLEEP_DELAY, 0x10);
3811 WREG32(mmRLC_PG_DELAY, data);
3841 3812
3842 data = RREG32(mmRLC_AUTO_PG_CTRL); 3813 WREG32_FIELD(RLC_PG_DELAY_2, SERDES_CMD_DELAY, 0x3);
3843 data &= ~RLC_AUTO_PG_CTRL__GRBM_REG_SAVE_GFX_IDLE_THRESHOLD_MASK; 3814 WREG32_FIELD(RLC_AUTO_PG_CTRL, GRBM_REG_SAVE_GFX_IDLE_THRESHOLD, 0x55f0);
3844 data |= (0x55f0 << RLC_AUTO_PG_CTRL__GRBM_REG_SAVE_GFX_IDLE_THRESHOLD__SHIFT);
3845 WREG32(mmRLC_AUTO_PG_CTRL, data);
3846 } 3815 }
3847} 3816}
3848 3817
3849static void cz_enable_sck_slow_down_on_power_up(struct amdgpu_device *adev, 3818static void cz_enable_sck_slow_down_on_power_up(struct amdgpu_device *adev,
3850 bool enable) 3819 bool enable)
3851{ 3820{
3852 u32 data, orig; 3821 WREG32_FIELD(RLC_PG_CNTL, SMU_CLK_SLOWDOWN_ON_PU_ENABLE, enable ? 1 : 0);
3853
3854 orig = data = RREG32(mmRLC_PG_CNTL);
3855
3856 if (enable)
3857 data |= RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK;
3858 else
3859 data &= ~RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK;
3860
3861 if (orig != data)
3862 WREG32(mmRLC_PG_CNTL, data);
3863} 3822}
3864 3823
3865static void cz_enable_sck_slow_down_on_power_down(struct amdgpu_device *adev, 3824static void cz_enable_sck_slow_down_on_power_down(struct amdgpu_device *adev,
3866 bool enable) 3825 bool enable)
3867{ 3826{
3868 u32 data, orig; 3827 WREG32_FIELD(RLC_PG_CNTL, SMU_CLK_SLOWDOWN_ON_PD_ENABLE, enable ? 1 : 0);
3869
3870 orig = data = RREG32(mmRLC_PG_CNTL);
3871
3872 if (enable)
3873 data |= RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK;
3874 else
3875 data &= ~RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK;
3876
3877 if (orig != data)
3878 WREG32(mmRLC_PG_CNTL, data);
3879} 3828}
3880 3829
3881static void cz_enable_cp_power_gating(struct amdgpu_device *adev, bool enable) 3830static void cz_enable_cp_power_gating(struct amdgpu_device *adev, bool enable)
3882{ 3831{
3883 u32 data, orig; 3832 WREG32_FIELD(RLC_PG_CNTL, CP_PG_DISABLE, enable ? 1 : 0);
3884
3885 orig = data = RREG32(mmRLC_PG_CNTL);
3886
3887 if (enable)
3888 data &= ~RLC_PG_CNTL__CP_PG_DISABLE_MASK;
3889 else
3890 data |= RLC_PG_CNTL__CP_PG_DISABLE_MASK;
3891
3892 if (orig != data)
3893 WREG32(mmRLC_PG_CNTL, data);
3894} 3833}
3895 3834
3896static void gfx_v8_0_init_pg(struct amdgpu_device *adev) 3835static void gfx_v8_0_init_pg(struct amdgpu_device *adev)
@@ -3929,34 +3868,24 @@ static void gfx_v8_0_init_pg(struct amdgpu_device *adev)
3929 3868
3930void gfx_v8_0_rlc_stop(struct amdgpu_device *adev) 3869void gfx_v8_0_rlc_stop(struct amdgpu_device *adev)
3931{ 3870{
3932 u32 tmp = RREG32(mmRLC_CNTL); 3871 WREG32_FIELD(RLC_CNTL, RLC_ENABLE_F32, 0);
3933
3934 tmp = REG_SET_FIELD(tmp, RLC_CNTL, RLC_ENABLE_F32, 0);
3935 WREG32(mmRLC_CNTL, tmp);
3936 3872
3937 gfx_v8_0_enable_gui_idle_interrupt(adev, false); 3873 gfx_v8_0_enable_gui_idle_interrupt(adev, false);
3938
3939 gfx_v8_0_wait_for_rlc_serdes(adev); 3874 gfx_v8_0_wait_for_rlc_serdes(adev);
3940} 3875}
3941 3876
3942static void gfx_v8_0_rlc_reset(struct amdgpu_device *adev) 3877static void gfx_v8_0_rlc_reset(struct amdgpu_device *adev)
3943{ 3878{
3944 u32 tmp = RREG32(mmGRBM_SOFT_RESET); 3879 WREG32_FIELD(GRBM_SOFT_RESET, SOFT_RESET_RLC, 1);
3945
3946 tmp = REG_SET_FIELD(tmp, GRBM_SOFT_RESET, SOFT_RESET_RLC, 1);
3947 WREG32(mmGRBM_SOFT_RESET, tmp);
3948 udelay(50); 3880 udelay(50);
3949 tmp = REG_SET_FIELD(tmp, GRBM_SOFT_RESET, SOFT_RESET_RLC, 0); 3881
3950 WREG32(mmGRBM_SOFT_RESET, tmp); 3882 WREG32_FIELD(GRBM_SOFT_RESET, SOFT_RESET_RLC, 0);
3951 udelay(50); 3883 udelay(50);
3952} 3884}
3953 3885
3954static void gfx_v8_0_rlc_start(struct amdgpu_device *adev) 3886static void gfx_v8_0_rlc_start(struct amdgpu_device *adev)
3955{ 3887{
3956 u32 tmp = RREG32(mmRLC_CNTL); 3888 WREG32_FIELD(RLC_CNTL, RLC_ENABLE_F32, 1);
3957
3958 tmp = REG_SET_FIELD(tmp, RLC_CNTL, RLC_ENABLE_F32, 1);
3959 WREG32(mmRLC_CNTL, tmp);
3960 3889
3961 /* carrizo do enable cp interrupt after cp inited */ 3890 /* carrizo do enable cp interrupt after cp inited */
3962 if (!(adev->flags & AMD_IS_APU)) 3891 if (!(adev->flags & AMD_IS_APU))
@@ -3998,14 +3927,13 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
3998 /* disable CG */ 3927 /* disable CG */
3999 WREG32(mmRLC_CGCG_CGLS_CTRL, 0); 3928 WREG32(mmRLC_CGCG_CGLS_CTRL, 0);
4000 if (adev->asic_type == CHIP_POLARIS11 || 3929 if (adev->asic_type == CHIP_POLARIS11 ||
4001 adev->asic_type == CHIP_POLARIS10) 3930 adev->asic_type == CHIP_POLARIS10)
4002 WREG32(mmRLC_CGCG_CGLS_CTRL_3D, 0); 3931 WREG32(mmRLC_CGCG_CGLS_CTRL_3D, 0);
4003 3932
4004 /* disable PG */ 3933 /* disable PG */
4005 WREG32(mmRLC_PG_CNTL, 0); 3934 WREG32(mmRLC_PG_CNTL, 0);
4006 3935
4007 gfx_v8_0_rlc_reset(adev); 3936 gfx_v8_0_rlc_reset(adev);
4008
4009 gfx_v8_0_init_pg(adev); 3937 gfx_v8_0_init_pg(adev);
4010 3938
4011 if (!adev->pp_enabled) { 3939 if (!adev->pp_enabled) {
@@ -4300,12 +4228,10 @@ static int gfx_v8_0_cp_gfx_resume(struct amdgpu_device *adev)
4300 gfx_v8_0_cp_gfx_start(adev); 4228 gfx_v8_0_cp_gfx_start(adev);
4301 ring->ready = true; 4229 ring->ready = true;
4302 r = amdgpu_ring_test_ring(ring); 4230 r = amdgpu_ring_test_ring(ring);
4303 if (r) { 4231 if (r)
4304 ring->ready = false; 4232 ring->ready = false;
4305 return r;
4306 }
4307 4233
4308 return 0; 4234 return r;
4309} 4235}
4310 4236
4311static void gfx_v8_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) 4237static void gfx_v8_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
@@ -4980,7 +4906,6 @@ static int gfx_v8_0_hw_init(void *handle)
4980 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 4906 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
4981 4907
4982 gfx_v8_0_init_golden_registers(adev); 4908 gfx_v8_0_init_golden_registers(adev);
4983
4984 gfx_v8_0_gpu_init(adev); 4909 gfx_v8_0_gpu_init(adev);
4985 4910
4986 r = gfx_v8_0_rlc_resume(adev); 4911 r = gfx_v8_0_rlc_resume(adev);
@@ -4988,8 +4913,6 @@ static int gfx_v8_0_hw_init(void *handle)
4988 return r; 4913 return r;
4989 4914
4990 r = gfx_v8_0_cp_resume(adev); 4915 r = gfx_v8_0_cp_resume(adev);
4991 if (r)
4992 return r;
4993 4916
4994 return r; 4917 return r;
4995} 4918}
@@ -5037,25 +4960,22 @@ static bool gfx_v8_0_is_idle(void *handle)
5037static int gfx_v8_0_wait_for_idle(void *handle) 4960static int gfx_v8_0_wait_for_idle(void *handle)
5038{ 4961{
5039 unsigned i; 4962 unsigned i;
5040 u32 tmp;
5041 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 4963 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
5042 4964
5043 for (i = 0; i < adev->usec_timeout; i++) { 4965 for (i = 0; i < adev->usec_timeout; i++) {
5044 /* read MC_STATUS */ 4966 if (gfx_v8_0_is_idle(handle))
5045 tmp = RREG32(mmGRBM_STATUS) & GRBM_STATUS__GUI_ACTIVE_MASK;
5046
5047 if (!REG_GET_FIELD(tmp, GRBM_STATUS, GUI_ACTIVE))
5048 return 0; 4967 return 0;
4968
5049 udelay(1); 4969 udelay(1);
5050 } 4970 }
5051 return -ETIMEDOUT; 4971 return -ETIMEDOUT;
5052} 4972}
5053 4973
5054static int gfx_v8_0_soft_reset(void *handle) 4974static int gfx_v8_0_check_soft_reset(void *handle)
5055{ 4975{
4976 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
5056 u32 grbm_soft_reset = 0, srbm_soft_reset = 0; 4977 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
5057 u32 tmp; 4978 u32 tmp;
5058 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
5059 4979
5060 /* GRBM_STATUS */ 4980 /* GRBM_STATUS */
5061 tmp = RREG32(mmGRBM_STATUS); 4981 tmp = RREG32(mmGRBM_STATUS);
@@ -5064,16 +4984,12 @@ static int gfx_v8_0_soft_reset(void *handle)
5064 GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK | 4984 GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK |
5065 GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK | 4985 GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK |
5066 GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK | 4986 GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK |
5067 GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK)) { 4987 GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK |
4988 GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) {
5068 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, 4989 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
5069 GRBM_SOFT_RESET, SOFT_RESET_CP, 1); 4990 GRBM_SOFT_RESET, SOFT_RESET_CP, 1);
5070 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, 4991 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
5071 GRBM_SOFT_RESET, SOFT_RESET_GFX, 1); 4992 GRBM_SOFT_RESET, SOFT_RESET_GFX, 1);
5072 }
5073
5074 if (tmp & (GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) {
5075 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
5076 GRBM_SOFT_RESET, SOFT_RESET_CP, 1);
5077 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, 4993 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
5078 SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1); 4994 SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1);
5079 } 4995 }
@@ -5084,73 +5000,199 @@ static int gfx_v8_0_soft_reset(void *handle)
5084 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, 5000 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
5085 GRBM_SOFT_RESET, SOFT_RESET_RLC, 1); 5001 GRBM_SOFT_RESET, SOFT_RESET_RLC, 1);
5086 5002
5003 if (REG_GET_FIELD(tmp, GRBM_STATUS2, CPF_BUSY) ||
5004 REG_GET_FIELD(tmp, GRBM_STATUS2, CPC_BUSY) ||
5005 REG_GET_FIELD(tmp, GRBM_STATUS2, CPG_BUSY)) {
5006 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET,
5007 SOFT_RESET_CPF, 1);
5008 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET,
5009 SOFT_RESET_CPC, 1);
5010 grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET,
5011 SOFT_RESET_CPG, 1);
5012 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET,
5013 SOFT_RESET_GRBM, 1);
5014 }
5015
5087 /* SRBM_STATUS */ 5016 /* SRBM_STATUS */
5088 tmp = RREG32(mmSRBM_STATUS); 5017 tmp = RREG32(mmSRBM_STATUS);
5089 if (REG_GET_FIELD(tmp, SRBM_STATUS, GRBM_RQ_PENDING)) 5018 if (REG_GET_FIELD(tmp, SRBM_STATUS, GRBM_RQ_PENDING))
5090 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, 5019 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
5091 SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1); 5020 SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1);
5021 if (REG_GET_FIELD(tmp, SRBM_STATUS, SEM_BUSY))
5022 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
5023 SRBM_SOFT_RESET, SOFT_RESET_SEM, 1);
5092 5024
5093 if (grbm_soft_reset || srbm_soft_reset) { 5025 if (grbm_soft_reset || srbm_soft_reset) {
5094 /* stop the rlc */ 5026 adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = true;
5095 gfx_v8_0_rlc_stop(adev); 5027 adev->gfx.grbm_soft_reset = grbm_soft_reset;
5028 adev->gfx.srbm_soft_reset = srbm_soft_reset;
5029 } else {
5030 adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = false;
5031 adev->gfx.grbm_soft_reset = 0;
5032 adev->gfx.srbm_soft_reset = 0;
5033 }
5034
5035 return 0;
5036}
5096 5037
5038static void gfx_v8_0_inactive_hqd(struct amdgpu_device *adev,
5039 struct amdgpu_ring *ring)
5040{
5041 int i;
5042
5043 vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
5044 if (RREG32(mmCP_HQD_ACTIVE) & CP_HQD_ACTIVE__ACTIVE_MASK) {
5045 u32 tmp;
5046 tmp = RREG32(mmCP_HQD_DEQUEUE_REQUEST);
5047 tmp = REG_SET_FIELD(tmp, CP_HQD_DEQUEUE_REQUEST,
5048 DEQUEUE_REQ, 2);
5049 WREG32(mmCP_HQD_DEQUEUE_REQUEST, tmp);
5050 for (i = 0; i < adev->usec_timeout; i++) {
5051 if (!(RREG32(mmCP_HQD_ACTIVE) & CP_HQD_ACTIVE__ACTIVE_MASK))
5052 break;
5053 udelay(1);
5054 }
5055 }
5056}
5057
5058static int gfx_v8_0_pre_soft_reset(void *handle)
5059{
5060 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
5061 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
5062
5063 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
5064 return 0;
5065
5066 grbm_soft_reset = adev->gfx.grbm_soft_reset;
5067 srbm_soft_reset = adev->gfx.srbm_soft_reset;
5068
5069 /* stop the rlc */
5070 gfx_v8_0_rlc_stop(adev);
5071
5072 if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP) ||
5073 REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_GFX))
5097 /* Disable GFX parsing/prefetching */ 5074 /* Disable GFX parsing/prefetching */
5098 gfx_v8_0_cp_gfx_enable(adev, false); 5075 gfx_v8_0_cp_gfx_enable(adev, false);
5099 5076
5077 if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP) ||
5078 REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPF) ||
5079 REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPC) ||
5080 REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPG)) {
5081 int i;
5082
5083 for (i = 0; i < adev->gfx.num_compute_rings; i++) {
5084 struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
5085
5086 gfx_v8_0_inactive_hqd(adev, ring);
5087 }
5100 /* Disable MEC parsing/prefetching */ 5088 /* Disable MEC parsing/prefetching */
5101 gfx_v8_0_cp_compute_enable(adev, false); 5089 gfx_v8_0_cp_compute_enable(adev, false);
5090 }
5102 5091
5103 if (grbm_soft_reset || srbm_soft_reset) { 5092 return 0;
5104 tmp = RREG32(mmGMCON_DEBUG); 5093}
5105 tmp = REG_SET_FIELD(tmp,
5106 GMCON_DEBUG, GFX_STALL, 1);
5107 tmp = REG_SET_FIELD(tmp,
5108 GMCON_DEBUG, GFX_CLEAR, 1);
5109 WREG32(mmGMCON_DEBUG, tmp);
5110 5094
5111 udelay(50); 5095static int gfx_v8_0_soft_reset(void *handle)
5112 } 5096{
5097 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
5098 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
5099 u32 tmp;
5113 5100
5114 if (grbm_soft_reset) { 5101 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
5115 tmp = RREG32(mmGRBM_SOFT_RESET); 5102 return 0;
5116 tmp |= grbm_soft_reset;
5117 dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
5118 WREG32(mmGRBM_SOFT_RESET, tmp);
5119 tmp = RREG32(mmGRBM_SOFT_RESET);
5120 5103
5121 udelay(50); 5104 grbm_soft_reset = adev->gfx.grbm_soft_reset;
5105 srbm_soft_reset = adev->gfx.srbm_soft_reset;
5122 5106
5123 tmp &= ~grbm_soft_reset; 5107 if (grbm_soft_reset || srbm_soft_reset) {
5124 WREG32(mmGRBM_SOFT_RESET, tmp); 5108 tmp = RREG32(mmGMCON_DEBUG);
5125 tmp = RREG32(mmGRBM_SOFT_RESET); 5109 tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 1);
5126 } 5110 tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 1);
5111 WREG32(mmGMCON_DEBUG, tmp);
5112 udelay(50);
5113 }
5127 5114
5128 if (srbm_soft_reset) { 5115 if (grbm_soft_reset) {
5129 tmp = RREG32(mmSRBM_SOFT_RESET); 5116 tmp = RREG32(mmGRBM_SOFT_RESET);
5130 tmp |= srbm_soft_reset; 5117 tmp |= grbm_soft_reset;
5131 dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); 5118 dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
5132 WREG32(mmSRBM_SOFT_RESET, tmp); 5119 WREG32(mmGRBM_SOFT_RESET, tmp);
5133 tmp = RREG32(mmSRBM_SOFT_RESET); 5120 tmp = RREG32(mmGRBM_SOFT_RESET);
5134 5121
5135 udelay(50); 5122 udelay(50);
5136 5123
5137 tmp &= ~srbm_soft_reset; 5124 tmp &= ~grbm_soft_reset;
5138 WREG32(mmSRBM_SOFT_RESET, tmp); 5125 WREG32(mmGRBM_SOFT_RESET, tmp);
5139 tmp = RREG32(mmSRBM_SOFT_RESET); 5126 tmp = RREG32(mmGRBM_SOFT_RESET);
5140 } 5127 }
5141 5128
5142 if (grbm_soft_reset || srbm_soft_reset) { 5129 if (srbm_soft_reset) {
5143 tmp = RREG32(mmGMCON_DEBUG); 5130 tmp = RREG32(mmSRBM_SOFT_RESET);
5144 tmp = REG_SET_FIELD(tmp, 5131 tmp |= srbm_soft_reset;
5145 GMCON_DEBUG, GFX_STALL, 0); 5132 dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
5146 tmp = REG_SET_FIELD(tmp, 5133 WREG32(mmSRBM_SOFT_RESET, tmp);
5147 GMCON_DEBUG, GFX_CLEAR, 0); 5134 tmp = RREG32(mmSRBM_SOFT_RESET);
5148 WREG32(mmGMCON_DEBUG, tmp);
5149 }
5150 5135
5151 /* Wait a little for things to settle down */
5152 udelay(50); 5136 udelay(50);
5137
5138 tmp &= ~srbm_soft_reset;
5139 WREG32(mmSRBM_SOFT_RESET, tmp);
5140 tmp = RREG32(mmSRBM_SOFT_RESET);
5153 } 5141 }
5142
5143 if (grbm_soft_reset || srbm_soft_reset) {
5144 tmp = RREG32(mmGMCON_DEBUG);
5145 tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 0);
5146 tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 0);
5147 WREG32(mmGMCON_DEBUG, tmp);
5148 }
5149
5150 /* Wait a little for things to settle down */
5151 udelay(50);
5152
5153 return 0;
5154}
5155
5156static void gfx_v8_0_init_hqd(struct amdgpu_device *adev,
5157 struct amdgpu_ring *ring)
5158{
5159 vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
5160 WREG32(mmCP_HQD_DEQUEUE_REQUEST, 0);
5161 WREG32(mmCP_HQD_PQ_RPTR, 0);
5162 WREG32(mmCP_HQD_PQ_WPTR, 0);
5163 vi_srbm_select(adev, 0, 0, 0, 0);
5164}
5165
5166static int gfx_v8_0_post_soft_reset(void *handle)
5167{
5168 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
5169 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
5170
5171 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
5172 return 0;
5173
5174 grbm_soft_reset = adev->gfx.grbm_soft_reset;
5175 srbm_soft_reset = adev->gfx.srbm_soft_reset;
5176
5177 if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP) ||
5178 REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_GFX))
5179 gfx_v8_0_cp_gfx_resume(adev);
5180
5181 if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP) ||
5182 REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPF) ||
5183 REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPC) ||
5184 REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CPG)) {
5185 int i;
5186
5187 for (i = 0; i < adev->gfx.num_compute_rings; i++) {
5188 struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
5189
5190 gfx_v8_0_init_hqd(adev, ring);
5191 }
5192 gfx_v8_0_cp_compute_resume(adev);
5193 }
5194 gfx_v8_0_rlc_start(adev);
5195
5154 return 0; 5196 return 0;
5155} 5197}
5156 5198
@@ -5269,8 +5311,6 @@ static int gfx_v8_0_late_init(void *handle)
5269static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev, 5311static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev,
5270 bool enable) 5312 bool enable)
5271{ 5313{
5272 uint32_t data, temp;
5273
5274 if (adev->asic_type == CHIP_POLARIS11) 5314 if (adev->asic_type == CHIP_POLARIS11)
5275 /* Send msg to SMU via Powerplay */ 5315 /* Send msg to SMU via Powerplay */
5276 amdgpu_set_powergating_state(adev, 5316 amdgpu_set_powergating_state(adev,
@@ -5278,83 +5318,35 @@ static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *ade
5278 enable ? 5318 enable ?
5279 AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE); 5319 AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE);
5280 5320
5281 temp = data = RREG32(mmRLC_PG_CNTL); 5321 WREG32_FIELD(RLC_PG_CNTL, STATIC_PER_CU_PG_ENABLE, enable ? 1 : 0);
5282 /* Enable static MGPG */
5283 if (enable)
5284 data |= RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK;
5285 else
5286 data &= ~RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK;
5287
5288 if (temp != data)
5289 WREG32(mmRLC_PG_CNTL, data);
5290} 5322}
5291 5323
5292static void gfx_v8_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *adev, 5324static void gfx_v8_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *adev,
5293 bool enable) 5325 bool enable)
5294{ 5326{
5295 uint32_t data, temp; 5327 WREG32_FIELD(RLC_PG_CNTL, DYN_PER_CU_PG_ENABLE, enable ? 1 : 0);
5296
5297 temp = data = RREG32(mmRLC_PG_CNTL);
5298 /* Enable dynamic MGPG */
5299 if (enable)
5300 data |= RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK;
5301 else
5302 data &= ~RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK;
5303
5304 if (temp != data)
5305 WREG32(mmRLC_PG_CNTL, data);
5306} 5328}
5307 5329
5308static void polaris11_enable_gfx_quick_mg_power_gating(struct amdgpu_device *adev, 5330static void polaris11_enable_gfx_quick_mg_power_gating(struct amdgpu_device *adev,
5309 bool enable) 5331 bool enable)
5310{ 5332{
5311 uint32_t data, temp; 5333 WREG32_FIELD(RLC_PG_CNTL, QUICK_PG_ENABLE, enable ? 1 : 0);
5312
5313 temp = data = RREG32(mmRLC_PG_CNTL);
5314 /* Enable quick PG */
5315 if (enable)
5316 data |= RLC_PG_CNTL__QUICK_PG_ENABLE_MASK;
5317 else
5318 data &= ~RLC_PG_CNTL__QUICK_PG_ENABLE_MASK;
5319
5320 if (temp != data)
5321 WREG32(mmRLC_PG_CNTL, data);
5322} 5334}
5323 5335
5324static void cz_enable_gfx_cg_power_gating(struct amdgpu_device *adev, 5336static void cz_enable_gfx_cg_power_gating(struct amdgpu_device *adev,
5325 bool enable) 5337 bool enable)
5326{ 5338{
5327 u32 data, orig; 5339 WREG32_FIELD(RLC_PG_CNTL, GFX_POWER_GATING_ENABLE, enable ? 1 : 0);
5328
5329 orig = data = RREG32(mmRLC_PG_CNTL);
5330
5331 if (enable)
5332 data |= RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK;
5333 else
5334 data &= ~RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK;
5335
5336 if (orig != data)
5337 WREG32(mmRLC_PG_CNTL, data);
5338} 5340}
5339 5341
5340static void cz_enable_gfx_pipeline_power_gating(struct amdgpu_device *adev, 5342static void cz_enable_gfx_pipeline_power_gating(struct amdgpu_device *adev,
5341 bool enable) 5343 bool enable)
5342{ 5344{
5343 u32 data, orig; 5345 WREG32_FIELD(RLC_PG_CNTL, GFX_PIPELINE_PG_ENABLE, enable ? 1 : 0);
5344
5345 orig = data = RREG32(mmRLC_PG_CNTL);
5346
5347 if (enable)
5348 data |= RLC_PG_CNTL__GFX_PIPELINE_PG_ENABLE_MASK;
5349 else
5350 data &= ~RLC_PG_CNTL__GFX_PIPELINE_PG_ENABLE_MASK;
5351
5352 if (orig != data)
5353 WREG32(mmRLC_PG_CNTL, data);
5354 5346
5355 /* Read any GFX register to wake up GFX. */ 5347 /* Read any GFX register to wake up GFX. */
5356 if (!enable) 5348 if (!enable)
5357 data = RREG32(mmDB_RENDER_CONTROL); 5349 RREG32(mmDB_RENDER_CONTROL);
5358} 5350}
5359 5351
5360static void cz_update_gfx_cg_power_gating(struct amdgpu_device *adev, 5352static void cz_update_gfx_cg_power_gating(struct amdgpu_device *adev,
@@ -5430,15 +5422,15 @@ static void gfx_v8_0_send_serdes_cmd(struct amdgpu_device *adev,
5430 5422
5431 data = RREG32(mmRLC_SERDES_WR_CTRL); 5423 data = RREG32(mmRLC_SERDES_WR_CTRL);
5432 if (adev->asic_type == CHIP_STONEY) 5424 if (adev->asic_type == CHIP_STONEY)
5433 data &= ~(RLC_SERDES_WR_CTRL__WRITE_COMMAND_MASK | 5425 data &= ~(RLC_SERDES_WR_CTRL__WRITE_COMMAND_MASK |
5434 RLC_SERDES_WR_CTRL__READ_COMMAND_MASK | 5426 RLC_SERDES_WR_CTRL__READ_COMMAND_MASK |
5435 RLC_SERDES_WR_CTRL__P1_SELECT_MASK | 5427 RLC_SERDES_WR_CTRL__P1_SELECT_MASK |
5436 RLC_SERDES_WR_CTRL__P2_SELECT_MASK | 5428 RLC_SERDES_WR_CTRL__P2_SELECT_MASK |
5437 RLC_SERDES_WR_CTRL__RDDATA_RESET_MASK | 5429 RLC_SERDES_WR_CTRL__RDDATA_RESET_MASK |
5438 RLC_SERDES_WR_CTRL__POWER_DOWN_MASK | 5430 RLC_SERDES_WR_CTRL__POWER_DOWN_MASK |
5439 RLC_SERDES_WR_CTRL__POWER_UP_MASK | 5431 RLC_SERDES_WR_CTRL__POWER_UP_MASK |
5440 RLC_SERDES_WR_CTRL__SHORT_FORMAT_MASK | 5432 RLC_SERDES_WR_CTRL__SHORT_FORMAT_MASK |
5441 RLC_SERDES_WR_CTRL__SRBM_OVERRIDE_MASK); 5433 RLC_SERDES_WR_CTRL__SRBM_OVERRIDE_MASK);
5442 else 5434 else
5443 data &= ~(RLC_SERDES_WR_CTRL__WRITE_COMMAND_MASK | 5435 data &= ~(RLC_SERDES_WR_CTRL__WRITE_COMMAND_MASK |
5444 RLC_SERDES_WR_CTRL__READ_COMMAND_MASK | 5436 RLC_SERDES_WR_CTRL__READ_COMMAND_MASK |
@@ -5461,10 +5453,10 @@ static void gfx_v8_0_send_serdes_cmd(struct amdgpu_device *adev,
5461 5453
5462#define MSG_ENTER_RLC_SAFE_MODE 1 5454#define MSG_ENTER_RLC_SAFE_MODE 1
5463#define MSG_EXIT_RLC_SAFE_MODE 0 5455#define MSG_EXIT_RLC_SAFE_MODE 0
5464 5456#define RLC_GPR_REG2__REQ_MASK 0x00000001
5465#define RLC_GPR_REG2__REQ_MASK 0x00000001 5457#define RLC_GPR_REG2__REQ__SHIFT 0
5466#define RLC_GPR_REG2__MESSAGE__SHIFT 0x00000001 5458#define RLC_GPR_REG2__MESSAGE__SHIFT 0x00000001
5467#define RLC_GPR_REG2__MESSAGE_MASK 0x0000001e 5459#define RLC_GPR_REG2__MESSAGE_MASK 0x0000001e
5468 5460
5469static void cz_enter_rlc_safe_mode(struct amdgpu_device *adev) 5461static void cz_enter_rlc_safe_mode(struct amdgpu_device *adev)
5470{ 5462{
@@ -5494,7 +5486,7 @@ static void cz_enter_rlc_safe_mode(struct amdgpu_device *adev)
5494 } 5486 }
5495 5487
5496 for (i = 0; i < adev->usec_timeout; i++) { 5488 for (i = 0; i < adev->usec_timeout; i++) {
5497 if ((RREG32(mmRLC_GPR_REG2) & RLC_GPR_REG2__REQ_MASK) == 0) 5489 if (!REG_GET_FIELD(RREG32(mmRLC_GPR_REG2), RLC_GPR_REG2, REQ))
5498 break; 5490 break;
5499 udelay(1); 5491 udelay(1);
5500 } 5492 }
@@ -5522,7 +5514,7 @@ static void cz_exit_rlc_safe_mode(struct amdgpu_device *adev)
5522 } 5514 }
5523 5515
5524 for (i = 0; i < adev->usec_timeout; i++) { 5516 for (i = 0; i < adev->usec_timeout; i++) {
5525 if ((RREG32(mmRLC_GPR_REG2) & RLC_GPR_REG2__REQ_MASK) == 0) 5517 if (!REG_GET_FIELD(RREG32(mmRLC_GPR_REG2), RLC_GPR_REG2, REQ))
5526 break; 5518 break;
5527 udelay(1); 5519 udelay(1);
5528 } 5520 }
@@ -5554,7 +5546,7 @@ static void iceland_enter_rlc_safe_mode(struct amdgpu_device *adev)
5554 } 5546 }
5555 5547
5556 for (i = 0; i < adev->usec_timeout; i++) { 5548 for (i = 0; i < adev->usec_timeout; i++) {
5557 if ((RREG32(mmRLC_SAFE_MODE) & RLC_SAFE_MODE__CMD_MASK) == 0) 5549 if (!REG_GET_FIELD(RREG32(mmRLC_SAFE_MODE), RLC_SAFE_MODE, CMD))
5558 break; 5550 break;
5559 udelay(1); 5551 udelay(1);
5560 } 5552 }
@@ -5581,7 +5573,7 @@ static void iceland_exit_rlc_safe_mode(struct amdgpu_device *adev)
5581 } 5573 }
5582 5574
5583 for (i = 0; i < adev->usec_timeout; i++) { 5575 for (i = 0; i < adev->usec_timeout; i++) {
5584 if ((RREG32(mmRLC_SAFE_MODE) & RLC_SAFE_MODE__CMD_MASK) == 0) 5576 if (!REG_GET_FIELD(RREG32(mmRLC_SAFE_MODE), RLC_SAFE_MODE, CMD))
5585 break; 5577 break;
5586 udelay(1); 5578 udelay(1);
5587 } 5579 }
@@ -5622,21 +5614,12 @@ static void gfx_v8_0_update_medium_grain_clock_gating(struct amdgpu_device *adev
5622 /* It is disabled by HW by default */ 5614 /* It is disabled by HW by default */
5623 if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGCG)) { 5615 if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGCG)) {
5624 if (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGLS) { 5616 if (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGLS) {
5625 if (adev->cg_flags & AMD_CG_SUPPORT_GFX_RLC_LS) { 5617 if (adev->cg_flags & AMD_CG_SUPPORT_GFX_RLC_LS)
5626 /* 1 - RLC memory Light sleep */ 5618 /* 1 - RLC memory Light sleep */
5627 temp = data = RREG32(mmRLC_MEM_SLP_CNTL); 5619 WREG32_FIELD(RLC_MEM_SLP_CNTL, RLC_MEM_LS_EN, 1);
5628 data |= RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK;
5629 if (temp != data)
5630 WREG32(mmRLC_MEM_SLP_CNTL, data);
5631 }
5632 5620
5633 if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CP_LS) { 5621 if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CP_LS)
5634 /* 2 - CP memory Light sleep */ 5622 WREG32_FIELD(CP_MEM_SLP_CNTL, CP_MEM_LS_EN, 1);
5635 temp = data = RREG32(mmCP_MEM_SLP_CNTL);
5636 data |= CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK;
5637 if (temp != data)
5638 WREG32(mmCP_MEM_SLP_CNTL, data);
5639 }
5640 } 5623 }
5641 5624
5642 /* 3 - RLC_CGTT_MGCG_OVERRIDE */ 5625 /* 3 - RLC_CGTT_MGCG_OVERRIDE */
@@ -5854,25 +5837,18 @@ static int gfx_v8_0_set_clockgating_state(void *handle,
5854 5837
5855static u32 gfx_v8_0_ring_get_rptr_gfx(struct amdgpu_ring *ring) 5838static u32 gfx_v8_0_ring_get_rptr_gfx(struct amdgpu_ring *ring)
5856{ 5839{
5857 u32 rptr; 5840 return ring->adev->wb.wb[ring->rptr_offs];
5858
5859 rptr = ring->adev->wb.wb[ring->rptr_offs];
5860
5861 return rptr;
5862} 5841}
5863 5842
5864static u32 gfx_v8_0_ring_get_wptr_gfx(struct amdgpu_ring *ring) 5843static u32 gfx_v8_0_ring_get_wptr_gfx(struct amdgpu_ring *ring)
5865{ 5844{
5866 struct amdgpu_device *adev = ring->adev; 5845 struct amdgpu_device *adev = ring->adev;
5867 u32 wptr;
5868 5846
5869 if (ring->use_doorbell) 5847 if (ring->use_doorbell)
5870 /* XXX check if swapping is necessary on BE */ 5848 /* XXX check if swapping is necessary on BE */
5871 wptr = ring->adev->wb.wb[ring->wptr_offs]; 5849 return ring->adev->wb.wb[ring->wptr_offs];
5872 else 5850 else
5873 wptr = RREG32(mmCP_RB0_WPTR); 5851 return RREG32(mmCP_RB0_WPTR);
5874
5875 return wptr;
5876} 5852}
5877 5853
5878static void gfx_v8_0_ring_set_wptr_gfx(struct amdgpu_ring *ring) 5854static void gfx_v8_0_ring_set_wptr_gfx(struct amdgpu_ring *ring)
@@ -5971,9 +5947,9 @@ static void gfx_v8_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
5971 amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 5947 amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
5972 amdgpu_ring_write(ring, 5948 amdgpu_ring_write(ring,
5973#ifdef __BIG_ENDIAN 5949#ifdef __BIG_ENDIAN
5974 (2 << 0) | 5950 (2 << 0) |
5975#endif 5951#endif
5976 (ib->gpu_addr & 0xFFFFFFFC)); 5952 (ib->gpu_addr & 0xFFFFFFFC));
5977 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); 5953 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
5978 amdgpu_ring_write(ring, control); 5954 amdgpu_ring_write(ring, control);
5979} 5955}
@@ -6118,33 +6094,14 @@ static void gfx_v8_0_ring_emit_fence_compute(struct amdgpu_ring *ring,
6118static void gfx_v8_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev, 6094static void gfx_v8_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
6119 enum amdgpu_interrupt_state state) 6095 enum amdgpu_interrupt_state state)
6120{ 6096{
6121 u32 cp_int_cntl; 6097 WREG32_FIELD(CP_INT_CNTL_RING0, TIME_STAMP_INT_ENABLE,
6122 6098 state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
6123 switch (state) {
6124 case AMDGPU_IRQ_STATE_DISABLE:
6125 cp_int_cntl = RREG32(mmCP_INT_CNTL_RING0);
6126 cp_int_cntl = REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
6127 TIME_STAMP_INT_ENABLE, 0);
6128 WREG32(mmCP_INT_CNTL_RING0, cp_int_cntl);
6129 break;
6130 case AMDGPU_IRQ_STATE_ENABLE:
6131 cp_int_cntl = RREG32(mmCP_INT_CNTL_RING0);
6132 cp_int_cntl =
6133 REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
6134 TIME_STAMP_INT_ENABLE, 1);
6135 WREG32(mmCP_INT_CNTL_RING0, cp_int_cntl);
6136 break;
6137 default:
6138 break;
6139 }
6140} 6099}
6141 6100
6142static void gfx_v8_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev, 6101static void gfx_v8_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev,
6143 int me, int pipe, 6102 int me, int pipe,
6144 enum amdgpu_interrupt_state state) 6103 enum amdgpu_interrupt_state state)
6145{ 6104{
6146 u32 mec_int_cntl, mec_int_cntl_reg;
6147
6148 /* 6105 /*
6149 * amdgpu controls only pipe 0 of MEC1. That's why this function only 6106 * amdgpu controls only pipe 0 of MEC1. That's why this function only
6150 * handles the setting of interrupts for this specific pipe. All other 6107 * handles the setting of interrupts for this specific pipe. All other
@@ -6154,7 +6111,6 @@ static void gfx_v8_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev,
6154 if (me == 1) { 6111 if (me == 1) {
6155 switch (pipe) { 6112 switch (pipe) {
6156 case 0: 6113 case 0:
6157 mec_int_cntl_reg = mmCP_ME1_PIPE0_INT_CNTL;
6158 break; 6114 break;
6159 default: 6115 default:
6160 DRM_DEBUG("invalid pipe %d\n", pipe); 6116 DRM_DEBUG("invalid pipe %d\n", pipe);
@@ -6165,22 +6121,8 @@ static void gfx_v8_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev,
6165 return; 6121 return;
6166 } 6122 }
6167 6123
6168 switch (state) { 6124 WREG32_FIELD(CP_ME1_PIPE0_INT_CNTL, TIME_STAMP_INT_ENABLE,
6169 case AMDGPU_IRQ_STATE_DISABLE: 6125 state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
6170 mec_int_cntl = RREG32(mec_int_cntl_reg);
6171 mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
6172 TIME_STAMP_INT_ENABLE, 0);
6173 WREG32(mec_int_cntl_reg, mec_int_cntl);
6174 break;
6175 case AMDGPU_IRQ_STATE_ENABLE:
6176 mec_int_cntl = RREG32(mec_int_cntl_reg);
6177 mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
6178 TIME_STAMP_INT_ENABLE, 1);
6179 WREG32(mec_int_cntl_reg, mec_int_cntl);
6180 break;
6181 default:
6182 break;
6183 }
6184} 6126}
6185 6127
6186static int gfx_v8_0_set_priv_reg_fault_state(struct amdgpu_device *adev, 6128static int gfx_v8_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
@@ -6188,24 +6130,8 @@ static int gfx_v8_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
6188 unsigned type, 6130 unsigned type,
6189 enum amdgpu_interrupt_state state) 6131 enum amdgpu_interrupt_state state)
6190{ 6132{
6191 u32 cp_int_cntl; 6133 WREG32_FIELD(CP_INT_CNTL_RING0, PRIV_REG_INT_ENABLE,
6192 6134 state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
6193 switch (state) {
6194 case AMDGPU_IRQ_STATE_DISABLE:
6195 cp_int_cntl = RREG32(mmCP_INT_CNTL_RING0);
6196 cp_int_cntl = REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
6197 PRIV_REG_INT_ENABLE, 0);
6198 WREG32(mmCP_INT_CNTL_RING0, cp_int_cntl);
6199 break;
6200 case AMDGPU_IRQ_STATE_ENABLE:
6201 cp_int_cntl = RREG32(mmCP_INT_CNTL_RING0);
6202 cp_int_cntl = REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
6203 PRIV_REG_INT_ENABLE, 1);
6204 WREG32(mmCP_INT_CNTL_RING0, cp_int_cntl);
6205 break;
6206 default:
6207 break;
6208 }
6209 6135
6210 return 0; 6136 return 0;
6211} 6137}
@@ -6215,24 +6141,8 @@ static int gfx_v8_0_set_priv_inst_fault_state(struct amdgpu_device *adev,
6215 unsigned type, 6141 unsigned type,
6216 enum amdgpu_interrupt_state state) 6142 enum amdgpu_interrupt_state state)
6217{ 6143{
6218 u32 cp_int_cntl; 6144 WREG32_FIELD(CP_INT_CNTL_RING0, PRIV_INSTR_INT_ENABLE,
6219 6145 state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1);
6220 switch (state) {
6221 case AMDGPU_IRQ_STATE_DISABLE:
6222 cp_int_cntl = RREG32(mmCP_INT_CNTL_RING0);
6223 cp_int_cntl = REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
6224 PRIV_INSTR_INT_ENABLE, 0);
6225 WREG32(mmCP_INT_CNTL_RING0, cp_int_cntl);
6226 break;
6227 case AMDGPU_IRQ_STATE_ENABLE:
6228 cp_int_cntl = RREG32(mmCP_INT_CNTL_RING0);
6229 cp_int_cntl = REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
6230 PRIV_INSTR_INT_ENABLE, 1);
6231 WREG32(mmCP_INT_CNTL_RING0, cp_int_cntl);
6232 break;
6233 default:
6234 break;
6235 }
6236 6146
6237 return 0; 6147 return 0;
6238} 6148}
@@ -6338,7 +6248,10 @@ const struct amd_ip_funcs gfx_v8_0_ip_funcs = {
6338 .resume = gfx_v8_0_resume, 6248 .resume = gfx_v8_0_resume,
6339 .is_idle = gfx_v8_0_is_idle, 6249 .is_idle = gfx_v8_0_is_idle,
6340 .wait_for_idle = gfx_v8_0_wait_for_idle, 6250 .wait_for_idle = gfx_v8_0_wait_for_idle,
6251 .check_soft_reset = gfx_v8_0_check_soft_reset,
6252 .pre_soft_reset = gfx_v8_0_pre_soft_reset,
6341 .soft_reset = gfx_v8_0_soft_reset, 6253 .soft_reset = gfx_v8_0_soft_reset,
6254 .post_soft_reset = gfx_v8_0_post_soft_reset,
6342 .set_clockgating_state = gfx_v8_0_set_clockgating_state, 6255 .set_clockgating_state = gfx_v8_0_set_clockgating_state,
6343 .set_powergating_state = gfx_v8_0_set_powergating_state, 6256 .set_powergating_state = gfx_v8_0_set_powergating_state,
6344}; 6257};
@@ -6479,15 +6392,12 @@ static u32 gfx_v8_0_get_cu_active_bitmap(struct amdgpu_device *adev)
6479{ 6392{
6480 u32 data, mask; 6393 u32 data, mask;
6481 6394
6482 data = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG); 6395 data = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG) |
6483 data |= RREG32(mmGC_USER_SHADER_ARRAY_CONFIG); 6396 RREG32(mmGC_USER_SHADER_ARRAY_CONFIG);
6484
6485 data &= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK;
6486 data >>= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT;
6487 6397
6488 mask = gfx_v8_0_create_bitmask(adev->gfx.config.max_cu_per_sh); 6398 mask = gfx_v8_0_create_bitmask(adev->gfx.config.max_cu_per_sh);
6489 6399
6490 return (~data) & mask; 6400 return ~REG_GET_FIELD(data, CC_GC_SHADER_ARRAY_CONFIG, INACTIVE_CUS) & mask;
6491} 6401}
6492 6402
6493static void gfx_v8_0_get_cu_info(struct amdgpu_device *adev) 6403static void gfx_v8_0_get_cu_info(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h
index bc82c794312c..ebed1f829297 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h
@@ -26,6 +26,4 @@
26 26
27extern const struct amd_ip_funcs gfx_v8_0_ip_funcs; 27extern const struct amd_ip_funcs gfx_v8_0_ip_funcs;
28 28
29void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num);
30
31#endif 29#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 0b0f08641eed..aa0c4b964621 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -183,7 +183,7 @@ static int gmc_v7_0_mc_load_microcode(struct amdgpu_device *adev)
183 const struct mc_firmware_header_v1_0 *hdr; 183 const struct mc_firmware_header_v1_0 *hdr;
184 const __le32 *fw_data = NULL; 184 const __le32 *fw_data = NULL;
185 const __le32 *io_mc_regs = NULL; 185 const __le32 *io_mc_regs = NULL;
186 u32 running, blackout = 0; 186 u32 running;
187 int i, ucode_size, regs_size; 187 int i, ucode_size, regs_size;
188 188
189 if (!adev->mc.fw) 189 if (!adev->mc.fw)
@@ -203,11 +203,6 @@ static int gmc_v7_0_mc_load_microcode(struct amdgpu_device *adev)
203 running = REG_GET_FIELD(RREG32(mmMC_SEQ_SUP_CNTL), MC_SEQ_SUP_CNTL, RUN); 203 running = REG_GET_FIELD(RREG32(mmMC_SEQ_SUP_CNTL), MC_SEQ_SUP_CNTL, RUN);
204 204
205 if (running == 0) { 205 if (running == 0) {
206 if (running) {
207 blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
208 WREG32(mmMC_SHARED_BLACKOUT_CNTL, blackout | 1);
209 }
210
211 /* reset the engine and set to writable */ 206 /* reset the engine and set to writable */
212 WREG32(mmMC_SEQ_SUP_CNTL, 0x00000008); 207 WREG32(mmMC_SEQ_SUP_CNTL, 0x00000008);
213 WREG32(mmMC_SEQ_SUP_CNTL, 0x00000010); 208 WREG32(mmMC_SEQ_SUP_CNTL, 0x00000010);
@@ -239,9 +234,6 @@ static int gmc_v7_0_mc_load_microcode(struct amdgpu_device *adev)
239 break; 234 break;
240 udelay(1); 235 udelay(1);
241 } 236 }
242
243 if (running)
244 WREG32(mmMC_SHARED_BLACKOUT_CNTL, blackout);
245 } 237 }
246 238
247 return 0; 239 return 0;
@@ -393,7 +385,7 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
393 * size equal to the 1024 or vram, whichever is larger. 385 * size equal to the 1024 or vram, whichever is larger.
394 */ 386 */
395 if (amdgpu_gart_size == -1) 387 if (amdgpu_gart_size == -1)
396 adev->mc.gtt_size = max((1024ULL << 20), adev->mc.mc_vram_size); 388 adev->mc.gtt_size = amdgpu_ttm_get_gtt_mem_size(adev);
397 else 389 else
398 adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20; 390 adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
399 391
@@ -953,6 +945,11 @@ static int gmc_v7_0_sw_init(void *handle)
953 return r; 945 return r;
954 } 946 }
955 947
948 r = amdgpu_ttm_global_init(adev);
949 if (r) {
950 return r;
951 }
952
956 r = gmc_v7_0_mc_init(adev); 953 r = gmc_v7_0_mc_init(adev);
957 if (r) 954 if (r)
958 return r; 955 return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index 2aee2c6f3cd5..84c10d5117a9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -261,7 +261,7 @@ static int gmc_v8_0_mc_load_microcode(struct amdgpu_device *adev)
261 const struct mc_firmware_header_v1_0 *hdr; 261 const struct mc_firmware_header_v1_0 *hdr;
262 const __le32 *fw_data = NULL; 262 const __le32 *fw_data = NULL;
263 const __le32 *io_mc_regs = NULL; 263 const __le32 *io_mc_regs = NULL;
264 u32 running, blackout = 0; 264 u32 running;
265 int i, ucode_size, regs_size; 265 int i, ucode_size, regs_size;
266 266
267 if (!adev->mc.fw) 267 if (!adev->mc.fw)
@@ -287,11 +287,6 @@ static int gmc_v8_0_mc_load_microcode(struct amdgpu_device *adev)
287 running = REG_GET_FIELD(RREG32(mmMC_SEQ_SUP_CNTL), MC_SEQ_SUP_CNTL, RUN); 287 running = REG_GET_FIELD(RREG32(mmMC_SEQ_SUP_CNTL), MC_SEQ_SUP_CNTL, RUN);
288 288
289 if (running == 0) { 289 if (running == 0) {
290 if (running) {
291 blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
292 WREG32(mmMC_SHARED_BLACKOUT_CNTL, blackout | 1);
293 }
294
295 /* reset the engine and set to writable */ 290 /* reset the engine and set to writable */
296 WREG32(mmMC_SEQ_SUP_CNTL, 0x00000008); 291 WREG32(mmMC_SEQ_SUP_CNTL, 0x00000008);
297 WREG32(mmMC_SEQ_SUP_CNTL, 0x00000010); 292 WREG32(mmMC_SEQ_SUP_CNTL, 0x00000010);
@@ -323,9 +318,6 @@ static int gmc_v8_0_mc_load_microcode(struct amdgpu_device *adev)
323 break; 318 break;
324 udelay(1); 319 udelay(1);
325 } 320 }
326
327 if (running)
328 WREG32(mmMC_SHARED_BLACKOUT_CNTL, blackout);
329 } 321 }
330 322
331 return 0; 323 return 0;
@@ -477,7 +469,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
477 * size equal to the 1024 or vram, whichever is larger. 469 * size equal to the 1024 or vram, whichever is larger.
478 */ 470 */
479 if (amdgpu_gart_size == -1) 471 if (amdgpu_gart_size == -1)
480 adev->mc.gtt_size = max((1024ULL << 20), adev->mc.mc_vram_size); 472 adev->mc.gtt_size = amdgpu_ttm_get_gtt_mem_size(adev);
481 else 473 else
482 adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20; 474 adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
483 475
@@ -957,6 +949,11 @@ static int gmc_v8_0_sw_init(void *handle)
957 return r; 949 return r;
958 } 950 }
959 951
952 r = amdgpu_ttm_global_init(adev);
953 if (r) {
954 return r;
955 }
956
960 r = gmc_v8_0_mc_init(adev); 957 r = gmc_v8_0_mc_init(adev);
961 if (r) 958 if (r)
962 return r; 959 return r;
@@ -1100,9 +1097,8 @@ static int gmc_v8_0_wait_for_idle(void *handle)
1100 1097
1101} 1098}
1102 1099
1103static int gmc_v8_0_soft_reset(void *handle) 1100static int gmc_v8_0_check_soft_reset(void *handle)
1104{ 1101{
1105 struct amdgpu_mode_mc_save save;
1106 u32 srbm_soft_reset = 0; 1102 u32 srbm_soft_reset = 0;
1107 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1103 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1108 u32 tmp = RREG32(mmSRBM_STATUS); 1104 u32 tmp = RREG32(mmSRBM_STATUS);
@@ -1117,13 +1113,42 @@ static int gmc_v8_0_soft_reset(void *handle)
1117 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, 1113 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset,
1118 SRBM_SOFT_RESET, SOFT_RESET_MC, 1); 1114 SRBM_SOFT_RESET, SOFT_RESET_MC, 1);
1119 } 1115 }
1120
1121 if (srbm_soft_reset) { 1116 if (srbm_soft_reset) {
1122 gmc_v8_0_mc_stop(adev, &save); 1117 adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = true;
1123 if (gmc_v8_0_wait_for_idle((void *)adev)) { 1118 adev->mc.srbm_soft_reset = srbm_soft_reset;
1124 dev_warn(adev->dev, "Wait for GMC idle timed out !\n"); 1119 } else {
1125 } 1120 adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = false;
1121 adev->mc.srbm_soft_reset = 0;
1122 }
1123 return 0;
1124}
1126 1125
1126static int gmc_v8_0_pre_soft_reset(void *handle)
1127{
1128 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1129
1130 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
1131 return 0;
1132
1133 gmc_v8_0_mc_stop(adev, &adev->mc.save);
1134 if (gmc_v8_0_wait_for_idle(adev)) {
1135 dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
1136 }
1137
1138 return 0;
1139}
1140
1141static int gmc_v8_0_soft_reset(void *handle)
1142{
1143 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1144 u32 srbm_soft_reset;
1145
1146 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
1147 return 0;
1148 srbm_soft_reset = adev->mc.srbm_soft_reset;
1149
1150 if (srbm_soft_reset) {
1151 u32 tmp;
1127 1152
1128 tmp = RREG32(mmSRBM_SOFT_RESET); 1153 tmp = RREG32(mmSRBM_SOFT_RESET);
1129 tmp |= srbm_soft_reset; 1154 tmp |= srbm_soft_reset;
@@ -1139,14 +1164,22 @@ static int gmc_v8_0_soft_reset(void *handle)
1139 1164
1140 /* Wait a little for things to settle down */ 1165 /* Wait a little for things to settle down */
1141 udelay(50); 1166 udelay(50);
1142
1143 gmc_v8_0_mc_resume(adev, &save);
1144 udelay(50);
1145 } 1167 }
1146 1168
1147 return 0; 1169 return 0;
1148} 1170}
1149 1171
1172static int gmc_v8_0_post_soft_reset(void *handle)
1173{
1174 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1175
1176 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
1177 return 0;
1178
1179 gmc_v8_0_mc_resume(adev, &adev->mc.save);
1180 return 0;
1181}
1182
1150static int gmc_v8_0_vm_fault_interrupt_state(struct amdgpu_device *adev, 1183static int gmc_v8_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
1151 struct amdgpu_irq_src *src, 1184 struct amdgpu_irq_src *src,
1152 unsigned type, 1185 unsigned type,
@@ -1414,7 +1447,10 @@ const struct amd_ip_funcs gmc_v8_0_ip_funcs = {
1414 .resume = gmc_v8_0_resume, 1447 .resume = gmc_v8_0_resume,
1415 .is_idle = gmc_v8_0_is_idle, 1448 .is_idle = gmc_v8_0_is_idle,
1416 .wait_for_idle = gmc_v8_0_wait_for_idle, 1449 .wait_for_idle = gmc_v8_0_wait_for_idle,
1450 .check_soft_reset = gmc_v8_0_check_soft_reset,
1451 .pre_soft_reset = gmc_v8_0_pre_soft_reset,
1417 .soft_reset = gmc_v8_0_soft_reset, 1452 .soft_reset = gmc_v8_0_soft_reset,
1453 .post_soft_reset = gmc_v8_0_post_soft_reset,
1418 .set_clockgating_state = gmc_v8_0_set_clockgating_state, 1454 .set_clockgating_state = gmc_v8_0_set_clockgating_state,
1419 .set_powergating_state = gmc_v8_0_set_powergating_state, 1455 .set_powergating_state = gmc_v8_0_set_powergating_state,
1420}; 1456};
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
index a845e883f5fa..f8618a3881a8 100644
--- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
@@ -2845,7 +2845,11 @@ static int kv_dpm_init(struct amdgpu_device *adev)
2845 pi->caps_tcp_ramping = true; 2845 pi->caps_tcp_ramping = true;
2846 } 2846 }
2847 2847
2848 pi->caps_sclk_ds = true; 2848 if (amdgpu_sclk_deep_sleep_en)
2849 pi->caps_sclk_ds = true;
2850 else
2851 pi->caps_sclk_ds = false;
2852
2849 pi->enable_auto_thermal_throttling = true; 2853 pi->enable_auto_thermal_throttling = true;
2850 pi->disable_nb_ps3_in_battery = false; 2854 pi->disable_nb_ps3_in_battery = false;
2851 if (amdgpu_bapm == 0) 2855 if (amdgpu_bapm == 0)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
index 1351c7e834a2..e82229686783 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
@@ -749,24 +749,16 @@ static void sdma_v2_4_vm_copy_pte(struct amdgpu_ib *ib,
749 uint64_t pe, uint64_t src, 749 uint64_t pe, uint64_t src,
750 unsigned count) 750 unsigned count)
751{ 751{
752 while (count) { 752 unsigned bytes = count * 8;
753 unsigned bytes = count * 8; 753
754 if (bytes > 0x1FFFF8) 754 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
755 bytes = 0x1FFFF8; 755 SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
756 756 ib->ptr[ib->length_dw++] = bytes;
757 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) | 757 ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
758 SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR); 758 ib->ptr[ib->length_dw++] = lower_32_bits(src);
759 ib->ptr[ib->length_dw++] = bytes; 759 ib->ptr[ib->length_dw++] = upper_32_bits(src);
760 ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */ 760 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
761 ib->ptr[ib->length_dw++] = lower_32_bits(src); 761 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
762 ib->ptr[ib->length_dw++] = upper_32_bits(src);
763 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
764 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
765
766 pe += bytes;
767 src += bytes;
768 count -= bytes / 8;
769 }
770} 762}
771 763
772/** 764/**
@@ -774,39 +766,27 @@ static void sdma_v2_4_vm_copy_pte(struct amdgpu_ib *ib,
774 * 766 *
775 * @ib: indirect buffer to fill with commands 767 * @ib: indirect buffer to fill with commands
776 * @pe: addr of the page entry 768 * @pe: addr of the page entry
777 * @addr: dst addr to write into pe 769 * @value: dst addr to write into pe
778 * @count: number of page entries to update 770 * @count: number of page entries to update
779 * @incr: increase next addr by incr bytes 771 * @incr: increase next addr by incr bytes
780 * @flags: access flags
781 * 772 *
782 * Update PTEs by writing them manually using sDMA (CIK). 773 * Update PTEs by writing them manually using sDMA (CIK).
783 */ 774 */
784static void sdma_v2_4_vm_write_pte(struct amdgpu_ib *ib, 775static void sdma_v2_4_vm_write_pte(struct amdgpu_ib *ib, uint64_t pe,
785 const dma_addr_t *pages_addr, uint64_t pe, 776 uint64_t value, unsigned count,
786 uint64_t addr, unsigned count, 777 uint32_t incr)
787 uint32_t incr, uint32_t flags)
788{ 778{
789 uint64_t value; 779 unsigned ndw = count * 2;
790 unsigned ndw; 780
791 781 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) |
792 while (count) { 782 SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
793 ndw = count * 2; 783 ib->ptr[ib->length_dw++] = pe;
794 if (ndw > 0xFFFFE) 784 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
795 ndw = 0xFFFFE; 785 ib->ptr[ib->length_dw++] = ndw;
796 786 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
797 /* for non-physically contiguous pages (system) */ 787 ib->ptr[ib->length_dw++] = lower_32_bits(value);
798 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | 788 ib->ptr[ib->length_dw++] = upper_32_bits(value);
799 SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR); 789 value += incr;
800 ib->ptr[ib->length_dw++] = pe;
801 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
802 ib->ptr[ib->length_dw++] = ndw;
803 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
804 value = amdgpu_vm_map_gart(pages_addr, addr);
805 addr += incr;
806 value |= flags;
807 ib->ptr[ib->length_dw++] = value;
808 ib->ptr[ib->length_dw++] = upper_32_bits(value);
809 }
810 } 790 }
811} 791}
812 792
@@ -822,40 +802,21 @@ static void sdma_v2_4_vm_write_pte(struct amdgpu_ib *ib,
822 * 802 *
823 * Update the page tables using sDMA (CIK). 803 * Update the page tables using sDMA (CIK).
824 */ 804 */
825static void sdma_v2_4_vm_set_pte_pde(struct amdgpu_ib *ib, 805static void sdma_v2_4_vm_set_pte_pde(struct amdgpu_ib *ib, uint64_t pe,
826 uint64_t pe,
827 uint64_t addr, unsigned count, 806 uint64_t addr, unsigned count,
828 uint32_t incr, uint32_t flags) 807 uint32_t incr, uint32_t flags)
829{ 808{
830 uint64_t value; 809 /* for physically contiguous pages (vram) */
831 unsigned ndw; 810 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_GEN_PTEPDE);
832 811 ib->ptr[ib->length_dw++] = lower_32_bits(pe); /* dst addr */
833 while (count) { 812 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
834 ndw = count; 813 ib->ptr[ib->length_dw++] = flags; /* mask */
835 if (ndw > 0x7FFFF) 814 ib->ptr[ib->length_dw++] = 0;
836 ndw = 0x7FFFF; 815 ib->ptr[ib->length_dw++] = lower_32_bits(addr); /* value */
837 816 ib->ptr[ib->length_dw++] = upper_32_bits(addr);
838 if (flags & AMDGPU_PTE_VALID) 817 ib->ptr[ib->length_dw++] = incr; /* increment size */
839 value = addr; 818 ib->ptr[ib->length_dw++] = 0;
840 else 819 ib->ptr[ib->length_dw++] = count; /* number of entries */
841 value = 0;
842
843 /* for physically contiguous pages (vram) */
844 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_GEN_PTEPDE);
845 ib->ptr[ib->length_dw++] = pe; /* dst addr */
846 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
847 ib->ptr[ib->length_dw++] = flags; /* mask */
848 ib->ptr[ib->length_dw++] = 0;
849 ib->ptr[ib->length_dw++] = value; /* value */
850 ib->ptr[ib->length_dw++] = upper_32_bits(value);
851 ib->ptr[ib->length_dw++] = incr; /* increment size */
852 ib->ptr[ib->length_dw++] = 0;
853 ib->ptr[ib->length_dw++] = ndw; /* number of entries */
854
855 pe += ndw * 8;
856 addr += ndw * incr;
857 count -= ndw;
858 }
859} 820}
860 821
861/** 822/**
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index 653ce5ed55ae..bee4978bec73 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -976,24 +976,16 @@ static void sdma_v3_0_vm_copy_pte(struct amdgpu_ib *ib,
976 uint64_t pe, uint64_t src, 976 uint64_t pe, uint64_t src,
977 unsigned count) 977 unsigned count)
978{ 978{
979 while (count) { 979 unsigned bytes = count * 8;
980 unsigned bytes = count * 8; 980
981 if (bytes > 0x1FFFF8) 981 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
982 bytes = 0x1FFFF8; 982 SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
983 983 ib->ptr[ib->length_dw++] = bytes;
984 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) | 984 ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
985 SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR); 985 ib->ptr[ib->length_dw++] = lower_32_bits(src);
986 ib->ptr[ib->length_dw++] = bytes; 986 ib->ptr[ib->length_dw++] = upper_32_bits(src);
987 ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */ 987 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
988 ib->ptr[ib->length_dw++] = lower_32_bits(src); 988 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
989 ib->ptr[ib->length_dw++] = upper_32_bits(src);
990 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
991 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
992
993 pe += bytes;
994 src += bytes;
995 count -= bytes / 8;
996 }
997} 989}
998 990
999/** 991/**
@@ -1001,39 +993,27 @@ static void sdma_v3_0_vm_copy_pte(struct amdgpu_ib *ib,
1001 * 993 *
1002 * @ib: indirect buffer to fill with commands 994 * @ib: indirect buffer to fill with commands
1003 * @pe: addr of the page entry 995 * @pe: addr of the page entry
1004 * @addr: dst addr to write into pe 996 * @value: dst addr to write into pe
1005 * @count: number of page entries to update 997 * @count: number of page entries to update
1006 * @incr: increase next addr by incr bytes 998 * @incr: increase next addr by incr bytes
1007 * @flags: access flags
1008 * 999 *
1009 * Update PTEs by writing them manually using sDMA (CIK). 1000 * Update PTEs by writing them manually using sDMA (CIK).
1010 */ 1001 */
1011static void sdma_v3_0_vm_write_pte(struct amdgpu_ib *ib, 1002static void sdma_v3_0_vm_write_pte(struct amdgpu_ib *ib, uint64_t pe,
1012 const dma_addr_t *pages_addr, uint64_t pe, 1003 uint64_t value, unsigned count,
1013 uint64_t addr, unsigned count, 1004 uint32_t incr)
1014 uint32_t incr, uint32_t flags) 1005{
1015{ 1006 unsigned ndw = count * 2;
1016 uint64_t value; 1007
1017 unsigned ndw; 1008 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) |
1018 1009 SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
1019 while (count) { 1010 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
1020 ndw = count * 2; 1011 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
1021 if (ndw > 0xFFFFE) 1012 ib->ptr[ib->length_dw++] = ndw;
1022 ndw = 0xFFFFE; 1013 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
1023 1014 ib->ptr[ib->length_dw++] = lower_32_bits(value);
1024 /* for non-physically contiguous pages (system) */ 1015 ib->ptr[ib->length_dw++] = upper_32_bits(value);
1025 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | 1016 value += incr;
1026 SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
1027 ib->ptr[ib->length_dw++] = pe;
1028 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
1029 ib->ptr[ib->length_dw++] = ndw;
1030 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
1031 value = amdgpu_vm_map_gart(pages_addr, addr);
1032 addr += incr;
1033 value |= flags;
1034 ib->ptr[ib->length_dw++] = value;
1035 ib->ptr[ib->length_dw++] = upper_32_bits(value);
1036 }
1037 } 1017 }
1038} 1018}
1039 1019
@@ -1049,40 +1029,21 @@ static void sdma_v3_0_vm_write_pte(struct amdgpu_ib *ib,
1049 * 1029 *
1050 * Update the page tables using sDMA (CIK). 1030 * Update the page tables using sDMA (CIK).
1051 */ 1031 */
1052static void sdma_v3_0_vm_set_pte_pde(struct amdgpu_ib *ib, 1032static void sdma_v3_0_vm_set_pte_pde(struct amdgpu_ib *ib, uint64_t pe,
1053 uint64_t pe,
1054 uint64_t addr, unsigned count, 1033 uint64_t addr, unsigned count,
1055 uint32_t incr, uint32_t flags) 1034 uint32_t incr, uint32_t flags)
1056{ 1035{
1057 uint64_t value; 1036 /* for physically contiguous pages (vram) */
1058 unsigned ndw; 1037 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_GEN_PTEPDE);
1059 1038 ib->ptr[ib->length_dw++] = lower_32_bits(pe); /* dst addr */
1060 while (count) { 1039 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
1061 ndw = count; 1040 ib->ptr[ib->length_dw++] = flags; /* mask */
1062 if (ndw > 0x7FFFF) 1041 ib->ptr[ib->length_dw++] = 0;
1063 ndw = 0x7FFFF; 1042 ib->ptr[ib->length_dw++] = lower_32_bits(addr); /* value */
1064 1043 ib->ptr[ib->length_dw++] = upper_32_bits(addr);
1065 if (flags & AMDGPU_PTE_VALID) 1044 ib->ptr[ib->length_dw++] = incr; /* increment size */
1066 value = addr; 1045 ib->ptr[ib->length_dw++] = 0;
1067 else 1046 ib->ptr[ib->length_dw++] = count; /* number of entries */
1068 value = 0;
1069
1070 /* for physically contiguous pages (vram) */
1071 ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_GEN_PTEPDE);
1072 ib->ptr[ib->length_dw++] = pe; /* dst addr */
1073 ib->ptr[ib->length_dw++] = upper_32_bits(pe);
1074 ib->ptr[ib->length_dw++] = flags; /* mask */
1075 ib->ptr[ib->length_dw++] = 0;
1076 ib->ptr[ib->length_dw++] = value; /* value */
1077 ib->ptr[ib->length_dw++] = upper_32_bits(value);
1078 ib->ptr[ib->length_dw++] = incr; /* increment size */
1079 ib->ptr[ib->length_dw++] = 0;
1080 ib->ptr[ib->length_dw++] = ndw; /* number of entries */
1081
1082 pe += ndw * 8;
1083 addr += ndw * incr;
1084 count -= ndw;
1085 }
1086} 1047}
1087 1048
1088/** 1049/**
@@ -1320,28 +1281,79 @@ static int sdma_v3_0_wait_for_idle(void *handle)
1320 return -ETIMEDOUT; 1281 return -ETIMEDOUT;
1321} 1282}
1322 1283
1323static int sdma_v3_0_soft_reset(void *handle) 1284static int sdma_v3_0_check_soft_reset(void *handle)
1324{ 1285{
1325 u32 srbm_soft_reset = 0;
1326 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1286 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1287 u32 srbm_soft_reset = 0;
1327 u32 tmp = RREG32(mmSRBM_STATUS2); 1288 u32 tmp = RREG32(mmSRBM_STATUS2);
1328 1289
1329 if (tmp & SRBM_STATUS2__SDMA_BUSY_MASK) { 1290 if ((tmp & SRBM_STATUS2__SDMA_BUSY_MASK) ||
1330 /* sdma0 */ 1291 (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK)) {
1331 tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET);
1332 tmp = REG_SET_FIELD(tmp, SDMA0_F32_CNTL, HALT, 0);
1333 WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp);
1334 srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; 1292 srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK;
1335 }
1336 if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) {
1337 /* sdma1 */
1338 tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET);
1339 tmp = REG_SET_FIELD(tmp, SDMA0_F32_CNTL, HALT, 0);
1340 WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp);
1341 srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; 1293 srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK;
1342 } 1294 }
1343 1295
1344 if (srbm_soft_reset) { 1296 if (srbm_soft_reset) {
1297 adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = true;
1298 adev->sdma.srbm_soft_reset = srbm_soft_reset;
1299 } else {
1300 adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = false;
1301 adev->sdma.srbm_soft_reset = 0;
1302 }
1303
1304 return 0;
1305}
1306
1307static int sdma_v3_0_pre_soft_reset(void *handle)
1308{
1309 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1310 u32 srbm_soft_reset = 0;
1311
1312 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
1313 return 0;
1314
1315 srbm_soft_reset = adev->sdma.srbm_soft_reset;
1316
1317 if (REG_GET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA) ||
1318 REG_GET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA1)) {
1319 sdma_v3_0_ctx_switch_enable(adev, false);
1320 sdma_v3_0_enable(adev, false);
1321 }
1322
1323 return 0;
1324}
1325
1326static int sdma_v3_0_post_soft_reset(void *handle)
1327{
1328 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1329 u32 srbm_soft_reset = 0;
1330
1331 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
1332 return 0;
1333
1334 srbm_soft_reset = adev->sdma.srbm_soft_reset;
1335
1336 if (REG_GET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA) ||
1337 REG_GET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA1)) {
1338 sdma_v3_0_gfx_resume(adev);
1339 sdma_v3_0_rlc_resume(adev);
1340 }
1341
1342 return 0;
1343}
1344
1345static int sdma_v3_0_soft_reset(void *handle)
1346{
1347 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1348 u32 srbm_soft_reset = 0;
1349 u32 tmp;
1350
1351 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
1352 return 0;
1353
1354 srbm_soft_reset = adev->sdma.srbm_soft_reset;
1355
1356 if (srbm_soft_reset) {
1345 tmp = RREG32(mmSRBM_SOFT_RESET); 1357 tmp = RREG32(mmSRBM_SOFT_RESET);
1346 tmp |= srbm_soft_reset; 1358 tmp |= srbm_soft_reset;
1347 dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); 1359 dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
@@ -1559,6 +1571,9 @@ const struct amd_ip_funcs sdma_v3_0_ip_funcs = {
1559 .resume = sdma_v3_0_resume, 1571 .resume = sdma_v3_0_resume,
1560 .is_idle = sdma_v3_0_is_idle, 1572 .is_idle = sdma_v3_0_is_idle,
1561 .wait_for_idle = sdma_v3_0_wait_for_idle, 1573 .wait_for_idle = sdma_v3_0_wait_for_idle,
1574 .check_soft_reset = sdma_v3_0_check_soft_reset,
1575 .pre_soft_reset = sdma_v3_0_pre_soft_reset,
1576 .post_soft_reset = sdma_v3_0_post_soft_reset,
1562 .soft_reset = sdma_v3_0_soft_reset, 1577 .soft_reset = sdma_v3_0_soft_reset,
1563 .set_clockgating_state = sdma_v3_0_set_clockgating_state, 1578 .set_clockgating_state = sdma_v3_0_set_clockgating_state,
1564 .set_powergating_state = sdma_v3_0_set_powergating_state, 1579 .set_powergating_state = sdma_v3_0_set_powergating_state,
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
index c92055805a45..d127d59f953a 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
@@ -373,10 +373,10 @@ static int tonga_ih_wait_for_idle(void *handle)
373 return -ETIMEDOUT; 373 return -ETIMEDOUT;
374} 374}
375 375
376static int tonga_ih_soft_reset(void *handle) 376static int tonga_ih_check_soft_reset(void *handle)
377{ 377{
378 u32 srbm_soft_reset = 0;
379 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 378 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
379 u32 srbm_soft_reset = 0;
380 u32 tmp = RREG32(mmSRBM_STATUS); 380 u32 tmp = RREG32(mmSRBM_STATUS);
381 381
382 if (tmp & SRBM_STATUS__IH_BUSY_MASK) 382 if (tmp & SRBM_STATUS__IH_BUSY_MASK)
@@ -384,6 +384,48 @@ static int tonga_ih_soft_reset(void *handle)
384 SOFT_RESET_IH, 1); 384 SOFT_RESET_IH, 1);
385 385
386 if (srbm_soft_reset) { 386 if (srbm_soft_reset) {
387 adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang = true;
388 adev->irq.srbm_soft_reset = srbm_soft_reset;
389 } else {
390 adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang = false;
391 adev->irq.srbm_soft_reset = 0;
392 }
393
394 return 0;
395}
396
397static int tonga_ih_pre_soft_reset(void *handle)
398{
399 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
400
401 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang)
402 return 0;
403
404 return tonga_ih_hw_fini(adev);
405}
406
407static int tonga_ih_post_soft_reset(void *handle)
408{
409 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
410
411 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang)
412 return 0;
413
414 return tonga_ih_hw_init(adev);
415}
416
417static int tonga_ih_soft_reset(void *handle)
418{
419 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
420 u32 srbm_soft_reset;
421
422 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang)
423 return 0;
424 srbm_soft_reset = adev->irq.srbm_soft_reset;
425
426 if (srbm_soft_reset) {
427 u32 tmp;
428
387 tmp = RREG32(mmSRBM_SOFT_RESET); 429 tmp = RREG32(mmSRBM_SOFT_RESET);
388 tmp |= srbm_soft_reset; 430 tmp |= srbm_soft_reset;
389 dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); 431 dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
@@ -427,7 +469,10 @@ const struct amd_ip_funcs tonga_ih_ip_funcs = {
427 .resume = tonga_ih_resume, 469 .resume = tonga_ih_resume,
428 .is_idle = tonga_ih_is_idle, 470 .is_idle = tonga_ih_is_idle,
429 .wait_for_idle = tonga_ih_wait_for_idle, 471 .wait_for_idle = tonga_ih_wait_for_idle,
472 .check_soft_reset = tonga_ih_check_soft_reset,
473 .pre_soft_reset = tonga_ih_pre_soft_reset,
430 .soft_reset = tonga_ih_soft_reset, 474 .soft_reset = tonga_ih_soft_reset,
475 .post_soft_reset = tonga_ih_post_soft_reset,
431 .set_clockgating_state = tonga_ih_set_clockgating_state, 476 .set_clockgating_state = tonga_ih_set_clockgating_state,
432 .set_powergating_state = tonga_ih_set_powergating_state, 477 .set_powergating_state = tonga_ih_set_powergating_state,
433}; 478};
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
index 132e613ed674..10c0407dcb6e 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
@@ -116,7 +116,7 @@ static int uvd_v4_2_sw_init(void *handle)
116 116
117 ring = &adev->uvd.ring; 117 ring = &adev->uvd.ring;
118 sprintf(ring->name, "uvd"); 118 sprintf(ring->name, "uvd");
119 r = amdgpu_ring_init(adev, ring, 512, CP_PACKET2, 0xf, 119 r = amdgpu_ring_init(adev, ring, 512, PACKET0(mmUVD_NO_OP, 0), 0xf,
120 &adev->uvd.irq, 0, AMDGPU_RING_TYPE_UVD); 120 &adev->uvd.irq, 0, AMDGPU_RING_TYPE_UVD);
121 121
122 return r; 122 return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
index 101de136ba63..8513376062c1 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
@@ -112,7 +112,7 @@ static int uvd_v5_0_sw_init(void *handle)
112 112
113 ring = &adev->uvd.ring; 113 ring = &adev->uvd.ring;
114 sprintf(ring->name, "uvd"); 114 sprintf(ring->name, "uvd");
115 r = amdgpu_ring_init(adev, ring, 512, CP_PACKET2, 0xf, 115 r = amdgpu_ring_init(adev, ring, 512, PACKET0(mmUVD_NO_OP, 0), 0xf,
116 &adev->uvd.irq, 0, AMDGPU_RING_TYPE_UVD); 116 &adev->uvd.irq, 0, AMDGPU_RING_TYPE_UVD);
117 117
118 return r; 118 return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
index 7f21102bfb99..2abe8a93c99f 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
@@ -116,7 +116,7 @@ static int uvd_v6_0_sw_init(void *handle)
116 116
117 ring = &adev->uvd.ring; 117 ring = &adev->uvd.ring;
118 sprintf(ring->name, "uvd"); 118 sprintf(ring->name, "uvd");
119 r = amdgpu_ring_init(adev, ring, 512, CP_PACKET2, 0xf, 119 r = amdgpu_ring_init(adev, ring, 512, PACKET0(mmUVD_NO_OP, 0), 0xf,
120 &adev->uvd.irq, 0, AMDGPU_RING_TYPE_UVD); 120 &adev->uvd.irq, 0, AMDGPU_RING_TYPE_UVD);
121 121
122 return r; 122 return r;
@@ -396,21 +396,14 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
396 396
397 uvd_v6_0_mc_resume(adev); 397 uvd_v6_0_mc_resume(adev);
398 398
399 /* Set dynamic clock gating in S/W control mode */ 399 /* disable clock gating */
400 if (adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG) { 400 WREG32_FIELD(UVD_CGC_CTRL, DYN_CLOCK_MODE, 0);
401 uvd_v6_0_set_sw_clock_gating(adev);
402 } else {
403 /* disable clock gating */
404 uint32_t data = RREG32(mmUVD_CGC_CTRL);
405 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
406 WREG32(mmUVD_CGC_CTRL, data);
407 }
408 401
409 /* disable interupt */ 402 /* disable interupt */
410 WREG32_P(mmUVD_MASTINT_EN, 0, ~UVD_MASTINT_EN__VCPU_EN_MASK); 403 WREG32_FIELD(UVD_MASTINT_EN, VCPU_EN, 0);
411 404
412 /* stall UMC and register bus before resetting VCPU */ 405 /* stall UMC and register bus before resetting VCPU */
413 WREG32_P(mmUVD_LMI_CTRL2, UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 406 WREG32_FIELD(UVD_LMI_CTRL2, STALL_ARB_UMC, 1);
414 mdelay(1); 407 mdelay(1);
415 408
416 /* put LMI, VCPU, RBC etc... into reset */ 409 /* put LMI, VCPU, RBC etc... into reset */
@@ -426,7 +419,7 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
426 mdelay(5); 419 mdelay(5);
427 420
428 /* take UVD block out of reset */ 421 /* take UVD block out of reset */
429 WREG32_P(mmSRBM_SOFT_RESET, 0, ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK); 422 WREG32_FIELD(SRBM_SOFT_RESET, SOFT_RESET_UVD, 0);
430 mdelay(5); 423 mdelay(5);
431 424
432 /* initialize UVD memory controller */ 425 /* initialize UVD memory controller */
@@ -461,7 +454,7 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
461 WREG32(mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK); 454 WREG32(mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK);
462 455
463 /* enable UMC */ 456 /* enable UMC */
464 WREG32_P(mmUVD_LMI_CTRL2, 0, ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); 457 WREG32_FIELD(UVD_LMI_CTRL2, STALL_ARB_UMC, 0);
465 458
466 /* boot up the VCPU */ 459 /* boot up the VCPU */
467 WREG32(mmUVD_SOFT_RESET, 0); 460 WREG32(mmUVD_SOFT_RESET, 0);
@@ -481,11 +474,9 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
481 break; 474 break;
482 475
483 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n"); 476 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
484 WREG32_P(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK, 477 WREG32_FIELD(UVD_SOFT_RESET, VCPU_SOFT_RESET, 1);
485 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
486 mdelay(10); 478 mdelay(10);
487 WREG32_P(mmUVD_SOFT_RESET, 0, 479 WREG32_FIELD(UVD_SOFT_RESET, VCPU_SOFT_RESET, 0);
488 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
489 mdelay(10); 480 mdelay(10);
490 r = -1; 481 r = -1;
491 } 482 }
@@ -502,15 +493,14 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
502 /* clear the bit 4 of UVD_STATUS */ 493 /* clear the bit 4 of UVD_STATUS */
503 WREG32_P(mmUVD_STATUS, 0, ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); 494 WREG32_P(mmUVD_STATUS, 0, ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
504 495
496 /* force RBC into idle state */
505 rb_bufsz = order_base_2(ring->ring_size); 497 rb_bufsz = order_base_2(ring->ring_size);
506 tmp = 0; 498 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
507 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
508 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); 499 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
509 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); 500 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
510 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); 501 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
511 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); 502 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
512 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); 503 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
513 /* force RBC into idle state */
514 WREG32(mmUVD_RBC_RB_CNTL, tmp); 504 WREG32(mmUVD_RBC_RB_CNTL, tmp);
515 505
516 /* set the write pointer delay */ 506 /* set the write pointer delay */
@@ -531,7 +521,7 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
531 ring->wptr = RREG32(mmUVD_RBC_RB_RPTR); 521 ring->wptr = RREG32(mmUVD_RBC_RB_RPTR);
532 WREG32(mmUVD_RBC_RB_WPTR, ring->wptr); 522 WREG32(mmUVD_RBC_RB_WPTR, ring->wptr);
533 523
534 WREG32_P(mmUVD_RBC_RB_CNTL, 0, ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); 524 WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0);
535 525
536 return 0; 526 return 0;
537} 527}
@@ -748,20 +738,82 @@ static int uvd_v6_0_wait_for_idle(void *handle)
748 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 738 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
749 739
750 for (i = 0; i < adev->usec_timeout; i++) { 740 for (i = 0; i < adev->usec_timeout; i++) {
751 if (!(RREG32(mmSRBM_STATUS) & SRBM_STATUS__UVD_BUSY_MASK)) 741 if (uvd_v6_0_is_idle(handle))
752 return 0; 742 return 0;
753 } 743 }
754 return -ETIMEDOUT; 744 return -ETIMEDOUT;
755} 745}
756 746
757static int uvd_v6_0_soft_reset(void *handle) 747#define AMDGPU_UVD_STATUS_BUSY_MASK 0xfd
748static int uvd_v6_0_check_soft_reset(void *handle)
758{ 749{
759 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 750 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
751 u32 srbm_soft_reset = 0;
752 u32 tmp = RREG32(mmSRBM_STATUS);
753
754 if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) ||
755 REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) ||
756 (RREG32(mmUVD_STATUS) & AMDGPU_UVD_STATUS_BUSY_MASK))
757 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1);
758
759 if (srbm_soft_reset) {
760 adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang = true;
761 adev->uvd.srbm_soft_reset = srbm_soft_reset;
762 } else {
763 adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang = false;
764 adev->uvd.srbm_soft_reset = 0;
765 }
766 return 0;
767}
768static int uvd_v6_0_pre_soft_reset(void *handle)
769{
770 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
771
772 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang)
773 return 0;
760 774
761 uvd_v6_0_stop(adev); 775 uvd_v6_0_stop(adev);
776 return 0;
777}
778
779static int uvd_v6_0_soft_reset(void *handle)
780{
781 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
782 u32 srbm_soft_reset;
783
784 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang)
785 return 0;
786 srbm_soft_reset = adev->uvd.srbm_soft_reset;
787
788 if (srbm_soft_reset) {
789 u32 tmp;
790
791 tmp = RREG32(mmSRBM_SOFT_RESET);
792 tmp |= srbm_soft_reset;
793 dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
794 WREG32(mmSRBM_SOFT_RESET, tmp);
795 tmp = RREG32(mmSRBM_SOFT_RESET);
796
797 udelay(50);
798
799 tmp &= ~srbm_soft_reset;
800 WREG32(mmSRBM_SOFT_RESET, tmp);
801 tmp = RREG32(mmSRBM_SOFT_RESET);
802
803 /* Wait a little for things to settle down */
804 udelay(50);
805 }
806
807 return 0;
808}
809
810static int uvd_v6_0_post_soft_reset(void *handle)
811{
812 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
813
814 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang)
815 return 0;
762 816
763 WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK,
764 ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK);
765 mdelay(5); 817 mdelay(5);
766 818
767 return uvd_v6_0_start(adev); 819 return uvd_v6_0_start(adev);
@@ -902,21 +954,15 @@ static int uvd_v6_0_set_clockgating_state(void *handle,
902 enum amd_clockgating_state state) 954 enum amd_clockgating_state state)
903{ 955{
904 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 956 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
905 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
906 static int curstate = -1;
907 957
908 if (adev->asic_type == CHIP_FIJI || 958 if (adev->asic_type == CHIP_FIJI ||
909 adev->asic_type == CHIP_POLARIS10) 959 adev->asic_type == CHIP_POLARIS10)
910 uvd_v6_set_bypass_mode(adev, enable); 960 uvd_v6_set_bypass_mode(adev, state == AMD_CG_STATE_GATE ? true : false);
911 961
912 if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG)) 962 if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG))
913 return 0; 963 return 0;
914 964
915 if (curstate == state) 965 if (state == AMD_CG_STATE_GATE) {
916 return 0;
917
918 curstate = state;
919 if (enable) {
920 /* disable HW gating and enable Sw gating */ 966 /* disable HW gating and enable Sw gating */
921 uvd_v6_0_set_sw_clock_gating(adev); 967 uvd_v6_0_set_sw_clock_gating(adev);
922 } else { 968 } else {
@@ -946,6 +992,8 @@ static int uvd_v6_0_set_powergating_state(void *handle,
946 if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD)) 992 if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD))
947 return 0; 993 return 0;
948 994
995 WREG32(mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK);
996
949 if (state == AMD_PG_STATE_GATE) { 997 if (state == AMD_PG_STATE_GATE) {
950 uvd_v6_0_stop(adev); 998 uvd_v6_0_stop(adev);
951 return 0; 999 return 0;
@@ -966,7 +1014,10 @@ const struct amd_ip_funcs uvd_v6_0_ip_funcs = {
966 .resume = uvd_v6_0_resume, 1014 .resume = uvd_v6_0_resume,
967 .is_idle = uvd_v6_0_is_idle, 1015 .is_idle = uvd_v6_0_is_idle,
968 .wait_for_idle = uvd_v6_0_wait_for_idle, 1016 .wait_for_idle = uvd_v6_0_wait_for_idle,
1017 .check_soft_reset = uvd_v6_0_check_soft_reset,
1018 .pre_soft_reset = uvd_v6_0_pre_soft_reset,
969 .soft_reset = uvd_v6_0_soft_reset, 1019 .soft_reset = uvd_v6_0_soft_reset,
1020 .post_soft_reset = uvd_v6_0_post_soft_reset,
970 .set_clockgating_state = uvd_v6_0_set_clockgating_state, 1021 .set_clockgating_state = uvd_v6_0_set_clockgating_state,
971 .set_powergating_state = uvd_v6_0_set_powergating_state, 1022 .set_powergating_state = uvd_v6_0_set_powergating_state,
972}; 1023};
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
index 80a37a602181..5fa55b52c00e 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
@@ -40,6 +40,7 @@
40#define VCE_V2_0_FW_SIZE (256 * 1024) 40#define VCE_V2_0_FW_SIZE (256 * 1024)
41#define VCE_V2_0_STACK_SIZE (64 * 1024) 41#define VCE_V2_0_STACK_SIZE (64 * 1024)
42#define VCE_V2_0_DATA_SIZE (23552 * AMDGPU_MAX_VCE_HANDLES) 42#define VCE_V2_0_DATA_SIZE (23552 * AMDGPU_MAX_VCE_HANDLES)
43#define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02
43 44
44static void vce_v2_0_mc_resume(struct amdgpu_device *adev); 45static void vce_v2_0_mc_resume(struct amdgpu_device *adev);
45static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev); 46static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev);
@@ -96,6 +97,49 @@ static void vce_v2_0_ring_set_wptr(struct amdgpu_ring *ring)
96 WREG32(mmVCE_RB_WPTR2, ring->wptr); 97 WREG32(mmVCE_RB_WPTR2, ring->wptr);
97} 98}
98 99
100static int vce_v2_0_lmi_clean(struct amdgpu_device *adev)
101{
102 int i, j;
103
104 for (i = 0; i < 10; ++i) {
105 for (j = 0; j < 100; ++j) {
106 uint32_t status = RREG32(mmVCE_LMI_STATUS);
107
108 if (status & 0x337f)
109 return 0;
110 mdelay(10);
111 }
112 }
113
114 return -ETIMEDOUT;
115}
116
117static int vce_v2_0_firmware_loaded(struct amdgpu_device *adev)
118{
119 int i, j;
120
121 for (i = 0; i < 10; ++i) {
122 for (j = 0; j < 100; ++j) {
123 uint32_t status = RREG32(mmVCE_STATUS);
124
125 if (status & VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK)
126 return 0;
127 mdelay(10);
128 }
129
130 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
131 WREG32_P(mmVCE_SOFT_RESET,
132 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
133 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
134 mdelay(10);
135 WREG32_P(mmVCE_SOFT_RESET, 0,
136 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
137 mdelay(10);
138 }
139
140 return -ETIMEDOUT;
141}
142
99/** 143/**
100 * vce_v2_0_start - start VCE block 144 * vce_v2_0_start - start VCE block
101 * 145 *
@@ -106,7 +150,7 @@ static void vce_v2_0_ring_set_wptr(struct amdgpu_ring *ring)
106static int vce_v2_0_start(struct amdgpu_device *adev) 150static int vce_v2_0_start(struct amdgpu_device *adev)
107{ 151{
108 struct amdgpu_ring *ring; 152 struct amdgpu_ring *ring;
109 int i, j, r; 153 int r;
110 154
111 vce_v2_0_mc_resume(adev); 155 vce_v2_0_mc_resume(adev);
112 156
@@ -127,36 +171,12 @@ static int vce_v2_0_start(struct amdgpu_device *adev)
127 WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 171 WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
128 WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4); 172 WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
129 173
130 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ~VCE_VCPU_CNTL__CLK_EN_MASK); 174 WREG32_FIELD(VCE_VCPU_CNTL, CLK_EN, 1);
131 175 WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 1);
132 WREG32_P(mmVCE_SOFT_RESET,
133 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
134 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
135
136 mdelay(100); 176 mdelay(100);
177 WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 0);
137 178
138 WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 179 r = vce_v2_0_firmware_loaded(adev);
139
140 for (i = 0; i < 10; ++i) {
141 uint32_t status;
142 for (j = 0; j < 100; ++j) {
143 status = RREG32(mmVCE_STATUS);
144 if (status & 2)
145 break;
146 mdelay(10);
147 }
148 r = 0;
149 if (status & 2)
150 break;
151
152 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
153 WREG32_P(mmVCE_SOFT_RESET, VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
154 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
155 mdelay(10);
156 WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
157 mdelay(10);
158 r = -1;
159 }
160 180
161 /* clear BUSY flag */ 181 /* clear BUSY flag */
162 WREG32_P(mmVCE_STATUS, 0, ~1); 182 WREG32_P(mmVCE_STATUS, 0, ~1);
@@ -338,47 +358,50 @@ static void vce_v2_0_set_sw_cg(struct amdgpu_device *adev, bool gated)
338 358
339static void vce_v2_0_set_dyn_cg(struct amdgpu_device *adev, bool gated) 359static void vce_v2_0_set_dyn_cg(struct amdgpu_device *adev, bool gated)
340{ 360{
341 u32 orig, tmp; 361 if (vce_v2_0_wait_for_idle(adev)) {
362 DRM_INFO("VCE is busy, Can't set clock gateing");
363 return;
364 }
342 365
343 if (gated) { 366 WREG32_P(mmVCE_LMI_CTRL2, 0x100, ~0x100);
344 if (vce_v2_0_wait_for_idle(adev)) { 367
345 DRM_INFO("VCE is busy, Can't set clock gateing"); 368 if (vce_v2_0_lmi_clean(adev)) {
346 return; 369 DRM_INFO("LMI is busy, Can't set clock gateing");
347 } 370 return;
348 WREG32_P(mmVCE_VCPU_CNTL, 0, ~VCE_VCPU_CNTL__CLK_EN_MASK);
349 WREG32_P(mmVCE_SOFT_RESET, VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
350 mdelay(100);
351 WREG32(mmVCE_STATUS, 0);
352 } else {
353 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ~VCE_VCPU_CNTL__CLK_EN_MASK);
354 WREG32_P(mmVCE_SOFT_RESET, VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
355 mdelay(100);
356 } 371 }
357 372
358 tmp = RREG32(mmVCE_CLOCK_GATING_B); 373 WREG32_P(mmVCE_VCPU_CNTL, 0, ~VCE_VCPU_CNTL__CLK_EN_MASK);
359 tmp &= ~0x00060006; 374 WREG32_P(mmVCE_SOFT_RESET,
375 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
376 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
377 WREG32(mmVCE_STATUS, 0);
378
379 if (gated)
380 WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
381 /* LMI_MC/LMI_UMC always set in dynamic, set {CGC_*_GATE_MODE, CGC_*_SW_GATE} = {0, 0} */
360 if (gated) { 382 if (gated) {
361 tmp |= 0xe10000; 383 /* Force CLOCK OFF , set {CGC_*_GATE_MODE, CGC_*_SW_GATE} = {*, 1} */
384 WREG32(mmVCE_CLOCK_GATING_B, 0xe90010);
362 } else { 385 } else {
363 tmp |= 0xe1; 386 /* Force CLOCK ON, set {CGC_*_GATE_MODE, CGC_*_SW_GATE} = {1, 0} */
364 tmp &= ~0xe10000; 387 WREG32(mmVCE_CLOCK_GATING_B, 0x800f1);
365 } 388 }
366 WREG32(mmVCE_CLOCK_GATING_B, tmp);
367 389
368 orig = tmp = RREG32(mmVCE_UENC_CLOCK_GATING); 390 /* Set VCE_UENC_CLOCK_GATING always in dynamic mode {*_FORCE_ON, *_FORCE_OFF} = {0, 0}*/;
369 tmp &= ~0x1fe000; 391 WREG32(mmVCE_UENC_CLOCK_GATING, 0x40);
370 tmp &= ~0xff000000;
371 if (tmp != orig)
372 WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
373 392
374 orig = tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING); 393 /* set VCE_UENC_REG_CLOCK_GATING always in dynamic mode */
375 tmp &= ~0x3fc; 394 WREG32(mmVCE_UENC_REG_CLOCK_GATING, 0x00);
376 if (tmp != orig)
377 WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
378 395
379 if (gated) 396 WREG32_P(mmVCE_LMI_CTRL2, 0, ~0x100);
380 WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0); 397 if(!gated) {
381 WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 398 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ~VCE_VCPU_CNTL__CLK_EN_MASK);
399 mdelay(100);
400 WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
401
402 vce_v2_0_firmware_loaded(adev);
403 WREG32_P(mmVCE_STATUS, 0, ~VCE_STATUS__JOB_BUSY_MASK);
404 }
382} 405}
383 406
384static void vce_v2_0_disable_cg(struct amdgpu_device *adev) 407static void vce_v2_0_disable_cg(struct amdgpu_device *adev)
@@ -458,9 +481,7 @@ static void vce_v2_0_mc_resume(struct amdgpu_device *adev)
458 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 481 WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
459 482
460 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100); 483 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
461 484 WREG32_FIELD(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, 1);
462 WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
463 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
464 485
465 vce_v2_0_init_cg(adev); 486 vce_v2_0_init_cg(adev);
466} 487}
@@ -474,11 +495,11 @@ static bool vce_v2_0_is_idle(void *handle)
474 495
475static int vce_v2_0_wait_for_idle(void *handle) 496static int vce_v2_0_wait_for_idle(void *handle)
476{ 497{
477 unsigned i;
478 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 498 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
499 unsigned i;
479 500
480 for (i = 0; i < adev->usec_timeout; i++) { 501 for (i = 0; i < adev->usec_timeout; i++) {
481 if (!(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK)) 502 if (vce_v2_0_is_idle(handle))
482 return 0; 503 return 0;
483 } 504 }
484 return -ETIMEDOUT; 505 return -ETIMEDOUT;
@@ -488,8 +509,7 @@ static int vce_v2_0_soft_reset(void *handle)
488{ 509{
489 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 510 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
490 511
491 WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK, 512 WREG32_FIELD(SRBM_SOFT_RESET, SOFT_RESET_VCE, 1);
492 ~SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK);
493 mdelay(5); 513 mdelay(5);
494 514
495 return vce_v2_0_start(adev); 515 return vce_v2_0_start(adev);
@@ -516,10 +536,8 @@ static int vce_v2_0_process_interrupt(struct amdgpu_device *adev,
516 DRM_DEBUG("IH: VCE\n"); 536 DRM_DEBUG("IH: VCE\n");
517 switch (entry->src_data) { 537 switch (entry->src_data) {
518 case 0: 538 case 0:
519 amdgpu_fence_process(&adev->vce.ring[0]);
520 break;
521 case 1: 539 case 1:
522 amdgpu_fence_process(&adev->vce.ring[1]); 540 amdgpu_fence_process(&adev->vce.ring[entry->src_data]);
523 break; 541 break;
524 default: 542 default:
525 DRM_ERROR("Unhandled interrupt: %d %d\n", 543 DRM_ERROR("Unhandled interrupt: %d %d\n",
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
index c271abffd8dd..615b8b16ad04 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
@@ -37,6 +37,9 @@
37#include "gca/gfx_8_0_d.h" 37#include "gca/gfx_8_0_d.h"
38#include "smu/smu_7_1_2_d.h" 38#include "smu/smu_7_1_2_d.h"
39#include "smu/smu_7_1_2_sh_mask.h" 39#include "smu/smu_7_1_2_sh_mask.h"
40#include "gca/gfx_8_0_d.h"
41#include "gca/gfx_8_0_sh_mask.h"
42
40 43
41#define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 44#define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04
42#define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 45#define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10
@@ -107,102 +110,72 @@ static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring)
107 110
108static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override) 111static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override)
109{ 112{
110 u32 tmp, data; 113 WREG32_FIELD(VCE_RB_ARB_CTRL, VCE_CGTT_OVERRIDE, override ? 1 : 0);
111
112 tmp = data = RREG32(mmVCE_RB_ARB_CTRL);
113 if (override)
114 data |= VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK;
115 else
116 data &= ~VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK;
117
118 if (tmp != data)
119 WREG32(mmVCE_RB_ARB_CTRL, data);
120} 114}
121 115
122static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev, 116static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev,
123 bool gated) 117 bool gated)
124{ 118{
125 u32 tmp, data; 119 u32 data;
120
126 /* Set Override to disable Clock Gating */ 121 /* Set Override to disable Clock Gating */
127 vce_v3_0_override_vce_clock_gating(adev, true); 122 vce_v3_0_override_vce_clock_gating(adev, true);
128 123
129 if (!gated) { 124 /* This function enables MGCG which is controlled by firmware.
130 /* Force CLOCK ON for VCE_CLOCK_GATING_B, 125 With the clocks in the gated state the core is still
131 * {*_FORCE_ON, *_FORCE_OFF} = {1, 0} 126 accessible but the firmware will throttle the clocks on the
132 * VREG can be FORCE ON or set to Dynamic, but can't be OFF 127 fly as necessary.
133 */ 128 */
134 tmp = data = RREG32(mmVCE_CLOCK_GATING_B); 129 if (gated) {
130 data = RREG32(mmVCE_CLOCK_GATING_B);
135 data |= 0x1ff; 131 data |= 0x1ff;
136 data &= ~0xef0000; 132 data &= ~0xef0000;
137 if (tmp != data) 133 WREG32(mmVCE_CLOCK_GATING_B, data);
138 WREG32(mmVCE_CLOCK_GATING_B, data);
139 134
140 /* Force CLOCK ON for VCE_UENC_CLOCK_GATING, 135 data = RREG32(mmVCE_UENC_CLOCK_GATING);
141 * {*_FORCE_ON, *_FORCE_OFF} = {1, 0}
142 */
143 tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING);
144 data |= 0x3ff000; 136 data |= 0x3ff000;
145 data &= ~0xffc00000; 137 data &= ~0xffc00000;
146 if (tmp != data) 138 WREG32(mmVCE_UENC_CLOCK_GATING, data);
147 WREG32(mmVCE_UENC_CLOCK_GATING, data);
148 139
149 /* set VCE_UENC_CLOCK_GATING_2 */ 140 data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
150 tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
151 data |= 0x2; 141 data |= 0x2;
152 data &= ~0x2; 142 data &= ~0x00010000;
153 if (tmp != data) 143 WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
154 WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
155 144
156 /* Force CLOCK ON for VCE_UENC_REG_CLOCK_GATING */ 145 data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
157 tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
158 data |= 0x37f; 146 data |= 0x37f;
159 if (tmp != data) 147 WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
160 WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
161 148
162 /* Force VCE_UENC_DMA_DCLK_CTRL Clock ON */ 149 data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
163 tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
164 data |= VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK | 150 data |= VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK |
165 VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK | 151 VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK |
166 VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK | 152 VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK |
167 0x8; 153 0x8;
168 if (tmp != data) 154 WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
169 WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
170 } else { 155 } else {
171 /* Force CLOCK OFF for VCE_CLOCK_GATING_B, 156 data = RREG32(mmVCE_CLOCK_GATING_B);
172 * {*, *_FORCE_OFF} = {*, 1}
173 * set VREG to Dynamic, as it can't be OFF
174 */
175 tmp = data = RREG32(mmVCE_CLOCK_GATING_B);
176 data &= ~0x80010; 157 data &= ~0x80010;
177 data |= 0xe70008; 158 data |= 0xe70008;
178 if (tmp != data) 159 WREG32(mmVCE_CLOCK_GATING_B, data);
179 WREG32(mmVCE_CLOCK_GATING_B, data); 160
180 /* Force CLOCK OFF for VCE_UENC_CLOCK_GATING, 161 data = RREG32(mmVCE_UENC_CLOCK_GATING);
181 * Force ClOCK OFF takes precedent over Force CLOCK ON setting.
182 * {*_FORCE_ON, *_FORCE_OFF} = {*, 1}
183 */
184 tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING);
185 data |= 0xffc00000; 162 data |= 0xffc00000;
186 if (tmp != data) 163 WREG32(mmVCE_UENC_CLOCK_GATING, data);
187 WREG32(mmVCE_UENC_CLOCK_GATING, data); 164
188 /* Set VCE_UENC_CLOCK_GATING_2 */ 165 data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
189 tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
190 data |= 0x10000; 166 data |= 0x10000;
191 if (tmp != data) 167 WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
192 WREG32(mmVCE_UENC_CLOCK_GATING_2, data); 168
193 /* Set VCE_UENC_REG_CLOCK_GATING to dynamic */ 169 data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
194 tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
195 data &= ~0xffc00000; 170 data &= ~0xffc00000;
196 if (tmp != data) 171 WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
197 WREG32(mmVCE_UENC_REG_CLOCK_GATING, data); 172
198 /* Set VCE_UENC_DMA_DCLK_CTRL CG always in dynamic mode */ 173 data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
199 tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
200 data &= ~(VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK | 174 data &= ~(VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK |
201 VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK | 175 VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK |
202 VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK | 176 VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK |
203 0x8); 177 0x8);
204 if (tmp != data) 178 WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
205 WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
206 } 179 }
207 vce_v3_0_override_vce_clock_gating(adev, false); 180 vce_v3_0_override_vce_clock_gating(adev, false);
208} 181}
@@ -221,12 +194,9 @@ static int vce_v3_0_firmware_loaded(struct amdgpu_device *adev)
221 } 194 }
222 195
223 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); 196 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
224 WREG32_P(mmVCE_SOFT_RESET, 197 WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 1);
225 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
226 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
227 mdelay(10); 198 mdelay(10);
228 WREG32_P(mmVCE_SOFT_RESET, 0, 199 WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 0);
229 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
230 mdelay(10); 200 mdelay(10);
231 } 201 }
232 202
@@ -264,38 +234,22 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
264 if (adev->vce.harvest_config & (1 << idx)) 234 if (adev->vce.harvest_config & (1 << idx))
265 continue; 235 continue;
266 236
267 if (idx == 0) 237 WREG32_FIELD(GRBM_GFX_INDEX, VCE_INSTANCE, idx);
268 WREG32_P(mmGRBM_GFX_INDEX, 0,
269 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
270 else
271 WREG32_P(mmGRBM_GFX_INDEX,
272 GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
273 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
274
275 vce_v3_0_mc_resume(adev, idx); 238 vce_v3_0_mc_resume(adev, idx);
276 239 WREG32_FIELD(VCE_STATUS, JOB_BUSY, 1);
277 WREG32_P(mmVCE_STATUS, VCE_STATUS__JOB_BUSY_MASK,
278 ~VCE_STATUS__JOB_BUSY_MASK);
279 240
280 if (adev->asic_type >= CHIP_STONEY) 241 if (adev->asic_type >= CHIP_STONEY)
281 WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001); 242 WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001);
282 else 243 else
283 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, 244 WREG32_FIELD(VCE_VCPU_CNTL, CLK_EN, 1);
284 ~VCE_VCPU_CNTL__CLK_EN_MASK);
285
286 WREG32_P(mmVCE_SOFT_RESET, 0,
287 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
288 245
246 WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 0);
289 mdelay(100); 247 mdelay(100);
290 248
291 r = vce_v3_0_firmware_loaded(adev); 249 r = vce_v3_0_firmware_loaded(adev);
292 250
293 /* clear BUSY flag */ 251 /* clear BUSY flag */
294 WREG32_P(mmVCE_STATUS, 0, ~VCE_STATUS__JOB_BUSY_MASK); 252 WREG32_FIELD(VCE_STATUS, JOB_BUSY, 0);
295
296 /* Set Clock-Gating off */
297 if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)
298 vce_v3_0_set_vce_sw_clock_gating(adev, false);
299 253
300 if (r) { 254 if (r) {
301 DRM_ERROR("VCE not responding, giving up!!!\n"); 255 DRM_ERROR("VCE not responding, giving up!!!\n");
@@ -304,7 +258,7 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
304 } 258 }
305 } 259 }
306 260
307 WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 261 WREG32_FIELD(GRBM_GFX_INDEX, VCE_INSTANCE, 0);
308 mutex_unlock(&adev->grbm_idx_mutex); 262 mutex_unlock(&adev->grbm_idx_mutex);
309 263
310 return 0; 264 return 0;
@@ -319,33 +273,25 @@ static int vce_v3_0_stop(struct amdgpu_device *adev)
319 if (adev->vce.harvest_config & (1 << idx)) 273 if (adev->vce.harvest_config & (1 << idx))
320 continue; 274 continue;
321 275
322 if (idx == 0) 276 WREG32_FIELD(GRBM_GFX_INDEX, VCE_INSTANCE, idx);
323 WREG32_P(mmGRBM_GFX_INDEX, 0,
324 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
325 else
326 WREG32_P(mmGRBM_GFX_INDEX,
327 GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
328 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
329 277
330 if (adev->asic_type >= CHIP_STONEY) 278 if (adev->asic_type >= CHIP_STONEY)
331 WREG32_P(mmVCE_VCPU_CNTL, 0, ~0x200001); 279 WREG32_P(mmVCE_VCPU_CNTL, 0, ~0x200001);
332 else 280 else
333 WREG32_P(mmVCE_VCPU_CNTL, 0, 281 WREG32_FIELD(VCE_VCPU_CNTL, CLK_EN, 0);
334 ~VCE_VCPU_CNTL__CLK_EN_MASK); 282
335 /* hold on ECPU */ 283 /* hold on ECPU */
336 WREG32_P(mmVCE_SOFT_RESET, 284 WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 1);
337 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
338 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
339 285
340 /* clear BUSY flag */ 286 /* clear BUSY flag */
341 WREG32_P(mmVCE_STATUS, 0, ~VCE_STATUS__JOB_BUSY_MASK); 287 WREG32_FIELD(VCE_STATUS, JOB_BUSY, 0);
342 288
343 /* Set Clock-Gating off */ 289 /* Set Clock-Gating off */
344 if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG) 290 if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)
345 vce_v3_0_set_vce_sw_clock_gating(adev, false); 291 vce_v3_0_set_vce_sw_clock_gating(adev, false);
346 } 292 }
347 293
348 WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 294 WREG32_FIELD(GRBM_GFX_INDEX, VCE_INSTANCE, 0);
349 mutex_unlock(&adev->grbm_idx_mutex); 295 mutex_unlock(&adev->grbm_idx_mutex);
350 296
351 return 0; 297 return 0;
@@ -534,7 +480,7 @@ static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx)
534 WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16)); 480 WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
535 WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); 481 WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
536 WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); 482 WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
537 WREG32(mmVCE_CLOCK_GATING_B, 0xf7); 483 WREG32(mmVCE_CLOCK_GATING_B, 0x1FF);
538 484
539 WREG32(mmVCE_LMI_CTRL, 0x00398000); 485 WREG32(mmVCE_LMI_CTRL, 0x00398000);
540 WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1); 486 WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
@@ -573,9 +519,7 @@ static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx)
573 } 519 }
574 520
575 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100); 521 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
576 522 WREG32_FIELD(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, 1);
577 WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
578 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
579} 523}
580 524
581static bool vce_v3_0_is_idle(void *handle) 525static bool vce_v3_0_is_idle(void *handle)
@@ -601,20 +545,108 @@ static int vce_v3_0_wait_for_idle(void *handle)
601 return -ETIMEDOUT; 545 return -ETIMEDOUT;
602} 546}
603 547
548#define VCE_STATUS_VCPU_REPORT_AUTO_BUSY_MASK 0x00000008L /* AUTO_BUSY */
549#define VCE_STATUS_VCPU_REPORT_RB0_BUSY_MASK 0x00000010L /* RB0_BUSY */
550#define VCE_STATUS_VCPU_REPORT_RB1_BUSY_MASK 0x00000020L /* RB1_BUSY */
551#define AMDGPU_VCE_STATUS_BUSY_MASK (VCE_STATUS_VCPU_REPORT_AUTO_BUSY_MASK | \
552 VCE_STATUS_VCPU_REPORT_RB0_BUSY_MASK)
553
554static int vce_v3_0_check_soft_reset(void *handle)
555{
556 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
557 u32 srbm_soft_reset = 0;
558
559 /* According to VCE team , we should use VCE_STATUS instead
560 * SRBM_STATUS.VCE_BUSY bit for busy status checking.
561 * GRBM_GFX_INDEX.INSTANCE_INDEX is used to specify which VCE
562 * instance's registers are accessed
563 * (0 for 1st instance, 10 for 2nd instance).
564 *
565 *VCE_STATUS
566 *|UENC|ACPI|AUTO ACTIVE|RB1 |RB0 |RB2 | |FW_LOADED|JOB |
567 *|----+----+-----------+----+----+----+----------+---------+----|
568 *|bit8|bit7| bit6 |bit5|bit4|bit3| bit2 | bit1 |bit0|
569 *
570 * VCE team suggest use bit 3--bit 6 for busy status check
571 */
572 mutex_lock(&adev->grbm_idx_mutex);
573 WREG32_FIELD(GRBM_GFX_INDEX, INSTANCE_INDEX, 0);
574 if (RREG32(mmVCE_STATUS) & AMDGPU_VCE_STATUS_BUSY_MASK) {
575 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE0, 1);
576 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE1, 1);
577 }
578 WREG32_FIELD(GRBM_GFX_INDEX, INSTANCE_INDEX, 0x10);
579 if (RREG32(mmVCE_STATUS) & AMDGPU_VCE_STATUS_BUSY_MASK) {
580 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE0, 1);
581 srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE1, 1);
582 }
583 WREG32_FIELD(GRBM_GFX_INDEX, INSTANCE_INDEX, 0);
584
585 if (srbm_soft_reset) {
586 adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang = true;
587 adev->vce.srbm_soft_reset = srbm_soft_reset;
588 } else {
589 adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang = false;
590 adev->vce.srbm_soft_reset = 0;
591 }
592 mutex_unlock(&adev->grbm_idx_mutex);
593 return 0;
594}
595
604static int vce_v3_0_soft_reset(void *handle) 596static int vce_v3_0_soft_reset(void *handle)
605{ 597{
606 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 598 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
607 u32 mask = 0; 599 u32 srbm_soft_reset;
600
601 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
602 return 0;
603 srbm_soft_reset = adev->vce.srbm_soft_reset;
604
605 if (srbm_soft_reset) {
606 u32 tmp;
607
608 tmp = RREG32(mmSRBM_SOFT_RESET);
609 tmp |= srbm_soft_reset;
610 dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
611 WREG32(mmSRBM_SOFT_RESET, tmp);
612 tmp = RREG32(mmSRBM_SOFT_RESET);
613
614 udelay(50);
615
616 tmp &= ~srbm_soft_reset;
617 WREG32(mmSRBM_SOFT_RESET, tmp);
618 tmp = RREG32(mmSRBM_SOFT_RESET);
619
620 /* Wait a little for things to settle down */
621 udelay(50);
622 }
623
624 return 0;
625}
626
627static int vce_v3_0_pre_soft_reset(void *handle)
628{
629 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
630
631 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
632 return 0;
633
634 mdelay(5);
608 635
609 mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK; 636 return vce_v3_0_suspend(adev);
610 mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK; 637}
638
639
640static int vce_v3_0_post_soft_reset(void *handle)
641{
642 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
643
644 if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
645 return 0;
611 646
612 WREG32_P(mmSRBM_SOFT_RESET, mask,
613 ~(SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK |
614 SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK));
615 mdelay(5); 647 mdelay(5);
616 648
617 return vce_v3_0_start(adev); 649 return vce_v3_0_resume(adev);
618} 650}
619 651
620static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev, 652static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev,
@@ -637,9 +669,7 @@ static int vce_v3_0_process_interrupt(struct amdgpu_device *adev,
637{ 669{
638 DRM_DEBUG("IH: VCE\n"); 670 DRM_DEBUG("IH: VCE\n");
639 671
640 WREG32_P(mmVCE_SYS_INT_STATUS, 672 WREG32_FIELD(VCE_SYS_INT_STATUS, VCE_SYS_INT_TRAP_INTERRUPT_INT, 1);
641 VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK,
642 ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK);
643 673
644 switch (entry->src_data) { 674 switch (entry->src_data) {
645 case 0: 675 case 0:
@@ -686,13 +716,7 @@ static int vce_v3_0_set_clockgating_state(void *handle,
686 if (adev->vce.harvest_config & (1 << i)) 716 if (adev->vce.harvest_config & (1 << i))
687 continue; 717 continue;
688 718
689 if (i == 0) 719 WREG32_FIELD(GRBM_GFX_INDEX, VCE_INSTANCE, i);
690 WREG32_P(mmGRBM_GFX_INDEX, 0,
691 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
692 else
693 WREG32_P(mmGRBM_GFX_INDEX,
694 GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
695 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
696 720
697 if (enable) { 721 if (enable) {
698 /* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */ 722 /* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */
@@ -711,7 +735,7 @@ static int vce_v3_0_set_clockgating_state(void *handle,
711 vce_v3_0_set_vce_sw_clock_gating(adev, enable); 735 vce_v3_0_set_vce_sw_clock_gating(adev, enable);
712 } 736 }
713 737
714 WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 738 WREG32_FIELD(GRBM_GFX_INDEX, VCE_INSTANCE, 0);
715 mutex_unlock(&adev->grbm_idx_mutex); 739 mutex_unlock(&adev->grbm_idx_mutex);
716 740
717 return 0; 741 return 0;
@@ -751,7 +775,10 @@ const struct amd_ip_funcs vce_v3_0_ip_funcs = {
751 .resume = vce_v3_0_resume, 775 .resume = vce_v3_0_resume,
752 .is_idle = vce_v3_0_is_idle, 776 .is_idle = vce_v3_0_is_idle,
753 .wait_for_idle = vce_v3_0_wait_for_idle, 777 .wait_for_idle = vce_v3_0_wait_for_idle,
778 .check_soft_reset = vce_v3_0_check_soft_reset,
779 .pre_soft_reset = vce_v3_0_pre_soft_reset,
754 .soft_reset = vce_v3_0_soft_reset, 780 .soft_reset = vce_v3_0_soft_reset,
781 .post_soft_reset = vce_v3_0_post_soft_reset,
755 .set_clockgating_state = vce_v3_0_set_clockgating_state, 782 .set_clockgating_state = vce_v3_0_set_clockgating_state,
756 .set_powergating_state = vce_v3_0_set_powergating_state, 783 .set_powergating_state = vce_v3_0_set_powergating_state,
757}; 784};
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 03a31c53aec3..f2e8aa1a0dbd 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -77,6 +77,7 @@
77#if defined(CONFIG_DRM_AMD_ACP) 77#if defined(CONFIG_DRM_AMD_ACP)
78#include "amdgpu_acp.h" 78#include "amdgpu_acp.h"
79#endif 79#endif
80#include "dce_virtual.h"
80 81
81MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); 82MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
82MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); 83MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
@@ -822,6 +823,60 @@ static const struct amdgpu_ip_block_version topaz_ip_blocks[] =
822 }, 823 },
823}; 824};
824 825
826static const struct amdgpu_ip_block_version topaz_ip_blocks_vd[] =
827{
828 /* ORDER MATTERS! */
829 {
830 .type = AMD_IP_BLOCK_TYPE_COMMON,
831 .major = 2,
832 .minor = 0,
833 .rev = 0,
834 .funcs = &vi_common_ip_funcs,
835 },
836 {
837 .type = AMD_IP_BLOCK_TYPE_GMC,
838 .major = 7,
839 .minor = 4,
840 .rev = 0,
841 .funcs = &gmc_v7_0_ip_funcs,
842 },
843 {
844 .type = AMD_IP_BLOCK_TYPE_IH,
845 .major = 2,
846 .minor = 4,
847 .rev = 0,
848 .funcs = &iceland_ih_ip_funcs,
849 },
850 {
851 .type = AMD_IP_BLOCK_TYPE_SMC,
852 .major = 7,
853 .minor = 1,
854 .rev = 0,
855 .funcs = &amdgpu_pp_ip_funcs,
856 },
857 {
858 .type = AMD_IP_BLOCK_TYPE_DCE,
859 .major = 1,
860 .minor = 0,
861 .rev = 0,
862 .funcs = &dce_virtual_ip_funcs,
863 },
864 {
865 .type = AMD_IP_BLOCK_TYPE_GFX,
866 .major = 8,
867 .minor = 0,
868 .rev = 0,
869 .funcs = &gfx_v8_0_ip_funcs,
870 },
871 {
872 .type = AMD_IP_BLOCK_TYPE_SDMA,
873 .major = 2,
874 .minor = 4,
875 .rev = 0,
876 .funcs = &sdma_v2_4_ip_funcs,
877 },
878};
879
825static const struct amdgpu_ip_block_version tonga_ip_blocks[] = 880static const struct amdgpu_ip_block_version tonga_ip_blocks[] =
826{ 881{
827 /* ORDER MATTERS! */ 882 /* ORDER MATTERS! */
@@ -890,6 +945,74 @@ static const struct amdgpu_ip_block_version tonga_ip_blocks[] =
890 }, 945 },
891}; 946};
892 947
948static const struct amdgpu_ip_block_version tonga_ip_blocks_vd[] =
949{
950 /* ORDER MATTERS! */
951 {
952 .type = AMD_IP_BLOCK_TYPE_COMMON,
953 .major = 2,
954 .minor = 0,
955 .rev = 0,
956 .funcs = &vi_common_ip_funcs,
957 },
958 {
959 .type = AMD_IP_BLOCK_TYPE_GMC,
960 .major = 8,
961 .minor = 0,
962 .rev = 0,
963 .funcs = &gmc_v8_0_ip_funcs,
964 },
965 {
966 .type = AMD_IP_BLOCK_TYPE_IH,
967 .major = 3,
968 .minor = 0,
969 .rev = 0,
970 .funcs = &tonga_ih_ip_funcs,
971 },
972 {
973 .type = AMD_IP_BLOCK_TYPE_SMC,
974 .major = 7,
975 .minor = 1,
976 .rev = 0,
977 .funcs = &amdgpu_pp_ip_funcs,
978 },
979 {
980 .type = AMD_IP_BLOCK_TYPE_DCE,
981 .major = 10,
982 .minor = 0,
983 .rev = 0,
984 .funcs = &dce_virtual_ip_funcs,
985 },
986 {
987 .type = AMD_IP_BLOCK_TYPE_GFX,
988 .major = 8,
989 .minor = 0,
990 .rev = 0,
991 .funcs = &gfx_v8_0_ip_funcs,
992 },
993 {
994 .type = AMD_IP_BLOCK_TYPE_SDMA,
995 .major = 3,
996 .minor = 0,
997 .rev = 0,
998 .funcs = &sdma_v3_0_ip_funcs,
999 },
1000 {
1001 .type = AMD_IP_BLOCK_TYPE_UVD,
1002 .major = 5,
1003 .minor = 0,
1004 .rev = 0,
1005 .funcs = &uvd_v5_0_ip_funcs,
1006 },
1007 {
1008 .type = AMD_IP_BLOCK_TYPE_VCE,
1009 .major = 3,
1010 .minor = 0,
1011 .rev = 0,
1012 .funcs = &vce_v3_0_ip_funcs,
1013 },
1014};
1015
893static const struct amdgpu_ip_block_version fiji_ip_blocks[] = 1016static const struct amdgpu_ip_block_version fiji_ip_blocks[] =
894{ 1017{
895 /* ORDER MATTERS! */ 1018 /* ORDER MATTERS! */
@@ -958,6 +1081,74 @@ static const struct amdgpu_ip_block_version fiji_ip_blocks[] =
958 }, 1081 },
959}; 1082};
960 1083
1084static const struct amdgpu_ip_block_version fiji_ip_blocks_vd[] =
1085{
1086 /* ORDER MATTERS! */
1087 {
1088 .type = AMD_IP_BLOCK_TYPE_COMMON,
1089 .major = 2,
1090 .minor = 0,
1091 .rev = 0,
1092 .funcs = &vi_common_ip_funcs,
1093 },
1094 {
1095 .type = AMD_IP_BLOCK_TYPE_GMC,
1096 .major = 8,
1097 .minor = 5,
1098 .rev = 0,
1099 .funcs = &gmc_v8_0_ip_funcs,
1100 },
1101 {
1102 .type = AMD_IP_BLOCK_TYPE_IH,
1103 .major = 3,
1104 .minor = 0,
1105 .rev = 0,
1106 .funcs = &tonga_ih_ip_funcs,
1107 },
1108 {
1109 .type = AMD_IP_BLOCK_TYPE_SMC,
1110 .major = 7,
1111 .minor = 1,
1112 .rev = 0,
1113 .funcs = &amdgpu_pp_ip_funcs,
1114 },
1115 {
1116 .type = AMD_IP_BLOCK_TYPE_DCE,
1117 .major = 10,
1118 .minor = 1,
1119 .rev = 0,
1120 .funcs = &dce_virtual_ip_funcs,
1121 },
1122 {
1123 .type = AMD_IP_BLOCK_TYPE_GFX,
1124 .major = 8,
1125 .minor = 0,
1126 .rev = 0,
1127 .funcs = &gfx_v8_0_ip_funcs,
1128 },
1129 {
1130 .type = AMD_IP_BLOCK_TYPE_SDMA,
1131 .major = 3,
1132 .minor = 0,
1133 .rev = 0,
1134 .funcs = &sdma_v3_0_ip_funcs,
1135 },
1136 {
1137 .type = AMD_IP_BLOCK_TYPE_UVD,
1138 .major = 6,
1139 .minor = 0,
1140 .rev = 0,
1141 .funcs = &uvd_v6_0_ip_funcs,
1142 },
1143 {
1144 .type = AMD_IP_BLOCK_TYPE_VCE,
1145 .major = 3,
1146 .minor = 0,
1147 .rev = 0,
1148 .funcs = &vce_v3_0_ip_funcs,
1149 },
1150};
1151
961static const struct amdgpu_ip_block_version polaris11_ip_blocks[] = 1152static const struct amdgpu_ip_block_version polaris11_ip_blocks[] =
962{ 1153{
963 /* ORDER MATTERS! */ 1154 /* ORDER MATTERS! */
@@ -1026,6 +1217,74 @@ static const struct amdgpu_ip_block_version polaris11_ip_blocks[] =
1026 }, 1217 },
1027}; 1218};
1028 1219
1220static const struct amdgpu_ip_block_version polaris11_ip_blocks_vd[] =
1221{
1222 /* ORDER MATTERS! */
1223 {
1224 .type = AMD_IP_BLOCK_TYPE_COMMON,
1225 .major = 2,
1226 .minor = 0,
1227 .rev = 0,
1228 .funcs = &vi_common_ip_funcs,
1229 },
1230 {
1231 .type = AMD_IP_BLOCK_TYPE_GMC,
1232 .major = 8,
1233 .minor = 1,
1234 .rev = 0,
1235 .funcs = &gmc_v8_0_ip_funcs,
1236 },
1237 {
1238 .type = AMD_IP_BLOCK_TYPE_IH,
1239 .major = 3,
1240 .minor = 1,
1241 .rev = 0,
1242 .funcs = &tonga_ih_ip_funcs,
1243 },
1244 {
1245 .type = AMD_IP_BLOCK_TYPE_SMC,
1246 .major = 7,
1247 .minor = 2,
1248 .rev = 0,
1249 .funcs = &amdgpu_pp_ip_funcs,
1250 },
1251 {
1252 .type = AMD_IP_BLOCK_TYPE_DCE,
1253 .major = 11,
1254 .minor = 2,
1255 .rev = 0,
1256 .funcs = &dce_virtual_ip_funcs,
1257 },
1258 {
1259 .type = AMD_IP_BLOCK_TYPE_GFX,
1260 .major = 8,
1261 .minor = 0,
1262 .rev = 0,
1263 .funcs = &gfx_v8_0_ip_funcs,
1264 },
1265 {
1266 .type = AMD_IP_BLOCK_TYPE_SDMA,
1267 .major = 3,
1268 .minor = 1,
1269 .rev = 0,
1270 .funcs = &sdma_v3_0_ip_funcs,
1271 },
1272 {
1273 .type = AMD_IP_BLOCK_TYPE_UVD,
1274 .major = 6,
1275 .minor = 3,
1276 .rev = 0,
1277 .funcs = &uvd_v6_0_ip_funcs,
1278 },
1279 {
1280 .type = AMD_IP_BLOCK_TYPE_VCE,
1281 .major = 3,
1282 .minor = 4,
1283 .rev = 0,
1284 .funcs = &vce_v3_0_ip_funcs,
1285 },
1286};
1287
1029static const struct amdgpu_ip_block_version cz_ip_blocks[] = 1288static const struct amdgpu_ip_block_version cz_ip_blocks[] =
1030{ 1289{
1031 /* ORDER MATTERS! */ 1290 /* ORDER MATTERS! */
@@ -1103,34 +1362,142 @@ static const struct amdgpu_ip_block_version cz_ip_blocks[] =
1103#endif 1362#endif
1104}; 1363};
1105 1364
1365static const struct amdgpu_ip_block_version cz_ip_blocks_vd[] =
1366{
1367 /* ORDER MATTERS! */
1368 {
1369 .type = AMD_IP_BLOCK_TYPE_COMMON,
1370 .major = 2,
1371 .minor = 0,
1372 .rev = 0,
1373 .funcs = &vi_common_ip_funcs,
1374 },
1375 {
1376 .type = AMD_IP_BLOCK_TYPE_GMC,
1377 .major = 8,
1378 .minor = 0,
1379 .rev = 0,
1380 .funcs = &gmc_v8_0_ip_funcs,
1381 },
1382 {
1383 .type = AMD_IP_BLOCK_TYPE_IH,
1384 .major = 3,
1385 .minor = 0,
1386 .rev = 0,
1387 .funcs = &cz_ih_ip_funcs,
1388 },
1389 {
1390 .type = AMD_IP_BLOCK_TYPE_SMC,
1391 .major = 8,
1392 .minor = 0,
1393 .rev = 0,
1394 .funcs = &amdgpu_pp_ip_funcs
1395 },
1396 {
1397 .type = AMD_IP_BLOCK_TYPE_DCE,
1398 .major = 11,
1399 .minor = 0,
1400 .rev = 0,
1401 .funcs = &dce_virtual_ip_funcs,
1402 },
1403 {
1404 .type = AMD_IP_BLOCK_TYPE_GFX,
1405 .major = 8,
1406 .minor = 0,
1407 .rev = 0,
1408 .funcs = &gfx_v8_0_ip_funcs,
1409 },
1410 {
1411 .type = AMD_IP_BLOCK_TYPE_SDMA,
1412 .major = 3,
1413 .minor = 0,
1414 .rev = 0,
1415 .funcs = &sdma_v3_0_ip_funcs,
1416 },
1417 {
1418 .type = AMD_IP_BLOCK_TYPE_UVD,
1419 .major = 6,
1420 .minor = 0,
1421 .rev = 0,
1422 .funcs = &uvd_v6_0_ip_funcs,
1423 },
1424 {
1425 .type = AMD_IP_BLOCK_TYPE_VCE,
1426 .major = 3,
1427 .minor = 0,
1428 .rev = 0,
1429 .funcs = &vce_v3_0_ip_funcs,
1430 },
1431#if defined(CONFIG_DRM_AMD_ACP)
1432 {
1433 .type = AMD_IP_BLOCK_TYPE_ACP,
1434 .major = 2,
1435 .minor = 2,
1436 .rev = 0,
1437 .funcs = &acp_ip_funcs,
1438 },
1439#endif
1440};
1441
1106int vi_set_ip_blocks(struct amdgpu_device *adev) 1442int vi_set_ip_blocks(struct amdgpu_device *adev)
1107{ 1443{
1108 switch (adev->asic_type) { 1444 if (adev->enable_virtual_display) {
1109 case CHIP_TOPAZ: 1445 switch (adev->asic_type) {
1110 adev->ip_blocks = topaz_ip_blocks; 1446 case CHIP_TOPAZ:
1111 adev->num_ip_blocks = ARRAY_SIZE(topaz_ip_blocks); 1447 adev->ip_blocks = topaz_ip_blocks_vd;
1112 break; 1448 adev->num_ip_blocks = ARRAY_SIZE(topaz_ip_blocks_vd);
1113 case CHIP_FIJI: 1449 break;
1114 adev->ip_blocks = fiji_ip_blocks; 1450 case CHIP_FIJI:
1115 adev->num_ip_blocks = ARRAY_SIZE(fiji_ip_blocks); 1451 adev->ip_blocks = fiji_ip_blocks_vd;
1116 break; 1452 adev->num_ip_blocks = ARRAY_SIZE(fiji_ip_blocks_vd);
1117 case CHIP_TONGA: 1453 break;
1118 adev->ip_blocks = tonga_ip_blocks; 1454 case CHIP_TONGA:
1119 adev->num_ip_blocks = ARRAY_SIZE(tonga_ip_blocks); 1455 adev->ip_blocks = tonga_ip_blocks_vd;
1120 break; 1456 adev->num_ip_blocks = ARRAY_SIZE(tonga_ip_blocks_vd);
1121 case CHIP_POLARIS11: 1457 break;
1122 case CHIP_POLARIS10: 1458 case CHIP_POLARIS11:
1123 adev->ip_blocks = polaris11_ip_blocks; 1459 case CHIP_POLARIS10:
1124 adev->num_ip_blocks = ARRAY_SIZE(polaris11_ip_blocks); 1460 adev->ip_blocks = polaris11_ip_blocks_vd;
1125 break; 1461 adev->num_ip_blocks = ARRAY_SIZE(polaris11_ip_blocks_vd);
1126 case CHIP_CARRIZO: 1462 break;
1127 case CHIP_STONEY: 1463
1128 adev->ip_blocks = cz_ip_blocks; 1464 case CHIP_CARRIZO:
1129 adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks); 1465 case CHIP_STONEY:
1130 break; 1466 adev->ip_blocks = cz_ip_blocks_vd;
1131 default: 1467 adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks_vd);
1132 /* FIXME: not supported yet */ 1468 break;
1133 return -EINVAL; 1469 default:
1470 /* FIXME: not supported yet */
1471 return -EINVAL;
1472 }
1473 } else {
1474 switch (adev->asic_type) {
1475 case CHIP_TOPAZ:
1476 adev->ip_blocks = topaz_ip_blocks;
1477 adev->num_ip_blocks = ARRAY_SIZE(topaz_ip_blocks);
1478 break;
1479 case CHIP_FIJI:
1480 adev->ip_blocks = fiji_ip_blocks;
1481 adev->num_ip_blocks = ARRAY_SIZE(fiji_ip_blocks);
1482 break;
1483 case CHIP_TONGA:
1484 adev->ip_blocks = tonga_ip_blocks;
1485 adev->num_ip_blocks = ARRAY_SIZE(tonga_ip_blocks);
1486 break;
1487 case CHIP_POLARIS11:
1488 case CHIP_POLARIS10:
1489 adev->ip_blocks = polaris11_ip_blocks;
1490 adev->num_ip_blocks = ARRAY_SIZE(polaris11_ip_blocks);
1491 break;
1492 case CHIP_CARRIZO:
1493 case CHIP_STONEY:
1494 adev->ip_blocks = cz_ip_blocks;
1495 adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks);
1496 break;
1497 default:
1498 /* FIXME: not supported yet */
1499 return -EINVAL;
1500 }
1134 } 1501 }
1135 1502
1136 return 0; 1503 return 0;
@@ -1248,8 +1615,17 @@ static int vi_common_early_init(void *handle)
1248 AMD_CG_SUPPORT_HDP_MGCG | 1615 AMD_CG_SUPPORT_HDP_MGCG |
1249 AMD_CG_SUPPORT_HDP_LS | 1616 AMD_CG_SUPPORT_HDP_LS |
1250 AMD_CG_SUPPORT_SDMA_MGCG | 1617 AMD_CG_SUPPORT_SDMA_MGCG |
1251 AMD_CG_SUPPORT_SDMA_LS; 1618 AMD_CG_SUPPORT_SDMA_LS |
1619 AMD_CG_SUPPORT_VCE_MGCG;
1620 /* rev0 hardware requires workarounds to support PG */
1252 adev->pg_flags = 0; 1621 adev->pg_flags = 0;
1622 if (adev->rev_id != 0x00) {
1623 adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
1624 AMD_PG_SUPPORT_GFX_SMG |
1625 AMD_PG_SUPPORT_GFX_PIPELINE |
1626 AMD_PG_SUPPORT_UVD |
1627 AMD_PG_SUPPORT_VCE;
1628 }
1253 adev->external_rev_id = adev->rev_id + 0x1; 1629 adev->external_rev_id = adev->rev_id + 0x1;
1254 break; 1630 break;
1255 case CHIP_STONEY: 1631 case CHIP_STONEY:
@@ -1267,7 +1643,13 @@ static int vi_common_early_init(void *handle)
1267 AMD_CG_SUPPORT_HDP_MGCG | 1643 AMD_CG_SUPPORT_HDP_MGCG |
1268 AMD_CG_SUPPORT_HDP_LS | 1644 AMD_CG_SUPPORT_HDP_LS |
1269 AMD_CG_SUPPORT_SDMA_MGCG | 1645 AMD_CG_SUPPORT_SDMA_MGCG |
1270 AMD_CG_SUPPORT_SDMA_LS; 1646 AMD_CG_SUPPORT_SDMA_LS |
1647 AMD_CG_SUPPORT_VCE_MGCG;
1648 adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
1649 AMD_PG_SUPPORT_GFX_SMG |
1650 AMD_PG_SUPPORT_GFX_PIPELINE |
1651 AMD_PG_SUPPORT_UVD |
1652 AMD_PG_SUPPORT_VCE;
1271 adev->external_rev_id = adev->rev_id + 0x1; 1653 adev->external_rev_id = adev->rev_id + 0x1;
1272 break; 1654 break;
1273 default: 1655 default:
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h
index a74a0d2ff1ca..db710418f35f 100644
--- a/drivers/gpu/drm/amd/include/amd_shared.h
+++ b/drivers/gpu/drm/amd/include/amd_shared.h
@@ -159,8 +159,14 @@ struct amd_ip_funcs {
159 bool (*is_idle)(void *handle); 159 bool (*is_idle)(void *handle);
160 /* poll for idle */ 160 /* poll for idle */
161 int (*wait_for_idle)(void *handle); 161 int (*wait_for_idle)(void *handle);
162 /* check soft reset the IP block */
163 int (*check_soft_reset)(void *handle);
164 /* pre soft reset the IP block */
165 int (*pre_soft_reset)(void *handle);
162 /* soft reset the IP block */ 166 /* soft reset the IP block */
163 int (*soft_reset)(void *handle); 167 int (*soft_reset)(void *handle);
168 /* post soft reset the IP block */
169 int (*post_soft_reset)(void *handle);
164 /* enable/disable cg for the IP block */ 170 /* enable/disable cg for the IP block */
165 int (*set_clockgating_state)(void *handle, 171 int (*set_clockgating_state)(void *handle,
166 enum amd_clockgating_state state); 172 enum amd_clockgating_state state);
diff --git a/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_4_2_d.h b/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_4_2_d.h
index f3e53b118361..19802e96417e 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_4_2_d.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_4_2_d.h
@@ -34,6 +34,7 @@
34#define mmUVD_UDEC_ADDR_CONFIG 0x3bd3 34#define mmUVD_UDEC_ADDR_CONFIG 0x3bd3
35#define mmUVD_UDEC_DB_ADDR_CONFIG 0x3bd4 35#define mmUVD_UDEC_DB_ADDR_CONFIG 0x3bd4
36#define mmUVD_UDEC_DBW_ADDR_CONFIG 0x3bd5 36#define mmUVD_UDEC_DBW_ADDR_CONFIG 0x3bd5
37#define mmUVD_NO_OP 0x3bff
37#define mmUVD_SEMA_CNTL 0x3d00 38#define mmUVD_SEMA_CNTL 0x3d00
38#define mmUVD_LMI_EXT40_ADDR 0x3d26 39#define mmUVD_LMI_EXT40_ADDR 0x3d26
39#define mmUVD_CTX_INDEX 0x3d28 40#define mmUVD_CTX_INDEX 0x3d28
diff --git a/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_5_0_d.h b/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_5_0_d.h
index eb4cf53427da..cc972d237a7e 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_5_0_d.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_5_0_d.h
@@ -34,6 +34,7 @@
34#define mmUVD_UDEC_ADDR_CONFIG 0x3bd3 34#define mmUVD_UDEC_ADDR_CONFIG 0x3bd3
35#define mmUVD_UDEC_DB_ADDR_CONFIG 0x3bd4 35#define mmUVD_UDEC_DB_ADDR_CONFIG 0x3bd4
36#define mmUVD_UDEC_DBW_ADDR_CONFIG 0x3bd5 36#define mmUVD_UDEC_DBW_ADDR_CONFIG 0x3bd5
37#define mmUVD_NO_OP 0x3bff
37#define mmUVD_LMI_RBC_RB_64BIT_BAR_LOW 0x3c69 38#define mmUVD_LMI_RBC_RB_64BIT_BAR_LOW 0x3c69
38#define mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH 0x3c68 39#define mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH 0x3c68
39#define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW 0x3c67 40#define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW 0x3c67
diff --git a/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h b/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h
index ec69869c55ff..378f4b6b43da 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h
@@ -35,6 +35,7 @@
35#define mmUVD_UDEC_DB_ADDR_CONFIG 0x3bd4 35#define mmUVD_UDEC_DB_ADDR_CONFIG 0x3bd4
36#define mmUVD_UDEC_DBW_ADDR_CONFIG 0x3bd5 36#define mmUVD_UDEC_DBW_ADDR_CONFIG 0x3bd5
37#define mmUVD_POWER_STATUS_U 0x3bfd 37#define mmUVD_POWER_STATUS_U 0x3bfd
38#define mmUVD_NO_OP 0x3bff
38#define mmUVD_LMI_RBC_RB_64BIT_BAR_LOW 0x3c69 39#define mmUVD_LMI_RBC_RB_64BIT_BAR_LOW 0x3c69
39#define mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH 0x3c68 40#define mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH 0x3c68
40#define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW 0x3c67 41#define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW 0x3c67
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index abbb658bdc1e..2de34a5a85c2 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -31,6 +31,7 @@
31#include "eventmanager.h" 31#include "eventmanager.h"
32#include "pp_debug.h" 32#include "pp_debug.h"
33 33
34
34#define PP_CHECK(handle) \ 35#define PP_CHECK(handle) \
35 do { \ 36 do { \
36 if ((handle) == NULL || (handle)->pp_valid != PP_VALID) \ 37 if ((handle) == NULL || (handle)->pp_valid != PP_VALID) \
@@ -162,12 +163,12 @@ static int pp_hw_fini(void *handle)
162 pp_handle = (struct pp_instance *)handle; 163 pp_handle = (struct pp_instance *)handle;
163 eventmgr = pp_handle->eventmgr; 164 eventmgr = pp_handle->eventmgr;
164 165
165 if (eventmgr != NULL || eventmgr->pp_eventmgr_fini != NULL) 166 if (eventmgr != NULL && eventmgr->pp_eventmgr_fini != NULL)
166 eventmgr->pp_eventmgr_fini(eventmgr); 167 eventmgr->pp_eventmgr_fini(eventmgr);
167 168
168 smumgr = pp_handle->smu_mgr; 169 smumgr = pp_handle->smu_mgr;
169 170
170 if (smumgr != NULL || smumgr->smumgr_funcs != NULL || 171 if (smumgr != NULL && smumgr->smumgr_funcs != NULL &&
171 smumgr->smumgr_funcs->smu_fini != NULL) 172 smumgr->smumgr_funcs->smu_fini != NULL)
172 smumgr->smumgr_funcs->smu_fini(smumgr); 173 smumgr->smumgr_funcs->smu_fini(smumgr);
173 174
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile
index f7ce4cb71346..abbcbc9f6eca 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile
@@ -4,13 +4,15 @@
4 4
5HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \ 5HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \
6 hardwaremanager.o pp_acpi.o cz_hwmgr.o \ 6 hardwaremanager.o pp_acpi.o cz_hwmgr.o \
7 cz_clockpowergating.o \ 7 cz_clockpowergating.o tonga_powertune.o\
8 tonga_processpptables.o ppatomctrl.o \ 8 tonga_processpptables.o ppatomctrl.o \
9 tonga_hwmgr.o pppcielanes.o tonga_thermal.o\ 9 tonga_hwmgr.o pppcielanes.o tonga_thermal.o\
10 fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o \ 10 fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o \
11 fiji_clockpowergating.o fiji_thermal.o \ 11 fiji_clockpowergating.o fiji_thermal.o \
12 polaris10_hwmgr.o polaris10_powertune.o polaris10_thermal.o \ 12 polaris10_hwmgr.o polaris10_powertune.o polaris10_thermal.o \
13 polaris10_clockpowergating.o 13 polaris10_clockpowergating.o iceland_hwmgr.o \
14 iceland_clockpowergating.o iceland_thermal.o \
15 iceland_powertune.o
14 16
15AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) 17AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR))
16 18
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
index 8cc0df9b534a..5ecef1732e20 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
@@ -178,7 +178,6 @@ static int cz_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
178 int result; 178 int result;
179 179
180 cz_hwmgr->gfx_ramp_step = 256*25/100; 180 cz_hwmgr->gfx_ramp_step = 256*25/100;
181
182 cz_hwmgr->gfx_ramp_delay = 1; /* by default, we delay 1us */ 181 cz_hwmgr->gfx_ramp_delay = 1; /* by default, we delay 1us */
183 182
184 for (i = 0; i < CZ_MAX_HARDWARE_POWERLEVELS; i++) 183 for (i = 0; i < CZ_MAX_HARDWARE_POWERLEVELS; i++)
@@ -186,33 +185,19 @@ static int cz_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
186 185
187 cz_hwmgr->mgcg_cgtt_local0 = 0x00000000; 186 cz_hwmgr->mgcg_cgtt_local0 = 0x00000000;
188 cz_hwmgr->mgcg_cgtt_local1 = 0x00000000; 187 cz_hwmgr->mgcg_cgtt_local1 = 0x00000000;
189
190 cz_hwmgr->clock_slow_down_freq = 25000; 188 cz_hwmgr->clock_slow_down_freq = 25000;
191
192 cz_hwmgr->skip_clock_slow_down = 1; 189 cz_hwmgr->skip_clock_slow_down = 1;
193
194 cz_hwmgr->enable_nb_ps_policy = 1; /* disable until UNB is ready, Enabled */ 190 cz_hwmgr->enable_nb_ps_policy = 1; /* disable until UNB is ready, Enabled */
195
196 cz_hwmgr->voltage_drop_in_dce_power_gating = 0; /* disable until fully verified */ 191 cz_hwmgr->voltage_drop_in_dce_power_gating = 0; /* disable until fully verified */
197
198 cz_hwmgr->voting_rights_clients = 0x00C00033; 192 cz_hwmgr->voting_rights_clients = 0x00C00033;
199
200 cz_hwmgr->static_screen_threshold = 8; 193 cz_hwmgr->static_screen_threshold = 8;
201
202 cz_hwmgr->ddi_power_gating_disabled = 0; 194 cz_hwmgr->ddi_power_gating_disabled = 0;
203
204 cz_hwmgr->bapm_enabled = 1; 195 cz_hwmgr->bapm_enabled = 1;
205
206 cz_hwmgr->voltage_drop_threshold = 0; 196 cz_hwmgr->voltage_drop_threshold = 0;
207
208 cz_hwmgr->gfx_power_gating_threshold = 500; 197 cz_hwmgr->gfx_power_gating_threshold = 500;
209
210 cz_hwmgr->vce_slow_sclk_threshold = 20000; 198 cz_hwmgr->vce_slow_sclk_threshold = 20000;
211
212 cz_hwmgr->dce_slow_sclk_threshold = 30000; 199 cz_hwmgr->dce_slow_sclk_threshold = 30000;
213
214 cz_hwmgr->disable_driver_thermal_policy = 1; 200 cz_hwmgr->disable_driver_thermal_policy = 1;
215
216 cz_hwmgr->disable_nb_ps3_in_battery = 0; 201 cz_hwmgr->disable_nb_ps3_in_battery = 0;
217 202
218 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 203 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
@@ -221,9 +206,6 @@ static int cz_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
221 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 206 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
222 PHM_PlatformCaps_NonABMSupportInPPLib); 207 PHM_PlatformCaps_NonABMSupportInPPLib);
223 208
224 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
225 PHM_PlatformCaps_SclkDeepSleep);
226
227 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 209 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
228 PHM_PlatformCaps_DynamicM3Arbiter); 210 PHM_PlatformCaps_DynamicM3Arbiter);
229 211
@@ -233,9 +215,7 @@ static int cz_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
233 PHM_PlatformCaps_DynamicPatchPowerState); 215 PHM_PlatformCaps_DynamicPatchPowerState);
234 216
235 cz_hwmgr->thermal_auto_throttling_treshold = 0; 217 cz_hwmgr->thermal_auto_throttling_treshold = 0;
236
237 cz_hwmgr->tdr_clock = 0; 218 cz_hwmgr->tdr_clock = 0;
238
239 cz_hwmgr->disable_gfx_power_gating_in_uvd = 0; 219 cz_hwmgr->disable_gfx_power_gating_in_uvd = 0;
240 220
241 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 221 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
@@ -450,19 +430,12 @@ static int cz_construct_boot_state(struct pp_hwmgr *hwmgr)
450 (uint8_t)cz_hwmgr->sys_info.bootup_nb_voltage_index; 430 (uint8_t)cz_hwmgr->sys_info.bootup_nb_voltage_index;
451 431
452 cz_hwmgr->boot_power_level.dsDividerIndex = 0; 432 cz_hwmgr->boot_power_level.dsDividerIndex = 0;
453
454 cz_hwmgr->boot_power_level.ssDividerIndex = 0; 433 cz_hwmgr->boot_power_level.ssDividerIndex = 0;
455
456 cz_hwmgr->boot_power_level.allowGnbSlow = 1; 434 cz_hwmgr->boot_power_level.allowGnbSlow = 1;
457
458 cz_hwmgr->boot_power_level.forceNBPstate = 0; 435 cz_hwmgr->boot_power_level.forceNBPstate = 0;
459
460 cz_hwmgr->boot_power_level.hysteresis_up = 0; 436 cz_hwmgr->boot_power_level.hysteresis_up = 0;
461
462 cz_hwmgr->boot_power_level.numSIMDToPowerDown = 0; 437 cz_hwmgr->boot_power_level.numSIMDToPowerDown = 0;
463
464 cz_hwmgr->boot_power_level.display_wm = 0; 438 cz_hwmgr->boot_power_level.display_wm = 0;
465
466 cz_hwmgr->boot_power_level.vce_wm = 0; 439 cz_hwmgr->boot_power_level.vce_wm = 0;
467 440
468 return 0; 441 return 0;
@@ -749,7 +722,6 @@ static int cz_tf_update_sclk_limit(struct pp_hwmgr *hwmgr,
749 cz_hwmgr->sclk_dpm.soft_max_clk = table->entries[table->count - 1].clk; 722 cz_hwmgr->sclk_dpm.soft_max_clk = table->entries[table->count - 1].clk;
750 723
751 clock = hwmgr->display_config.min_core_set_clock; 724 clock = hwmgr->display_config.min_core_set_clock;
752;
753 if (clock == 0) 725 if (clock == 0)
754 printk(KERN_INFO "[ powerplay ] min_core_set_clock not set\n"); 726 printk(KERN_INFO "[ powerplay ] min_core_set_clock not set\n");
755 727
@@ -832,7 +804,7 @@ static int cz_tf_set_watermark_threshold(struct pp_hwmgr *hwmgr,
832 804
833 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 805 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
834 PPSMC_MSG_SetWatermarkFrequency, 806 PPSMC_MSG_SetWatermarkFrequency,
835 cz_hwmgr->sclk_dpm.soft_max_clk); 807 cz_hwmgr->sclk_dpm.soft_max_clk);
836 808
837 return 0; 809 return 0;
838} 810}
@@ -858,9 +830,9 @@ static int cz_tf_enable_nb_dpm(struct pp_hwmgr *hwmgr,
858 PP_DBG_LOG("enabling ALL SMU features.\n"); 830 PP_DBG_LOG("enabling ALL SMU features.\n");
859 dpm_features |= NB_DPM_MASK; 831 dpm_features |= NB_DPM_MASK;
860 ret = smum_send_msg_to_smc_with_parameter( 832 ret = smum_send_msg_to_smc_with_parameter(
861 hwmgr->smumgr, 833 hwmgr->smumgr,
862 PPSMC_MSG_EnableAllSmuFeatures, 834 PPSMC_MSG_EnableAllSmuFeatures,
863 dpm_features); 835 dpm_features);
864 if (ret == 0) 836 if (ret == 0)
865 cz_hwmgr->is_nb_dpm_enabled = true; 837 cz_hwmgr->is_nb_dpm_enabled = true;
866 } 838 }
@@ -1246,7 +1218,7 @@ static int cz_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
1246 1218
1247static int cz_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) 1219static int cz_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
1248{ 1220{
1249 if (hwmgr != NULL || hwmgr->backend != NULL) { 1221 if (hwmgr != NULL && hwmgr->backend != NULL) {
1250 kfree(hwmgr->backend); 1222 kfree(hwmgr->backend);
1251 kfree(hwmgr); 1223 kfree(hwmgr);
1252 } 1224 }
@@ -1402,10 +1374,12 @@ int cz_dpm_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
1402 PPSMC_MSG_SetUvdHardMin)); 1374 PPSMC_MSG_SetUvdHardMin));
1403 1375
1404 cz_enable_disable_uvd_dpm(hwmgr, true); 1376 cz_enable_disable_uvd_dpm(hwmgr, true);
1405 } else 1377 } else {
1406 cz_enable_disable_uvd_dpm(hwmgr, true); 1378 cz_enable_disable_uvd_dpm(hwmgr, true);
1407 } else 1379 }
1380 } else {
1408 cz_enable_disable_uvd_dpm(hwmgr, false); 1381 cz_enable_disable_uvd_dpm(hwmgr, false);
1382 }
1409 1383
1410 return 0; 1384 return 0;
1411} 1385}
@@ -1690,13 +1664,10 @@ static int cz_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time,
1690 struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend); 1664 struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
1691 1665
1692 if (separation_time != 1666 if (separation_time !=
1693 hw_data->cc6_settings.cpu_pstate_separation_time 1667 hw_data->cc6_settings.cpu_pstate_separation_time ||
1694 || cc6_disable != 1668 cc6_disable != hw_data->cc6_settings.cpu_cc6_disable ||
1695 hw_data->cc6_settings.cpu_cc6_disable 1669 pstate_disable != hw_data->cc6_settings.cpu_pstate_disable ||
1696 || pstate_disable != 1670 pstate_switch_disable != hw_data->cc6_settings.nb_pstate_switch_disable) {
1697 hw_data->cc6_settings.cpu_pstate_disable
1698 || pstate_switch_disable !=
1699 hw_data->cc6_settings.nb_pstate_switch_disable) {
1700 1671
1701 hw_data->cc6_settings.cc6_setting_changed = true; 1672 hw_data->cc6_settings.cc6_setting_changed = true;
1702 1673
@@ -1799,8 +1770,7 @@ static int cz_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_p
1799 ps = cast_const_PhwCzPowerState(state); 1770 ps = cast_const_PhwCzPowerState(state);
1800 1771
1801 level_index = index > ps->level - 1 ? ps->level - 1 : index; 1772 level_index = index > ps->level - 1 ? ps->level - 1 : index;
1802 1773 level->coreClock = ps->levels[level_index].engineClock;
1803 level->coreClock = ps->levels[level_index].engineClock;
1804 1774
1805 if (designation == PHM_PerformanceLevelDesignation_PowerContainment) { 1775 if (designation == PHM_PerformanceLevelDesignation_PowerContainment) {
1806 for (i = 1; i < ps->level; i++) { 1776 for (i = 1; i < ps->level; i++) {
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
index 6483d680bbc8..9368e21f5695 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
@@ -618,9 +618,6 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
618 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 618 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
619 PHM_PlatformCaps_TablelessHardwareInterface); 619 PHM_PlatformCaps_TablelessHardwareInterface);
620 620
621 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
622 PHM_PlatformCaps_SclkDeepSleep);
623
624 data->gpio_debug = 0; 621 data->gpio_debug = 0;
625 622
626 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 623 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c
index 44658451a8d2..f5992ea0c56f 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c
@@ -57,8 +57,6 @@ void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
57 57
58 /* Assume disabled */ 58 /* Assume disabled */
59 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 59 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
60 PHM_PlatformCaps_PowerContainment);
61 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
62 PHM_PlatformCaps_CAC); 60 PHM_PlatformCaps_CAC);
63 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 61 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
64 PHM_PlatformCaps_SQRamping); 62 PHM_PlatformCaps_SQRamping);
@@ -77,9 +75,8 @@ void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
77 75
78 fiji_hwmgr->fast_watermark_threshold = 100; 76 fiji_hwmgr->fast_watermark_threshold = 100;
79 77
80 if (hwmgr->powercontainment_enabled) { 78 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
81 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 79 PHM_PlatformCaps_PowerContainment)) {
82 PHM_PlatformCaps_PowerContainment);
83 tmp = 1; 80 tmp = 1;
84 fiji_hwmgr->enable_dte_feature = tmp ? false : true; 81 fiji_hwmgr->enable_dte_feature = tmp ? false : true;
85 fiji_hwmgr->enable_tdc_limit_feature = tmp ? true : false; 82 fiji_hwmgr->enable_tdc_limit_feature = tmp ? true : false;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
index 27e07624ac28..d829076ed9ea 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
@@ -39,6 +39,26 @@ extern int cz_hwmgr_init(struct pp_hwmgr *hwmgr);
39extern int tonga_hwmgr_init(struct pp_hwmgr *hwmgr); 39extern int tonga_hwmgr_init(struct pp_hwmgr *hwmgr);
40extern int fiji_hwmgr_init(struct pp_hwmgr *hwmgr); 40extern int fiji_hwmgr_init(struct pp_hwmgr *hwmgr);
41extern int polaris10_hwmgr_init(struct pp_hwmgr *hwmgr); 41extern int polaris10_hwmgr_init(struct pp_hwmgr *hwmgr);
42extern int iceland_hwmgr_init(struct pp_hwmgr *hwmgr);
43
44static int hwmgr_set_features_platform_caps(struct pp_hwmgr *hwmgr)
45{
46 if (amdgpu_sclk_deep_sleep_en)
47 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
48 PHM_PlatformCaps_SclkDeepSleep);
49 else
50 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
51 PHM_PlatformCaps_SclkDeepSleep);
52
53 if (amdgpu_powercontainment)
54 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
55 PHM_PlatformCaps_PowerContainment);
56 else
57 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
58 PHM_PlatformCaps_PowerContainment);
59
60 return 0;
61}
42 62
43int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle) 63int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
44{ 64{
@@ -57,9 +77,12 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
57 hwmgr->chip_family = pp_init->chip_family; 77 hwmgr->chip_family = pp_init->chip_family;
58 hwmgr->chip_id = pp_init->chip_id; 78 hwmgr->chip_id = pp_init->chip_id;
59 hwmgr->hw_revision = pp_init->rev_id; 79 hwmgr->hw_revision = pp_init->rev_id;
80 hwmgr->sub_sys_id = pp_init->sub_sys_id;
81 hwmgr->sub_vendor_id = pp_init->sub_vendor_id;
60 hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; 82 hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
61 hwmgr->power_source = PP_PowerSource_AC; 83 hwmgr->power_source = PP_PowerSource_AC;
62 hwmgr->powercontainment_enabled = pp_init->powercontainment_enabled; 84
85 hwmgr_set_features_platform_caps(hwmgr);
63 86
64 switch (hwmgr->chip_family) { 87 switch (hwmgr->chip_family) {
65 case AMDGPU_FAMILY_CZ: 88 case AMDGPU_FAMILY_CZ:
@@ -67,6 +90,9 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
67 break; 90 break;
68 case AMDGPU_FAMILY_VI: 91 case AMDGPU_FAMILY_VI:
69 switch (hwmgr->chip_id) { 92 switch (hwmgr->chip_id) {
93 case CHIP_TOPAZ:
94 iceland_hwmgr_init(hwmgr);
95 break;
70 case CHIP_TONGA: 96 case CHIP_TONGA:
71 tonga_hwmgr_init(hwmgr); 97 tonga_hwmgr_init(hwmgr);
72 break; 98 break;
@@ -182,29 +208,7 @@ int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
182 return 0; 208 return 0;
183} 209}
184 210
185int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
186 uint32_t index, uint32_t value, uint32_t mask)
187{
188 uint32_t i;
189 uint32_t cur_value;
190 211
191 if (hwmgr == NULL || hwmgr->device == NULL) {
192 printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
193 return -EINVAL;
194 }
195
196 for (i = 0; i < hwmgr->usec_timeout; i++) {
197 cur_value = cgs_read_register(hwmgr->device, index);
198 if ((cur_value & mask) != (value & mask))
199 break;
200 udelay(1);
201 }
202
203 /* timeout means wrong logic*/
204 if (i == hwmgr->usec_timeout)
205 return -1;
206 return 0;
207}
208 212
209 213
210/** 214/**
@@ -227,21 +231,7 @@ void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
227 phm_wait_on_register(hwmgr, indirect_port + 1, mask, value); 231 phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);
228} 232}
229 233
230void phm_wait_for_indirect_register_unequal(struct pp_hwmgr *hwmgr,
231 uint32_t indirect_port,
232 uint32_t index,
233 uint32_t value,
234 uint32_t mask)
235{
236 if (hwmgr == NULL || hwmgr->device == NULL) {
237 printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
238 return;
239 }
240 234
241 cgs_write_register(hwmgr->device, indirect_port, index);
242 phm_wait_for_register_unequal(hwmgr, indirect_port + 1,
243 value, mask);
244}
245 235
246bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr) 236bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr)
247{ 237{
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_clockpowergating.c
new file mode 100644
index 000000000000..47949f5cd073
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_clockpowergating.c
@@ -0,0 +1,119 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25
26#include "hwmgr.h"
27#include "iceland_clockpowergating.h"
28#include "ppsmc.h"
29#include "iceland_hwmgr.h"
30
31int iceland_phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
32{
33 /* iceland does not have MM hardware block */
34 return 0;
35}
36
37static int iceland_phm_powerup_uvd(struct pp_hwmgr *hwmgr)
38{
39 /* iceland does not have MM hardware block */
40 return 0;
41}
42
43static int iceland_phm_powerdown_vce(struct pp_hwmgr *hwmgr)
44{
45 /* iceland does not have MM hardware block */
46 return 0;
47}
48
49static int iceland_phm_powerup_vce(struct pp_hwmgr *hwmgr)
50{
51 /* iceland does not have MM hardware block */
52 return 0;
53}
54
55int iceland_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum
56 PHM_AsicBlock block, enum PHM_ClockGateSetting gating)
57{
58 int ret = 0;
59
60 switch (block) {
61 case PHM_AsicBlock_UVD_MVC:
62 case PHM_AsicBlock_UVD:
63 case PHM_AsicBlock_UVD_HD:
64 case PHM_AsicBlock_UVD_SD:
65 if (gating == PHM_ClockGateSetting_StaticOff)
66 ret = iceland_phm_powerdown_uvd(hwmgr);
67 else
68 ret = iceland_phm_powerup_uvd(hwmgr);
69 break;
70 case PHM_AsicBlock_GFX:
71 default:
72 break;
73 }
74
75 return ret;
76}
77
78int iceland_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
79{
80 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
81
82 data->uvd_power_gated = false;
83 data->vce_power_gated = false;
84
85 iceland_phm_powerup_uvd(hwmgr);
86 iceland_phm_powerup_vce(hwmgr);
87
88 return 0;
89}
90
91int iceland_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
92{
93 if (bgate) {
94 iceland_update_uvd_dpm(hwmgr, true);
95 iceland_phm_powerdown_uvd(hwmgr);
96 } else {
97 iceland_phm_powerup_uvd(hwmgr);
98 iceland_update_uvd_dpm(hwmgr, false);
99 }
100
101 return 0;
102}
103
104int iceland_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
105{
106 if (bgate)
107 return iceland_phm_powerdown_vce(hwmgr);
108 else
109 return iceland_phm_powerup_vce(hwmgr);
110
111 return 0;
112}
113
114int iceland_phm_update_clock_gatings(struct pp_hwmgr *hwmgr,
115 const uint32_t *msg_id)
116{
117 /* iceland does not have MM hardware block */
118 return 0;
119}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_clockpowergating.h b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_clockpowergating.h
new file mode 100644
index 000000000000..ff5ef00c7c68
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_clockpowergating.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25
26#ifndef _ICELAND_CLOCK_POWER_GATING_H_
27#define _ICELAND_CLOCK_POWER_GATING_H_
28
29#include "iceland_hwmgr.h"
30#include "pp_asicblocks.h"
31
32extern int iceland_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating);
33extern int iceland_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate);
34extern int iceland_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate);
35extern int iceland_phm_powerdown_uvd(struct pp_hwmgr *hwmgr);
36extern int iceland_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr);
37extern int iceland_phm_update_clock_gatings(struct pp_hwmgr *hwmgr, const uint32_t *msg_id);
38#endif /* _ICELAND_CLOCK_POWER_GATING_H_ */
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_dyn_defaults.h b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_dyn_defaults.h
new file mode 100644
index 000000000000..a7b4bc6caea2
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_dyn_defaults.h
@@ -0,0 +1,41 @@
1#ifndef ICELAND_DYN_DEFAULTS_H
2#define ICELAND_DYN_DEFAULTS_H
3
4enum ICELANDdpm_TrendDetection
5{
6 ICELANDdpm_TrendDetection_AUTO,
7 ICELANDdpm_TrendDetection_UP,
8 ICELANDdpm_TrendDetection_DOWN
9};
10typedef enum ICELANDdpm_TrendDetection ICELANDdpm_TrendDetection;
11
12
13#define PPICELAND_VOTINGRIGHTSCLIENTS_DFLT0 0x3FFFC102
14#define PPICELAND_VOTINGRIGHTSCLIENTS_DFLT1 0x000400
15#define PPICELAND_VOTINGRIGHTSCLIENTS_DFLT2 0xC00080
16#define PPICELAND_VOTINGRIGHTSCLIENTS_DFLT3 0xC00200
17#define PPICELAND_VOTINGRIGHTSCLIENTS_DFLT4 0xC01680
18#define PPICELAND_VOTINGRIGHTSCLIENTS_DFLT5 0xC00033
19#define PPICELAND_VOTINGRIGHTSCLIENTS_DFLT6 0xC00033
20#define PPICELAND_VOTINGRIGHTSCLIENTS_DFLT7 0x3FFFC000
21
22
23#define PPICELAND_THERMALPROTECTCOUNTER_DFLT 0x200
24
25#define PPICELAND_STATICSCREENTHRESHOLDUNIT_DFLT 0
26
27#define PPICELAND_STATICSCREENTHRESHOLD_DFLT 0x00C8
28
29#define PPICELAND_GFXIDLECLOCKSTOPTHRESHOLD_DFLT 0x200
30
31#define PPICELAND_REFERENCEDIVIDER_DFLT 4
32
33#define PPICELAND_ULVVOLTAGECHANGEDELAY_DFLT 1687
34
35#define PPICELAND_CGULVPARAMETER_DFLT 0x00040035
36#define PPICELAND_CGULVCONTROL_DFLT 0x00007450
37#define PPICELAND_TARGETACTIVITY_DFLT 30
38#define PPICELAND_MCLK_TARGETACTIVITY_DFLT 10
39
40#endif
41
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c
new file mode 100644
index 000000000000..8a7ada50551c
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.c
@@ -0,0 +1,5692 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/fb.h>
28#include "linux/delay.h"
29#include "pp_acpi.h"
30#include "hwmgr.h"
31#include <atombios.h>
32#include "iceland_hwmgr.h"
33#include "pptable.h"
34#include "processpptables.h"
35#include "pp_debug.h"
36#include "ppsmc.h"
37#include "cgs_common.h"
38#include "pppcielanes.h"
39#include "iceland_dyn_defaults.h"
40#include "smumgr.h"
41#include "iceland_smumgr.h"
42#include "iceland_clockpowergating.h"
43#include "iceland_thermal.h"
44#include "iceland_powertune.h"
45
46#include "gmc/gmc_8_1_d.h"
47#include "gmc/gmc_8_1_sh_mask.h"
48
49#include "bif/bif_5_0_d.h"
50#include "bif/bif_5_0_sh_mask.h"
51
52#include "smu/smu_7_1_1_d.h"
53#include "smu/smu_7_1_1_sh_mask.h"
54
55#include "cgs_linux.h"
56#include "eventmgr.h"
57#include "amd_pcie_helpers.h"
58
59#define MC_CG_ARB_FREQ_F0 0x0a
60#define MC_CG_ARB_FREQ_F1 0x0b
61#define MC_CG_ARB_FREQ_F2 0x0c
62#define MC_CG_ARB_FREQ_F3 0x0d
63
64#define MC_CG_SEQ_DRAMCONF_S0 0x05
65#define MC_CG_SEQ_DRAMCONF_S1 0x06
66#define MC_CG_SEQ_YCLK_SUSPEND 0x04
67#define MC_CG_SEQ_YCLK_RESUME 0x0a
68
69#define PCIE_BUS_CLK 10000
70#define TCLK (PCIE_BUS_CLK / 10)
71
72#define SMC_RAM_END 0x40000
73#define SMC_CG_IND_START 0xc0030000
74#define SMC_CG_IND_END 0xc0040000 /* First byte after SMC_CG_IND*/
75
76#define VOLTAGE_SCALE 4
77#define VOLTAGE_VID_OFFSET_SCALE1 625
78#define VOLTAGE_VID_OFFSET_SCALE2 100
79
80const uint32_t iceland_magic = (uint32_t)(PHM_VIslands_Magic);
81
82#define MC_SEQ_MISC0_GDDR5_SHIFT 28
83#define MC_SEQ_MISC0_GDDR5_MASK 0xf0000000
84#define MC_SEQ_MISC0_GDDR5_VALUE 5
85
86/** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */
87enum DPM_EVENT_SRC {
88 DPM_EVENT_SRC_ANALOG = 0, /* Internal analog trip point */
89 DPM_EVENT_SRC_EXTERNAL = 1, /* External (GPIO 17) signal */
90 DPM_EVENT_SRC_DIGITAL = 2, /* Internal digital trip point (DIG_THERM_DPM) */
91 DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3, /* Internal analog or external */
92 DPM_EVENT_SRC_DIGITAL_OR_EXTERNAL = 4 /* Internal digital or external */
93};
94
95static int iceland_read_clock_registers(struct pp_hwmgr *hwmgr)
96{
97 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
98
99 data->clock_registers.vCG_SPLL_FUNC_CNTL =
100 cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_FUNC_CNTL);
101 data->clock_registers.vCG_SPLL_FUNC_CNTL_2 =
102 cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_FUNC_CNTL_2);
103 data->clock_registers.vCG_SPLL_FUNC_CNTL_3 =
104 cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_FUNC_CNTL_3);
105 data->clock_registers.vCG_SPLL_FUNC_CNTL_4 =
106 cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_FUNC_CNTL_4);
107 data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM =
108 cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_SPREAD_SPECTRUM);
109 data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2 =
110 cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_SPLL_SPREAD_SPECTRUM_2);
111 data->clock_registers.vDLL_CNTL =
112 cgs_read_register(hwmgr->device, mmDLL_CNTL);
113 data->clock_registers.vMCLK_PWRMGT_CNTL =
114 cgs_read_register(hwmgr->device, mmMCLK_PWRMGT_CNTL);
115 data->clock_registers.vMPLL_AD_FUNC_CNTL =
116 cgs_read_register(hwmgr->device, mmMPLL_AD_FUNC_CNTL);
117 data->clock_registers.vMPLL_DQ_FUNC_CNTL =
118 cgs_read_register(hwmgr->device, mmMPLL_DQ_FUNC_CNTL);
119 data->clock_registers.vMPLL_FUNC_CNTL =
120 cgs_read_register(hwmgr->device, mmMPLL_FUNC_CNTL);
121 data->clock_registers.vMPLL_FUNC_CNTL_1 =
122 cgs_read_register(hwmgr->device, mmMPLL_FUNC_CNTL_1);
123 data->clock_registers.vMPLL_FUNC_CNTL_2 =
124 cgs_read_register(hwmgr->device, mmMPLL_FUNC_CNTL_2);
125 data->clock_registers.vMPLL_SS1 =
126 cgs_read_register(hwmgr->device, mmMPLL_SS1);
127 data->clock_registers.vMPLL_SS2 =
128 cgs_read_register(hwmgr->device, mmMPLL_SS2);
129
130 return 0;
131}
132
133/**
134 * Find out if memory is GDDR5.
135 *
136 * @param hwmgr the address of the powerplay hardware manager.
137 * @return always 0
138 */
139int iceland_get_memory_type(struct pp_hwmgr *hwmgr)
140{
141 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
142 uint32_t temp;
143
144 temp = cgs_read_register(hwmgr->device, mmMC_SEQ_MISC0);
145
146 data->is_memory_GDDR5 = (MC_SEQ_MISC0_GDDR5_VALUE ==
147 ((temp & MC_SEQ_MISC0_GDDR5_MASK) >>
148 MC_SEQ_MISC0_GDDR5_SHIFT));
149
150 return 0;
151}
152
153int iceland_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
154{
155 /* iceland does not have MM hardware blocks */
156 return 0;
157}
158
159/**
160 * Enables Dynamic Power Management by SMC
161 *
162 * @param hwmgr the address of the powerplay hardware manager.
163 * @return always 0
164 */
165int iceland_enable_acpi_power_management(struct pp_hwmgr *hwmgr)
166{
167 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, STATIC_PM_EN, 1);
168
169 return 0;
170}
171
172/**
173 * Find the MC microcode version and store it in the HwMgr struct
174 *
175 * @param hwmgr the address of the powerplay hardware manager.
176 * @return always 0
177 */
178int iceland_get_mc_microcode_version(struct pp_hwmgr *hwmgr)
179{
180 cgs_write_register(hwmgr->device, mmMC_SEQ_IO_DEBUG_INDEX, 0x9F);
181
182 hwmgr->microcode_version_info.MC = cgs_read_register(hwmgr->device, mmMC_SEQ_IO_DEBUG_DATA);
183
184 return 0;
185}
186
187static int iceland_init_sclk_threshold(struct pp_hwmgr *hwmgr)
188{
189 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
190
191 data->low_sclk_interrupt_threshold = 0;
192
193 return 0;
194}
195
196
197static int iceland_setup_asic_task(struct pp_hwmgr *hwmgr)
198{
199 int tmp_result, result = 0;
200
201 tmp_result = iceland_read_clock_registers(hwmgr);
202 PP_ASSERT_WITH_CODE((0 == tmp_result),
203 "Failed to read clock registers!", result = tmp_result);
204
205 tmp_result = iceland_get_memory_type(hwmgr);
206 PP_ASSERT_WITH_CODE((0 == tmp_result),
207 "Failed to get memory type!", result = tmp_result);
208
209 tmp_result = iceland_enable_acpi_power_management(hwmgr);
210 PP_ASSERT_WITH_CODE((0 == tmp_result),
211 "Failed to enable ACPI power management!", result = tmp_result);
212
213 tmp_result = iceland_get_mc_microcode_version(hwmgr);
214 PP_ASSERT_WITH_CODE((0 == tmp_result),
215 "Failed to get MC microcode version!", result = tmp_result);
216
217 tmp_result = iceland_init_sclk_threshold(hwmgr);
218 PP_ASSERT_WITH_CODE((0 == tmp_result),
219 "Failed to init sclk threshold!", result = tmp_result);
220
221 return result;
222}
223
224static bool cf_iceland_voltage_control(struct pp_hwmgr *hwmgr)
225{
226 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
227
228 return ICELAND_VOLTAGE_CONTROL_NONE != data->voltage_control;
229}
230
231/*
232 * -------------- Voltage Tables ----------------------
233 * If the voltage table would be bigger than what will fit into the
234 * state table on the SMC keep only the higher entries.
235 */
236
237static void iceland_trim_voltage_table_to_fit_state_table(
238 struct pp_hwmgr *hwmgr,
239 uint32_t max_voltage_steps,
240 pp_atomctrl_voltage_table *voltage_table)
241{
242 unsigned int i, diff;
243
244 if (voltage_table->count <= max_voltage_steps) {
245 return;
246 }
247
248 diff = voltage_table->count - max_voltage_steps;
249
250 for (i = 0; i < max_voltage_steps; i++) {
251 voltage_table->entries[i] = voltage_table->entries[i + diff];
252 }
253
254 voltage_table->count = max_voltage_steps;
255
256 return;
257}
258
259/**
260 * Enable voltage control
261 *
262 * @param hwmgr the address of the powerplay hardware manager.
263 * @return always 0
264 */
265int iceland_enable_voltage_control(struct pp_hwmgr *hwmgr)
266{
267 /* enable voltage control */
268 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, VOLT_PWRMGT_EN, 1);
269
270 return 0;
271}
272
273static int iceland_get_svi2_voltage_table(struct pp_hwmgr *hwmgr,
274 struct phm_clock_voltage_dependency_table *voltage_dependency_table,
275 pp_atomctrl_voltage_table *voltage_table)
276{
277 uint32_t i;
278
279 PP_ASSERT_WITH_CODE((NULL != voltage_table),
280 "Voltage Dependency Table empty.", return -EINVAL;);
281
282 voltage_table->mask_low = 0;
283 voltage_table->phase_delay = 0;
284 voltage_table->count = voltage_dependency_table->count;
285
286 for (i = 0; i < voltage_dependency_table->count; i++) {
287 voltage_table->entries[i].value =
288 voltage_dependency_table->entries[i].v;
289 voltage_table->entries[i].smio_low = 0;
290 }
291
292 return 0;
293}
294
295/**
296 * Create Voltage Tables.
297 *
298 * @param hwmgr the address of the powerplay hardware manager.
299 * @return always 0
300 */
301int iceland_construct_voltage_tables(struct pp_hwmgr *hwmgr)
302{
303 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
304 int result;
305
306 /* GPIO voltage */
307 if (ICELAND_VOLTAGE_CONTROL_BY_GPIO == data->voltage_control) {
308 result = atomctrl_get_voltage_table_v3(hwmgr,
309 VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_GPIO_LUT,
310 &data->vddc_voltage_table);
311 PP_ASSERT_WITH_CODE((0 == result),
312 "Failed to retrieve VDDC table.", return result;);
313 } else if (ICELAND_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control) {
314 /* SVI2 VDDC voltage */
315 result = iceland_get_svi2_voltage_table(hwmgr,
316 hwmgr->dyn_state.vddc_dependency_on_mclk,
317 &data->vddc_voltage_table);
318 PP_ASSERT_WITH_CODE((0 == result),
319 "Failed to retrieve SVI2 VDDC table from dependancy table.", return result;);
320 }
321
322 PP_ASSERT_WITH_CODE(
323 (data->vddc_voltage_table.count <= (SMU71_MAX_LEVELS_VDDC)),
324 "Too many voltage values for VDDC. Trimming to fit state table.",
325 iceland_trim_voltage_table_to_fit_state_table(hwmgr,
326 SMU71_MAX_LEVELS_VDDC, &(data->vddc_voltage_table));
327 );
328
329 /* GPIO */
330 if (ICELAND_VOLTAGE_CONTROL_BY_GPIO == data->vdd_ci_control) {
331 result = atomctrl_get_voltage_table_v3(hwmgr,
332 VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_GPIO_LUT, &(data->vddci_voltage_table));
333 PP_ASSERT_WITH_CODE((0 == result),
334 "Failed to retrieve VDDCI table.", return result;);
335 }
336
337 /* SVI2 VDDCI voltage */
338 if (ICELAND_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_ci_control) {
339 result = iceland_get_svi2_voltage_table(hwmgr,
340 hwmgr->dyn_state.vddci_dependency_on_mclk,
341 &data->vddci_voltage_table);
342 PP_ASSERT_WITH_CODE((0 == result),
343 "Failed to retrieve SVI2 VDDCI table from dependancy table.", return result;);
344 }
345
346 PP_ASSERT_WITH_CODE(
347 (data->vddci_voltage_table.count <= (SMU71_MAX_LEVELS_VDDCI)),
348 "Too many voltage values for VDDCI. Trimming to fit state table.",
349 iceland_trim_voltage_table_to_fit_state_table(hwmgr,
350 SMU71_MAX_LEVELS_VDDCI, &(data->vddci_voltage_table));
351 );
352
353
354 /* GPIO */
355 if (ICELAND_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) {
356 result = atomctrl_get_voltage_table_v3(hwmgr,
357 VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_GPIO_LUT, &(data->mvdd_voltage_table));
358 PP_ASSERT_WITH_CODE((0 == result),
359 "Failed to retrieve table.", return result;);
360 }
361
362 /* SVI2 voltage control */
363 if (ICELAND_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) {
364 result = iceland_get_svi2_voltage_table(hwmgr,
365 hwmgr->dyn_state.mvdd_dependency_on_mclk,
366 &data->mvdd_voltage_table);
367 PP_ASSERT_WITH_CODE((0 == result),
368 "Failed to retrieve SVI2 MVDD table from dependancy table.", return result;);
369 }
370
371 PP_ASSERT_WITH_CODE(
372 (data->mvdd_voltage_table.count <= (SMU71_MAX_LEVELS_MVDD)),
373 "Too many voltage values for MVDD. Trimming to fit state table.",
374 iceland_trim_voltage_table_to_fit_state_table(hwmgr,
375 SMU71_MAX_LEVELS_MVDD, &(data->mvdd_voltage_table));
376 );
377
378 return 0;
379}
380
381/*---------------------------MC----------------------------*/
382
383uint8_t iceland_get_memory_module_index(struct pp_hwmgr *hwmgr)
384{
385 return (uint8_t) (0xFF & (cgs_read_register(hwmgr->device, mmBIOS_SCRATCH_4) >> 16));
386}
387
388bool iceland_check_s0_mc_reg_index(uint16_t inReg, uint16_t *outReg)
389{
390 bool result = true;
391
392 switch (inReg) {
393 case mmMC_SEQ_RAS_TIMING:
394 *outReg = mmMC_SEQ_RAS_TIMING_LP;
395 break;
396
397 case mmMC_SEQ_DLL_STBY:
398 *outReg = mmMC_SEQ_DLL_STBY_LP;
399 break;
400
401 case mmMC_SEQ_G5PDX_CMD0:
402 *outReg = mmMC_SEQ_G5PDX_CMD0_LP;
403 break;
404
405 case mmMC_SEQ_G5PDX_CMD1:
406 *outReg = mmMC_SEQ_G5PDX_CMD1_LP;
407 break;
408
409 case mmMC_SEQ_G5PDX_CTRL:
410 *outReg = mmMC_SEQ_G5PDX_CTRL_LP;
411 break;
412
413 case mmMC_SEQ_CAS_TIMING:
414 *outReg = mmMC_SEQ_CAS_TIMING_LP;
415 break;
416
417 case mmMC_SEQ_MISC_TIMING:
418 *outReg = mmMC_SEQ_MISC_TIMING_LP;
419 break;
420
421 case mmMC_SEQ_MISC_TIMING2:
422 *outReg = mmMC_SEQ_MISC_TIMING2_LP;
423 break;
424
425 case mmMC_SEQ_PMG_DVS_CMD:
426 *outReg = mmMC_SEQ_PMG_DVS_CMD_LP;
427 break;
428
429 case mmMC_SEQ_PMG_DVS_CTL:
430 *outReg = mmMC_SEQ_PMG_DVS_CTL_LP;
431 break;
432
433 case mmMC_SEQ_RD_CTL_D0:
434 *outReg = mmMC_SEQ_RD_CTL_D0_LP;
435 break;
436
437 case mmMC_SEQ_RD_CTL_D1:
438 *outReg = mmMC_SEQ_RD_CTL_D1_LP;
439 break;
440
441 case mmMC_SEQ_WR_CTL_D0:
442 *outReg = mmMC_SEQ_WR_CTL_D0_LP;
443 break;
444
445 case mmMC_SEQ_WR_CTL_D1:
446 *outReg = mmMC_SEQ_WR_CTL_D1_LP;
447 break;
448
449 case mmMC_PMG_CMD_EMRS:
450 *outReg = mmMC_SEQ_PMG_CMD_EMRS_LP;
451 break;
452
453 case mmMC_PMG_CMD_MRS:
454 *outReg = mmMC_SEQ_PMG_CMD_MRS_LP;
455 break;
456
457 case mmMC_PMG_CMD_MRS1:
458 *outReg = mmMC_SEQ_PMG_CMD_MRS1_LP;
459 break;
460
461 case mmMC_SEQ_PMG_TIMING:
462 *outReg = mmMC_SEQ_PMG_TIMING_LP;
463 break;
464
465 case mmMC_PMG_CMD_MRS2:
466 *outReg = mmMC_SEQ_PMG_CMD_MRS2_LP;
467 break;
468
469 case mmMC_SEQ_WR_CTL_2:
470 *outReg = mmMC_SEQ_WR_CTL_2_LP;
471 break;
472
473 default:
474 result = false;
475 break;
476 }
477
478 return result;
479}
480
481int iceland_set_s0_mc_reg_index(phw_iceland_mc_reg_table *table)
482{
483 uint32_t i;
484 uint16_t address;
485
486 for (i = 0; i < table->last; i++) {
487 table->mc_reg_address[i].s0 =
488 iceland_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address)
489 ? address : table->mc_reg_address[i].s1;
490 }
491 return 0;
492}
493
494int iceland_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, phw_iceland_mc_reg_table *ni_table)
495{
496 uint8_t i, j;
497
498 PP_ASSERT_WITH_CODE((table->last <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE),
499 "Invalid VramInfo table.", return -1);
500 PP_ASSERT_WITH_CODE((table->num_entries <= MAX_AC_TIMING_ENTRIES),
501 "Invalid VramInfo table.", return -1);
502
503 for (i = 0; i < table->last; i++) {
504 ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
505 }
506 ni_table->last = table->last;
507
508 for (i = 0; i < table->num_entries; i++) {
509 ni_table->mc_reg_table_entry[i].mclk_max =
510 table->mc_reg_table_entry[i].mclk_max;
511 for (j = 0; j < table->last; j++) {
512 ni_table->mc_reg_table_entry[i].mc_data[j] =
513 table->mc_reg_table_entry[i].mc_data[j];
514 }
515 }
516
517 ni_table->num_entries = table->num_entries;
518
519 return 0;
520}
521
522/**
523 * VBIOS omits some information to reduce size, we need to recover them here.
524 * 1. when we see mmMC_SEQ_MISC1, bit[31:16] EMRS1, need to be write to mmMC_PMG_CMD_EMRS /_LP[15:0].
525 * Bit[15:0] MRS, need to be update mmMC_PMG_CMD_MRS/_LP[15:0]
526 * 2. when we see mmMC_SEQ_RESERVE_M, bit[15:0] EMRS2, need to be write to mmMC_PMG_CMD_MRS1/_LP[15:0].
527 * 3. need to set these data for each clock range
528 *
529 * @param hwmgr the address of the powerplay hardware manager.
530 * @param table the address of MCRegTable
531 * @return always 0
532 */
533static int iceland_set_mc_special_registers(struct pp_hwmgr *hwmgr, phw_iceland_mc_reg_table *table)
534{
535 uint8_t i, j, k;
536 uint32_t temp_reg;
537 const iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
538
539 for (i = 0, j = table->last; i < table->last; i++) {
540 PP_ASSERT_WITH_CODE((j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE),
541 "Invalid VramInfo table.", return -1);
542 switch (table->mc_reg_address[i].s1) {
543 /*
544 * mmMC_SEQ_MISC1, bit[31:16] EMRS1, need to be write
545 * to mmMC_PMG_CMD_EMRS/_LP[15:0]. Bit[15:0] MRS, need
546 * to be update mmMC_PMG_CMD_MRS/_LP[15:0]
547 */
548 case mmMC_SEQ_MISC1:
549 temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS);
550 table->mc_reg_address[j].s1 = mmMC_PMG_CMD_EMRS;
551 table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_EMRS_LP;
552 for (k = 0; k < table->num_entries; k++) {
553 table->mc_reg_table_entry[k].mc_data[j] =
554 ((temp_reg & 0xffff0000)) |
555 ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
556 }
557 j++;
558 PP_ASSERT_WITH_CODE((j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE),
559 "Invalid VramInfo table.", return -1);
560
561 temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS);
562 table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS;
563 table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP;
564 for (k = 0; k < table->num_entries; k++) {
565 table->mc_reg_table_entry[k].mc_data[j] =
566 (temp_reg & 0xffff0000) |
567 (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
568
569 if (!data->is_memory_GDDR5) {
570 table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
571 }
572 }
573 j++;
574 PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE),
575 "Invalid VramInfo table.", return -1);
576
577 if (!data->is_memory_GDDR5) {
578 table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD;
579 table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD;
580 for (k = 0; k < table->num_entries; k++) {
581 table->mc_reg_table_entry[k].mc_data[j] =
582 (table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;
583 }
584 j++;
585 PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE),
586 "Invalid VramInfo table.", return -1);
587 }
588
589 break;
590
591 case mmMC_SEQ_RESERVE_M:
592 temp_reg = cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1);
593 table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS1;
594 table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS1_LP;
595 for (k = 0; k < table->num_entries; k++) {
596 table->mc_reg_table_entry[k].mc_data[j] =
597 (temp_reg & 0xffff0000) |
598 (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
599 }
600 j++;
601 PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE),
602 "Invalid VramInfo table.", return -1);
603 break;
604
605 default:
606 break;
607 }
608
609 }
610
611 table->last = j;
612
613 return 0;
614}
615
616
617static int iceland_set_valid_flag(phw_iceland_mc_reg_table *table)
618{
619 uint8_t i, j;
620 for (i = 0; i < table->last; i++) {
621 for (j = 1; j < table->num_entries; j++) {
622 if (table->mc_reg_table_entry[j-1].mc_data[i] !=
623 table->mc_reg_table_entry[j].mc_data[i]) {
624 table->validflag |= (1<<i);
625 break;
626 }
627 }
628 }
629
630 return 0;
631}
632
633static int iceland_initialize_mc_reg_table(struct pp_hwmgr *hwmgr)
634{
635 int result;
636 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
637 pp_atomctrl_mc_reg_table *table;
638 phw_iceland_mc_reg_table *ni_table = &data->iceland_mc_reg_table;
639 uint8_t module_index = iceland_get_memory_module_index(hwmgr);
640
641 table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL);
642
643 if (NULL == table)
644 return -ENOMEM;
645
646 /* Program additional LP registers that are no longer programmed by VBIOS */
647 cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING));
648 cgs_write_register(hwmgr->device, mmMC_SEQ_CAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_CAS_TIMING));
649 cgs_write_register(hwmgr->device, mmMC_SEQ_DLL_STBY_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_DLL_STBY));
650 cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD0));
651 cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CMD1));
652 cgs_write_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_G5PDX_CTRL));
653 cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CMD));
654 cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_DVS_CTL));
655 cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING));
656 cgs_write_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_MISC_TIMING2));
657 cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_EMRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_EMRS));
658 cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS));
659 cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS1_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS1));
660 cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D0));
661 cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_D1));
662 cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D0));
663 cgs_write_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RD_CTL_D1));
664 cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_PMG_TIMING));
665 cgs_write_register(hwmgr->device, mmMC_SEQ_PMG_CMD_MRS2_LP, cgs_read_register(hwmgr->device, mmMC_PMG_CMD_MRS2));
666 cgs_write_register(hwmgr->device, mmMC_SEQ_WR_CTL_2_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_WR_CTL_2));
667
668 memset(table, 0x00, sizeof(pp_atomctrl_mc_reg_table));
669
670 result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table);
671
672 if (0 == result)
673 result = iceland_copy_vbios_smc_reg_table(table, ni_table);
674
675 if (0 == result) {
676 iceland_set_s0_mc_reg_index(ni_table);
677 result = iceland_set_mc_special_registers(hwmgr, ni_table);
678 }
679
680 if (0 == result)
681 iceland_set_valid_flag(ni_table);
682
683 kfree(table);
684 return result;
685}
686
687/**
688 * Programs static screed detection parameters
689 *
690 * @param hwmgr the address of the powerplay hardware manager.
691 * @return always 0
692 */
693int iceland_program_static_screen_threshold_parameters(struct pp_hwmgr *hwmgr)
694{
695 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
696
697 /* Set static screen threshold unit*/
698 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device,
699 CGS_IND_REG__SMC, CG_STATIC_SCREEN_PARAMETER, STATIC_SCREEN_THRESHOLD_UNIT,
700 data->static_screen_threshold_unit);
701 /* Set static screen threshold*/
702 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device,
703 CGS_IND_REG__SMC, CG_STATIC_SCREEN_PARAMETER, STATIC_SCREEN_THRESHOLD,
704 data->static_screen_threshold);
705
706 return 0;
707}
708
709/**
710 * Setup display gap for glitch free memory clock switching.
711 *
712 * @param hwmgr the address of the powerplay hardware manager.
713 * @return always 0
714 */
715int iceland_enable_display_gap(struct pp_hwmgr *hwmgr)
716{
717 uint32_t display_gap = cgs_read_ind_register(hwmgr->device,
718 CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL);
719
720 display_gap = PHM_SET_FIELD(display_gap,
721 CG_DISPLAY_GAP_CNTL, DISP_GAP, DISPLAY_GAP_IGNORE);
722
723 display_gap = PHM_SET_FIELD(display_gap,
724 CG_DISPLAY_GAP_CNTL, DISP_GAP_MCHG, DISPLAY_GAP_VBLANK);
725
726 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
727 ixCG_DISPLAY_GAP_CNTL, display_gap);
728
729 return 0;
730}
731
732/**
733 * Programs activity state transition voting clients
734 *
735 * @param hwmgr the address of the powerplay hardware manager.
736 * @return always 0
737 */
738int iceland_program_voting_clients(struct pp_hwmgr *hwmgr)
739{
740 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
741
742 /* Clear reset for voting clients before enabling DPM */
743 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
744 SCLK_PWRMGT_CNTL, RESET_SCLK_CNT, 0);
745 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
746 SCLK_PWRMGT_CNTL, RESET_BUSY_CNT, 0);
747
748 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
749 ixCG_FREQ_TRAN_VOTING_0, data->voting_rights_clients0);
750 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
751 ixCG_FREQ_TRAN_VOTING_1, data->voting_rights_clients1);
752 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
753 ixCG_FREQ_TRAN_VOTING_2, data->voting_rights_clients2);
754 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
755 ixCG_FREQ_TRAN_VOTING_3, data->voting_rights_clients3);
756 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
757 ixCG_FREQ_TRAN_VOTING_4, data->voting_rights_clients4);
758 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
759 ixCG_FREQ_TRAN_VOTING_5, data->voting_rights_clients5);
760 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
761 ixCG_FREQ_TRAN_VOTING_6, data->voting_rights_clients6);
762 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
763 ixCG_FREQ_TRAN_VOTING_7, data->voting_rights_clients7);
764
765 return 0;
766}
767
768static int iceland_upload_firmware(struct pp_hwmgr *hwmgr)
769{
770 int ret = 0;
771
772 if (!iceland_is_smc_ram_running(hwmgr->smumgr))
773 ret = iceland_smu_upload_firmware_image(hwmgr->smumgr);
774
775 return ret;
776}
777
778/**
779 * Get the location of various tables inside the FW image.
780 *
781 * @param hwmgr the address of the powerplay hardware manager.
782 * @return always 0
783 */
784int iceland_process_firmware_header(struct pp_hwmgr *hwmgr)
785{
786 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
787
788 uint32_t tmp;
789 int result;
790 bool error = 0;
791
792 result = iceland_read_smc_sram_dword(hwmgr->smumgr,
793 SMU71_FIRMWARE_HEADER_LOCATION +
794 offsetof(SMU71_Firmware_Header, DpmTable),
795 &tmp, data->sram_end);
796
797 if (0 == result) {
798 data->dpm_table_start = tmp;
799 }
800
801 error |= (0 != result);
802
803 result = iceland_read_smc_sram_dword(hwmgr->smumgr,
804 SMU71_FIRMWARE_HEADER_LOCATION +
805 offsetof(SMU71_Firmware_Header, SoftRegisters),
806 &tmp, data->sram_end);
807
808 if (0 == result) {
809 data->soft_regs_start = tmp;
810 }
811
812 error |= (0 != result);
813
814
815 result = iceland_read_smc_sram_dword(hwmgr->smumgr,
816 SMU71_FIRMWARE_HEADER_LOCATION +
817 offsetof(SMU71_Firmware_Header, mcRegisterTable),
818 &tmp, data->sram_end);
819
820 if (0 == result) {
821 data->mc_reg_table_start = tmp;
822 }
823
824 result = iceland_read_smc_sram_dword(hwmgr->smumgr,
825 SMU71_FIRMWARE_HEADER_LOCATION +
826 offsetof(SMU71_Firmware_Header, FanTable),
827 &tmp, data->sram_end);
828
829 if (0 == result) {
830 data->fan_table_start = tmp;
831 }
832
833 error |= (0 != result);
834
835 result = iceland_read_smc_sram_dword(hwmgr->smumgr,
836 SMU71_FIRMWARE_HEADER_LOCATION +
837 offsetof(SMU71_Firmware_Header, mcArbDramTimingTable),
838 &tmp, data->sram_end);
839
840 if (0 == result) {
841 data->arb_table_start = tmp;
842 }
843
844 error |= (0 != result);
845
846
847 result = iceland_read_smc_sram_dword(hwmgr->smumgr,
848 SMU71_FIRMWARE_HEADER_LOCATION +
849 offsetof(SMU71_Firmware_Header, Version),
850 &tmp, data->sram_end);
851
852 if (0 == result) {
853 hwmgr->microcode_version_info.SMC = tmp;
854 }
855
856 error |= (0 != result);
857
858 result = iceland_read_smc_sram_dword(hwmgr->smumgr,
859 SMU71_FIRMWARE_HEADER_LOCATION +
860 offsetof(SMU71_Firmware_Header, UlvSettings),
861 &tmp, data->sram_end);
862
863 if (0 == result) {
864 data->ulv_settings_start = tmp;
865 }
866
867 error |= (0 != result);
868
869 return error ? 1 : 0;
870}
871
872/*
873* Copy one arb setting to another and then switch the active set.
874* arbFreqSrc and arbFreqDest is one of the MC_CG_ARB_FREQ_Fx constants.
875*/
876int iceland_copy_and_switch_arb_sets(struct pp_hwmgr *hwmgr,
877 uint32_t arbFreqSrc, uint32_t arbFreqDest)
878{
879 uint32_t mc_arb_dram_timing;
880 uint32_t mc_arb_dram_timing2;
881 uint32_t burst_time;
882 uint32_t mc_cg_config;
883
884 switch (arbFreqSrc) {
885 case MC_CG_ARB_FREQ_F0:
886 mc_arb_dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING);
887 mc_arb_dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2);
888 burst_time = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0);
889 break;
890
891 case MC_CG_ARB_FREQ_F1:
892 mc_arb_dram_timing = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING_1);
893 mc_arb_dram_timing2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2_1);
894 burst_time = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE1);
895 break;
896
897 default:
898 return -1;
899 }
900
901 switch (arbFreqDest) {
902 case MC_CG_ARB_FREQ_F0:
903 cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING, mc_arb_dram_timing);
904 cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);
905 PHM_WRITE_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0, burst_time);
906 break;
907
908 case MC_CG_ARB_FREQ_F1:
909 cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);
910 cgs_write_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);
911 PHM_WRITE_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE1, burst_time);
912 break;
913
914 default:
915 return -1;
916 }
917
918 mc_cg_config = cgs_read_register(hwmgr->device, mmMC_CG_CONFIG);
919 mc_cg_config |= 0x0000000F;
920 cgs_write_register(hwmgr->device, mmMC_CG_CONFIG, mc_cg_config);
921 PHM_WRITE_FIELD(hwmgr->device, MC_ARB_CG, CG_ARB_REQ, arbFreqDest);
922
923 return 0;
924}
925
926/**
927 * Initial switch from ARB F0->F1
928 *
929 * @param hwmgr the address of the powerplay hardware manager.
930 * @return always 0
931 * This function is to be called from the SetPowerState table.
932 */
933int iceland_initial_switch_from_arb_f0_to_f1(struct pp_hwmgr *hwmgr)
934{
935 return iceland_copy_and_switch_arb_sets(hwmgr, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
936}
937
938/* ---------------------------------------- ULV related functions ----------------------------------------------------*/
939
940
941static int iceland_reset_single_dpm_table(
942 struct pp_hwmgr *hwmgr,
943 struct iceland_single_dpm_table *dpm_table,
944 uint32_t count)
945{
946 uint32_t i;
947 if (!(count <= MAX_REGULAR_DPM_NUMBER))
948 printk(KERN_ERR "[ powerplay ] Fatal error, can not set up single DPM \
949 table entries to exceed max number! \n");
950
951 dpm_table->count = count;
952 for (i = 0; i < MAX_REGULAR_DPM_NUMBER; i++) {
953 dpm_table->dpm_levels[i].enabled = 0;
954 }
955
956 return 0;
957}
958
959static void iceland_setup_pcie_table_entry(
960 struct iceland_single_dpm_table *dpm_table,
961 uint32_t index, uint32_t pcie_gen,
962 uint32_t pcie_lanes)
963{
964 dpm_table->dpm_levels[index].value = pcie_gen;
965 dpm_table->dpm_levels[index].param1 = pcie_lanes;
966 dpm_table->dpm_levels[index].enabled = 1;
967}
968
969/*
970 * Set up the PCIe DPM table as follows:
971 *
972 * A = Performance State, Max, Gen Speed
973 * C = Performance State, Min, Gen Speed
974 * 1 = Performance State, Max, Lane #
975 * 3 = Performance State, Min, Lane #
976 *
977 * B = Power Saving State, Max, Gen Speed
978 * D = Power Saving State, Min, Gen Speed
979 * 2 = Power Saving State, Max, Lane #
980 * 4 = Power Saving State, Min, Lane #
981 *
982 *
983 * DPM Index Gen Speed Lane #
984 * 5 A 1
985 * 4 B 2
986 * 3 C 1
987 * 2 D 2
988 * 1 C 3
989 * 0 D 4
990 *
991 */
992static int iceland_setup_default_pcie_tables(struct pp_hwmgr *hwmgr)
993{
994 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
995
996 PP_ASSERT_WITH_CODE((data->use_pcie_performance_levels ||
997 data->use_pcie_power_saving_levels),
998 "No pcie performance levels!", return -EINVAL);
999
1000 if (data->use_pcie_performance_levels && !data->use_pcie_power_saving_levels) {
1001 data->pcie_gen_power_saving = data->pcie_gen_performance;
1002 data->pcie_lane_power_saving = data->pcie_lane_performance;
1003 } else if (!data->use_pcie_performance_levels && data->use_pcie_power_saving_levels) {
1004 data->pcie_gen_performance = data->pcie_gen_power_saving;
1005 data->pcie_lane_performance = data->pcie_lane_power_saving;
1006 }
1007
1008 iceland_reset_single_dpm_table(hwmgr, &data->dpm_table.pcie_speed_table, SMU71_MAX_LEVELS_LINK);
1009
1010 /* Hardcode Pcie Table */
1011 iceland_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 0,
1012 get_pcie_gen_support(data->pcie_gen_cap, PP_Min_PCIEGen),
1013 get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
1014 iceland_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 1,
1015 get_pcie_gen_support(data->pcie_gen_cap, PP_Min_PCIEGen),
1016 get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
1017 iceland_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 2,
1018 get_pcie_gen_support(data->pcie_gen_cap, PP_Max_PCIEGen),
1019 get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
1020 iceland_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 3,
1021 get_pcie_gen_support(data->pcie_gen_cap, PP_Max_PCIEGen),
1022 get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
1023 iceland_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 4,
1024 get_pcie_gen_support(data->pcie_gen_cap, PP_Max_PCIEGen),
1025 get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
1026 iceland_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table, 5,
1027 get_pcie_gen_support(data->pcie_gen_cap, PP_Max_PCIEGen),
1028 get_pcie_lane_support(data->pcie_lane_cap, PP_Max_PCIELane));
1029 data->dpm_table.pcie_speed_table.count = 6;
1030
1031 return 0;
1032
1033}
1034
1035
1036/*
1037 * This function is to initalize all DPM state tables for SMU7 based on the dependency table.
1038 * Dynamic state patching function will then trim these state tables to the allowed range based
1039 * on the power policy or external client requests, such as UVD request, etc.
1040 */
1041static int iceland_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
1042{
1043 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1044 uint32_t i;
1045
1046 struct phm_clock_voltage_dependency_table *allowed_vdd_sclk_table =
1047 hwmgr->dyn_state.vddc_dependency_on_sclk;
1048 struct phm_clock_voltage_dependency_table *allowed_vdd_mclk_table =
1049 hwmgr->dyn_state.vddc_dependency_on_mclk;
1050 struct phm_cac_leakage_table *std_voltage_table =
1051 hwmgr->dyn_state.cac_leakage_table;
1052
1053 PP_ASSERT_WITH_CODE(allowed_vdd_sclk_table != NULL,
1054 "SCLK dependency table is missing. This table is mandatory", return -1);
1055 PP_ASSERT_WITH_CODE(allowed_vdd_sclk_table->count >= 1,
1056 "SCLK dependency table has to have is missing. This table is mandatory", return -1);
1057
1058 PP_ASSERT_WITH_CODE(allowed_vdd_mclk_table != NULL,
1059 "MCLK dependency table is missing. This table is mandatory", return -1);
1060 PP_ASSERT_WITH_CODE(allowed_vdd_mclk_table->count >= 1,
1061 "VMCLK dependency table has to have is missing. This table is mandatory", return -1);
1062
1063 /* clear the state table to reset everything to default */
1064 memset(&(data->dpm_table), 0x00, sizeof(data->dpm_table));
1065 iceland_reset_single_dpm_table(hwmgr, &data->dpm_table.sclk_table, SMU71_MAX_LEVELS_GRAPHICS);
1066 iceland_reset_single_dpm_table(hwmgr, &data->dpm_table.mclk_table, SMU71_MAX_LEVELS_MEMORY);
1067 iceland_reset_single_dpm_table(hwmgr, &data->dpm_table.vddc_table, SMU71_MAX_LEVELS_VDDC);
1068 iceland_reset_single_dpm_table(hwmgr, &data->dpm_table.vdd_ci_table, SMU71_MAX_LEVELS_VDDCI);
1069 iceland_reset_single_dpm_table(hwmgr, &data->dpm_table.mvdd_table, SMU71_MAX_LEVELS_MVDD);
1070
1071 PP_ASSERT_WITH_CODE(allowed_vdd_sclk_table != NULL,
1072 "SCLK dependency table is missing. This table is mandatory", return -1);
1073 /* Initialize Sclk DPM table based on allow Sclk values*/
1074 data->dpm_table.sclk_table.count = 0;
1075
1076 for (i = 0; i < allowed_vdd_sclk_table->count; i++) {
1077 if (i == 0 || data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count-1].value !=
1078 allowed_vdd_sclk_table->entries[i].clk) {
1079 data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].value =
1080 allowed_vdd_sclk_table->entries[i].clk;
1081 data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].enabled = 1; /*(i==0) ? 1 : 0; to do */
1082 data->dpm_table.sclk_table.count++;
1083 }
1084 }
1085
1086 PP_ASSERT_WITH_CODE(allowed_vdd_mclk_table != NULL,
1087 "MCLK dependency table is missing. This table is mandatory", return -1);
1088 /* Initialize Mclk DPM table based on allow Mclk values */
1089 data->dpm_table.mclk_table.count = 0;
1090 for (i = 0; i < allowed_vdd_mclk_table->count; i++) {
1091 if (i == 0 || data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count-1].value !=
1092 allowed_vdd_mclk_table->entries[i].clk) {
1093 data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].value =
1094 allowed_vdd_mclk_table->entries[i].clk;
1095 data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].enabled = 1; /*(i==0) ? 1 : 0; */
1096 data->dpm_table.mclk_table.count++;
1097 }
1098 }
1099
1100 /* Initialize Vddc DPM table based on allow Vddc values. And populate corresponding std values. */
1101 for (i = 0; i < allowed_vdd_sclk_table->count; i++) {
1102 data->dpm_table.vddc_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].v;
1103 data->dpm_table.vddc_table.dpm_levels[i].param1 = std_voltage_table->entries[i].Leakage;
1104 /* param1 is for corresponding std voltage */
1105 data->dpm_table.vddc_table.dpm_levels[i].enabled = 1;
1106 }
1107
1108 data->dpm_table.vddc_table.count = allowed_vdd_sclk_table->count;
1109 allowed_vdd_mclk_table = hwmgr->dyn_state.vddci_dependency_on_mclk;
1110
1111 if (NULL != allowed_vdd_mclk_table) {
1112 /* Initialize Vddci DPM table based on allow Mclk values */
1113 for (i = 0; i < allowed_vdd_mclk_table->count; i++) {
1114 data->dpm_table.vdd_ci_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].v;
1115 data->dpm_table.vdd_ci_table.dpm_levels[i].enabled = 1;
1116 }
1117 data->dpm_table.vdd_ci_table.count = allowed_vdd_mclk_table->count;
1118 }
1119
1120 allowed_vdd_mclk_table = hwmgr->dyn_state.mvdd_dependency_on_mclk;
1121
1122 if (NULL != allowed_vdd_mclk_table) {
1123 /*
1124 * Initialize MVDD DPM table based on allow Mclk
1125 * values
1126 */
1127 for (i = 0; i < allowed_vdd_mclk_table->count; i++) {
1128 data->dpm_table.mvdd_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].v;
1129 data->dpm_table.mvdd_table.dpm_levels[i].enabled = 1;
1130 }
1131 data->dpm_table.mvdd_table.count = allowed_vdd_mclk_table->count;
1132 }
1133
1134 /* setup PCIE gen speed levels*/
1135 iceland_setup_default_pcie_tables(hwmgr);
1136
1137 /* save a copy of the default DPM table*/
1138 memcpy(&(data->golden_dpm_table), &(data->dpm_table), sizeof(struct iceland_dpm_table));
1139
1140 return 0;
1141}
1142
1143/**
1144 * @brief PhwIceland_GetVoltageOrder
1145 * Returns index of requested voltage record in lookup(table)
1146 * @param hwmgr - pointer to hardware manager
1147 * @param lookutab - lookup list to search in
1148 * @param voltage - voltage to look for
1149 * @return 0 on success
1150 */
1151uint8_t iceland_get_voltage_index(phm_ppt_v1_voltage_lookup_table *look_up_table,
1152 uint16_t voltage)
1153{
1154 uint8_t count = (uint8_t) (look_up_table->count);
1155 uint8_t i;
1156
1157 PP_ASSERT_WITH_CODE((NULL != look_up_table), "Lookup Table empty.", return 0;);
1158 PP_ASSERT_WITH_CODE((0 != count), "Lookup Table empty.", return 0;);
1159
1160 for (i = 0; i < count; i++) {
1161 /* find first voltage equal or bigger than requested */
1162 if (look_up_table->entries[i].us_vdd >= voltage)
1163 return i;
1164 }
1165
1166 /* voltage is bigger than max voltage in the table */
1167 return i-1;
1168}
1169
1170
1171static int iceland_get_std_voltage_value_sidd(struct pp_hwmgr *hwmgr,
1172 pp_atomctrl_voltage_table_entry *tab, uint16_t *hi,
1173 uint16_t *lo)
1174{
1175 uint16_t v_index;
1176 bool vol_found = false;
1177 *hi = tab->value * VOLTAGE_SCALE;
1178 *lo = tab->value * VOLTAGE_SCALE;
1179
1180 /* SCLK/VDDC Dependency Table has to exist. */
1181 PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.vddc_dependency_on_sclk,
1182 "The SCLK/VDDC Dependency Table does not exist.\n",
1183 return -EINVAL);
1184
1185 if (NULL == hwmgr->dyn_state.cac_leakage_table) {
1186 pr_warning("CAC Leakage Table does not exist, using vddc.\n");
1187 return 0;
1188 }
1189
1190 /*
1191 * Since voltage in the sclk/vddc dependency table is not
1192 * necessarily in ascending order because of ELB voltage
1193 * patching, loop through entire list to find exact voltage.
1194 */
1195 for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) {
1196 if (tab->value == hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) {
1197 vol_found = true;
1198 if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) {
1199 *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE;
1200 *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage * VOLTAGE_SCALE);
1201 } else {
1202 pr_warning("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index, using maximum index from CAC table.\n");
1203 *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE;
1204 *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE);
1205 }
1206 break;
1207 }
1208 }
1209
1210 /*
1211 * If voltage is not found in the first pass, loop again to
1212 * find the best match, equal or higher value.
1213 */
1214 if (!vol_found) {
1215 for (v_index = 0; (uint32_t)v_index < hwmgr->dyn_state.vddc_dependency_on_sclk->count; v_index++) {
1216 if (tab->value <= hwmgr->dyn_state.vddc_dependency_on_sclk->entries[v_index].v) {
1217 vol_found = true;
1218 if ((uint32_t)v_index < hwmgr->dyn_state.cac_leakage_table->count) {
1219 *lo = hwmgr->dyn_state.cac_leakage_table->entries[v_index].Vddc * VOLTAGE_SCALE;
1220 *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[v_index].Leakage) * VOLTAGE_SCALE;
1221 } else {
1222 pr_warning("Index from SCLK/VDDC Dependency Table exceeds the CAC Leakage Table index in second look up, using maximum index from CAC table.");
1223 *lo = hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Vddc * VOLTAGE_SCALE;
1224 *hi = (uint16_t)(hwmgr->dyn_state.cac_leakage_table->entries[hwmgr->dyn_state.cac_leakage_table->count - 1].Leakage * VOLTAGE_SCALE);
1225 }
1226 break;
1227 }
1228 }
1229
1230 if (!vol_found)
1231 pr_warning("Unable to get std_vddc from SCLK/VDDC Dependency Table, using vddc.\n");
1232 }
1233
1234 return 0;
1235}
1236
1237static int iceland_populate_smc_voltage_table(struct pp_hwmgr *hwmgr,
1238 pp_atomctrl_voltage_table_entry *tab,
1239 SMU71_Discrete_VoltageLevel *smc_voltage_tab) {
1240 int result;
1241
1242
1243 result = iceland_get_std_voltage_value_sidd(hwmgr, tab,
1244 &smc_voltage_tab->StdVoltageHiSidd,
1245 &smc_voltage_tab->StdVoltageLoSidd);
1246 if (0 != result) {
1247 smc_voltage_tab->StdVoltageHiSidd = tab->value * VOLTAGE_SCALE;
1248 smc_voltage_tab->StdVoltageLoSidd = tab->value * VOLTAGE_SCALE;
1249 }
1250
1251 smc_voltage_tab->Voltage = PP_HOST_TO_SMC_US(tab->value * VOLTAGE_SCALE);
1252 CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageHiSidd);
1253 CONVERT_FROM_HOST_TO_SMC_US(smc_voltage_tab->StdVoltageHiSidd);
1254
1255 return 0;
1256}
1257
1258/**
1259 * Vddc table preparation for SMC.
1260 *
1261 * @param hwmgr the address of the hardware manager
1262 * @param table the SMC DPM table structure to be populated
1263 * @return always 0
1264 */
1265static int iceland_populate_smc_vddc_table(struct pp_hwmgr *hwmgr,
1266 SMU71_Discrete_DpmTable *table)
1267{
1268 unsigned int count;
1269 int result;
1270
1271 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1272
1273 table->VddcLevelCount = data->vddc_voltage_table.count;
1274 for (count = 0; count < table->VddcLevelCount; count++) {
1275 result = iceland_populate_smc_voltage_table(hwmgr,
1276 &data->vddc_voltage_table.entries[count],
1277 &table->VddcLevel[count]);
1278 PP_ASSERT_WITH_CODE(0 == result, "do not populate SMC VDDC voltage table", return -EINVAL);
1279
1280 /* GPIO voltage control */
1281 if (ICELAND_VOLTAGE_CONTROL_BY_GPIO == data->voltage_control)
1282 table->VddcLevel[count].Smio |= data->vddc_voltage_table.entries[count].smio_low;
1283 else if (ICELAND_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control)
1284 table->VddcLevel[count].Smio = 0;
1285 }
1286
1287 CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount);
1288
1289 return 0;
1290}
1291
1292/**
1293 * Vddci table preparation for SMC.
1294 *
1295 * @param *hwmgr The address of the hardware manager.
1296 * @param *table The SMC DPM table structure to be populated.
1297 * @return 0
1298 */
1299static int iceland_populate_smc_vdd_ci_table(struct pp_hwmgr *hwmgr,
1300 SMU71_Discrete_DpmTable *table)
1301{
1302 int result;
1303 uint32_t count;
1304 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1305
1306 table->VddciLevelCount = data->vddci_voltage_table.count;
1307 for (count = 0; count < table->VddciLevelCount; count++) {
1308 result = iceland_populate_smc_voltage_table(hwmgr,
1309 &data->vddci_voltage_table.entries[count],
1310 &table->VddciLevel[count]);
1311 PP_ASSERT_WITH_CODE(0 == result, "do not populate SMC VDDCI voltage table", return -EINVAL);
1312
1313 /* GPIO voltage control */
1314 if (ICELAND_VOLTAGE_CONTROL_BY_GPIO == data->vdd_ci_control)
1315 table->VddciLevel[count].Smio |= data->vddci_voltage_table.entries[count].smio_low;
1316 else
1317 table->VddciLevel[count].Smio = 0;
1318 }
1319
1320 CONVERT_FROM_HOST_TO_SMC_UL(table->VddcLevelCount);
1321
1322 return 0;
1323}
1324
1325/**
1326 * Mvdd table preparation for SMC.
1327 *
1328 * @param *hwmgr The address of the hardware manager.
1329 * @param *table The SMC DPM table structure to be populated.
1330 * @return 0
1331 */
1332static int iceland_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr,
1333 SMU71_Discrete_DpmTable *table)
1334{
1335 int result;
1336 uint32_t count;
1337 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1338
1339 table->MvddLevelCount = data->mvdd_voltage_table.count;
1340 for (count = 0; count < table->MvddLevelCount; count++) {
1341 result = iceland_populate_smc_voltage_table(hwmgr,
1342 &data->mvdd_voltage_table.entries[count],
1343 &table->MvddLevel[count]);
1344 PP_ASSERT_WITH_CODE(0 == result, "do not populate SMC VDDCI voltage table", return -EINVAL);
1345
1346 /* GPIO voltage control */
1347 if (ICELAND_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control)
1348 table->MvddLevel[count].Smio |= data->mvdd_voltage_table.entries[count].smio_low;
1349 else
1350 table->MvddLevel[count].Smio = 0;
1351 }
1352
1353 CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount);
1354
1355 return 0;
1356}
1357
1358/**
1359 * Convert a voltage value in mv unit to VID number required by SMU firmware
1360 */
1361static uint8_t convert_to_vid(uint16_t vddc)
1362{
1363 return (uint8_t) ((6200 - (vddc * VOLTAGE_SCALE)) / 25);
1364}
1365
1366int iceland_populate_bapm_vddc_vid_sidd(struct pp_hwmgr *hwmgr)
1367{
1368 int i;
1369 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
1370 uint8_t * hi_vid = data->power_tune_table.BapmVddCVidHiSidd;
1371 uint8_t * lo_vid = data->power_tune_table.BapmVddCVidLoSidd;
1372
1373 PP_ASSERT_WITH_CODE(NULL != hwmgr->dyn_state.cac_leakage_table,
1374 "The CAC Leakage table does not exist!", return -EINVAL);
1375 PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count <= 8,
1376 "There should never be more than 8 entries for BapmVddcVid!!!", return -EINVAL);
1377 PP_ASSERT_WITH_CODE(hwmgr->dyn_state.cac_leakage_table->count == hwmgr->dyn_state.vddc_dependency_on_sclk->count,
1378 "CACLeakageTable->count and VddcDependencyOnSCLk->count not equal", return -EINVAL);
1379
1380 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_EVV)) {
1381 for (i = 0; (uint32_t) i < hwmgr->dyn_state.cac_leakage_table->count; i++) {
1382 lo_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc1);
1383 hi_vid[i] = convert_to_vid(hwmgr->dyn_state.cac_leakage_table->entries[i].Vddc2);
1384 }
1385 } else {
1386 PP_ASSERT_WITH_CODE(false, "Iceland should always support EVV", return -EINVAL);
1387 }
1388
1389 return 0;
1390}
1391
1392int iceland_populate_vddc_vid(struct pp_hwmgr *hwmgr)
1393{
1394 int i;
1395 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
1396 uint8_t *vid = data->power_tune_table.VddCVid;
1397
1398 PP_ASSERT_WITH_CODE(data->vddc_voltage_table.count <= 8,
1399 "There should never be more than 8 entries for VddcVid!!!",
1400 return -EINVAL);
1401
1402 for (i = 0; i < (int)data->vddc_voltage_table.count; i++) {
1403 vid[i] = convert_to_vid(data->vddc_voltage_table.entries[i].value);
1404 }
1405
1406 return 0;
1407}
1408
1409/**
1410 * Preparation of voltage tables for SMC.
1411 *
1412 * @param hwmgr the address of the hardware manager
1413 * @param table the SMC DPM table structure to be populated
1414 * @return always 0
1415 */
1416
1417int iceland_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr,
1418 SMU71_Discrete_DpmTable *table)
1419{
1420 int result;
1421
1422 result = iceland_populate_smc_vddc_table(hwmgr, table);
1423 PP_ASSERT_WITH_CODE(0 == result,
1424 "can not populate VDDC voltage table to SMC", return -1);
1425
1426 result = iceland_populate_smc_vdd_ci_table(hwmgr, table);
1427 PP_ASSERT_WITH_CODE(0 == result,
1428 "can not populate VDDCI voltage table to SMC", return -1);
1429
1430 result = iceland_populate_smc_mvdd_table(hwmgr, table);
1431 PP_ASSERT_WITH_CODE(0 == result,
1432 "can not populate MVDD voltage table to SMC", return -1);
1433
1434 return 0;
1435}
1436
1437
1438/**
1439 * Re-generate the DPM level mask value
1440 * @param hwmgr the address of the hardware manager
1441 */
1442static uint32_t iceland_get_dpm_level_enable_mask_value(
1443 struct iceland_single_dpm_table * dpm_table)
1444{
1445 uint32_t i;
1446 uint32_t mask_value = 0;
1447
1448 for (i = dpm_table->count; i > 0; i--) {
1449 mask_value = mask_value << 1;
1450
1451 if (dpm_table->dpm_levels[i-1].enabled)
1452 mask_value |= 0x1;
1453 else
1454 mask_value &= 0xFFFFFFFE;
1455 }
1456 return mask_value;
1457}
1458
1459int iceland_populate_memory_timing_parameters(
1460 struct pp_hwmgr *hwmgr,
1461 uint32_t engine_clock,
1462 uint32_t memory_clock,
1463 struct SMU71_Discrete_MCArbDramTimingTableEntry *arb_regs
1464 )
1465{
1466 uint32_t dramTiming;
1467 uint32_t dramTiming2;
1468 uint32_t burstTime;
1469 int result;
1470
1471 result = atomctrl_set_engine_dram_timings_rv770(hwmgr,
1472 engine_clock, memory_clock);
1473
1474 PP_ASSERT_WITH_CODE(result == 0,
1475 "Error calling VBIOS to set DRAM_TIMING.", return result);
1476
1477 dramTiming = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING);
1478 dramTiming2 = cgs_read_register(hwmgr->device, mmMC_ARB_DRAM_TIMING2);
1479 burstTime = PHM_READ_FIELD(hwmgr->device, MC_ARB_BURST_TIME, STATE0);
1480
1481 arb_regs->McArbDramTiming = PP_HOST_TO_SMC_UL(dramTiming);
1482 arb_regs->McArbDramTiming2 = PP_HOST_TO_SMC_UL(dramTiming2);
1483 arb_regs->McArbBurstTime = (uint8_t)burstTime;
1484
1485 return 0;
1486}
1487
1488/**
1489 * Setup parameters for the MC ARB.
1490 *
1491 * @param hwmgr the address of the powerplay hardware manager.
1492 * @return always 0
1493 * This function is to be called from the SetPowerState table.
1494 */
1495int iceland_program_memory_timing_parameters(struct pp_hwmgr *hwmgr)
1496{
1497 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1498 int result = 0;
1499 SMU71_Discrete_MCArbDramTimingTable arb_regs;
1500 uint32_t i, j;
1501
1502 memset(&arb_regs, 0x00, sizeof(SMU71_Discrete_MCArbDramTimingTable));
1503
1504 for (i = 0; i < data->dpm_table.sclk_table.count; i++) {
1505 for (j = 0; j < data->dpm_table.mclk_table.count; j++) {
1506 result = iceland_populate_memory_timing_parameters
1507 (hwmgr, data->dpm_table.sclk_table.dpm_levels[i].value,
1508 data->dpm_table.mclk_table.dpm_levels[j].value,
1509 &arb_regs.entries[i][j]);
1510
1511 if (0 != result) {
1512 break;
1513 }
1514 }
1515 }
1516
1517 if (0 == result) {
1518 result = iceland_copy_bytes_to_smc(
1519 hwmgr->smumgr,
1520 data->arb_table_start,
1521 (uint8_t *)&arb_regs,
1522 sizeof(SMU71_Discrete_MCArbDramTimingTable),
1523 data->sram_end
1524 );
1525 }
1526
1527 return result;
1528}
1529
1530static int iceland_populate_smc_link_level(struct pp_hwmgr *hwmgr, SMU71_Discrete_DpmTable *table)
1531{
1532 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1533 struct iceland_dpm_table *dpm_table = &data->dpm_table;
1534 uint32_t i;
1535
1536 /* Index (dpm_table->pcie_speed_table.count) is reserved for PCIE boot level. */
1537 for (i = 0; i <= dpm_table->pcie_speed_table.count; i++) {
1538 table->LinkLevel[i].PcieGenSpeed =
1539 (uint8_t)dpm_table->pcie_speed_table.dpm_levels[i].value;
1540 table->LinkLevel[i].PcieLaneCount =
1541 (uint8_t)encode_pcie_lane_width(dpm_table->pcie_speed_table.dpm_levels[i].param1);
1542 table->LinkLevel[i].EnabledForActivity =
1543 1;
1544 table->LinkLevel[i].SPC =
1545 (uint8_t)(data->pcie_spc_cap & 0xff);
1546 table->LinkLevel[i].DownThreshold =
1547 PP_HOST_TO_SMC_UL(5);
1548 table->LinkLevel[i].UpThreshold =
1549 PP_HOST_TO_SMC_UL(30);
1550 }
1551
1552 data->smc_state_table.LinkLevelCount =
1553 (uint8_t)dpm_table->pcie_speed_table.count;
1554 data->dpm_level_enable_mask.pcie_dpm_enable_mask =
1555 iceland_get_dpm_level_enable_mask_value(&dpm_table->pcie_speed_table);
1556
1557 return 0;
1558}
1559
1560static int iceland_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
1561 SMU71_Discrete_DpmTable *table)
1562{
1563 return 0;
1564}
1565
1566uint8_t iceland_get_voltage_id(pp_atomctrl_voltage_table *voltage_table,
1567 uint32_t voltage)
1568{
1569 uint8_t count = (uint8_t) (voltage_table->count);
1570 uint8_t i = 0;
1571
1572 PP_ASSERT_WITH_CODE((NULL != voltage_table),
1573 "Voltage Table empty.", return 0;);
1574 PP_ASSERT_WITH_CODE((0 != count),
1575 "Voltage Table empty.", return 0;);
1576
1577 for (i = 0; i < count; i++) {
1578 /* find first voltage bigger than requested */
1579 if (voltage_table->entries[i].value >= voltage)
1580 return i;
1581 }
1582
1583 /* voltage is bigger than max voltage in the table */
1584 return i - 1;
1585}
1586
1587static int iceland_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
1588 SMU71_Discrete_DpmTable *table)
1589{
1590 return 0;
1591}
1592
1593static int iceland_populate_smc_acp_level(struct pp_hwmgr *hwmgr,
1594 SMU71_Discrete_DpmTable *table)
1595{
1596 return 0;
1597}
1598
1599static int iceland_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
1600 SMU71_Discrete_DpmTable *table)
1601{
1602 return 0;
1603}
1604
1605
1606static int iceland_populate_smc_svi2_config(struct pp_hwmgr *hwmgr,
1607 SMU71_Discrete_DpmTable *tab)
1608{
1609 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1610
1611 if(ICELAND_VOLTAGE_CONTROL_BY_SVID2 == data->voltage_control)
1612 tab->SVI2Enable |= VDDC_ON_SVI2;
1613
1614 if(ICELAND_VOLTAGE_CONTROL_BY_SVID2 == data->vdd_ci_control)
1615 tab->SVI2Enable |= VDDCI_ON_SVI2;
1616 else
1617 tab->MergedVddci = 1;
1618
1619 if(ICELAND_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control)
1620 tab->SVI2Enable |= MVDD_ON_SVI2;
1621
1622 PP_ASSERT_WITH_CODE( tab->SVI2Enable != (VDDC_ON_SVI2 | VDDCI_ON_SVI2 | MVDD_ON_SVI2) &&
1623 (tab->SVI2Enable & VDDC_ON_SVI2), "SVI2 domain configuration is incorrect!", return -EINVAL);
1624
1625 return 0;
1626}
1627
1628static int iceland_get_dependecy_volt_by_clk(struct pp_hwmgr *hwmgr,
1629 struct phm_clock_voltage_dependency_table *allowed_clock_voltage_table,
1630 uint32_t clock, uint32_t *vol)
1631{
1632 uint32_t i = 0;
1633
1634 /* clock - voltage dependency table is empty table */
1635 if (allowed_clock_voltage_table->count == 0)
1636 return -EINVAL;
1637
1638 for (i = 0; i < allowed_clock_voltage_table->count; i++) {
1639 /* find first sclk bigger than request */
1640 if (allowed_clock_voltage_table->entries[i].clk >= clock) {
1641 *vol = allowed_clock_voltage_table->entries[i].v;
1642 return 0;
1643 }
1644 }
1645
1646 /* sclk is bigger than max sclk in the dependence table */
1647 *vol = allowed_clock_voltage_table->entries[i - 1].v;
1648
1649 return 0;
1650}
1651
1652static uint8_t iceland_get_mclk_frequency_ratio(uint32_t memory_clock,
1653 bool strobe_mode)
1654{
1655 uint8_t mc_para_index;
1656
1657 if (strobe_mode) {
1658 if (memory_clock < 12500) {
1659 mc_para_index = 0x00;
1660 } else if (memory_clock > 47500) {
1661 mc_para_index = 0x0f;
1662 } else {
1663 mc_para_index = (uint8_t)((memory_clock - 10000) / 2500);
1664 }
1665 } else {
1666 if (memory_clock < 65000) {
1667 mc_para_index = 0x00;
1668 } else if (memory_clock > 135000) {
1669 mc_para_index = 0x0f;
1670 } else {
1671 mc_para_index = (uint8_t)((memory_clock - 60000) / 5000);
1672 }
1673 }
1674
1675 return mc_para_index;
1676}
1677
1678static uint8_t iceland_get_ddr3_mclk_frequency_ratio(uint32_t memory_clock)
1679{
1680 uint8_t mc_para_index;
1681
1682 if (memory_clock < 10000) {
1683 mc_para_index = 0;
1684 } else if (memory_clock >= 80000) {
1685 mc_para_index = 0x0f;
1686 } else {
1687 mc_para_index = (uint8_t)((memory_clock - 10000) / 5000 + 1);
1688 }
1689
1690 return mc_para_index;
1691}
1692
1693static int iceland_populate_phase_value_based_on_sclk(struct pp_hwmgr *hwmgr, const struct phm_phase_shedding_limits_table *pl,
1694 uint32_t sclk, uint32_t *p_shed)
1695{
1696 unsigned int i;
1697
1698 /* use the minimum phase shedding */
1699 *p_shed = 1;
1700
1701 /*
1702 * PPGen ensures the phase shedding limits table is sorted
1703 * from lowest voltage/sclk/mclk to highest voltage/sclk/mclk.
1704 * VBIOS ensures the phase shedding masks table is sorted from
1705 * least phases enabled (phase shedding on) to most phases
1706 * enabled (phase shedding off).
1707 */
1708 for (i = 0; i < pl->count; i++) {
1709 if (sclk < pl->entries[i].Sclk) {
1710 /* Enable phase shedding */
1711 *p_shed = i;
1712 break;
1713 }
1714 }
1715
1716 return 0;
1717}
1718
1719static int iceland_populate_phase_value_based_on_mclk(struct pp_hwmgr *hwmgr, const struct phm_phase_shedding_limits_table *pl,
1720 uint32_t memory_clock, uint32_t *p_shed)
1721{
1722 unsigned int i;
1723
1724 /* use the minimum phase shedding */
1725 *p_shed = 1;
1726
1727 /*
1728 * PPGen ensures the phase shedding limits table is sorted
1729 * from lowest voltage/sclk/mclk to highest voltage/sclk/mclk.
1730 * VBIOS ensures the phase shedding masks table is sorted from
1731 * least phases enabled (phase shedding on) to most phases
1732 * enabled (phase shedding off).
1733 */
1734 for (i = 0; i < pl->count; i++) {
1735 if (memory_clock < pl->entries[i].Mclk) {
1736 /* Enable phase shedding */
1737 *p_shed = i;
1738 break;
1739 }
1740 }
1741
1742 return 0;
1743}
1744
1745/**
1746 * Populates the SMC MCLK structure using the provided memory clock
1747 *
1748 * @param hwmgr the address of the hardware manager
1749 * @param memory_clock the memory clock to use to populate the structure
1750 * @param sclk the SMC SCLK structure to be populated
1751 */
1752static int iceland_calculate_mclk_params(
1753 struct pp_hwmgr *hwmgr,
1754 uint32_t memory_clock,
1755 SMU71_Discrete_MemoryLevel *mclk,
1756 bool strobe_mode,
1757 bool dllStateOn
1758 )
1759{
1760 const iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1761 uint32_t dll_cntl = data->clock_registers.vDLL_CNTL;
1762 uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL;
1763 uint32_t mpll_ad_func_cntl = data->clock_registers.vMPLL_AD_FUNC_CNTL;
1764 uint32_t mpll_dq_func_cntl = data->clock_registers.vMPLL_DQ_FUNC_CNTL;
1765 uint32_t mpll_func_cntl = data->clock_registers.vMPLL_FUNC_CNTL;
1766 uint32_t mpll_func_cntl_1 = data->clock_registers.vMPLL_FUNC_CNTL_1;
1767 uint32_t mpll_func_cntl_2 = data->clock_registers.vMPLL_FUNC_CNTL_2;
1768 uint32_t mpll_ss1 = data->clock_registers.vMPLL_SS1;
1769 uint32_t mpll_ss2 = data->clock_registers.vMPLL_SS2;
1770
1771 pp_atomctrl_memory_clock_param mpll_param;
1772 int result;
1773
1774 result = atomctrl_get_memory_pll_dividers_si(hwmgr,
1775 memory_clock, &mpll_param, strobe_mode);
1776 PP_ASSERT_WITH_CODE(0 == result,
1777 "Error retrieving Memory Clock Parameters from VBIOS.", return result);
1778
1779 /* MPLL_FUNC_CNTL setup*/
1780 mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, mpll_param.bw_ctrl);
1781
1782 /* MPLL_FUNC_CNTL_1 setup*/
1783 mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1,
1784 MPLL_FUNC_CNTL_1, CLKF, mpll_param.mpll_fb_divider.cl_kf);
1785 mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1,
1786 MPLL_FUNC_CNTL_1, CLKFRAC, mpll_param.mpll_fb_divider.clk_frac);
1787 mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1,
1788 MPLL_FUNC_CNTL_1, VCO_MODE, mpll_param.vco_mode);
1789
1790 /* MPLL_AD_FUNC_CNTL setup*/
1791 mpll_ad_func_cntl = PHM_SET_FIELD(mpll_ad_func_cntl,
1792 MPLL_AD_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider);
1793
1794 if (data->is_memory_GDDR5) {
1795 /* MPLL_DQ_FUNC_CNTL setup*/
1796 mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl,
1797 MPLL_DQ_FUNC_CNTL, YCLK_SEL, mpll_param.yclk_sel);
1798 mpll_dq_func_cntl = PHM_SET_FIELD(mpll_dq_func_cntl,
1799 MPLL_DQ_FUNC_CNTL, YCLK_POST_DIV, mpll_param.mpll_post_divider);
1800 }
1801
1802 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1803 PHM_PlatformCaps_MemorySpreadSpectrumSupport)) {
1804 /*
1805 ************************************
1806 Fref = Reference Frequency
1807 NF = Feedback divider ratio
1808 NR = Reference divider ratio
1809 Fnom = Nominal VCO output frequency = Fref * NF / NR
1810 Fs = Spreading Rate
1811 D = Percentage down-spread / 2
1812 Fint = Reference input frequency to PFD = Fref / NR
1813 NS = Spreading rate divider ratio = int(Fint / (2 * Fs))
1814 CLKS = NS - 1 = ISS_STEP_NUM[11:0]
1815 NV = D * Fs / Fnom * 4 * ((Fnom/Fref * NR) ^ 2)
1816 CLKV = 65536 * NV = ISS_STEP_SIZE[25:0]
1817 *************************************
1818 */
1819 pp_atomctrl_internal_ss_info ss_info;
1820 uint32_t freq_nom;
1821 uint32_t tmp;
1822 uint32_t reference_clock = atomctrl_get_mpll_reference_clock(hwmgr);
1823
1824 /* for GDDR5 for all modes and DDR3 */
1825 if (1 == mpll_param.qdr)
1826 freq_nom = memory_clock * 4 * (1 << mpll_param.mpll_post_divider);
1827 else
1828 freq_nom = memory_clock * 2 * (1 << mpll_param.mpll_post_divider);
1829
1830 /* tmp = (freq_nom / reference_clock * reference_divider) ^ 2 Note: S.I. reference_divider = 1*/
1831 tmp = (freq_nom / reference_clock);
1832 tmp = tmp * tmp;
1833
1834 if (0 == atomctrl_get_memory_clock_spread_spectrum(hwmgr, freq_nom, &ss_info)) {
1835 /* ss_info.speed_spectrum_percentage -- in unit of 0.01% */
1836 /* ss.Info.speed_spectrum_rate -- in unit of khz */
1837 /* CLKS = reference_clock / (2 * speed_spectrum_rate * reference_divider) * 10 */
1838 /* = reference_clock * 5 / speed_spectrum_rate */
1839 uint32_t clks = reference_clock * 5 / ss_info.speed_spectrum_rate;
1840
1841 /* CLKV = 65536 * speed_spectrum_percentage / 2 * spreadSpecrumRate / freq_nom * 4 / 100000 * ((freq_nom / reference_clock) ^ 2) */
1842 /* = 131 * speed_spectrum_percentage * speed_spectrum_rate / 100 * ((freq_nom / reference_clock) ^ 2) / freq_nom */
1843 uint32_t clkv =
1844 (uint32_t)((((131 * ss_info.speed_spectrum_percentage *
1845 ss_info.speed_spectrum_rate) / 100) * tmp) / freq_nom);
1846
1847 mpll_ss1 = PHM_SET_FIELD(mpll_ss1, MPLL_SS1, CLKV, clkv);
1848 mpll_ss2 = PHM_SET_FIELD(mpll_ss2, MPLL_SS2, CLKS, clks);
1849 }
1850 }
1851
1852 /* MCLK_PWRMGT_CNTL setup */
1853 mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
1854 MCLK_PWRMGT_CNTL, DLL_SPEED, mpll_param.dll_speed);
1855 mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
1856 MCLK_PWRMGT_CNTL, MRDCK0_PDNB, dllStateOn);
1857 mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
1858 MCLK_PWRMGT_CNTL, MRDCK1_PDNB, dllStateOn);
1859
1860
1861 /* Save the result data to outpupt memory level structure */
1862 mclk->MclkFrequency = memory_clock;
1863 mclk->MpllFuncCntl = mpll_func_cntl;
1864 mclk->MpllFuncCntl_1 = mpll_func_cntl_1;
1865 mclk->MpllFuncCntl_2 = mpll_func_cntl_2;
1866 mclk->MpllAdFuncCntl = mpll_ad_func_cntl;
1867 mclk->MpllDqFuncCntl = mpll_dq_func_cntl;
1868 mclk->MclkPwrmgtCntl = mclk_pwrmgt_cntl;
1869 mclk->DllCntl = dll_cntl;
1870 mclk->MpllSs1 = mpll_ss1;
1871 mclk->MpllSs2 = mpll_ss2;
1872
1873 return 0;
1874}
1875
1876static int iceland_populate_single_memory_level(
1877 struct pp_hwmgr *hwmgr,
1878 uint32_t memory_clock,
1879 SMU71_Discrete_MemoryLevel *memory_level
1880 )
1881{
1882 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
1883 int result = 0;
1884 bool dllStateOn;
1885 struct cgs_display_info info = {0};
1886
1887
1888 if (NULL != hwmgr->dyn_state.vddc_dependency_on_mclk) {
1889 result = iceland_get_dependecy_volt_by_clk(hwmgr,
1890 hwmgr->dyn_state.vddc_dependency_on_mclk, memory_clock, &memory_level->MinVddc);
1891 PP_ASSERT_WITH_CODE((0 == result),
1892 "can not find MinVddc voltage value from memory VDDC voltage dependency table", return result);
1893 }
1894
1895 if (data->vdd_ci_control == ICELAND_VOLTAGE_CONTROL_NONE) {
1896 memory_level->MinVddci = memory_level->MinVddc;
1897 } else if (NULL != hwmgr->dyn_state.vddci_dependency_on_mclk) {
1898 result = iceland_get_dependecy_volt_by_clk(hwmgr,
1899 hwmgr->dyn_state.vddci_dependency_on_mclk,
1900 memory_clock,
1901 &memory_level->MinVddci);
1902 PP_ASSERT_WITH_CODE((0 == result),
1903 "can not find MinVddci voltage value from memory VDDCI voltage dependency table", return result);
1904 }
1905
1906 if (NULL != hwmgr->dyn_state.mvdd_dependency_on_mclk) {
1907 result = iceland_get_dependecy_volt_by_clk(hwmgr,
1908 hwmgr->dyn_state.mvdd_dependency_on_mclk, memory_clock, &memory_level->MinMvdd);
1909 PP_ASSERT_WITH_CODE((0 == result),
1910 "can not find MinMVDD voltage value from memory MVDD voltage dependency table", return result);
1911 }
1912
1913 memory_level->MinVddcPhases = 1;
1914
1915 if (data->vddc_phase_shed_control) {
1916 iceland_populate_phase_value_based_on_mclk(hwmgr, hwmgr->dyn_state.vddc_phase_shed_limits_table,
1917 memory_clock, &memory_level->MinVddcPhases);
1918 }
1919
1920 memory_level->EnabledForThrottle = 1;
1921 memory_level->EnabledForActivity = 1;
1922 memory_level->UpHyst = 0;
1923 memory_level->DownHyst = 100;
1924 memory_level->VoltageDownHyst = 0;
1925
1926 /* Indicates maximum activity level for this performance level.*/
1927 memory_level->ActivityLevel = (uint16_t)data->mclk_activity_target;
1928 memory_level->StutterEnable = 0;
1929 memory_level->StrobeEnable = 0;
1930 memory_level->EdcReadEnable = 0;
1931 memory_level->EdcWriteEnable = 0;
1932 memory_level->RttEnable = 0;
1933
1934 /* default set to low watermark. Highest level will be set to high later.*/
1935 memory_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
1936
1937 cgs_get_active_displays_info(hwmgr->device, &info);
1938 data->display_timing.num_existing_displays = info.display_count;
1939
1940 //if ((data->mclk_stutter_mode_threshold != 0) &&
1941 // (memory_clock <= data->mclk_stutter_mode_threshold) &&
1942 // (data->is_uvd_enabled == 0)
1943 // && (PHM_READ_FIELD(hwmgr->device, DPG_PIPE_STUTTER_CONTROL, STUTTER_ENABLE) & 0x1)
1944 // && (data->display_timing.num_existing_displays <= 2)
1945 // && (data->display_timing.num_existing_displays != 0))
1946 // memory_level->StutterEnable = 1;
1947
1948 /* decide strobe mode*/
1949 memory_level->StrobeEnable = (data->mclk_strobe_mode_threshold != 0) &&
1950 (memory_clock <= data->mclk_strobe_mode_threshold);
1951
1952 /* decide EDC mode and memory clock ratio*/
1953 if (data->is_memory_GDDR5) {
1954 memory_level->StrobeRatio = iceland_get_mclk_frequency_ratio(memory_clock,
1955 memory_level->StrobeEnable);
1956
1957 if ((data->mclk_edc_enable_threshold != 0) &&
1958 (memory_clock > data->mclk_edc_enable_threshold)) {
1959 memory_level->EdcReadEnable = 1;
1960 }
1961
1962 if ((data->mclk_edc_wr_enable_threshold != 0) &&
1963 (memory_clock > data->mclk_edc_wr_enable_threshold)) {
1964 memory_level->EdcWriteEnable = 1;
1965 }
1966
1967 if (memory_level->StrobeEnable) {
1968 if (iceland_get_mclk_frequency_ratio(memory_clock, 1) >=
1969 ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC7) >> 16) & 0xf)) {
1970 dllStateOn = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0;
1971 } else {
1972 dllStateOn = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC6) >> 1) & 0x1) ? 1 : 0;
1973 }
1974
1975 } else {
1976 dllStateOn = data->dll_defaule_on;
1977 }
1978 } else {
1979 memory_level->StrobeRatio =
1980 iceland_get_ddr3_mclk_frequency_ratio(memory_clock);
1981 dllStateOn = ((cgs_read_register(hwmgr->device, mmMC_SEQ_MISC5) >> 1) & 0x1) ? 1 : 0;
1982 }
1983
1984 result = iceland_calculate_mclk_params(hwmgr,
1985 memory_clock, memory_level, memory_level->StrobeEnable, dllStateOn);
1986
1987 if (0 == result) {
1988 memory_level->MinVddc = PP_HOST_TO_SMC_UL(memory_level->MinVddc * VOLTAGE_SCALE);
1989 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MinVddcPhases);
1990 memory_level->MinVddci = PP_HOST_TO_SMC_UL(memory_level->MinVddci * VOLTAGE_SCALE);
1991 memory_level->MinMvdd = PP_HOST_TO_SMC_UL(memory_level->MinMvdd * VOLTAGE_SCALE);
1992 /* MCLK frequency in units of 10KHz*/
1993 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkFrequency);
1994 /* Indicates maximum activity level for this performance level.*/
1995 CONVERT_FROM_HOST_TO_SMC_US(memory_level->ActivityLevel);
1996 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl);
1997 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_1);
1998 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllFuncCntl_2);
1999 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllAdFuncCntl);
2000 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllDqFuncCntl);
2001 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MclkPwrmgtCntl);
2002 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->DllCntl);
2003 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs1);
2004 CONVERT_FROM_HOST_TO_SMC_UL(memory_level->MpllSs2);
2005 }
2006
2007 return result;
2008}
2009
2010/**
2011 * Populates the SMC MVDD structure using the provided memory clock.
2012 *
2013 * @param hwmgr the address of the hardware manager
2014 * @param mclk the MCLK value to be used in the decision if MVDD should be high or low.
2015 * @param voltage the SMC VOLTAGE structure to be populated
2016 */
2017int iceland_populate_mvdd_value(struct pp_hwmgr *hwmgr, uint32_t mclk, SMU71_Discrete_VoltageLevel *voltage)
2018{
2019 const iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2020 uint32_t i = 0;
2021
2022 if (ICELAND_VOLTAGE_CONTROL_NONE != data->mvdd_control) {
2023 /* find mvdd value which clock is more than request */
2024 for (i = 0; i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count; i++) {
2025 if (mclk <= hwmgr->dyn_state.mvdd_dependency_on_mclk->entries[i].clk) {
2026 /* Always round to higher voltage. */
2027 voltage->Voltage = data->mvdd_voltage_table.entries[i].value;
2028 break;
2029 }
2030 }
2031
2032 PP_ASSERT_WITH_CODE(i < hwmgr->dyn_state.mvdd_dependency_on_mclk->count,
2033 "MVDD Voltage is outside the supported range.", return -1);
2034
2035 } else {
2036 return -1;
2037 }
2038
2039 return 0;
2040}
2041
2042
2043static int iceland_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
2044 SMU71_Discrete_DpmTable *table)
2045{
2046 int result = 0;
2047 const iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2048 pp_atomctrl_clock_dividers_vi dividers;
2049 SMU71_Discrete_VoltageLevel voltage_level;
2050 uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL;
2051 uint32_t spll_func_cntl_2 = data->clock_registers.vCG_SPLL_FUNC_CNTL_2;
2052 uint32_t dll_cntl = data->clock_registers.vDLL_CNTL;
2053 uint32_t mclk_pwrmgt_cntl = data->clock_registers.vMCLK_PWRMGT_CNTL;
2054
2055 /* The ACPI state should not do DPM on DC (or ever).*/
2056 table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC;
2057
2058 if (data->acpi_vddc)
2059 table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->acpi_vddc * VOLTAGE_SCALE);
2060 else
2061 table->ACPILevel.MinVddc = PP_HOST_TO_SMC_UL(data->min_vddc_in_pp_table * VOLTAGE_SCALE);
2062
2063 table->ACPILevel.MinVddcPhases = (data->vddc_phase_shed_control) ? 0 : 1;
2064
2065 /* assign zero for now*/
2066 table->ACPILevel.SclkFrequency = atomctrl_get_reference_clock(hwmgr);
2067
2068 /* get the engine clock dividers for this clock value*/
2069 result = atomctrl_get_engine_pll_dividers_vi(hwmgr,
2070 table->ACPILevel.SclkFrequency, &dividers);
2071
2072 PP_ASSERT_WITH_CODE(result == 0,
2073 "Error retrieving Engine Clock dividers from VBIOS.", return result);
2074
2075 /* divider ID for required SCLK*/
2076 table->ACPILevel.SclkDid = (uint8_t)dividers.pll_post_divider;
2077 table->ACPILevel.DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
2078 table->ACPILevel.DeepSleepDivId = 0;
2079
2080 spll_func_cntl = PHM_SET_FIELD(spll_func_cntl,
2081 CG_SPLL_FUNC_CNTL, SPLL_PWRON, 0);
2082 spll_func_cntl = PHM_SET_FIELD(spll_func_cntl,
2083 CG_SPLL_FUNC_CNTL, SPLL_RESET, 1);
2084 spll_func_cntl_2 = PHM_SET_FIELD(spll_func_cntl_2,
2085 CG_SPLL_FUNC_CNTL_2, SCLK_MUX_SEL, 4);
2086
2087 table->ACPILevel.CgSpllFuncCntl = spll_func_cntl;
2088 table->ACPILevel.CgSpllFuncCntl2 = spll_func_cntl_2;
2089 table->ACPILevel.CgSpllFuncCntl3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3;
2090 table->ACPILevel.CgSpllFuncCntl4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4;
2091 table->ACPILevel.SpllSpreadSpectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM;
2092 table->ACPILevel.SpllSpreadSpectrum2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2;
2093 table->ACPILevel.CcPwrDynRm = 0;
2094 table->ACPILevel.CcPwrDynRm1 = 0;
2095
2096
2097 /* For various features to be enabled/disabled while this level is active.*/
2098 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.Flags);
2099 /* SCLK frequency in units of 10KHz*/
2100 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SclkFrequency);
2101 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl);
2102 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl2);
2103 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl3);
2104 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CgSpllFuncCntl4);
2105 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum);
2106 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.SpllSpreadSpectrum2);
2107 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm);
2108 CONVERT_FROM_HOST_TO_SMC_UL(table->ACPILevel.CcPwrDynRm1);
2109
2110 table->MemoryACPILevel.MinVddc = table->ACPILevel.MinVddc;
2111 table->MemoryACPILevel.MinVddcPhases = table->ACPILevel.MinVddcPhases;
2112
2113 /* CONVERT_FROM_HOST_TO_SMC_UL(table->MemoryACPILevel.MinVoltage);*/
2114
2115 if (0 == iceland_populate_mvdd_value(hwmgr, 0, &voltage_level))
2116 table->MemoryACPILevel.MinMvdd =
2117 PP_HOST_TO_SMC_UL(voltage_level.Voltage * VOLTAGE_SCALE);
2118 else
2119 table->MemoryACPILevel.MinMvdd = 0;
2120
2121 /* Force reset on DLL*/
2122 mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
2123 MCLK_PWRMGT_CNTL, MRDCK0_RESET, 0x1);
2124 mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
2125 MCLK_PWRMGT_CNTL, MRDCK1_RESET, 0x1);
2126
2127 /* Disable DLL in ACPIState*/
2128 mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
2129 MCLK_PWRMGT_CNTL, MRDCK0_PDNB, 0);
2130 mclk_pwrmgt_cntl = PHM_SET_FIELD(mclk_pwrmgt_cntl,
2131 MCLK_PWRMGT_CNTL, MRDCK1_PDNB, 0);
2132
2133 /* Enable DLL bypass signal*/
2134 dll_cntl = PHM_SET_FIELD(dll_cntl,
2135 DLL_CNTL, MRDCK0_BYPASS, 0);
2136 dll_cntl = PHM_SET_FIELD(dll_cntl,
2137 DLL_CNTL, MRDCK1_BYPASS, 0);
2138
2139 table->MemoryACPILevel.DllCntl =
2140 PP_HOST_TO_SMC_UL(dll_cntl);
2141 table->MemoryACPILevel.MclkPwrmgtCntl =
2142 PP_HOST_TO_SMC_UL(mclk_pwrmgt_cntl);
2143 table->MemoryACPILevel.MpllAdFuncCntl =
2144 PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_AD_FUNC_CNTL);
2145 table->MemoryACPILevel.MpllDqFuncCntl =
2146 PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_DQ_FUNC_CNTL);
2147 table->MemoryACPILevel.MpllFuncCntl =
2148 PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL);
2149 table->MemoryACPILevel.MpllFuncCntl_1 =
2150 PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_1);
2151 table->MemoryACPILevel.MpllFuncCntl_2 =
2152 PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_FUNC_CNTL_2);
2153 table->MemoryACPILevel.MpllSs1 =
2154 PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS1);
2155 table->MemoryACPILevel.MpllSs2 =
2156 PP_HOST_TO_SMC_UL(data->clock_registers.vMPLL_SS2);
2157
2158 table->MemoryACPILevel.EnabledForThrottle = 0;
2159 table->MemoryACPILevel.EnabledForActivity = 0;
2160 table->MemoryACPILevel.UpHyst = 0;
2161 table->MemoryACPILevel.DownHyst = 100;
2162 table->MemoryACPILevel.VoltageDownHyst = 0;
2163 /* Indicates maximum activity level for this performance level.*/
2164 table->MemoryACPILevel.ActivityLevel = PP_HOST_TO_SMC_US((uint16_t)data->mclk_activity_target);
2165
2166 table->MemoryACPILevel.StutterEnable = 0;
2167 table->MemoryACPILevel.StrobeEnable = 0;
2168 table->MemoryACPILevel.EdcReadEnable = 0;
2169 table->MemoryACPILevel.EdcWriteEnable = 0;
2170 table->MemoryACPILevel.RttEnable = 0;
2171
2172 return result;
2173}
2174
2175static int iceland_find_boot_level(struct iceland_single_dpm_table *table, uint32_t value, uint32_t *boot_level)
2176{
2177 int result = 0;
2178 uint32_t i;
2179
2180 for (i = 0; i < table->count; i++) {
2181 if (value == table->dpm_levels[i].value) {
2182 *boot_level = i;
2183 result = 0;
2184 }
2185 }
2186 return result;
2187}
2188
2189/**
2190 * Calculates the SCLK dividers using the provided engine clock
2191 *
2192 * @param hwmgr the address of the hardware manager
2193 * @param engine_clock the engine clock to use to populate the structure
2194 * @param sclk the SMC SCLK structure to be populated
2195 */
2196int iceland_calculate_sclk_params(struct pp_hwmgr *hwmgr,
2197 uint32_t engine_clock, SMU71_Discrete_GraphicsLevel *sclk)
2198{
2199 const iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2200 pp_atomctrl_clock_dividers_vi dividers;
2201 uint32_t spll_func_cntl = data->clock_registers.vCG_SPLL_FUNC_CNTL;
2202 uint32_t spll_func_cntl_3 = data->clock_registers.vCG_SPLL_FUNC_CNTL_3;
2203 uint32_t spll_func_cntl_4 = data->clock_registers.vCG_SPLL_FUNC_CNTL_4;
2204 uint32_t cg_spll_spread_spectrum = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM;
2205 uint32_t cg_spll_spread_spectrum_2 = data->clock_registers.vCG_SPLL_SPREAD_SPECTRUM_2;
2206 uint32_t reference_clock;
2207 uint32_t reference_divider;
2208 uint32_t fbdiv;
2209 int result;
2210
2211 /* get the engine clock dividers for this clock value*/
2212 result = atomctrl_get_engine_pll_dividers_vi(hwmgr, engine_clock, &dividers);
2213
2214 PP_ASSERT_WITH_CODE(result == 0,
2215 "Error retrieving Engine Clock dividers from VBIOS.", return result);
2216
2217 /* To get FBDIV we need to multiply this by 16384 and divide it by Fref.*/
2218 reference_clock = atomctrl_get_reference_clock(hwmgr);
2219
2220 reference_divider = 1 + dividers.uc_pll_ref_div;
2221
2222 /* low 14 bits is fraction and high 12 bits is divider*/
2223 fbdiv = dividers.ul_fb_div.ul_fb_divider & 0x3FFFFFF;
2224
2225 /* SPLL_FUNC_CNTL setup*/
2226 spll_func_cntl = PHM_SET_FIELD(spll_func_cntl,
2227 CG_SPLL_FUNC_CNTL, SPLL_REF_DIV, dividers.uc_pll_ref_div);
2228 spll_func_cntl = PHM_SET_FIELD(spll_func_cntl,
2229 CG_SPLL_FUNC_CNTL, SPLL_PDIV_A, dividers.uc_pll_post_div);
2230
2231 /* SPLL_FUNC_CNTL_3 setup*/
2232 spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3,
2233 CG_SPLL_FUNC_CNTL_3, SPLL_FB_DIV, fbdiv);
2234
2235 /* set to use fractional accumulation*/
2236 spll_func_cntl_3 = PHM_SET_FIELD(spll_func_cntl_3,
2237 CG_SPLL_FUNC_CNTL_3, SPLL_DITHEN, 1);
2238
2239 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2240 PHM_PlatformCaps_EngineSpreadSpectrumSupport)) {
2241 pp_atomctrl_internal_ss_info ss_info;
2242
2243 uint32_t vcoFreq = engine_clock * dividers.uc_pll_post_div;
2244 if (0 == atomctrl_get_engine_clock_spread_spectrum(hwmgr, vcoFreq, &ss_info)) {
2245 /*
2246 * ss_info.speed_spectrum_percentage -- in unit of 0.01%
2247 * ss_info.speed_spectrum_rate -- in unit of khz
2248 */
2249 /* clks = reference_clock * 10 / (REFDIV + 1) / speed_spectrum_rate / 2 */
2250 uint32_t clkS = reference_clock * 5 / (reference_divider * ss_info.speed_spectrum_rate);
2251
2252 /* clkv = 2 * D * fbdiv / NS */
2253 uint32_t clkV = 4 * ss_info.speed_spectrum_percentage * fbdiv / (clkS * 10000);
2254
2255 cg_spll_spread_spectrum =
2256 PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, CLKS, clkS);
2257 cg_spll_spread_spectrum =
2258 PHM_SET_FIELD(cg_spll_spread_spectrum, CG_SPLL_SPREAD_SPECTRUM, SSEN, 1);
2259 cg_spll_spread_spectrum_2 =
2260 PHM_SET_FIELD(cg_spll_spread_spectrum_2, CG_SPLL_SPREAD_SPECTRUM_2, CLKV, clkV);
2261 }
2262 }
2263
2264 sclk->SclkFrequency = engine_clock;
2265 sclk->CgSpllFuncCntl3 = spll_func_cntl_3;
2266 sclk->CgSpllFuncCntl4 = spll_func_cntl_4;
2267 sclk->SpllSpreadSpectrum = cg_spll_spread_spectrum;
2268 sclk->SpllSpreadSpectrum2 = cg_spll_spread_spectrum_2;
2269 sclk->SclkDid = (uint8_t)dividers.pll_post_divider;
2270
2271 return 0;
2272}
2273
2274static uint8_t iceland_get_sleep_divider_id_from_clock(struct pp_hwmgr *hwmgr,
2275 uint32_t engine_clock, uint32_t min_engine_clock_in_sr)
2276{
2277 uint32_t i, temp;
2278 uint32_t min = (min_engine_clock_in_sr > ICELAND_MINIMUM_ENGINE_CLOCK) ?
2279 min_engine_clock_in_sr : ICELAND_MINIMUM_ENGINE_CLOCK;
2280
2281 PP_ASSERT_WITH_CODE((engine_clock >= min),
2282 "Engine clock can't satisfy stutter requirement!", return 0);
2283
2284 for (i = ICELAND_MAX_DEEPSLEEP_DIVIDER_ID;; i--) {
2285 temp = engine_clock / (1 << i);
2286
2287 if(temp >= min || i == 0)
2288 break;
2289 }
2290 return (uint8_t)i;
2291}
2292
2293/**
2294 * Populates single SMC SCLK structure using the provided engine clock
2295 *
2296 * @param hwmgr the address of the hardware manager
2297 * @param engine_clock the engine clock to use to populate the structure
2298 * @param sclk the SMC SCLK structure to be populated
2299 */
2300static int iceland_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
2301 uint32_t engine_clock, uint16_t sclk_activity_level_threshold,
2302 SMU71_Discrete_GraphicsLevel *graphic_level)
2303{
2304 int result;
2305 uint32_t threshold;
2306 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2307
2308 result = iceland_calculate_sclk_params(hwmgr, engine_clock, graphic_level);
2309
2310
2311 /* populate graphics levels*/
2312 result = iceland_get_dependecy_volt_by_clk(hwmgr,
2313 hwmgr->dyn_state.vddc_dependency_on_sclk, engine_clock, &graphic_level->MinVddc);
2314 PP_ASSERT_WITH_CODE((0 == result),
2315 "can not find VDDC voltage value for VDDC engine clock dependency table", return result);
2316
2317 /* SCLK frequency in units of 10KHz*/
2318 graphic_level->SclkFrequency = engine_clock;
2319
2320 /*
2321 * Minimum VDDC phases required to support this level, it
2322 * should get from dependence table.
2323 */
2324 graphic_level->MinVddcPhases = 1;
2325
2326 if (data->vddc_phase_shed_control) {
2327 iceland_populate_phase_value_based_on_sclk(hwmgr,
2328 hwmgr->dyn_state.vddc_phase_shed_limits_table,
2329 engine_clock,
2330 &graphic_level->MinVddcPhases);
2331 }
2332
2333 /* Indicates maximum activity level for this performance level. 50% for now*/
2334 graphic_level->ActivityLevel = sclk_activity_level_threshold;
2335
2336 graphic_level->CcPwrDynRm = 0;
2337 graphic_level->CcPwrDynRm1 = 0;
2338 /* this level can be used if activity is high enough.*/
2339 graphic_level->EnabledForActivity = 1;
2340 /* this level can be used for throttling.*/
2341 graphic_level->EnabledForThrottle = 1;
2342 graphic_level->UpHyst = 0;
2343 graphic_level->DownHyst = 100;
2344 graphic_level->VoltageDownHyst = 0;
2345 graphic_level->PowerThrottle = 0;
2346
2347 threshold = engine_clock * data->fast_watermark_threshold / 100;
2348
2349 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2350 PHM_PlatformCaps_SclkDeepSleep)) {
2351 graphic_level->DeepSleepDivId =
2352 iceland_get_sleep_divider_id_from_clock(hwmgr, engine_clock,
2353 data->display_timing.min_clock_insr);
2354 }
2355
2356 /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/
2357 graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
2358
2359 if (0 == result) {
2360 graphic_level->MinVddc = PP_HOST_TO_SMC_UL(graphic_level->MinVddc * VOLTAGE_SCALE);
2361 /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVoltage);*/
2362 CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVddcPhases);
2363 CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SclkFrequency);
2364 CONVERT_FROM_HOST_TO_SMC_US(graphic_level->ActivityLevel);
2365 CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl3);
2366 CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CgSpllFuncCntl4);
2367 CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum);
2368 CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SpllSpreadSpectrum2);
2369 CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm);
2370 CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->CcPwrDynRm1);
2371 }
2372
2373 return result;
2374}
2375
2376/**
2377 * Populates all SMC SCLK levels' structure based on the trimmed allowed dpm engine clock states
2378 *
2379 * @param hwmgr the address of the hardware manager
2380 */
2381static int iceland_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
2382{
2383 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2384 struct iceland_dpm_table *dpm_table = &data->dpm_table;
2385 int result = 0;
2386 uint32_t level_array_adress = data->dpm_table_start +
2387 offsetof(SMU71_Discrete_DpmTable, GraphicsLevel);
2388
2389 uint32_t level_array_size = sizeof(SMU71_Discrete_GraphicsLevel) * SMU71_MAX_LEVELS_GRAPHICS;
2390 SMU71_Discrete_GraphicsLevel *levels = data->smc_state_table.GraphicsLevel;
2391 uint32_t i;
2392 uint8_t highest_pcie_level_enabled = 0, lowest_pcie_level_enabled = 0, mid_pcie_level_enabled = 0, count = 0;
2393 memset(levels, 0x00, level_array_size);
2394
2395 for (i = 0; i < dpm_table->sclk_table.count; i++) {
2396 result = iceland_populate_single_graphic_level(hwmgr,
2397 dpm_table->sclk_table.dpm_levels[i].value,
2398 (uint16_t)data->activity_target[i],
2399 &(data->smc_state_table.GraphicsLevel[i]));
2400 if (0 != result)
2401 return result;
2402
2403 /* Making sure only DPM level 0-1 have Deep Sleep Div ID populated. */
2404 if (i > 1)
2405 data->smc_state_table.GraphicsLevel[i].DeepSleepDivId = 0;
2406 }
2407
2408 /* set highest level watermark to high */
2409 if (dpm_table->sclk_table.count > 1)
2410 data->smc_state_table.GraphicsLevel[dpm_table->sclk_table.count-1].DisplayWatermark =
2411 PPSMC_DISPLAY_WATERMARK_HIGH;
2412
2413 data->smc_state_table.GraphicsDpmLevelCount =
2414 (uint8_t)dpm_table->sclk_table.count;
2415 data->dpm_level_enable_mask.sclk_dpm_enable_mask =
2416 iceland_get_dpm_level_enable_mask_value(&dpm_table->sclk_table);
2417
2418 while ((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
2419 (1 << (highest_pcie_level_enabled + 1))) != 0) {
2420 highest_pcie_level_enabled++;
2421 }
2422
2423 while ((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
2424 (1 << lowest_pcie_level_enabled)) == 0) {
2425 lowest_pcie_level_enabled++;
2426 }
2427
2428 while ((count < highest_pcie_level_enabled) &&
2429 ((data->dpm_level_enable_mask.pcie_dpm_enable_mask &
2430 (1 << (lowest_pcie_level_enabled + 1 + count))) == 0)) {
2431 count++;
2432 }
2433
2434 mid_pcie_level_enabled = (lowest_pcie_level_enabled+1+count) < highest_pcie_level_enabled ?
2435 (lowest_pcie_level_enabled + 1 + count) : highest_pcie_level_enabled;
2436
2437 /* set pcieDpmLevel to highest_pcie_level_enabled*/
2438 for (i = 2; i < dpm_table->sclk_table.count; i++) {
2439 data->smc_state_table.GraphicsLevel[i].pcieDpmLevel = highest_pcie_level_enabled;
2440 }
2441
2442 /* set pcieDpmLevel to lowest_pcie_level_enabled*/
2443 data->smc_state_table.GraphicsLevel[0].pcieDpmLevel = lowest_pcie_level_enabled;
2444
2445 /* set pcieDpmLevel to mid_pcie_level_enabled*/
2446 data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled;
2447
2448 /* level count will send to smc once at init smc table and never change*/
2449 result = iceland_copy_bytes_to_smc(hwmgr->smumgr, level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, data->sram_end);
2450
2451 if (0 != result)
2452 return result;
2453
2454 return 0;
2455}
2456
2457/**
2458 * Populates all SMC MCLK levels' structure based on the trimmed allowed dpm memory clock states
2459 *
2460 * @param hwmgr the address of the hardware manager
2461 */
2462
2463static int iceland_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
2464{
2465 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2466 struct iceland_dpm_table *dpm_table = &data->dpm_table;
2467 int result;
2468 /* populate MCLK dpm table to SMU7 */
2469 uint32_t level_array_adress = data->dpm_table_start + offsetof(SMU71_Discrete_DpmTable, MemoryLevel);
2470 uint32_t level_array_size = sizeof(SMU71_Discrete_MemoryLevel) * SMU71_MAX_LEVELS_MEMORY;
2471 SMU71_Discrete_MemoryLevel *levels = data->smc_state_table.MemoryLevel;
2472 uint32_t i;
2473
2474 memset(levels, 0x00, level_array_size);
2475
2476 for (i = 0; i < dpm_table->mclk_table.count; i++) {
2477 PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value),
2478 "can not populate memory level as memory clock is zero", return -1);
2479 result = iceland_populate_single_memory_level(hwmgr, dpm_table->mclk_table.dpm_levels[i].value,
2480 &(data->smc_state_table.MemoryLevel[i]));
2481 if (0 != result) {
2482 return result;
2483 }
2484 }
2485
2486 /* Only enable level 0 for now.*/
2487 data->smc_state_table.MemoryLevel[0].EnabledForActivity = 1;
2488
2489 /*
2490 * in order to prevent MC activity from stutter mode to push DPM up.
2491 * the UVD change complements this by putting the MCLK in a higher state
2492 * by default such that we are not effected by up threshold or and MCLK DPM latency.
2493 */
2494 data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F;
2495 CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.MemoryLevel[0].ActivityLevel);
2496
2497 data->smc_state_table.MemoryDpmLevelCount = (uint8_t)dpm_table->mclk_table.count;
2498 data->dpm_level_enable_mask.mclk_dpm_enable_mask = iceland_get_dpm_level_enable_mask_value(&dpm_table->mclk_table);
2499 /* set highest level watermark to high*/
2500 data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH;
2501
2502 /* level count will send to smc once at init smc table and never change*/
2503 result = iceland_copy_bytes_to_smc(hwmgr->smumgr,
2504 level_array_adress, (uint8_t *)levels, (uint32_t)level_array_size, data->sram_end);
2505
2506 if (0 != result) {
2507 return result;
2508 }
2509
2510 return 0;
2511}
2512
2513struct ICELAND_DLL_SPEED_SETTING
2514{
2515 uint16_t Min; /* Minimum Data Rate*/
2516 uint16_t Max; /* Maximum Data Rate*/
2517 uint32_t dll_speed; /* The desired DLL_SPEED setting*/
2518};
2519
2520static int iceland_populate_ulv_level(struct pp_hwmgr *hwmgr, SMU71_Discrete_Ulv *pstate)
2521{
2522 int result = 0;
2523 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2524 uint32_t voltage_response_time, ulv_voltage;
2525
2526 pstate->CcPwrDynRm = 0;
2527 pstate->CcPwrDynRm1 = 0;
2528
2529 //backbiasResponseTime is use for ULV state voltage value.
2530 result = pp_tables_get_response_times(hwmgr, &voltage_response_time, &ulv_voltage);
2531 PP_ASSERT_WITH_CODE((0 == result), "can not get ULV voltage value", return result;);
2532
2533 if(!ulv_voltage) {
2534 data->ulv.ulv_supported = false;
2535 return 0;
2536 }
2537
2538 if (ICELAND_VOLTAGE_CONTROL_BY_SVID2 != data->voltage_control) {
2539 /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */
2540 if (ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) {
2541 pstate->VddcOffset = 0;
2542 }
2543 else {
2544 /* used in SMIO Mode. not implemented for now. this is backup only for CI. */
2545 pstate->VddcOffset = (uint16_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage);
2546 }
2547 } else {
2548 /* use minimum voltage if ulv voltage in pptable is bigger than minimum voltage */
2549 if(ulv_voltage > hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v) {
2550 pstate->VddcOffsetVid = 0;
2551 } else {
2552 /* used in SVI2 Mode */
2553 pstate->VddcOffsetVid = (uint8_t)((hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].v - ulv_voltage) * VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1);
2554 }
2555 }
2556
2557 /* used in SVI2 Mode to shed phase */
2558 pstate->VddcPhase = (data->vddc_phase_shed_control) ? 0 : 1;
2559
2560 if (0 == result) {
2561 CONVERT_FROM_HOST_TO_SMC_UL(pstate->CcPwrDynRm);
2562 CONVERT_FROM_HOST_TO_SMC_UL(pstate->CcPwrDynRm1);
2563 CONVERT_FROM_HOST_TO_SMC_US(pstate->VddcOffset);
2564 }
2565
2566 return result;
2567}
2568
2569static int iceland_populate_ulv_state(struct pp_hwmgr *hwmgr, SMU71_Discrete_Ulv *ulv)
2570{
2571 return iceland_populate_ulv_level(hwmgr, ulv);
2572}
2573
2574static int iceland_populate_smc_initial_state(struct pp_hwmgr *hwmgr)
2575{
2576 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2577 uint8_t count, level;
2578
2579 count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_sclk->count);
2580
2581 for (level = 0; level < count; level++) {
2582 if (hwmgr->dyn_state.vddc_dependency_on_sclk->entries[level].clk
2583 >= data->vbios_boot_state.sclk_bootup_value) {
2584 data->smc_state_table.GraphicsBootLevel = level;
2585 break;
2586 }
2587 }
2588
2589 count = (uint8_t)(hwmgr->dyn_state.vddc_dependency_on_mclk->count);
2590
2591 for (level = 0; level < count; level++) {
2592 if (hwmgr->dyn_state.vddc_dependency_on_mclk->entries[level].clk
2593 >= data->vbios_boot_state.mclk_bootup_value) {
2594 data->smc_state_table.MemoryBootLevel = level;
2595 break;
2596 }
2597 }
2598
2599 return 0;
2600}
2601
2602/**
2603 * Initializes the SMC table and uploads it
2604 *
2605 * @param hwmgr the address of the powerplay hardware manager.
2606 * @param pInput the pointer to input data (PowerState)
2607 * @return always 0
2608 */
2609int iceland_init_smc_table(struct pp_hwmgr *hwmgr)
2610{
2611 int result;
2612 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2613 SMU71_Discrete_DpmTable *table = &(data->smc_state_table);
2614 const struct phw_iceland_ulv_parm *ulv = &(data->ulv);
2615
2616 result = iceland_setup_default_dpm_tables(hwmgr);
2617 PP_ASSERT_WITH_CODE(0 == result,
2618 "Failed to setup default DPM tables!", return result;);
2619 memset(&(data->smc_state_table), 0x00, sizeof(data->smc_state_table));
2620
2621 if (ICELAND_VOLTAGE_CONTROL_NONE != data->voltage_control) {
2622 iceland_populate_smc_voltage_tables(hwmgr, table);
2623 }
2624
2625 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2626 PHM_PlatformCaps_AutomaticDCTransition)) {
2627 table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
2628 }
2629
2630 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2631 PHM_PlatformCaps_StepVddc)) {
2632 table->SystemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
2633 }
2634
2635 if (data->is_memory_GDDR5) {
2636 table->SystemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
2637 }
2638
2639 if (ulv->ulv_supported) {
2640 result = iceland_populate_ulv_state(hwmgr, &data->ulv_setting);
2641 PP_ASSERT_WITH_CODE(0 == result,
2642 "Failed to initialize ULV state!", return result;);
2643
2644 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
2645 ixCG_ULV_PARAMETER, ulv->ch_ulv_parameter);
2646 }
2647
2648 result = iceland_populate_smc_link_level(hwmgr, table);
2649 PP_ASSERT_WITH_CODE(0 == result,
2650 "Failed to initialize Link Level!", return result;);
2651
2652 result = iceland_populate_all_graphic_levels(hwmgr);
2653 PP_ASSERT_WITH_CODE(0 == result,
2654 "Failed to initialize Graphics Level!", return result;);
2655
2656 result = iceland_populate_all_memory_levels(hwmgr);
2657 PP_ASSERT_WITH_CODE(0 == result,
2658 "Failed to initialize Memory Level!", return result;);
2659
2660 result = iceland_populate_smc_acpi_level(hwmgr, table);
2661 PP_ASSERT_WITH_CODE(0 == result,
2662 "Failed to initialize ACPI Level!", return result;);
2663
2664 result = iceland_populate_smc_vce_level(hwmgr, table);
2665 PP_ASSERT_WITH_CODE(0 == result,
2666 "Failed to initialize VCE Level!", return result;);
2667
2668 result = iceland_populate_smc_acp_level(hwmgr, table);
2669 PP_ASSERT_WITH_CODE(0 == result,
2670 "Failed to initialize ACP Level!", return result;);
2671
2672 result = iceland_populate_smc_samu_level(hwmgr, table);
2673 PP_ASSERT_WITH_CODE(0 == result,
2674 "Failed to initialize SAMU Level!", return result;);
2675
2676 /*
2677 * Since only the initial state is completely set up at this
2678 * point (the other states are just copies of the boot state)
2679 * we only need to populate the ARB settings for the initial
2680 * state.
2681 */
2682 result = iceland_program_memory_timing_parameters(hwmgr);
2683 PP_ASSERT_WITH_CODE(0 == result,
2684 "Failed to Write ARB settings for the initial state.", return result;);
2685
2686 result = iceland_populate_smc_uvd_level(hwmgr, table);
2687 PP_ASSERT_WITH_CODE(0 == result,
2688 "Failed to initialize UVD Level!", return result;);
2689
2690 table->GraphicsBootLevel = 0;
2691 table->MemoryBootLevel = 0;
2692
2693 /* find boot level from dpm table */
2694 result = iceland_find_boot_level(&(data->dpm_table.sclk_table),
2695 data->vbios_boot_state.sclk_bootup_value,
2696 (uint32_t *)&(data->smc_state_table.GraphicsBootLevel));
2697
2698 if (result)
2699 pr_warning("VBIOS did not find boot engine clock value in dependency table.\n");
2700
2701 result = iceland_find_boot_level(&(data->dpm_table.mclk_table),
2702 data->vbios_boot_state.mclk_bootup_value,
2703 (uint32_t *)&(data->smc_state_table.MemoryBootLevel));
2704
2705 if (result)
2706 pr_warning("VBIOS did not find boot memory clock value in dependency table.\n");
2707
2708 table->BootVddc = data->vbios_boot_state.vddc_bootup_value;
2709 if (ICELAND_VOLTAGE_CONTROL_NONE == data->vdd_ci_control) {
2710 table->BootVddci = table->BootVddc;
2711 }
2712 else {
2713 table->BootVddci = data->vbios_boot_state.vddci_bootup_value;
2714 }
2715 table->BootMVdd = data->vbios_boot_state.mvdd_bootup_value;
2716
2717 result = iceland_populate_smc_initial_state(hwmgr);
2718 PP_ASSERT_WITH_CODE(0 == result, "Failed to initialize Boot State!", return result);
2719
2720 result = iceland_populate_bapm_parameters_in_dpm_table(hwmgr);
2721 PP_ASSERT_WITH_CODE(0 == result, "Failed to populate BAPM Parameters!", return result);
2722
2723 table->GraphicsVoltageChangeEnable = 1;
2724 table->GraphicsThermThrottleEnable = 1;
2725 table->GraphicsInterval = 1;
2726 table->VoltageInterval = 1;
2727 table->ThermalInterval = 1;
2728 table->TemperatureLimitHigh =
2729 (data->thermal_temp_setting.temperature_high *
2730 ICELAND_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
2731 table->TemperatureLimitLow =
2732 (data->thermal_temp_setting.temperature_low *
2733 ICELAND_Q88_FORMAT_CONVERSION_UNIT) / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
2734 table->MemoryVoltageChangeEnable = 1;
2735 table->MemoryInterval = 1;
2736 table->VoltageResponseTime = 0;
2737 table->PhaseResponseTime = 0;
2738 table->MemoryThermThrottleEnable = 1;
2739 table->PCIeBootLinkLevel = 0;
2740 table->PCIeGenInterval = 1;
2741
2742 result = iceland_populate_smc_svi2_config(hwmgr, table);
2743 PP_ASSERT_WITH_CODE(0 == result,
2744 "Failed to populate SVI2 setting!", return result);
2745
2746 table->ThermGpio = 17;
2747 table->SclkStepSize = 0x4000;
2748
2749 CONVERT_FROM_HOST_TO_SMC_UL(table->SystemFlags);
2750 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcVid);
2751 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddcPhase);
2752 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskVddciVid);
2753 CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMaskMvddVid);
2754 CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize);
2755 CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh);
2756 CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow);
2757 CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime);
2758 CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime);
2759
2760 table->BootVddc = PP_HOST_TO_SMC_US(table->BootVddc * VOLTAGE_SCALE);
2761 table->BootVddci = PP_HOST_TO_SMC_US(table->BootVddci * VOLTAGE_SCALE);
2762 table->BootMVdd = PP_HOST_TO_SMC_US(table->BootMVdd * VOLTAGE_SCALE);
2763
2764 /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */
2765 result = iceland_copy_bytes_to_smc(hwmgr->smumgr, data->dpm_table_start +
2766 offsetof(SMU71_Discrete_DpmTable, SystemFlags),
2767 (uint8_t *)&(table->SystemFlags),
2768 sizeof(SMU71_Discrete_DpmTable) - 3 * sizeof(SMU71_PIDController),
2769 data->sram_end);
2770
2771 PP_ASSERT_WITH_CODE(0 == result,
2772 "Failed to upload dpm data to SMC memory!", return result);
2773
2774 /* Upload all ulv setting to SMC memory.(dpm level, dpm level count etc) */
2775 result = iceland_copy_bytes_to_smc(hwmgr->smumgr,
2776 data->ulv_settings_start,
2777 (uint8_t *)&(data->ulv_setting),
2778 sizeof(SMU71_Discrete_Ulv),
2779 data->sram_end);
2780
2781#if 0
2782 /* Notify SMC to follow new GPIO scheme */
2783 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2784 PHM_PlatformCaps_AutomaticDCTransition)) {
2785 if (0 == iceland_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_UseNewGPIOScheme))
2786 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2787 PHM_PlatformCaps_SMCtoPPLIBAcdcGpioScheme);
2788 }
2789#endif
2790
2791 return result;
2792}
2793
2794int iceland_populate_mc_reg_address(struct pp_hwmgr *hwmgr, SMU71_Discrete_MCRegisters *mc_reg_table)
2795{
2796 const struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
2797
2798 uint32_t i, j;
2799
2800 for (i = 0, j = 0; j < data->iceland_mc_reg_table.last; j++) {
2801 if (data->iceland_mc_reg_table.validflag & 1<<j) {
2802 PP_ASSERT_WITH_CODE(i < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE,
2803 "Index of mc_reg_table->address[] array out of boundary", return -1);
2804 mc_reg_table->address[i].s0 =
2805 PP_HOST_TO_SMC_US(data->iceland_mc_reg_table.mc_reg_address[j].s0);
2806 mc_reg_table->address[i].s1 =
2807 PP_HOST_TO_SMC_US(data->iceland_mc_reg_table.mc_reg_address[j].s1);
2808 i++;
2809 }
2810 }
2811
2812 mc_reg_table->last = (uint8_t)i;
2813
2814 return 0;
2815}
2816
2817/* convert register values from driver to SMC format */
2818void iceland_convert_mc_registers(
2819 const phw_iceland_mc_reg_entry * pEntry,
2820 SMU71_Discrete_MCRegisterSet *pData,
2821 uint32_t numEntries, uint32_t validflag)
2822{
2823 uint32_t i, j;
2824
2825 for (i = 0, j = 0; j < numEntries; j++) {
2826 if (validflag & 1<<j) {
2827 pData->value[i] = PP_HOST_TO_SMC_UL(pEntry->mc_data[j]);
2828 i++;
2829 }
2830 }
2831}
2832
2833/* find the entry in the memory range table, then populate the value to SMC's iceland_mc_reg_table */
2834int iceland_convert_mc_reg_table_entry_to_smc(
2835 struct pp_hwmgr *hwmgr,
2836 const uint32_t memory_clock,
2837 SMU71_Discrete_MCRegisterSet *mc_reg_table_data
2838 )
2839{
2840 const iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
2841 uint32_t i = 0;
2842
2843 for (i = 0; i < data->iceland_mc_reg_table.num_entries; i++) {
2844 if (memory_clock <=
2845 data->iceland_mc_reg_table.mc_reg_table_entry[i].mclk_max) {
2846 break;
2847 }
2848 }
2849
2850 if ((i == data->iceland_mc_reg_table.num_entries) && (i > 0))
2851 --i;
2852
2853 iceland_convert_mc_registers(&data->iceland_mc_reg_table.mc_reg_table_entry[i],
2854 mc_reg_table_data, data->iceland_mc_reg_table.last, data->iceland_mc_reg_table.validflag);
2855
2856 return 0;
2857}
2858
2859int iceland_convert_mc_reg_table_to_smc(struct pp_hwmgr *hwmgr,
2860 SMU71_Discrete_MCRegisters *mc_reg_table)
2861{
2862 int result = 0;
2863 iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
2864 int res;
2865 uint32_t i;
2866
2867 for (i = 0; i < data->dpm_table.mclk_table.count; i++) {
2868 res = iceland_convert_mc_reg_table_entry_to_smc(
2869 hwmgr,
2870 data->dpm_table.mclk_table.dpm_levels[i].value,
2871 &mc_reg_table->data[i]
2872 );
2873
2874 if (0 != res)
2875 result = res;
2876 }
2877
2878 return result;
2879}
2880
2881int iceland_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr)
2882{
2883 int result;
2884 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
2885
2886 memset(&data->mc_reg_table, 0x00, sizeof(SMU71_Discrete_MCRegisters));
2887 result = iceland_populate_mc_reg_address(hwmgr, &(data->mc_reg_table));
2888 PP_ASSERT_WITH_CODE(0 == result,
2889 "Failed to initialize MCRegTable for the MC register addresses!", return result;);
2890
2891 result = iceland_convert_mc_reg_table_to_smc(hwmgr, &data->mc_reg_table);
2892 PP_ASSERT_WITH_CODE(0 == result,
2893 "Failed to initialize MCRegTable for driver state!", return result;);
2894
2895 return iceland_copy_bytes_to_smc(hwmgr->smumgr, data->mc_reg_table_start,
2896 (uint8_t *)&data->mc_reg_table, sizeof(SMU71_Discrete_MCRegisters), data->sram_end);
2897}
2898
2899int iceland_notify_smc_display_change(struct pp_hwmgr *hwmgr, bool has_display)
2900{
2901 PPSMC_Msg msg = has_display? (PPSMC_Msg)PPSMC_HasDisplay : (PPSMC_Msg)PPSMC_NoDisplay;
2902
2903 return (smum_send_msg_to_smc(hwmgr->smumgr, msg) == 0) ? 0 : -1;
2904}
2905
2906int iceland_enable_sclk_control(struct pp_hwmgr *hwmgr)
2907{
2908 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, 0);
2909
2910 return 0;
2911}
2912
2913int iceland_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
2914{
2915 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2916
2917 /* enable SCLK dpm */
2918 if (0 == data->sclk_dpm_key_disabled) {
2919 PP_ASSERT_WITH_CODE(
2920 (0 == smum_send_msg_to_smc(hwmgr->smumgr,
2921 PPSMC_MSG_DPM_Enable)),
2922 "Failed to enable SCLK DPM during DPM Start Function!",
2923 return -1);
2924 }
2925
2926 /* enable MCLK dpm */
2927 if (0 == data->mclk_dpm_key_disabled) {
2928 PP_ASSERT_WITH_CODE(
2929 (0 == smum_send_msg_to_smc(hwmgr->smumgr,
2930 PPSMC_MSG_MCLKDPM_Enable)),
2931 "Failed to enable MCLK DPM during DPM Start Function!",
2932 return -1);
2933
2934 PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1);
2935
2936 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
2937 ixLCAC_MC0_CNTL, 0x05);/* CH0,1 read */
2938 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
2939 ixLCAC_MC1_CNTL, 0x05);/* CH2,3 read */
2940 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
2941 ixLCAC_CPL_CNTL, 0x100005);/*Read */
2942
2943 udelay(10);
2944
2945 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
2946 ixLCAC_MC0_CNTL, 0x400005);/* CH0,1 write */
2947 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
2948 ixLCAC_MC1_CNTL, 0x400005);/* CH2,3 write */
2949 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
2950 ixLCAC_CPL_CNTL, 0x500005);/* write */
2951
2952 }
2953
2954 return 0;
2955}
2956
2957int iceland_start_dpm(struct pp_hwmgr *hwmgr)
2958{
2959 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
2960
2961 /* enable general power management */
2962 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, 1);
2963 /* enable sclk deep sleep */
2964 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL, DYNAMIC_PM_EN, 1);
2965
2966 /* prepare for PCIE DPM */
2967 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SOFT_REGISTERS_TABLE_12, VoltageChangeTimeout, 0x1000);
2968
2969 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__PCIE, SWRST_COMMAND_1, RESETLC, 0x0);
2970
2971 PP_ASSERT_WITH_CODE(
2972 (0 == smum_send_msg_to_smc(hwmgr->smumgr,
2973 PPSMC_MSG_Voltage_Cntl_Enable)),
2974 "Failed to enable voltage DPM during DPM Start Function!",
2975 return -1);
2976
2977 if (0 != iceland_enable_sclk_mclk_dpm(hwmgr)) {
2978 PP_ASSERT_WITH_CODE(0, "Failed to enable Sclk DPM and Mclk DPM!", return -1);
2979 }
2980
2981 /* enable PCIE dpm */
2982 if (0 == data->pcie_dpm_key_disabled) {
2983 PP_ASSERT_WITH_CODE(
2984 (0 == smum_send_msg_to_smc(hwmgr->smumgr,
2985 PPSMC_MSG_PCIeDPM_Enable)),
2986 "Failed to enable pcie DPM during DPM Start Function!",
2987 return -1
2988 );
2989 }
2990
2991 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2992 PHM_PlatformCaps_Falcon_QuickTransition)) {
2993 smum_send_msg_to_smc(hwmgr->smumgr,
2994 PPSMC_MSG_EnableACDCGPIOInterrupt);
2995 }
2996
2997 return 0;
2998}
2999
3000static void iceland_set_dpm_event_sources(struct pp_hwmgr *hwmgr,
3001 uint32_t sources)
3002{
3003 bool protection;
3004 enum DPM_EVENT_SRC src;
3005
3006 switch (sources) {
3007 default:
3008 printk(KERN_ERR "Unknown throttling event sources.");
3009 /* fall through */
3010 case 0:
3011 protection = false;
3012 /* src is unused */
3013 break;
3014 case (1 << PHM_AutoThrottleSource_Thermal):
3015 protection = true;
3016 src = DPM_EVENT_SRC_DIGITAL;
3017 break;
3018 case (1 << PHM_AutoThrottleSource_External):
3019 protection = true;
3020 src = DPM_EVENT_SRC_EXTERNAL;
3021 break;
3022 case (1 << PHM_AutoThrottleSource_External) |
3023 (1 << PHM_AutoThrottleSource_Thermal):
3024 protection = true;
3025 src = DPM_EVENT_SRC_DIGITAL_OR_EXTERNAL;
3026 break;
3027 }
3028 /* Order matters - don't enable thermal protection for the wrong source. */
3029 if (protection) {
3030 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_CTRL,
3031 DPM_EVENT_SRC, src);
3032 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT,
3033 THERMAL_PROTECTION_DIS,
3034 !phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
3035 PHM_PlatformCaps_ThermalController));
3036 } else
3037 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT,
3038 THERMAL_PROTECTION_DIS, 1);
3039}
3040
3041static int iceland_enable_auto_throttle_source(struct pp_hwmgr *hwmgr,
3042 PHM_AutoThrottleSource source)
3043{
3044 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
3045
3046 if (!(data->active_auto_throttle_sources & (1 << source))) {
3047 data->active_auto_throttle_sources |= 1 << source;
3048 iceland_set_dpm_event_sources(hwmgr, data->active_auto_throttle_sources);
3049 }
3050 return 0;
3051}
3052
3053static int iceland_enable_thermal_auto_throttle(struct pp_hwmgr *hwmgr)
3054{
3055 return iceland_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal);
3056}
3057
3058static int iceland_tf_start_smc(struct pp_hwmgr *hwmgr)
3059{
3060 int ret = 0;
3061
3062 if (!iceland_is_smc_ram_running(hwmgr->smumgr))
3063 ret = iceland_smu_start_smc(hwmgr->smumgr);
3064
3065 return ret;
3066}
3067
3068/**
3069* Programs the Deep Sleep registers
3070*
3071* @param pHwMgr the address of the powerplay hardware manager.
3072* @param pInput the pointer to input data (PhwEvergreen_DisplayConfiguration)
3073* @param pOutput the pointer to output data (unused)
3074* @param pStorage the pointer to temporary storage (unused)
3075* @param Result the last failure code (unused)
3076* @return always 0
3077*/
3078static int iceland_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
3079{
3080 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
3081 PHM_PlatformCaps_SclkDeepSleep)) {
3082 if (smum_send_msg_to_smc(hwmgr->smumgr,
3083 PPSMC_MSG_MASTER_DeepSleep_ON) != 0)
3084 PP_ASSERT_WITH_CODE(false,
3085 "Attempt to enable Master Deep Sleep switch failed!",
3086 return -EINVAL);
3087 } else {
3088 if (smum_send_msg_to_smc(hwmgr->smumgr,
3089 PPSMC_MSG_MASTER_DeepSleep_OFF) != 0)
3090 PP_ASSERT_WITH_CODE(false,
3091 "Attempt to disable Master Deep Sleep switch failed!",
3092 return -EINVAL);
3093 }
3094
3095 return 0;
3096}
3097
3098static int iceland_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
3099{
3100 int tmp_result, result = 0;
3101
3102 if (cf_iceland_voltage_control(hwmgr)) {
3103 tmp_result = iceland_enable_voltage_control(hwmgr);
3104 PP_ASSERT_WITH_CODE((0 == tmp_result),
3105 "Failed to enable voltage control!", return tmp_result);
3106
3107 tmp_result = iceland_construct_voltage_tables(hwmgr);
3108 PP_ASSERT_WITH_CODE((0 == tmp_result),
3109 "Failed to contruct voltage tables!", return tmp_result);
3110 }
3111
3112 tmp_result = iceland_initialize_mc_reg_table(hwmgr);
3113 PP_ASSERT_WITH_CODE((0 == tmp_result),
3114 "Failed to initialize MC reg table!", return tmp_result);
3115
3116 tmp_result = iceland_program_static_screen_threshold_parameters(hwmgr);
3117 PP_ASSERT_WITH_CODE((0 == tmp_result),
3118 "Failed to program static screen threshold parameters!", return tmp_result);
3119
3120 tmp_result = iceland_enable_display_gap(hwmgr);
3121 PP_ASSERT_WITH_CODE((0 == tmp_result),
3122 "Failed to enable display gap!", return tmp_result);
3123
3124 tmp_result = iceland_program_voting_clients(hwmgr);
3125 PP_ASSERT_WITH_CODE((0 == tmp_result),
3126 "Failed to program voting clients!", return tmp_result);
3127
3128 tmp_result = iceland_upload_firmware(hwmgr);
3129 PP_ASSERT_WITH_CODE((0 == tmp_result),
3130 "Failed to upload firmware header!", return tmp_result);
3131
3132 tmp_result = iceland_process_firmware_header(hwmgr);
3133 PP_ASSERT_WITH_CODE((0 == tmp_result),
3134 "Failed to process firmware header!", return tmp_result);
3135
3136 tmp_result = iceland_initial_switch_from_arb_f0_to_f1(hwmgr);
3137 PP_ASSERT_WITH_CODE((0 == tmp_result),
3138 "Failed to initialize switch from ArbF0 to F1!", return tmp_result);
3139
3140 tmp_result = iceland_init_smc_table(hwmgr);
3141 PP_ASSERT_WITH_CODE((0 == tmp_result),
3142 "Failed to initialize SMC table!", return tmp_result);
3143
3144 tmp_result = iceland_populate_initial_mc_reg_table(hwmgr);
3145 PP_ASSERT_WITH_CODE((0 == tmp_result),
3146 "Failed to populate initialize MC Reg table!", return tmp_result);
3147
3148 tmp_result = iceland_populate_pm_fuses(hwmgr);
3149 PP_ASSERT_WITH_CODE((0 == tmp_result),
3150 "Failed to populate PM fuses!", return tmp_result);
3151
3152 /* start SMC */
3153 tmp_result = iceland_tf_start_smc(hwmgr);
3154 PP_ASSERT_WITH_CODE((0 == tmp_result),
3155 "Failed to start SMC!", return tmp_result);
3156
3157 /* enable SCLK control */
3158 tmp_result = iceland_enable_sclk_control(hwmgr);
3159 PP_ASSERT_WITH_CODE((0 == tmp_result),
3160 "Failed to enable SCLK control!", return tmp_result);
3161
3162 tmp_result = iceland_enable_deep_sleep_master_switch(hwmgr);
3163 PP_ASSERT_WITH_CODE((tmp_result == 0),
3164 "Failed to enable deep sleep!", return tmp_result);
3165
3166 /* enable DPM */
3167 tmp_result = iceland_start_dpm(hwmgr);
3168 PP_ASSERT_WITH_CODE((0 == tmp_result),
3169 "Failed to start DPM!", return tmp_result);
3170
3171 tmp_result = iceland_enable_smc_cac(hwmgr);
3172 PP_ASSERT_WITH_CODE((0 == tmp_result),
3173 "Failed to enable SMC CAC!", return tmp_result);
3174
3175 tmp_result = iceland_enable_power_containment(hwmgr);
3176 PP_ASSERT_WITH_CODE((0 == tmp_result),
3177 "Failed to enable power containment!", return tmp_result);
3178
3179 tmp_result = iceland_power_control_set_level(hwmgr);
3180 PP_ASSERT_WITH_CODE((0 == tmp_result),
3181 "Failed to power control set level!", result = tmp_result);
3182
3183 tmp_result = iceland_enable_thermal_auto_throttle(hwmgr);
3184 PP_ASSERT_WITH_CODE((0 == tmp_result),
3185 "Failed to enable thermal auto throttle!", result = tmp_result);
3186
3187 return result;
3188}
3189
3190static int iceland_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
3191{
3192 return phm_hwmgr_backend_fini(hwmgr);
3193}
3194
3195static void iceland_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
3196{
3197 iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
3198 struct phw_iceland_ulv_parm *ulv;
3199
3200 ulv = &data->ulv;
3201 ulv->ch_ulv_parameter = PPICELAND_CGULVPARAMETER_DFLT;
3202 data->voting_rights_clients0 = PPICELAND_VOTINGRIGHTSCLIENTS_DFLT0;
3203 data->voting_rights_clients1 = PPICELAND_VOTINGRIGHTSCLIENTS_DFLT1;
3204 data->voting_rights_clients2 = PPICELAND_VOTINGRIGHTSCLIENTS_DFLT2;
3205 data->voting_rights_clients3 = PPICELAND_VOTINGRIGHTSCLIENTS_DFLT3;
3206 data->voting_rights_clients4 = PPICELAND_VOTINGRIGHTSCLIENTS_DFLT4;
3207 data->voting_rights_clients5 = PPICELAND_VOTINGRIGHTSCLIENTS_DFLT5;
3208 data->voting_rights_clients6 = PPICELAND_VOTINGRIGHTSCLIENTS_DFLT6;
3209 data->voting_rights_clients7 = PPICELAND_VOTINGRIGHTSCLIENTS_DFLT7;
3210
3211 data->static_screen_threshold_unit = PPICELAND_STATICSCREENTHRESHOLDUNIT_DFLT;
3212 data->static_screen_threshold = PPICELAND_STATICSCREENTHRESHOLD_DFLT;
3213
3214 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3215 PHM_PlatformCaps_ABM);
3216 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3217 PHM_PlatformCaps_NonABMSupportInPPLib);
3218
3219 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3220 PHM_PlatformCaps_DynamicACTiming);
3221
3222 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3223 PHM_PlatformCaps_DisableMemoryTransition);
3224
3225 iceland_initialize_power_tune_defaults(hwmgr);
3226
3227 data->mclk_strobe_mode_threshold = 40000;
3228 data->mclk_stutter_mode_threshold = 30000;
3229 data->mclk_edc_enable_threshold = 40000;
3230 data->mclk_edc_wr_enable_threshold = 40000;
3231
3232 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3233 PHM_PlatformCaps_DisableMCLS);
3234
3235 data->pcie_gen_performance.max = PP_PCIEGen1;
3236 data->pcie_gen_performance.min = PP_PCIEGen3;
3237 data->pcie_gen_power_saving.max = PP_PCIEGen1;
3238 data->pcie_gen_power_saving.min = PP_PCIEGen3;
3239
3240 data->pcie_lane_performance.max = 0;
3241 data->pcie_lane_performance.min = 16;
3242 data->pcie_lane_power_saving.max = 0;
3243 data->pcie_lane_power_saving.min = 16;
3244
3245 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3246 PHM_PlatformCaps_SclkThrottleLowNotification);
3247}
3248
3249static int iceland_get_evv_voltage(struct pp_hwmgr *hwmgr)
3250{
3251 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
3252 uint16_t virtual_voltage_id;
3253 uint16_t vddc = 0;
3254 uint16_t i;
3255
3256 /* the count indicates actual number of entries */
3257 data->vddc_leakage.count = 0;
3258 data->vddci_leakage.count = 0;
3259
3260 if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_EVV)) {
3261 pr_err("Iceland should always support EVV\n");
3262 return -EINVAL;
3263 }
3264
3265 /* retrieve voltage for leakage ID (0xff01 + i) */
3266 for (i = 0; i < ICELAND_MAX_LEAKAGE_COUNT; i++) {
3267 virtual_voltage_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;
3268
3269 PP_ASSERT_WITH_CODE((0 == atomctrl_get_voltage_evv(hwmgr, virtual_voltage_id, &vddc)),
3270 "Error retrieving EVV voltage value!\n", continue);
3271
3272 if (vddc >= 2000)
3273 pr_warning("Invalid VDDC value!\n");
3274
3275 if (vddc != 0 && vddc != virtual_voltage_id) {
3276 data->vddc_leakage.actual_voltage[data->vddc_leakage.count] = vddc;
3277 data->vddc_leakage.leakage_id[data->vddc_leakage.count] = virtual_voltage_id;
3278 data->vddc_leakage.count++;
3279 }
3280 }
3281
3282 return 0;
3283}
3284
3285static void iceland_patch_with_vddc_leakage(struct pp_hwmgr *hwmgr,
3286 uint32_t *vddc)
3287{
3288 iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
3289 uint32_t leakage_index;
3290 struct phw_iceland_leakage_voltage *leakage_table = &data->vddc_leakage;
3291
3292 /* search for leakage voltage ID 0xff01 ~ 0xff08 */
3293 for (leakage_index = 0; leakage_index < leakage_table->count; leakage_index++) {
3294 /*
3295 * If this voltage matches a leakage voltage ID, patch
3296 * with actual leakage voltage.
3297 */
3298 if (leakage_table->leakage_id[leakage_index] == *vddc) {
3299 /*
3300 * Need to make sure vddc is less than 2v or
3301 * else, it could burn the ASIC.
3302 */
3303 if (leakage_table->actual_voltage[leakage_index] >= 2000)
3304 pr_warning("Invalid VDDC value!\n");
3305 *vddc = leakage_table->actual_voltage[leakage_index];
3306 /* we found leakage voltage */
3307 break;
3308 }
3309 }
3310
3311 if (*vddc >= ATOM_VIRTUAL_VOLTAGE_ID0)
3312 pr_warning("Voltage value looks like a Leakage ID but it's not patched\n");
3313}
3314
3315static void iceland_patch_with_vddci_leakage(struct pp_hwmgr *hwmgr,
3316 uint32_t *vddci)
3317{
3318 iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
3319 uint32_t leakage_index;
3320 struct phw_iceland_leakage_voltage *leakage_table = &data->vddci_leakage;
3321
3322 /* search for leakage voltage ID 0xff01 ~ 0xff08 */
3323 for (leakage_index = 0; leakage_index < leakage_table->count; leakage_index++) {
3324 /*
3325 * If this voltage matches a leakage voltage ID, patch
3326 * with actual leakage voltage.
3327 */
3328 if (leakage_table->leakage_id[leakage_index] == *vddci) {
3329 *vddci = leakage_table->actual_voltage[leakage_index];
3330 /* we found leakage voltage */
3331 break;
3332 }
3333 }
3334
3335 if (*vddci >= ATOM_VIRTUAL_VOLTAGE_ID0)
3336 pr_warning("Voltage value looks like a Leakage ID but it's not patched\n");
3337}
3338
3339static int iceland_patch_vddc(struct pp_hwmgr *hwmgr,
3340 struct phm_clock_voltage_dependency_table *tab)
3341{
3342 uint16_t i;
3343
3344 if (tab)
3345 for (i = 0; i < tab->count; i++)
3346 iceland_patch_with_vddc_leakage(hwmgr, &tab->entries[i].v);
3347
3348 return 0;
3349}
3350
3351static int iceland_patch_vddci(struct pp_hwmgr *hwmgr,
3352 struct phm_clock_voltage_dependency_table *tab)
3353{
3354 uint16_t i;
3355
3356 if (tab)
3357 for (i = 0; i < tab->count; i++)
3358 iceland_patch_with_vddci_leakage(hwmgr, &tab->entries[i].v);
3359
3360 return 0;
3361}
3362
3363static int iceland_patch_vce_vddc(struct pp_hwmgr *hwmgr,
3364 struct phm_vce_clock_voltage_dependency_table *tab)
3365{
3366 uint16_t i;
3367
3368 if (tab)
3369 for (i = 0; i < tab->count; i++)
3370 iceland_patch_with_vddc_leakage(hwmgr, &tab->entries[i].v);
3371
3372 return 0;
3373}
3374
3375
3376static int iceland_patch_uvd_vddc(struct pp_hwmgr *hwmgr,
3377 struct phm_uvd_clock_voltage_dependency_table *tab)
3378{
3379 uint16_t i;
3380
3381 if (tab)
3382 for (i = 0; i < tab->count; i++)
3383 iceland_patch_with_vddc_leakage(hwmgr, &tab->entries[i].v);
3384
3385 return 0;
3386}
3387
3388static int iceland_patch_vddc_shed_limit(struct pp_hwmgr *hwmgr,
3389 struct phm_phase_shedding_limits_table *tab)
3390{
3391 uint16_t i;
3392
3393 if (tab)
3394 for (i = 0; i < tab->count; i++)
3395 iceland_patch_with_vddc_leakage(hwmgr, &tab->entries[i].Voltage);
3396
3397 return 0;
3398}
3399
3400static int iceland_patch_samu_vddc(struct pp_hwmgr *hwmgr,
3401 struct phm_samu_clock_voltage_dependency_table *tab)
3402{
3403 uint16_t i;
3404
3405 if (tab)
3406 for (i = 0; i < tab->count; i++)
3407 iceland_patch_with_vddc_leakage(hwmgr, &tab->entries[i].v);
3408
3409 return 0;
3410}
3411
3412static int iceland_patch_acp_vddc(struct pp_hwmgr *hwmgr,
3413 struct phm_acp_clock_voltage_dependency_table *tab)
3414{
3415 uint16_t i;
3416
3417 if (tab)
3418 for (i = 0; i < tab->count; i++)
3419 iceland_patch_with_vddc_leakage(hwmgr, &tab->entries[i].v);
3420
3421 return 0;
3422}
3423
3424static int iceland_patch_limits_vddc(struct pp_hwmgr *hwmgr,
3425 struct phm_clock_and_voltage_limits *tab)
3426{
3427 if (tab) {
3428 iceland_patch_with_vddc_leakage(hwmgr, (uint32_t *)&tab->vddc);
3429 iceland_patch_with_vddci_leakage(hwmgr, (uint32_t *)&tab->vddci);
3430 }
3431
3432 return 0;
3433}
3434
3435static int iceland_patch_cac_vddc(struct pp_hwmgr *hwmgr, struct phm_cac_leakage_table *tab)
3436{
3437 uint32_t i;
3438 uint32_t vddc;
3439
3440 if (tab) {
3441 for (i = 0; i < tab->count; i++) {
3442 vddc = (uint32_t)(tab->entries[i].Vddc);
3443 iceland_patch_with_vddc_leakage(hwmgr, &vddc);
3444 tab->entries[i].Vddc = (uint16_t)vddc;
3445 }
3446 }
3447
3448 return 0;
3449}
3450
3451static int iceland_patch_dependency_tables_with_leakage(struct pp_hwmgr *hwmgr)
3452{
3453 int tmp;
3454
3455 tmp = iceland_patch_vddc(hwmgr, hwmgr->dyn_state.vddc_dependency_on_sclk);
3456 if(tmp)
3457 return -EINVAL;
3458
3459 tmp = iceland_patch_vddc(hwmgr, hwmgr->dyn_state.vddc_dependency_on_mclk);
3460 if(tmp)
3461 return -EINVAL;
3462
3463 tmp = iceland_patch_vddc(hwmgr, hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
3464 if(tmp)
3465 return -EINVAL;
3466
3467 tmp = iceland_patch_vddci(hwmgr, hwmgr->dyn_state.vddci_dependency_on_mclk);
3468 if(tmp)
3469 return -EINVAL;
3470
3471 tmp = iceland_patch_vce_vddc(hwmgr, hwmgr->dyn_state.vce_clock_voltage_dependency_table);
3472 if(tmp)
3473 return -EINVAL;
3474
3475 tmp = iceland_patch_uvd_vddc(hwmgr, hwmgr->dyn_state.uvd_clock_voltage_dependency_table);
3476 if(tmp)
3477 return -EINVAL;
3478
3479 tmp = iceland_patch_samu_vddc(hwmgr, hwmgr->dyn_state.samu_clock_voltage_dependency_table);
3480 if(tmp)
3481 return -EINVAL;
3482
3483 tmp = iceland_patch_acp_vddc(hwmgr, hwmgr->dyn_state.acp_clock_voltage_dependency_table);
3484 if(tmp)
3485 return -EINVAL;
3486
3487 tmp = iceland_patch_vddc_shed_limit(hwmgr, hwmgr->dyn_state.vddc_phase_shed_limits_table);
3488 if(tmp)
3489 return -EINVAL;
3490
3491 tmp = iceland_patch_limits_vddc(hwmgr, &hwmgr->dyn_state.max_clock_voltage_on_ac);
3492 if(tmp)
3493 return -EINVAL;
3494
3495 tmp = iceland_patch_limits_vddc(hwmgr, &hwmgr->dyn_state.max_clock_voltage_on_dc);
3496 if(tmp)
3497 return -EINVAL;
3498
3499 tmp = iceland_patch_cac_vddc(hwmgr, hwmgr->dyn_state.cac_leakage_table);
3500 if(tmp)
3501 return -EINVAL;
3502
3503 return 0;
3504}
3505
3506static int iceland_set_private_var_based_on_pptale(struct pp_hwmgr *hwmgr)
3507{
3508 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
3509
3510 struct phm_clock_voltage_dependency_table *allowed_sclk_vddc_table = hwmgr->dyn_state.vddc_dependency_on_sclk;
3511 struct phm_clock_voltage_dependency_table *allowed_mclk_vddc_table = hwmgr->dyn_state.vddc_dependency_on_mclk;
3512 struct phm_clock_voltage_dependency_table *allowed_mclk_vddci_table = hwmgr->dyn_state.vddci_dependency_on_mclk;
3513
3514 PP_ASSERT_WITH_CODE(allowed_sclk_vddc_table != NULL,
3515 "VDDC dependency on SCLK table is missing. This table is mandatory\n", return -EINVAL);
3516 PP_ASSERT_WITH_CODE(allowed_sclk_vddc_table->count >= 1,
3517 "VDDC dependency on SCLK table has to have is missing. This table is mandatory\n", return -EINVAL);
3518
3519 PP_ASSERT_WITH_CODE(allowed_mclk_vddc_table != NULL,
3520 "VDDC dependency on MCLK table is missing. This table is mandatory\n", return -EINVAL);
3521 PP_ASSERT_WITH_CODE(allowed_mclk_vddc_table->count >= 1,
3522 "VDD dependency on MCLK table has to have is missing. This table is mandatory\n", return -EINVAL);
3523
3524 data->min_vddc_in_pp_table = (uint16_t)allowed_sclk_vddc_table->entries[0].v;
3525 data->max_vddc_in_pp_table = (uint16_t)allowed_sclk_vddc_table->entries[allowed_sclk_vddc_table->count - 1].v;
3526
3527 hwmgr->dyn_state.max_clock_voltage_on_ac.sclk =
3528 allowed_sclk_vddc_table->entries[allowed_sclk_vddc_table->count - 1].clk;
3529 hwmgr->dyn_state.max_clock_voltage_on_ac.mclk =
3530 allowed_mclk_vddc_table->entries[allowed_mclk_vddc_table->count - 1].clk;
3531 hwmgr->dyn_state.max_clock_voltage_on_ac.vddc =
3532 allowed_sclk_vddc_table->entries[allowed_sclk_vddc_table->count - 1].v;
3533
3534 if (allowed_mclk_vddci_table != NULL && allowed_mclk_vddci_table->count >= 1) {
3535 data->min_vddci_in_pp_table = (uint16_t)allowed_mclk_vddci_table->entries[0].v;
3536 data->max_vddci_in_pp_table = (uint16_t)allowed_mclk_vddci_table->entries[allowed_mclk_vddci_table->count - 1].v;
3537 }
3538
3539 if (hwmgr->dyn_state.vddci_dependency_on_mclk != NULL && hwmgr->dyn_state.vddci_dependency_on_mclk->count > 1)
3540 hwmgr->dyn_state.max_clock_voltage_on_ac.vddci = hwmgr->dyn_state.vddci_dependency_on_mclk->entries[hwmgr->dyn_state.vddci_dependency_on_mclk->count - 1].v;
3541
3542 return 0;
3543}
3544
3545static int iceland_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr)
3546{
3547 uint32_t table_size;
3548 struct phm_clock_voltage_dependency_table *table_clk_vlt;
3549
3550 hwmgr->dyn_state.mclk_sclk_ratio = 4;
3551 hwmgr->dyn_state.sclk_mclk_delta = 15000; /* 150 MHz */
3552 hwmgr->dyn_state.vddc_vddci_delta = 200; /* 200mV */
3553
3554 /* initialize vddc_dep_on_dal_pwrl table */
3555 table_size = sizeof(uint32_t) + 4 * sizeof(struct phm_clock_voltage_dependency_record);
3556 table_clk_vlt = (struct phm_clock_voltage_dependency_table *)kzalloc(table_size, GFP_KERNEL);
3557
3558 if (NULL == table_clk_vlt) {
3559 pr_err("[ powerplay ] Can not allocate space for vddc_dep_on_dal_pwrl! \n");
3560 return -ENOMEM;
3561 } else {
3562 table_clk_vlt->count = 4;
3563 table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_ULTRALOW;
3564 table_clk_vlt->entries[0].v = 0;
3565 table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_LOW;
3566 table_clk_vlt->entries[1].v = 720;
3567 table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_NOMINAL;
3568 table_clk_vlt->entries[2].v = 810;
3569 table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_PERFORMANCE;
3570 table_clk_vlt->entries[3].v = 900;
3571 hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
3572 }
3573
3574 return 0;
3575}
3576
3577/**
3578 * Initializes the Volcanic Islands Hardware Manager
3579 *
3580 * @param hwmgr the address of the powerplay hardware manager.
3581 * @return 1 if success; otherwise appropriate error code.
3582 */
3583static int iceland_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
3584{
3585 int result = 0;
3586 SMU71_Discrete_DpmTable *table = NULL;
3587 iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
3588 pp_atomctrl_gpio_pin_assignment gpio_pin_assignment;
3589 bool stay_in_boot;
3590 struct phw_iceland_ulv_parm *ulv;
3591 struct cgs_system_info sys_info = {0};
3592
3593 PP_ASSERT_WITH_CODE((NULL != hwmgr),
3594 "Invalid Parameter!", return -EINVAL;);
3595
3596 data->dll_defaule_on = 0;
3597 data->sram_end = SMC_RAM_END;
3598
3599 data->activity_target[0] = PPICELAND_TARGETACTIVITY_DFLT;
3600 data->activity_target[1] = PPICELAND_TARGETACTIVITY_DFLT;
3601 data->activity_target[2] = PPICELAND_TARGETACTIVITY_DFLT;
3602 data->activity_target[3] = PPICELAND_TARGETACTIVITY_DFLT;
3603 data->activity_target[4] = PPICELAND_TARGETACTIVITY_DFLT;
3604 data->activity_target[5] = PPICELAND_TARGETACTIVITY_DFLT;
3605 data->activity_target[6] = PPICELAND_TARGETACTIVITY_DFLT;
3606 data->activity_target[7] = PPICELAND_TARGETACTIVITY_DFLT;
3607
3608 data->mclk_activity_target = PPICELAND_MCLK_TARGETACTIVITY_DFLT;
3609
3610 data->sclk_dpm_key_disabled = 0;
3611 data->mclk_dpm_key_disabled = 0;
3612 data->pcie_dpm_key_disabled = 0;
3613 data->pcc_monitor_enabled = 0;
3614
3615 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3616 PHM_PlatformCaps_UnTabledHardwareInterface);
3617
3618 data->gpio_debug = 0;
3619 data->engine_clock_data = 0;
3620 data->memory_clock_data = 0;
3621
3622 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3623 PHM_PlatformCaps_SclkDeepSleepAboveLow);
3624
3625 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3626 PHM_PlatformCaps_DynamicPatchPowerState);
3627
3628 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3629 PHM_PlatformCaps_TablelessHardwareInterface);
3630
3631 /* Initializes DPM default values. */
3632 iceland_initialize_dpm_defaults(hwmgr);
3633
3634 /* Enable Platform EVV support. */
3635 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3636 PHM_PlatformCaps_EVV);
3637
3638 /* Get leakage voltage based on leakage ID. */
3639 result = iceland_get_evv_voltage(hwmgr);
3640 if (result)
3641 goto failed;
3642
3643 /**
3644 * Patch our voltage dependency table with actual leakage
3645 * voltage. We need to perform leakage translation before it's
3646 * used by other functions such as
3647 * iceland_set_hwmgr_variables_based_on_pptable.
3648 */
3649 result = iceland_patch_dependency_tables_with_leakage(hwmgr);
3650 if (result)
3651 goto failed;
3652
3653 /* Parse pptable data read from VBIOS. */
3654 result = iceland_set_private_var_based_on_pptale(hwmgr);
3655 if (result)
3656 goto failed;
3657
3658 /* ULV support */
3659 ulv = &(data->ulv);
3660 ulv->ulv_supported = 1;
3661
3662 /* Initalize Dynamic State Adjustment Rule Settings*/
3663 result = iceland_initializa_dynamic_state_adjustment_rule_settings(hwmgr);
3664 if (result) {
3665 pr_err("[ powerplay ] iceland_initializa_dynamic_state_adjustment_rule_settings failed!\n");
3666 goto failed;
3667 }
3668
3669 data->voltage_control = ICELAND_VOLTAGE_CONTROL_NONE;
3670 data->vdd_ci_control = ICELAND_VOLTAGE_CONTROL_NONE;
3671 data->mvdd_control = ICELAND_VOLTAGE_CONTROL_NONE;
3672
3673 /*
3674 * Hardcode thermal temperature settings for now, these will
3675 * be overwritten if a custom policy exists.
3676 */
3677 data->thermal_temp_setting.temperature_low = 99500;
3678 data->thermal_temp_setting.temperature_high = 100000;
3679 data->thermal_temp_setting.temperature_shutdown = 104000;
3680 data->uvd_enabled = false;
3681
3682 table = &data->smc_state_table;
3683
3684 if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID,
3685 &gpio_pin_assignment)) {
3686 table->VRHotGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift;
3687 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3688 PHM_PlatformCaps_RegulatorHot);
3689 } else {
3690 table->VRHotGpio = ICELAND_UNUSED_GPIO_PIN;
3691 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3692 PHM_PlatformCaps_RegulatorHot);
3693 }
3694
3695 if (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID,
3696 &gpio_pin_assignment)) {
3697 table->AcDcGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift;
3698 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3699 PHM_PlatformCaps_AutomaticDCTransition);
3700 } else {
3701 table->AcDcGpio = ICELAND_UNUSED_GPIO_PIN;
3702 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3703 PHM_PlatformCaps_AutomaticDCTransition);
3704 }
3705
3706 /*
3707 * If ucGPIO_ID=VDDC_PCC_GPIO_PINID in GPIO_LUTable, Peak.
3708 * Current Control feature is enabled and we should program
3709 * PCC HW register
3710 */
3711 if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_PCC_GPIO_PINID,
3712 &gpio_pin_assignment)) {
3713 uint32_t temp_reg = cgs_read_ind_register(hwmgr->device,
3714 CGS_IND_REG__SMC,
3715 ixCNB_PWRMGT_CNTL);
3716
3717 switch (gpio_pin_assignment.uc_gpio_pin_bit_shift) {
3718 case 0:
3719 temp_reg = PHM_SET_FIELD(temp_reg,
3720 CNB_PWRMGT_CNTL, GNB_SLOW_MODE, 0x1);
3721 break;
3722 case 1:
3723 temp_reg = PHM_SET_FIELD(temp_reg,
3724 CNB_PWRMGT_CNTL, GNB_SLOW_MODE, 0x2);
3725 break;
3726 case 2:
3727 temp_reg = PHM_SET_FIELD(temp_reg,
3728 CNB_PWRMGT_CNTL, GNB_SLOW, 0x1);
3729 break;
3730 case 3:
3731 temp_reg = PHM_SET_FIELD(temp_reg,
3732 CNB_PWRMGT_CNTL, FORCE_NB_PS1, 0x1);
3733 break;
3734 case 4:
3735 temp_reg = PHM_SET_FIELD(temp_reg,
3736 CNB_PWRMGT_CNTL, DPM_ENABLED, 0x1);
3737 break;
3738 default:
3739 pr_warning("[ powerplay ] Failed to setup PCC HW register! Wrong GPIO assigned for VDDC_PCC_GPIO_PINID!\n");
3740 break;
3741 }
3742 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
3743 ixCNB_PWRMGT_CNTL, temp_reg);
3744 }
3745
3746 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3747 PHM_PlatformCaps_EnableSMU7ThermalManagement);
3748 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3749 PHM_PlatformCaps_SMU7);
3750
3751 if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
3752 VOLTAGE_TYPE_VDDC,
3753 VOLTAGE_OBJ_GPIO_LUT))
3754 data->voltage_control = ICELAND_VOLTAGE_CONTROL_BY_GPIO;
3755 else if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
3756 VOLTAGE_TYPE_VDDC,
3757 VOLTAGE_OBJ_SVID2))
3758 data->voltage_control = ICELAND_VOLTAGE_CONTROL_BY_SVID2;
3759
3760 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
3761 PHM_PlatformCaps_ControlVDDCI)) {
3762 if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
3763 VOLTAGE_TYPE_VDDCI,
3764 VOLTAGE_OBJ_GPIO_LUT))
3765 data->vdd_ci_control = ICELAND_VOLTAGE_CONTROL_BY_GPIO;
3766 else if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
3767 VOLTAGE_TYPE_VDDCI,
3768 VOLTAGE_OBJ_SVID2))
3769 data->vdd_ci_control = ICELAND_VOLTAGE_CONTROL_BY_SVID2;
3770 }
3771
3772 if (data->vdd_ci_control == ICELAND_VOLTAGE_CONTROL_NONE)
3773 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3774 PHM_PlatformCaps_ControlVDDCI);
3775
3776 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
3777 PHM_PlatformCaps_EnableMVDDControl)) {
3778 if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
3779 VOLTAGE_TYPE_MVDDC,
3780 VOLTAGE_OBJ_GPIO_LUT))
3781 data->mvdd_control = ICELAND_VOLTAGE_CONTROL_BY_GPIO;
3782 else if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
3783 VOLTAGE_TYPE_MVDDC,
3784 VOLTAGE_OBJ_SVID2))
3785 data->mvdd_control = ICELAND_VOLTAGE_CONTROL_BY_SVID2;
3786 }
3787
3788 if (data->mvdd_control == ICELAND_VOLTAGE_CONTROL_NONE)
3789 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3790 PHM_PlatformCaps_EnableMVDDControl);
3791
3792 data->vddc_phase_shed_control = false;
3793
3794 stay_in_boot = phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
3795 PHM_PlatformCaps_StayInBootState);
3796
3797 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3798 PHM_PlatformCaps_DynamicPowerManagement);
3799
3800 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3801 PHM_PlatformCaps_ActivityReporting);
3802
3803 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3804 PHM_PlatformCaps_GFXClockGatingSupport);
3805
3806 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3807 PHM_PlatformCaps_MemorySpreadSpectrumSupport);
3808 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3809 PHM_PlatformCaps_EngineSpreadSpectrumSupport);
3810
3811 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3812 PHM_PlatformCaps_DynamicPCIEGen2Support);
3813 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3814 PHM_PlatformCaps_SMC);
3815
3816 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3817 PHM_PlatformCaps_DisablePowerGating);
3818 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3819 PHM_PlatformCaps_BACO);
3820
3821 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3822 PHM_PlatformCaps_ThermalAutoThrottling);
3823 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3824 PHM_PlatformCaps_DisableLSClockGating);
3825 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3826 PHM_PlatformCaps_SamuDPM);
3827 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3828 PHM_PlatformCaps_AcpDPM);
3829 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3830 PHM_PlatformCaps_OD6inACSupport);
3831 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3832 PHM_PlatformCaps_EnablePlatformPowerManagement);
3833
3834 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3835 PHM_PlatformCaps_PauseMMSessions);
3836
3837 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3838 PHM_PlatformCaps_OD6PlusinACSupport);
3839 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3840 PHM_PlatformCaps_PauseMMSessions);
3841 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3842 PHM_PlatformCaps_GFXClockGatingManagedInCAIL);
3843 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3844 PHM_PlatformCaps_IcelandULPSSWWorkAround);
3845
3846
3847 /* iceland doesn't support UVD and VCE */
3848 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3849 PHM_PlatformCaps_UVDPowerGating);
3850 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
3851 PHM_PlatformCaps_VCEPowerGating);
3852
3853 sys_info.size = sizeof(struct cgs_system_info);
3854 sys_info.info_id = CGS_SYSTEM_INFO_PG_FLAGS;
3855 result = cgs_query_system_info(hwmgr->device, &sys_info);
3856 if (!result) {
3857 if (sys_info.value & AMD_PG_SUPPORT_UVD)
3858 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3859 PHM_PlatformCaps_UVDPowerGating);
3860 if (sys_info.value & AMD_PG_SUPPORT_VCE)
3861 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
3862 PHM_PlatformCaps_VCEPowerGating);
3863
3864 data->is_tlu_enabled = false;
3865 hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
3866 ICELAND_MAX_HARDWARE_POWERLEVELS;
3867 hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
3868 hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
3869
3870 sys_info.size = sizeof(struct cgs_system_info);
3871 sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO;
3872 result = cgs_query_system_info(hwmgr->device, &sys_info);
3873 if (result)
3874 data->pcie_gen_cap = AMDGPU_DEFAULT_PCIE_GEN_MASK;
3875 else
3876 data->pcie_gen_cap = (uint32_t)sys_info.value;
3877 if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
3878 data->pcie_spc_cap = 20;
3879 sys_info.size = sizeof(struct cgs_system_info);
3880 sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW;
3881 result = cgs_query_system_info(hwmgr->device, &sys_info);
3882 if (result)
3883 data->pcie_lane_cap = AMDGPU_DEFAULT_PCIE_MLW_MASK;
3884 else
3885 data->pcie_lane_cap = (uint32_t)sys_info.value;
3886 } else {
3887 /* Ignore return value in here, we are cleaning up a mess. */
3888 iceland_hwmgr_backend_fini(hwmgr);
3889 }
3890
3891 return 0;
3892failed:
3893 return result;
3894}
3895
3896static int iceland_get_num_of_entries(struct pp_hwmgr *hwmgr)
3897{
3898 int result;
3899 unsigned long ret = 0;
3900
3901 result = pp_tables_get_num_of_entries(hwmgr, &ret);
3902
3903 return result ? 0 : ret;
3904}
3905
3906static const unsigned long PhwIceland_Magic = (unsigned long)(PHM_VIslands_Magic);
3907
3908struct iceland_power_state *cast_phw_iceland_power_state(
3909 struct pp_hw_power_state *hw_ps)
3910{
3911 if (hw_ps == NULL)
3912 return NULL;
3913
3914 PP_ASSERT_WITH_CODE((PhwIceland_Magic == hw_ps->magic),
3915 "Invalid Powerstate Type!",
3916 return NULL);
3917
3918 return (struct iceland_power_state *)hw_ps;
3919}
3920
3921static int iceland_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
3922 struct pp_power_state *prequest_ps,
3923 const struct pp_power_state *pcurrent_ps)
3924{
3925 struct iceland_power_state *iceland_ps =
3926 cast_phw_iceland_power_state(&prequest_ps->hardware);
3927
3928 uint32_t sclk;
3929 uint32_t mclk;
3930 struct PP_Clocks minimum_clocks = {0};
3931 bool disable_mclk_switching;
3932 bool disable_mclk_switching_for_frame_lock;
3933 struct cgs_display_info info = {0};
3934 const struct phm_clock_and_voltage_limits *max_limits;
3935 uint32_t i;
3936 iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
3937
3938 int32_t count;
3939 int32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
3940
3941 data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label);
3942
3943 PP_ASSERT_WITH_CODE(iceland_ps->performance_level_count == 2,
3944 "VI should always have 2 performance levels",
3945 );
3946
3947 max_limits = (PP_PowerSource_AC == hwmgr->power_source) ?
3948 &(hwmgr->dyn_state.max_clock_voltage_on_ac) :
3949 &(hwmgr->dyn_state.max_clock_voltage_on_dc);
3950
3951 if (PP_PowerSource_DC == hwmgr->power_source) {
3952 for (i = 0; i < iceland_ps->performance_level_count; i++) {
3953 if (iceland_ps->performance_levels[i].memory_clock > max_limits->mclk)
3954 iceland_ps->performance_levels[i].memory_clock = max_limits->mclk;
3955 if (iceland_ps->performance_levels[i].engine_clock > max_limits->sclk)
3956 iceland_ps->performance_levels[i].engine_clock = max_limits->sclk;
3957 }
3958 }
3959
3960 iceland_ps->vce_clocks.EVCLK = hwmgr->vce_arbiter.evclk;
3961 iceland_ps->vce_clocks.ECCLK = hwmgr->vce_arbiter.ecclk;
3962
3963 cgs_get_active_displays_info(hwmgr->device, &info);
3964
3965 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) {
3966
3967 max_limits = &(hwmgr->dyn_state.max_clock_voltage_on_ac);
3968 stable_pstate_sclk = (max_limits->sclk * 75) / 100;
3969
3970 for (count = hwmgr->dyn_state.vddc_dependency_on_sclk->count-1; count >= 0; count--) {
3971 if (stable_pstate_sclk >= hwmgr->dyn_state.vddc_dependency_on_sclk->entries[count].clk) {
3972 stable_pstate_sclk = hwmgr->dyn_state.vddc_dependency_on_sclk->entries[count].clk;
3973 break;
3974 }
3975 }
3976
3977 if (count < 0)
3978 stable_pstate_sclk = hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].clk;
3979
3980 stable_pstate_mclk = max_limits->mclk;
3981
3982 minimum_clocks.engineClock = stable_pstate_sclk;
3983 minimum_clocks.memoryClock = stable_pstate_mclk;
3984 }
3985
3986 if (minimum_clocks.engineClock < hwmgr->gfx_arbiter.sclk)
3987 minimum_clocks.engineClock = hwmgr->gfx_arbiter.sclk;
3988
3989 if (minimum_clocks.memoryClock < hwmgr->gfx_arbiter.mclk)
3990 minimum_clocks.memoryClock = hwmgr->gfx_arbiter.mclk;
3991
3992 iceland_ps->sclk_threshold = hwmgr->gfx_arbiter.sclk_threshold;
3993
3994 if (0 != hwmgr->gfx_arbiter.sclk_over_drive) {
3995 PP_ASSERT_WITH_CODE((hwmgr->gfx_arbiter.sclk_over_drive <= hwmgr->platform_descriptor.overdriveLimit.engineClock),
3996 "Overdrive sclk exceeds limit",
3997 hwmgr->gfx_arbiter.sclk_over_drive = hwmgr->platform_descriptor.overdriveLimit.engineClock);
3998
3999 if (hwmgr->gfx_arbiter.sclk_over_drive >= hwmgr->gfx_arbiter.sclk)
4000 iceland_ps->performance_levels[1].engine_clock = hwmgr->gfx_arbiter.sclk_over_drive;
4001 }
4002
4003 if (0 != hwmgr->gfx_arbiter.mclk_over_drive) {
4004 PP_ASSERT_WITH_CODE((hwmgr->gfx_arbiter.mclk_over_drive <= hwmgr->platform_descriptor.overdriveLimit.memoryClock),
4005 "Overdrive mclk exceeds limit",
4006 hwmgr->gfx_arbiter.mclk_over_drive = hwmgr->platform_descriptor.overdriveLimit.memoryClock);
4007
4008 if (hwmgr->gfx_arbiter.mclk_over_drive >= hwmgr->gfx_arbiter.mclk)
4009 iceland_ps->performance_levels[1].memory_clock = hwmgr->gfx_arbiter.mclk_over_drive;
4010 }
4011
4012 disable_mclk_switching_for_frame_lock = phm_cap_enabled(
4013 hwmgr->platform_descriptor.platformCaps,
4014 PHM_PlatformCaps_DisableMclkSwitchingForFrameLock);
4015
4016 disable_mclk_switching = (1 < info.display_count) ||
4017 disable_mclk_switching_for_frame_lock;
4018
4019 sclk = iceland_ps->performance_levels[0].engine_clock;
4020 mclk = iceland_ps->performance_levels[0].memory_clock;
4021
4022 if (disable_mclk_switching)
4023 mclk = iceland_ps->performance_levels[iceland_ps->performance_level_count - 1].memory_clock;
4024
4025 if (sclk < minimum_clocks.engineClock)
4026 sclk = (minimum_clocks.engineClock > max_limits->sclk) ? max_limits->sclk : minimum_clocks.engineClock;
4027
4028 if (mclk < minimum_clocks.memoryClock)
4029 mclk = (minimum_clocks.memoryClock > max_limits->mclk) ? max_limits->mclk : minimum_clocks.memoryClock;
4030
4031 iceland_ps->performance_levels[0].engine_clock = sclk;
4032 iceland_ps->performance_levels[0].memory_clock = mclk;
4033
4034 iceland_ps->performance_levels[1].engine_clock =
4035 (iceland_ps->performance_levels[1].engine_clock >= iceland_ps->performance_levels[0].engine_clock) ?
4036 iceland_ps->performance_levels[1].engine_clock :
4037 iceland_ps->performance_levels[0].engine_clock;
4038
4039 if (disable_mclk_switching) {
4040 if (mclk < iceland_ps->performance_levels[1].memory_clock)
4041 mclk = iceland_ps->performance_levels[1].memory_clock;
4042
4043 iceland_ps->performance_levels[0].memory_clock = mclk;
4044 iceland_ps->performance_levels[1].memory_clock = mclk;
4045 } else {
4046 if (iceland_ps->performance_levels[1].memory_clock < iceland_ps->performance_levels[0].memory_clock)
4047 iceland_ps->performance_levels[1].memory_clock = iceland_ps->performance_levels[0].memory_clock;
4048 }
4049
4050 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) {
4051 for (i=0; i < iceland_ps->performance_level_count; i++) {
4052 iceland_ps->performance_levels[i].engine_clock = stable_pstate_sclk;
4053 iceland_ps->performance_levels[i].memory_clock = stable_pstate_mclk;
4054 iceland_ps->performance_levels[i].pcie_gen = data->pcie_gen_performance.max;
4055 iceland_ps->performance_levels[i].pcie_lane = data->pcie_gen_performance.max;
4056 }
4057 }
4058
4059 return 0;
4060}
4061
4062static bool iceland_is_dpm_running(struct pp_hwmgr *hwmgr)
4063{
4064 /*
4065 * We return the status of Voltage Control instead of checking SCLK/MCLK DPM
4066 * because we may have test scenarios that need us intentionly disable SCLK/MCLK DPM,
4067 * whereas voltage control is a fundemental change that will not be disabled
4068 */
4069 return (0 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
4070 FEATURE_STATUS, VOLTAGE_CONTROLLER_ON) ? 1 : 0);
4071}
4072
4073/**
4074 * force DPM power State
4075 *
4076 * @param hwmgr: the address of the powerplay hardware manager.
4077 * @param n : DPM level
4078 * @return The response that came from the SMC.
4079 */
4080int iceland_dpm_force_state(struct pp_hwmgr *hwmgr, uint32_t n)
4081{
4082 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
4083
4084 /* Checking if DPM is running. If we discover hang because of this, we should skip this message. */
4085 PP_ASSERT_WITH_CODE(0 == iceland_is_dpm_running(hwmgr),
4086 "Trying to force SCLK when DPM is disabled", return -1;);
4087 if (0 == data->sclk_dpm_key_disabled)
4088 return (0 == smum_send_msg_to_smc_with_parameter(
4089 hwmgr->smumgr,
4090 PPSMC_MSG_DPM_ForceState,
4091 n) ? 0 : 1);
4092
4093 return 0;
4094}
4095
4096/**
4097 * force DPM power State
4098 *
4099 * @param hwmgr: the address of the powerplay hardware manager.
4100 * @param n : DPM level
4101 * @return The response that came from the SMC.
4102 */
4103int iceland_dpm_force_state_mclk(struct pp_hwmgr *hwmgr, uint32_t n)
4104{
4105 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
4106
4107 /* Checking if DPM is running. If we discover hang because of this, we should skip this message. */
4108 PP_ASSERT_WITH_CODE(0 == iceland_is_dpm_running(hwmgr),
4109 "Trying to Force MCLK when DPM is disabled", return -1;);
4110 if (0 == data->mclk_dpm_key_disabled)
4111 return (0 == smum_send_msg_to_smc_with_parameter(
4112 hwmgr->smumgr,
4113 PPSMC_MSG_MCLKDPM_ForceState,
4114 n) ? 0 : 1);
4115
4116 return 0;
4117}
4118
4119/**
4120 * force DPM power State
4121 *
4122 * @param hwmgr: the address of the powerplay hardware manager.
4123 * @param n : DPM level
4124 * @return The response that came from the SMC.
4125 */
4126int iceland_dpm_force_state_pcie(struct pp_hwmgr *hwmgr, uint32_t n)
4127{
4128 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
4129
4130 /* Checking if DPM is running. If we discover hang because of this, we should skip this message.*/
4131 PP_ASSERT_WITH_CODE(0 == iceland_is_dpm_running(hwmgr),
4132 "Trying to Force PCIE level when DPM is disabled", return -1;);
4133 if (0 == data->pcie_dpm_key_disabled)
4134 return (0 == smum_send_msg_to_smc_with_parameter(
4135 hwmgr->smumgr,
4136 PPSMC_MSG_PCIeDPM_ForceLevel,
4137 n) ? 0 : 1);
4138
4139 return 0;
4140}
4141
4142static int iceland_force_dpm_highest(struct pp_hwmgr *hwmgr)
4143{
4144 uint32_t level, tmp;
4145 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
4146
4147 if (0 == data->sclk_dpm_key_disabled) {
4148 /* SCLK */
4149 if (data->dpm_level_enable_mask.sclk_dpm_enable_mask != 0) {
4150 level = 0;
4151 tmp = data->dpm_level_enable_mask.sclk_dpm_enable_mask;
4152 while (tmp >>= 1)
4153 level++ ;
4154
4155 if (0 != level) {
4156 PP_ASSERT_WITH_CODE((0 == iceland_dpm_force_state(hwmgr, level)),
4157 "force highest sclk dpm state failed!", return -1);
4158 PHM_WAIT_INDIRECT_FIELD(hwmgr->device,
4159 SMC_IND, TARGET_AND_CURRENT_PROFILE_INDEX, CURR_SCLK_INDEX, level);
4160 }
4161 }
4162 }
4163
4164 if (0 == data->mclk_dpm_key_disabled) {
4165 /* MCLK */
4166 if (data->dpm_level_enable_mask.mclk_dpm_enable_mask != 0) {
4167 level = 0;
4168 tmp = data->dpm_level_enable_mask.mclk_dpm_enable_mask;
4169 while (tmp >>= 1)
4170 level++ ;
4171
4172 if (0 != level) {
4173 PP_ASSERT_WITH_CODE((0 == iceland_dpm_force_state_mclk(hwmgr, level)),
4174 "force highest mclk dpm state failed!", return -1);
4175 PHM_WAIT_INDIRECT_FIELD(hwmgr->device, SMC_IND,
4176 TARGET_AND_CURRENT_PROFILE_INDEX, CURR_MCLK_INDEX, level);
4177 }
4178 }
4179 }
4180
4181 if (0 == data->pcie_dpm_key_disabled) {
4182 /* PCIE */
4183 if (data->dpm_level_enable_mask.pcie_dpm_enable_mask != 0) {
4184 level = 0;
4185 tmp = data->dpm_level_enable_mask.pcie_dpm_enable_mask;
4186 while (tmp >>= 1)
4187 level++ ;
4188
4189 if (0 != level) {
4190 PP_ASSERT_WITH_CODE((0 == iceland_dpm_force_state_pcie(hwmgr, level)),
4191 "force highest pcie dpm state failed!", return -1);
4192 }
4193 }
4194 }
4195
4196 return 0;
4197}
4198
4199static uint32_t iceland_get_lowest_enable_level(struct pp_hwmgr *hwmgr,
4200 uint32_t level_mask)
4201{
4202 uint32_t level = 0;
4203
4204 while (0 == (level_mask & (1 << level)))
4205 level++;
4206
4207 return level;
4208}
4209
4210static int iceland_force_dpm_lowest(struct pp_hwmgr *hwmgr)
4211{
4212 uint32_t level;
4213 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
4214
4215 /* for now force only sclk */
4216 if (0 != data->dpm_level_enable_mask.sclk_dpm_enable_mask) {
4217 level = iceland_get_lowest_enable_level(hwmgr,
4218 data->dpm_level_enable_mask.sclk_dpm_enable_mask);
4219
4220 PP_ASSERT_WITH_CODE((0 == iceland_dpm_force_state(hwmgr, level)),
4221 "force sclk dpm state failed!", return -1);
4222
4223 PHM_WAIT_INDIRECT_FIELD(hwmgr->device, SMC_IND,
4224 TARGET_AND_CURRENT_PROFILE_INDEX,
4225 CURR_SCLK_INDEX,
4226 level);
4227 }
4228
4229 return 0;
4230}
4231
4232int iceland_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
4233{
4234 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
4235
4236 PP_ASSERT_WITH_CODE (0 == iceland_is_dpm_running(hwmgr),
4237 "Trying to Unforce DPM when DPM is disabled. Returning without sending SMC message.",
4238 return -1);
4239
4240 if (0 == data->sclk_dpm_key_disabled) {
4241 PP_ASSERT_WITH_CODE((0 == smum_send_msg_to_smc(
4242 hwmgr->smumgr,
4243 PPSMC_MSG_NoForcedLevel)),
4244 "unforce sclk dpm state failed!",
4245 return -1);
4246 }
4247
4248 if (0 == data->mclk_dpm_key_disabled) {
4249 PP_ASSERT_WITH_CODE((0 == smum_send_msg_to_smc(
4250 hwmgr->smumgr,
4251 PPSMC_MSG_MCLKDPM_NoForcedLevel)),
4252 "unforce mclk dpm state failed!",
4253 return -1);
4254 }
4255
4256 if (0 == data->pcie_dpm_key_disabled) {
4257 PP_ASSERT_WITH_CODE((0 == smum_send_msg_to_smc(
4258 hwmgr->smumgr,
4259 PPSMC_MSG_PCIeDPM_UnForceLevel)),
4260 "unforce pcie level failed!",
4261 return -1);
4262 }
4263
4264 return 0;
4265}
4266
4267static int iceland_force_dpm_level(struct pp_hwmgr *hwmgr,
4268 enum amd_dpm_forced_level level)
4269{
4270 int ret = 0;
4271
4272 switch (level) {
4273 case AMD_DPM_FORCED_LEVEL_HIGH:
4274 ret = iceland_force_dpm_highest(hwmgr);
4275 if (ret)
4276 return ret;
4277 break;
4278 case AMD_DPM_FORCED_LEVEL_LOW:
4279 ret = iceland_force_dpm_lowest(hwmgr);
4280 if (ret)
4281 return ret;
4282 break;
4283 case AMD_DPM_FORCED_LEVEL_AUTO:
4284 ret = iceland_unforce_dpm_levels(hwmgr);
4285 if (ret)
4286 return ret;
4287 break;
4288 default:
4289 break;
4290 }
4291
4292 hwmgr->dpm_level = level;
4293 return ret;
4294}
4295
4296const struct iceland_power_state *cast_const_phw_iceland_power_state(
4297 const struct pp_hw_power_state *hw_ps)
4298{
4299 if (hw_ps == NULL)
4300 return NULL;
4301
4302 PP_ASSERT_WITH_CODE((PhwIceland_Magic == hw_ps->magic),
4303 "Invalid Powerstate Type!",
4304 return NULL);
4305
4306 return (const struct iceland_power_state *)hw_ps;
4307}
4308
4309static int iceland_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
4310{
4311 const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
4312 const struct iceland_power_state *iceland_ps = cast_const_phw_iceland_power_state(states->pnew_state);
4313 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4314 struct iceland_single_dpm_table *psclk_table = &(data->dpm_table.sclk_table);
4315 uint32_t sclk = iceland_ps->performance_levels[iceland_ps->performance_level_count-1].engine_clock;
4316 struct iceland_single_dpm_table *pmclk_table = &(data->dpm_table.mclk_table);
4317 uint32_t mclk = iceland_ps->performance_levels[iceland_ps->performance_level_count-1].memory_clock;
4318 struct PP_Clocks min_clocks = {0};
4319 uint32_t i;
4320 struct cgs_display_info info = {0};
4321
4322 data->need_update_smu7_dpm_table = 0;
4323
4324 for (i = 0; i < psclk_table->count; i++) {
4325 if (sclk == psclk_table->dpm_levels[i].value)
4326 break;
4327 }
4328
4329 if (i >= psclk_table->count)
4330 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
4331 else {
4332 /*
4333 * TODO: Check SCLK in DAL's minimum clocks in case DeepSleep
4334 * divider update is required.
4335 */
4336 if(data->display_timing.min_clock_insr != min_clocks.engineClockInSR)
4337 data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_SCLK;
4338 }
4339
4340 for (i = 0; i < pmclk_table->count; i++) {
4341 if (mclk == pmclk_table->dpm_levels[i].value)
4342 break;
4343 }
4344
4345 if (i >= pmclk_table->count)
4346 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
4347
4348 cgs_get_active_displays_info(hwmgr->device, &info);
4349
4350 if (data->display_timing.num_existing_displays != info.display_count)
4351 data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK;
4352
4353 return 0;
4354}
4355
4356static uint16_t iceland_get_maximum_link_speed(struct pp_hwmgr *hwmgr, const struct iceland_power_state *hw_ps)
4357{
4358 uint32_t i;
4359 uint32_t pcie_speed, max_speed = 0;
4360
4361 for (i = 0; i < hw_ps->performance_level_count; i++) {
4362 pcie_speed = hw_ps->performance_levels[i].pcie_gen;
4363 if (max_speed < pcie_speed)
4364 max_speed = pcie_speed;
4365 }
4366
4367 return max_speed;
4368}
4369
4370static uint16_t iceland_get_current_pcie_speed(struct pp_hwmgr *hwmgr)
4371{
4372 uint32_t speed_cntl = 0;
4373
4374 speed_cntl = cgs_read_ind_register(hwmgr->device,
4375 CGS_IND_REG__PCIE,
4376 ixPCIE_LC_SPEED_CNTL);
4377 return((uint16_t)PHM_GET_FIELD(speed_cntl,
4378 PCIE_LC_SPEED_CNTL, LC_CURRENT_DATA_RATE));
4379}
4380
4381
4382static int iceland_request_link_speed_change_before_state_change(struct pp_hwmgr *hwmgr, const void *input)
4383{
4384 const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
4385 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4386 const struct iceland_power_state *iceland_nps = cast_const_phw_iceland_power_state(states->pnew_state);
4387 const struct iceland_power_state *iceland_cps = cast_const_phw_iceland_power_state(states->pcurrent_state);
4388
4389 uint16_t target_link_speed = iceland_get_maximum_link_speed(hwmgr, iceland_nps);
4390 uint16_t current_link_speed;
4391
4392 if (data->force_pcie_gen == PP_PCIEGenInvalid)
4393 current_link_speed = iceland_get_maximum_link_speed(hwmgr, iceland_cps);
4394 else
4395 current_link_speed = data->force_pcie_gen;
4396
4397 data->force_pcie_gen = PP_PCIEGenInvalid;
4398 data->pspp_notify_required = false;
4399 if (target_link_speed > current_link_speed) {
4400 switch(target_link_speed) {
4401 case PP_PCIEGen3:
4402 if (0 == acpi_pcie_perf_request(hwmgr->device, PCIE_PERF_REQ_GEN3, false))
4403 break;
4404 data->force_pcie_gen = PP_PCIEGen2;
4405 if (current_link_speed == PP_PCIEGen2)
4406 break;
4407 case PP_PCIEGen2:
4408 if (0 == acpi_pcie_perf_request(hwmgr->device, PCIE_PERF_REQ_GEN2, false))
4409 break;
4410 default:
4411 data->force_pcie_gen = iceland_get_current_pcie_speed(hwmgr);
4412 break;
4413 }
4414 } else {
4415 if (target_link_speed < current_link_speed)
4416 data->pspp_notify_required = true;
4417 }
4418
4419 return 0;
4420}
4421
4422static int iceland_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
4423{
4424 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4425
4426 if (0 == data->need_update_smu7_dpm_table)
4427 return 0;
4428
4429 if ((0 == data->sclk_dpm_key_disabled) &&
4430 (data->need_update_smu7_dpm_table &
4431 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) {
4432 PP_ASSERT_WITH_CODE(
4433 0 == iceland_is_dpm_running(hwmgr),
4434 "Trying to freeze SCLK DPM when DPM is disabled",
4435 );
4436 PP_ASSERT_WITH_CODE(
4437 0 == smum_send_msg_to_smc(hwmgr->smumgr,
4438 PPSMC_MSG_SCLKDPM_FreezeLevel),
4439 "Failed to freeze SCLK DPM during FreezeSclkMclkDPM Function!",
4440 return -1);
4441 }
4442
4443 if ((0 == data->mclk_dpm_key_disabled) &&
4444 (data->need_update_smu7_dpm_table &
4445 DPMTABLE_OD_UPDATE_MCLK)) {
4446 PP_ASSERT_WITH_CODE(0 == iceland_is_dpm_running(hwmgr),
4447 "Trying to freeze MCLK DPM when DPM is disabled",
4448 );
4449 PP_ASSERT_WITH_CODE(
4450 0 == smum_send_msg_to_smc(hwmgr->smumgr,
4451 PPSMC_MSG_MCLKDPM_FreezeLevel),
4452 "Failed to freeze MCLK DPM during FreezeSclkMclkDPM Function!",
4453 return -1);
4454 }
4455
4456 return 0;
4457}
4458
4459static int iceland_populate_and_upload_sclk_mclk_dpm_levels(struct pp_hwmgr *hwmgr, const void *input)
4460{
4461 int result = 0;
4462
4463 const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
4464 const struct iceland_power_state *iceland_ps = cast_const_phw_iceland_power_state(states->pnew_state);
4465 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4466 uint32_t sclk = iceland_ps->performance_levels[iceland_ps->performance_level_count-1].engine_clock;
4467 uint32_t mclk = iceland_ps->performance_levels[iceland_ps->performance_level_count-1].memory_clock;
4468 struct iceland_dpm_table *pdpm_table = &data->dpm_table;
4469
4470 struct iceland_dpm_table *pgolden_dpm_table = &data->golden_dpm_table;
4471 uint32_t dpm_count, clock_percent;
4472 uint32_t i;
4473
4474 if (0 == data->need_update_smu7_dpm_table)
4475 return 0;
4476
4477 if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_SCLK) {
4478 pdpm_table->sclk_table.dpm_levels[pdpm_table->sclk_table.count-1].value = sclk;
4479
4480 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinACSupport) ||
4481 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinDCSupport)) {
4482 /*
4483 * Need to do calculation based on the golden DPM table
4484 * as the Heatmap GPU Clock axis is also based on the default values
4485 */
4486 PP_ASSERT_WITH_CODE(
4487 (pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value != 0),
4488 "Divide by 0!",
4489 return -1);
4490 dpm_count = pdpm_table->sclk_table.count < 2 ? 0 : pdpm_table->sclk_table.count-2;
4491 for (i = dpm_count; i > 1; i--) {
4492 if (sclk > pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value) {
4493 clock_percent = ((sclk - pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value)*100) /
4494 pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value;
4495
4496 pdpm_table->sclk_table.dpm_levels[i].value =
4497 pgolden_dpm_table->sclk_table.dpm_levels[i].value +
4498 (pgolden_dpm_table->sclk_table.dpm_levels[i].value * clock_percent)/100;
4499
4500 } else if (pgolden_dpm_table->sclk_table.dpm_levels[pdpm_table->sclk_table.count-1].value > sclk) {
4501 clock_percent = ((pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value - sclk)*100) /
4502 pgolden_dpm_table->sclk_table.dpm_levels[pgolden_dpm_table->sclk_table.count-1].value;
4503
4504 pdpm_table->sclk_table.dpm_levels[i].value =
4505 pgolden_dpm_table->sclk_table.dpm_levels[i].value -
4506 (pgolden_dpm_table->sclk_table.dpm_levels[i].value * clock_percent)/100;
4507 } else
4508 pdpm_table->sclk_table.dpm_levels[i].value =
4509 pgolden_dpm_table->sclk_table.dpm_levels[i].value;
4510 }
4511 }
4512 }
4513
4514 if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK) {
4515 pdpm_table->mclk_table.dpm_levels[pdpm_table->mclk_table.count-1].value = mclk;
4516
4517 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinACSupport) ||
4518 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinDCSupport)) {
4519
4520 PP_ASSERT_WITH_CODE(
4521 (pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value != 0),
4522 "Divide by 0!",
4523 return -1);
4524 dpm_count = pdpm_table->mclk_table.count < 2? 0 : pdpm_table->mclk_table.count-2;
4525 for (i = dpm_count; i > 1; i--) {
4526 if (mclk > pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value) {
4527 clock_percent = ((mclk - pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value)*100) /
4528 pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value;
4529
4530 pdpm_table->mclk_table.dpm_levels[i].value =
4531 pgolden_dpm_table->mclk_table.dpm_levels[i].value +
4532 (pgolden_dpm_table->mclk_table.dpm_levels[i].value * clock_percent)/100;
4533
4534 } else if (pgolden_dpm_table->mclk_table.dpm_levels[pdpm_table->mclk_table.count-1].value > mclk) {
4535 clock_percent = ((pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value - mclk)*100) /
4536 pgolden_dpm_table->mclk_table.dpm_levels[pgolden_dpm_table->mclk_table.count-1].value;
4537
4538 pdpm_table->mclk_table.dpm_levels[i].value =
4539 pgolden_dpm_table->mclk_table.dpm_levels[i].value -
4540 (pgolden_dpm_table->mclk_table.dpm_levels[i].value * clock_percent)/100;
4541 } else
4542 pdpm_table->mclk_table.dpm_levels[i].value = pgolden_dpm_table->mclk_table.dpm_levels[i].value;
4543 }
4544 }
4545 }
4546
4547
4548 if (data->need_update_smu7_dpm_table & (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK)) {
4549 result = iceland_populate_all_graphic_levels(hwmgr);
4550 PP_ASSERT_WITH_CODE((0 == result),
4551 "Failed to populate SCLK during PopulateNewDPMClocksStates Function!",
4552 return result);
4553 }
4554
4555 if (data->need_update_smu7_dpm_table & (DPMTABLE_OD_UPDATE_MCLK + DPMTABLE_UPDATE_MCLK)) {
4556 /*populate MCLK dpm table to SMU7 */
4557 result = iceland_populate_all_memory_levels(hwmgr);
4558 PP_ASSERT_WITH_CODE((0 == result),
4559 "Failed to populate MCLK during PopulateNewDPMClocksStates Function!",
4560 return result);
4561 }
4562
4563 return result;
4564}
4565
4566static int iceland_trim_single_dpm_states(struct pp_hwmgr *hwmgr,
4567 struct iceland_single_dpm_table *pdpm_table,
4568 uint32_t low_limit, uint32_t high_limit)
4569{
4570 uint32_t i;
4571
4572 for (i = 0; i < pdpm_table->count; i++) {
4573 if ((pdpm_table->dpm_levels[i].value < low_limit) ||
4574 (pdpm_table->dpm_levels[i].value > high_limit))
4575 pdpm_table->dpm_levels[i].enabled = false;
4576 else
4577 pdpm_table->dpm_levels[i].enabled = true;
4578 }
4579 return 0;
4580}
4581
4582static int iceland_trim_dpm_states(struct pp_hwmgr *hwmgr, const struct iceland_power_state *hw_state)
4583{
4584 int result = 0;
4585 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4586 uint32_t high_limit_count;
4587
4588 PP_ASSERT_WITH_CODE((hw_state->performance_level_count >= 1),
4589 "power state did not have any performance level",
4590 return -1);
4591
4592 high_limit_count = (1 == hw_state->performance_level_count) ? 0: 1;
4593
4594 iceland_trim_single_dpm_states(hwmgr, &(data->dpm_table.sclk_table),
4595 hw_state->performance_levels[0].engine_clock,
4596 hw_state->performance_levels[high_limit_count].engine_clock);
4597
4598 iceland_trim_single_dpm_states(hwmgr, &(data->dpm_table.mclk_table),
4599 hw_state->performance_levels[0].memory_clock,
4600 hw_state->performance_levels[high_limit_count].memory_clock);
4601
4602 return result;
4603}
4604
4605static int iceland_generate_dpm_level_enable_mask(struct pp_hwmgr *hwmgr, const void *input)
4606{
4607 int result;
4608 const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
4609 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4610 const struct iceland_power_state *iceland_ps = cast_const_phw_iceland_power_state(states->pnew_state);
4611
4612 result = iceland_trim_dpm_states(hwmgr, iceland_ps);
4613 if (0 != result)
4614 return result;
4615
4616 data->dpm_level_enable_mask.sclk_dpm_enable_mask = iceland_get_dpm_level_enable_mask_value(&data->dpm_table.sclk_table);
4617 data->dpm_level_enable_mask.mclk_dpm_enable_mask = iceland_get_dpm_level_enable_mask_value(&data->dpm_table.mclk_table);
4618 data->last_mclk_dpm_enable_mask = data->dpm_level_enable_mask.mclk_dpm_enable_mask;
4619 if (data->uvd_enabled && (data->dpm_level_enable_mask.mclk_dpm_enable_mask & 1))
4620 data->dpm_level_enable_mask.mclk_dpm_enable_mask &= 0xFFFFFFFE;
4621
4622 data->dpm_level_enable_mask.pcie_dpm_enable_mask = iceland_get_dpm_level_enable_mask_value(&data->dpm_table.pcie_speed_table);
4623
4624 return 0;
4625}
4626
4627static int iceland_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input)
4628{
4629 return 0;
4630}
4631
4632int iceland_update_sclk_threshold(struct pp_hwmgr *hwmgr)
4633{
4634 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
4635
4636 int result = 0;
4637 uint32_t low_sclk_interrupt_threshold = 0;
4638
4639 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
4640 PHM_PlatformCaps_SclkThrottleLowNotification)
4641 && (hwmgr->gfx_arbiter.sclk_threshold != data->low_sclk_interrupt_threshold)) {
4642 data->low_sclk_interrupt_threshold = hwmgr->gfx_arbiter.sclk_threshold;
4643 low_sclk_interrupt_threshold = data->low_sclk_interrupt_threshold;
4644
4645 CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold);
4646
4647 result = iceland_copy_bytes_to_smc(
4648 hwmgr->smumgr,
4649 data->dpm_table_start + offsetof(SMU71_Discrete_DpmTable,
4650 LowSclkInterruptThreshold),
4651 (uint8_t *)&low_sclk_interrupt_threshold,
4652 sizeof(uint32_t),
4653 data->sram_end
4654 );
4655 }
4656
4657 return result;
4658}
4659
4660static int iceland_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr)
4661{
4662 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4663
4664 uint32_t address;
4665 int32_t result;
4666
4667 if (0 == (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK))
4668 return 0;
4669
4670
4671 memset(&data->mc_reg_table, 0, sizeof(SMU71_Discrete_MCRegisters));
4672
4673 result = iceland_convert_mc_reg_table_to_smc(hwmgr, &(data->mc_reg_table));
4674
4675 if(result != 0)
4676 return result;
4677
4678
4679 address = data->mc_reg_table_start + (uint32_t)offsetof(SMU71_Discrete_MCRegisters, data[0]);
4680
4681 return iceland_copy_bytes_to_smc(hwmgr->smumgr, address,
4682 (uint8_t *)&data->mc_reg_table.data[0],
4683 sizeof(SMU71_Discrete_MCRegisterSet) * data->dpm_table.mclk_table.count,
4684 data->sram_end);
4685}
4686
4687static int iceland_program_memory_timing_parameters_conditionally(struct pp_hwmgr *hwmgr)
4688{
4689 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4690
4691 if (data->need_update_smu7_dpm_table &
4692 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_OD_UPDATE_MCLK))
4693 return iceland_program_memory_timing_parameters(hwmgr);
4694
4695 return 0;
4696}
4697
4698static int iceland_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
4699{
4700 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4701
4702 if (0 == data->need_update_smu7_dpm_table)
4703 return 0;
4704
4705 if ((0 == data->sclk_dpm_key_disabled) &&
4706 (data->need_update_smu7_dpm_table &
4707 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) {
4708
4709 PP_ASSERT_WITH_CODE(0 == iceland_is_dpm_running(hwmgr),
4710 "Trying to Unfreeze SCLK DPM when DPM is disabled",
4711 );
4712 PP_ASSERT_WITH_CODE(
4713 0 == smum_send_msg_to_smc(hwmgr->smumgr,
4714 PPSMC_MSG_SCLKDPM_UnfreezeLevel),
4715 "Failed to unfreeze SCLK DPM during UnFreezeSclkMclkDPM Function!",
4716 return -1);
4717 }
4718
4719 if ((0 == data->mclk_dpm_key_disabled) &&
4720 (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) {
4721
4722 PP_ASSERT_WITH_CODE(
4723 0 == iceland_is_dpm_running(hwmgr),
4724 "Trying to Unfreeze MCLK DPM when DPM is disabled",
4725 );
4726 PP_ASSERT_WITH_CODE(
4727 0 == smum_send_msg_to_smc(hwmgr->smumgr,
4728 PPSMC_MSG_MCLKDPM_UnfreezeLevel),
4729 "Failed to unfreeze MCLK DPM during UnFreezeSclkMclkDPM Function!",
4730 return -1);
4731 }
4732
4733 data->need_update_smu7_dpm_table = 0;
4734
4735 return 0;
4736}
4737
4738static int iceland_notify_link_speed_change_after_state_change(struct pp_hwmgr *hwmgr, const void *input)
4739{
4740 const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
4741 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4742 const struct iceland_power_state *iceland_ps = cast_const_phw_iceland_power_state(states->pnew_state);
4743 uint16_t target_link_speed = iceland_get_maximum_link_speed(hwmgr, iceland_ps);
4744 uint8_t request;
4745
4746 if (data->pspp_notify_required ||
4747 data->pcie_performance_request) {
4748 if (target_link_speed == PP_PCIEGen3)
4749 request = PCIE_PERF_REQ_GEN3;
4750 else if (target_link_speed == PP_PCIEGen2)
4751 request = PCIE_PERF_REQ_GEN2;
4752 else
4753 request = PCIE_PERF_REQ_GEN1;
4754
4755 if(request == PCIE_PERF_REQ_GEN1 && iceland_get_current_pcie_speed(hwmgr) > 0) {
4756 data->pcie_performance_request = false;
4757 return 0;
4758 }
4759
4760 if (0 != acpi_pcie_perf_request(hwmgr->device, request, false)) {
4761 if (PP_PCIEGen2 == target_link_speed)
4762 printk("PSPP request to switch to Gen2 from Gen3 Failed!");
4763 else
4764 printk("PSPP request to switch to Gen1 from Gen2 Failed!");
4765 }
4766 }
4767
4768 data->pcie_performance_request = false;
4769 return 0;
4770}
4771
4772int iceland_upload_dpm_level_enable_mask(struct pp_hwmgr *hwmgr)
4773{
4774 PPSMC_Result result;
4775 iceland_hwmgr *data = (iceland_hwmgr *)(hwmgr->backend);
4776
4777 if (0 == data->sclk_dpm_key_disabled) {
4778 /* Checking if DPM is running. If we discover hang because of this, we should skip this message.*/
4779 if (0 != iceland_is_dpm_running(hwmgr))
4780 printk(KERN_ERR "[ powerplay ] Trying to set Enable Sclk Mask when DPM is disabled \n");
4781
4782 if (0 != data->dpm_level_enable_mask.sclk_dpm_enable_mask) {
4783 result = smum_send_msg_to_smc_with_parameter(
4784 hwmgr->smumgr,
4785 (PPSMC_Msg)PPSMC_MSG_SCLKDPM_SetEnabledMask,
4786 data->dpm_level_enable_mask.sclk_dpm_enable_mask);
4787 PP_ASSERT_WITH_CODE((0 == result),
4788 "Set Sclk Dpm enable Mask failed", return -1);
4789 }
4790 }
4791
4792 if (0 == data->mclk_dpm_key_disabled) {
4793 /* Checking if DPM is running. If we discover hang because of this, we should skip this message.*/
4794 if (0 != iceland_is_dpm_running(hwmgr))
4795 printk(KERN_ERR "[ powerplay ] Trying to set Enable Mclk Mask when DPM is disabled \n");
4796
4797 if (0 != data->dpm_level_enable_mask.mclk_dpm_enable_mask) {
4798 result = smum_send_msg_to_smc_with_parameter(
4799 hwmgr->smumgr,
4800 (PPSMC_Msg)PPSMC_MSG_MCLKDPM_SetEnabledMask,
4801 data->dpm_level_enable_mask.mclk_dpm_enable_mask);
4802 PP_ASSERT_WITH_CODE((0 == result),
4803 "Set Mclk Dpm enable Mask failed", return -1);
4804 }
4805 }
4806
4807 return 0;
4808}
4809
4810static int iceland_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input)
4811{
4812 int tmp_result, result = 0;
4813
4814 tmp_result = iceland_find_dpm_states_clocks_in_dpm_table(hwmgr, input);
4815 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to find DPM states clocks in DPM table!", result = tmp_result);
4816
4817 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest)) {
4818 tmp_result = iceland_request_link_speed_change_before_state_change(hwmgr, input);
4819 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to request link speed change before state change!", result = tmp_result);
4820 }
4821
4822 tmp_result = iceland_freeze_sclk_mclk_dpm(hwmgr);
4823 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to freeze SCLK MCLK DPM!", result = tmp_result);
4824
4825 tmp_result = iceland_populate_and_upload_sclk_mclk_dpm_levels(hwmgr, input);
4826 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to populate and upload SCLK MCLK DPM levels!", result = tmp_result);
4827
4828 tmp_result = iceland_generate_dpm_level_enable_mask(hwmgr, input);
4829 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to generate DPM level enabled mask!", result = tmp_result);
4830
4831 tmp_result = iceland_update_vce_dpm(hwmgr, input);
4832 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to update VCE DPM!", result = tmp_result);
4833
4834 tmp_result = iceland_update_sclk_threshold(hwmgr);
4835 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to update SCLK threshold!", result = tmp_result);
4836
4837 tmp_result = iceland_update_and_upload_mc_reg_table(hwmgr);
4838 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to upload MC reg table!", result = tmp_result);
4839
4840 tmp_result = iceland_program_memory_timing_parameters_conditionally(hwmgr);
4841 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to program memory timing parameters!", result = tmp_result);
4842
4843 tmp_result = iceland_unfreeze_sclk_mclk_dpm(hwmgr);
4844 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to unfreeze SCLK MCLK DPM!", result = tmp_result);
4845
4846 tmp_result = iceland_upload_dpm_level_enable_mask(hwmgr);
4847 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to upload DPM level enabled mask!", result = tmp_result);
4848
4849 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest)) {
4850 tmp_result = iceland_notify_link_speed_change_after_state_change(hwmgr, input);
4851 PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to notify link speed change after state change!", result = tmp_result);
4852 }
4853
4854 return result;
4855}
4856
4857static int iceland_get_power_state_size(struct pp_hwmgr *hwmgr)
4858{
4859 return sizeof(struct iceland_power_state);
4860}
4861
4862static int iceland_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
4863{
4864 struct pp_power_state *ps;
4865 struct iceland_power_state *iceland_ps;
4866
4867 if (hwmgr == NULL)
4868 return -EINVAL;
4869
4870 ps = hwmgr->request_ps;
4871
4872 if (ps == NULL)
4873 return -EINVAL;
4874
4875 iceland_ps = cast_phw_iceland_power_state(&ps->hardware);
4876
4877 if (low)
4878 return iceland_ps->performance_levels[0].memory_clock;
4879 else
4880 return iceland_ps->performance_levels[iceland_ps->performance_level_count-1].memory_clock;
4881}
4882
4883static int iceland_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low)
4884{
4885 struct pp_power_state *ps;
4886 struct iceland_power_state *iceland_ps;
4887
4888 if (hwmgr == NULL)
4889 return -EINVAL;
4890
4891 ps = hwmgr->request_ps;
4892
4893 if (ps == NULL)
4894 return -EINVAL;
4895
4896 iceland_ps = cast_phw_iceland_power_state(&ps->hardware);
4897
4898 if (low)
4899 return iceland_ps->performance_levels[0].engine_clock;
4900 else
4901 return iceland_ps->performance_levels[iceland_ps->performance_level_count-1].engine_clock;
4902}
4903
4904static int iceland_get_current_pcie_lane_number(
4905 struct pp_hwmgr *hwmgr)
4906{
4907 uint32_t link_width;
4908
4909 link_width = PHM_READ_INDIRECT_FIELD(hwmgr->device,
4910 CGS_IND_REG__PCIE,
4911 PCIE_LC_LINK_WIDTH_CNTL,
4912 LC_LINK_WIDTH_RD);
4913
4914 PP_ASSERT_WITH_CODE((7 >= link_width),
4915 "Invalid PCIe lane width!", return 0);
4916
4917 return decode_pcie_lane_width(link_width);
4918}
4919
4920static int iceland_dpm_patch_boot_state(struct pp_hwmgr *hwmgr,
4921 struct pp_hw_power_state *hw_ps)
4922{
4923 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4924 struct iceland_power_state *ps = (struct iceland_power_state *)hw_ps;
4925 ATOM_FIRMWARE_INFO_V2_2 *fw_info;
4926 uint16_t size;
4927 uint8_t frev, crev;
4928 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
4929
4930 /* First retrieve the Boot clocks and VDDC from the firmware info table.
4931 * We assume here that fw_info is unchanged if this call fails.
4932 */
4933 fw_info = (ATOM_FIRMWARE_INFO_V2_2 *)cgs_atom_get_data_table(
4934 hwmgr->device, index,
4935 &size, &frev, &crev);
4936 if (!fw_info)
4937 /* During a test, there is no firmware info table. */
4938 return 0;
4939
4940 /* Patch the state. */
4941 data->vbios_boot_state.sclk_bootup_value = le32_to_cpu(fw_info->ulDefaultEngineClock);
4942 data->vbios_boot_state.mclk_bootup_value = le32_to_cpu(fw_info->ulDefaultMemoryClock);
4943 data->vbios_boot_state.mvdd_bootup_value = le16_to_cpu(fw_info->usBootUpMVDDCVoltage);
4944 data->vbios_boot_state.vddc_bootup_value = le16_to_cpu(fw_info->usBootUpVDDCVoltage);
4945 data->vbios_boot_state.vddci_bootup_value = le16_to_cpu(fw_info->usBootUpVDDCIVoltage);
4946 data->vbios_boot_state.pcie_gen_bootup_value = iceland_get_current_pcie_speed(hwmgr);
4947 data->vbios_boot_state.pcie_lane_bootup_value =
4948 (uint16_t)iceland_get_current_pcie_lane_number(hwmgr);
4949
4950 /* set boot power state */
4951 ps->performance_levels[0].memory_clock = data->vbios_boot_state.mclk_bootup_value;
4952 ps->performance_levels[0].engine_clock = data->vbios_boot_state.sclk_bootup_value;
4953 ps->performance_levels[0].pcie_gen = data->vbios_boot_state.pcie_gen_bootup_value;
4954 ps->performance_levels[0].pcie_lane = data->vbios_boot_state.pcie_lane_bootup_value;
4955
4956 return 0;
4957}
4958
4959static int iceland_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
4960 struct pp_hw_power_state *power_state,
4961 unsigned int index, const void *clock_info)
4962{
4963 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
4964 struct iceland_power_state *iceland_power_state = cast_phw_iceland_power_state(power_state);
4965 const ATOM_PPLIB_CI_CLOCK_INFO *visland_clk_info = clock_info;
4966 struct iceland_performance_level *performance_level;
4967 uint32_t engine_clock, memory_clock;
4968 uint16_t pcie_gen_from_bios;
4969
4970 engine_clock = visland_clk_info->ucEngineClockHigh << 16 | visland_clk_info->usEngineClockLow;
4971 memory_clock = visland_clk_info->ucMemoryClockHigh << 16 | visland_clk_info->usMemoryClockLow;
4972
4973 if (!(data->mc_micro_code_feature & DISABLE_MC_LOADMICROCODE) && memory_clock > data->highest_mclk)
4974 data->highest_mclk = memory_clock;
4975
4976 performance_level = &(iceland_power_state->performance_levels
4977 [iceland_power_state->performance_level_count++]);
4978
4979 PP_ASSERT_WITH_CODE(
4980 (iceland_power_state->performance_level_count < SMU71_MAX_LEVELS_GRAPHICS),
4981 "Performance levels exceeds SMC limit!",
4982 return -1);
4983
4984 PP_ASSERT_WITH_CODE(
4985 (iceland_power_state->performance_level_count <=
4986 hwmgr->platform_descriptor.hardwareActivityPerformanceLevels),
4987 "Performance levels exceeds Driver limit!",
4988 return -1);
4989
4990 /* Performance levels are arranged from low to high. */
4991 performance_level->memory_clock = memory_clock;
4992 performance_level->engine_clock = engine_clock;
4993
4994 pcie_gen_from_bios = visland_clk_info->ucPCIEGen;
4995
4996 performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, pcie_gen_from_bios);
4997 performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, visland_clk_info->usPCIELane);
4998
4999 return 0;
5000}
5001
5002static int iceland_get_pp_table_entry(struct pp_hwmgr *hwmgr,
5003 unsigned long entry_index, struct pp_power_state *state)
5004{
5005 int result;
5006 struct iceland_power_state *ps;
5007 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5008 struct phm_clock_voltage_dependency_table *dep_mclk_table =
5009 hwmgr->dyn_state.vddci_dependency_on_mclk;
5010
5011 memset(&state->hardware, 0x00, sizeof(struct pp_hw_power_state));
5012
5013 state->hardware.magic = PHM_VIslands_Magic;
5014
5015 ps = (struct iceland_power_state *)(&state->hardware);
5016
5017 result = pp_tables_get_entry(hwmgr, entry_index, state,
5018 iceland_get_pp_table_entry_callback_func);
5019
5020 /*
5021 * This is the earliest time we have all the dependency table
5022 * and the VBIOS boot state as
5023 * PP_Tables_GetPowerPlayTableEntry retrieves the VBIOS boot
5024 * state if there is only one VDDCI/MCLK level, check if it's
5025 * the same as VBIOS boot state
5026 */
5027 if (dep_mclk_table != NULL && dep_mclk_table->count == 1) {
5028 if (dep_mclk_table->entries[0].clk !=
5029 data->vbios_boot_state.mclk_bootup_value)
5030 printk(KERN_ERR "Single MCLK entry VDDCI/MCLK dependency table "
5031 "does not match VBIOS boot MCLK level");
5032 if (dep_mclk_table->entries[0].v !=
5033 data->vbios_boot_state.vddci_bootup_value)
5034 printk(KERN_ERR "Single VDDCI entry VDDCI/MCLK dependency table "
5035 "does not match VBIOS boot VDDCI level");
5036 }
5037
5038 /* set DC compatible flag if this state supports DC */
5039 if (!state->validation.disallowOnDC)
5040 ps->dc_compatible = true;
5041
5042 if (state->classification.flags & PP_StateClassificationFlag_ACPI)
5043 data->acpi_pcie_gen = ps->performance_levels[0].pcie_gen;
5044 else if (0 != (state->classification.flags & PP_StateClassificationFlag_Boot)) {
5045 if (data->bacos.best_match == 0xffff) {
5046 /* For C.I. use boot state as base BACO state */
5047 data->bacos.best_match = PP_StateClassificationFlag_Boot;
5048 data->bacos.performance_level = ps->performance_levels[0];
5049 }
5050 }
5051
5052
5053 ps->uvd_clocks.VCLK = state->uvd_clocks.VCLK;
5054 ps->uvd_clocks.DCLK = state->uvd_clocks.DCLK;
5055
5056 if (!result) {
5057 uint32_t i;
5058
5059 switch (state->classification.ui_label) {
5060 case PP_StateUILabel_Performance:
5061 data->use_pcie_performance_levels = true;
5062
5063 for (i = 0; i < ps->performance_level_count; i++) {
5064 if (data->pcie_gen_performance.max <
5065 ps->performance_levels[i].pcie_gen)
5066 data->pcie_gen_performance.max =
5067 ps->performance_levels[i].pcie_gen;
5068
5069 if (data->pcie_gen_performance.min >
5070 ps->performance_levels[i].pcie_gen)
5071 data->pcie_gen_performance.min =
5072 ps->performance_levels[i].pcie_gen;
5073
5074 if (data->pcie_lane_performance.max <
5075 ps->performance_levels[i].pcie_lane)
5076 data->pcie_lane_performance.max =
5077 ps->performance_levels[i].pcie_lane;
5078
5079 if (data->pcie_lane_performance.min >
5080 ps->performance_levels[i].pcie_lane)
5081 data->pcie_lane_performance.min =
5082 ps->performance_levels[i].pcie_lane;
5083 }
5084 break;
5085 case PP_StateUILabel_Battery:
5086 data->use_pcie_power_saving_levels = true;
5087
5088 for (i = 0; i < ps->performance_level_count; i++) {
5089 if (data->pcie_gen_power_saving.max <
5090 ps->performance_levels[i].pcie_gen)
5091 data->pcie_gen_power_saving.max =
5092 ps->performance_levels[i].pcie_gen;
5093
5094 if (data->pcie_gen_power_saving.min >
5095 ps->performance_levels[i].pcie_gen)
5096 data->pcie_gen_power_saving.min =
5097 ps->performance_levels[i].pcie_gen;
5098
5099 if (data->pcie_lane_power_saving.max <
5100 ps->performance_levels[i].pcie_lane)
5101 data->pcie_lane_power_saving.max =
5102 ps->performance_levels[i].pcie_lane;
5103
5104 if (data->pcie_lane_power_saving.min >
5105 ps->performance_levels[i].pcie_lane)
5106 data->pcie_lane_power_saving.min =
5107 ps->performance_levels[i].pcie_lane;
5108 }
5109 break;
5110 default:
5111 break;
5112 }
5113 }
5114 return 0;
5115}
5116
5117static void
5118iceland_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m)
5119{
5120 uint32_t sclk, mclk, activity_percent;
5121 uint32_t offset;
5122 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5123
5124 smum_send_msg_to_smc(hwmgr->smumgr, (PPSMC_Msg)(PPSMC_MSG_API_GetSclkFrequency));
5125
5126 sclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
5127
5128 smum_send_msg_to_smc(hwmgr->smumgr, (PPSMC_Msg)(PPSMC_MSG_API_GetMclkFrequency));
5129
5130 mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
5131 seq_printf(m, "\n [ mclk ]: %u MHz\n\n [ sclk ]: %u MHz\n", mclk/100, sclk/100);
5132
5133 offset = data->soft_regs_start + offsetof(SMU71_SoftRegisters, AverageGraphicsActivity);
5134 activity_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset);
5135 activity_percent += 0x80;
5136 activity_percent >>= 8;
5137
5138 seq_printf(m, "\n [GPU load]: %u%%\n\n", activity_percent > 100 ? 100 : activity_percent);
5139
5140 seq_printf(m, "uvd %sabled\n", data->uvd_power_gated ? "dis" : "en");
5141
5142 seq_printf(m, "vce %sabled\n", data->vce_power_gated ? "dis" : "en");
5143}
5144
5145int iceland_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr)
5146{
5147 uint32_t num_active_displays = 0;
5148 struct cgs_display_info info = {0};
5149 info.mode_info = NULL;
5150
5151 cgs_get_active_displays_info(hwmgr->device, &info);
5152
5153 num_active_displays = info.display_count;
5154
5155 if (num_active_displays > 1) /* to do && (pHwMgr->pPECI->displayConfiguration.bMultiMonitorInSync != TRUE)) */
5156 iceland_notify_smc_display_change(hwmgr, false);
5157 else
5158 iceland_notify_smc_display_change(hwmgr, true);
5159
5160 return 0;
5161}
5162
5163/**
5164* Programs the display gap
5165*
5166* @param hwmgr the address of the powerplay hardware manager.
5167* @return always OK
5168*/
5169int iceland_program_display_gap(struct pp_hwmgr *hwmgr)
5170{
5171 uint32_t num_active_displays = 0;
5172 uint32_t display_gap = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL);
5173 uint32_t display_gap2;
5174 uint32_t pre_vbi_time_in_us;
5175 uint32_t frame_time_in_us;
5176 uint32_t ref_clock;
5177 uint32_t refresh_rate = 0;
5178 struct cgs_display_info info = {0};
5179 struct cgs_mode_info mode_info;
5180
5181 info.mode_info = &mode_info;
5182
5183 cgs_get_active_displays_info(hwmgr->device, &info);
5184 num_active_displays = info.display_count;
5185
5186 display_gap = PHM_SET_FIELD(display_gap, CG_DISPLAY_GAP_CNTL, DISP_GAP, (num_active_displays > 0)? DISPLAY_GAP_VBLANK_OR_WM : DISPLAY_GAP_IGNORE);
5187 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL, display_gap);
5188
5189 ref_clock = mode_info.ref_clock;
5190 refresh_rate = mode_info.refresh_rate;
5191
5192 if(0 == refresh_rate)
5193 refresh_rate = 60;
5194
5195 frame_time_in_us = 1000000 / refresh_rate;
5196
5197 pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us;
5198 display_gap2 = pre_vbi_time_in_us * (ref_clock / 100);
5199
5200 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL2, display_gap2);
5201
5202 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SOFT_REGISTERS_TABLE_4, PreVBlankGap, 0x64);
5203
5204 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SOFT_REGISTERS_TABLE_5, VBlankTimeout, (frame_time_in_us - pre_vbi_time_in_us));
5205
5206 if (num_active_displays == 1)
5207 iceland_notify_smc_display_change(hwmgr, true);
5208
5209 return 0;
5210}
5211
5212int iceland_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
5213{
5214 iceland_program_display_gap(hwmgr);
5215
5216 return 0;
5217}
5218
5219/**
5220* Set maximum target operating fan output PWM
5221*
5222* @param pHwMgr: the address of the powerplay hardware manager.
5223* @param usMaxFanPwm: max operating fan PWM in percents
5224* @return The response that came from the SMC.
5225*/
5226static int iceland_set_max_fan_pwm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_pwm)
5227{
5228 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanPWM = us_max_fan_pwm;
5229
5230 if (phm_is_hw_access_blocked(hwmgr))
5231 return 0;
5232
5233 return (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanPwmMax, us_max_fan_pwm) ? 0 : -1);
5234}
5235
5236/**
5237* Set maximum target operating fan output RPM
5238*
5239* @param pHwMgr: the address of the powerplay hardware manager.
5240* @param usMaxFanRpm: max operating fan RPM value.
5241* @return The response that came from the SMC.
5242*/
5243static int iceland_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_pwm)
5244{
5245 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM = us_max_fan_pwm;
5246
5247 if (phm_is_hw_access_blocked(hwmgr))
5248 return 0;
5249
5250 return (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanRpmMax, us_max_fan_pwm) ? 0 : -1);
5251}
5252
5253static int iceland_dpm_set_interrupt_state(void *private_data,
5254 unsigned src_id, unsigned type,
5255 int enabled)
5256{
5257 uint32_t cg_thermal_int;
5258 struct pp_hwmgr *hwmgr = ((struct pp_eventmgr *)private_data)->hwmgr;
5259
5260 if (hwmgr == NULL)
5261 return -EINVAL;
5262
5263 switch (type) {
5264 case AMD_THERMAL_IRQ_LOW_TO_HIGH:
5265 if (enabled) {
5266 cg_thermal_int = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT);
5267 cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK;
5268 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
5269 } else {
5270 cg_thermal_int = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT);
5271 cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK;
5272 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
5273 }
5274 break;
5275
5276 case AMD_THERMAL_IRQ_HIGH_TO_LOW:
5277 if (enabled) {
5278 cg_thermal_int = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT);
5279 cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK;
5280 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
5281 } else {
5282 cg_thermal_int = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT);
5283 cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK;
5284 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_THERMAL_INT, cg_thermal_int);
5285 }
5286 break;
5287 default:
5288 break;
5289 }
5290 return 0;
5291}
5292
5293static int iceland_register_internal_thermal_interrupt(struct pp_hwmgr *hwmgr,
5294 const void *thermal_interrupt_info)
5295{
5296 int result;
5297 const struct pp_interrupt_registration_info *info =
5298 (const struct pp_interrupt_registration_info *)thermal_interrupt_info;
5299
5300 if (info == NULL)
5301 return -EINVAL;
5302
5303 result = cgs_add_irq_source(hwmgr->device, 230, AMD_THERMAL_IRQ_LAST,
5304 iceland_dpm_set_interrupt_state,
5305 info->call_back, info->context);
5306
5307 if (result)
5308 return -EINVAL;
5309
5310 result = cgs_add_irq_source(hwmgr->device, 231, AMD_THERMAL_IRQ_LAST,
5311 iceland_dpm_set_interrupt_state,
5312 info->call_back, info->context);
5313
5314 if (result)
5315 return -EINVAL;
5316
5317 return 0;
5318}
5319
5320
5321static bool iceland_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
5322{
5323 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5324 bool is_update_required = false;
5325 struct cgs_display_info info = {0,0,NULL};
5326
5327 cgs_get_active_displays_info(hwmgr->device, &info);
5328
5329 if (data->display_timing.num_existing_displays != info.display_count)
5330 is_update_required = true;
5331/* TO DO NEED TO GET DEEP SLEEP CLOCK FROM DAL
5332 if (phm_cap_enabled(hwmgr->hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
5333 cgs_get_min_clock_settings(hwmgr->device, &min_clocks);
5334 if(min_clocks.engineClockInSR != data->display_timing.minClockInSR)
5335 is_update_required = true;
5336*/
5337 return is_update_required;
5338}
5339
5340
5341static inline bool iceland_are_power_levels_equal(const struct iceland_performance_level *pl1,
5342 const struct iceland_performance_level *pl2)
5343{
5344 return ((pl1->memory_clock == pl2->memory_clock) &&
5345 (pl1->engine_clock == pl2->engine_clock) &&
5346 (pl1->pcie_gen == pl2->pcie_gen) &&
5347 (pl1->pcie_lane == pl2->pcie_lane));
5348}
5349
5350int iceland_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1,
5351 const struct pp_hw_power_state *pstate2, bool *equal)
5352{
5353 const struct iceland_power_state *psa = cast_const_phw_iceland_power_state(pstate1);
5354 const struct iceland_power_state *psb = cast_const_phw_iceland_power_state(pstate2);
5355 int i;
5356
5357 if (equal == NULL || psa == NULL || psb == NULL)
5358 return -EINVAL;
5359
5360 /* If the two states don't even have the same number of performance levels they cannot be the same state. */
5361 if (psa->performance_level_count != psb->performance_level_count) {
5362 *equal = false;
5363 return 0;
5364 }
5365
5366 for (i = 0; i < psa->performance_level_count; i++) {
5367 if (!iceland_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) {
5368 /* If we have found even one performance level pair that is different the states are different. */
5369 *equal = false;
5370 return 0;
5371 }
5372 }
5373
5374 /* If all performance levels are the same try to use the UVD clocks to break the tie.*/
5375 *equal = ((psa->uvd_clocks.VCLK == psb->uvd_clocks.VCLK) && (psa->uvd_clocks.DCLK == psb->uvd_clocks.DCLK));
5376 *equal &= ((psa->vce_clocks.EVCLK == psb->vce_clocks.EVCLK) && (psa->vce_clocks.ECCLK == psb->vce_clocks.ECCLK));
5377 *equal &= (psa->sclk_threshold == psb->sclk_threshold);
5378 *equal &= (psa->acp_clk == psb->acp_clk);
5379
5380 return 0;
5381}
5382
5383static int iceland_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
5384{
5385 if (mode) {
5386 /* stop auto-manage */
5387 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
5388 PHM_PlatformCaps_MicrocodeFanControl))
5389 iceland_fan_ctrl_stop_smc_fan_control(hwmgr);
5390 iceland_fan_ctrl_set_static_mode(hwmgr, mode);
5391 } else
5392 /* restart auto-manage */
5393 iceland_fan_ctrl_reset_fan_speed_to_default(hwmgr);
5394
5395 return 0;
5396}
5397
5398static int iceland_get_fan_control_mode(struct pp_hwmgr *hwmgr)
5399{
5400 if (hwmgr->fan_ctrl_is_in_default_mode)
5401 return hwmgr->fan_ctrl_default_mode;
5402 else
5403 return PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
5404 CG_FDO_CTRL2, FDO_PWM_MODE);
5405}
5406
5407static int iceland_force_clock_level(struct pp_hwmgr *hwmgr,
5408 enum pp_clock_type type, uint32_t mask)
5409{
5410 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5411
5412 if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
5413 return -EINVAL;
5414
5415 switch (type) {
5416 case PP_SCLK:
5417 if (!data->sclk_dpm_key_disabled)
5418 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
5419 PPSMC_MSG_SCLKDPM_SetEnabledMask,
5420 data->dpm_level_enable_mask.sclk_dpm_enable_mask & mask);
5421 break;
5422 case PP_MCLK:
5423 if (!data->mclk_dpm_key_disabled)
5424 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
5425 PPSMC_MSG_MCLKDPM_SetEnabledMask,
5426 data->dpm_level_enable_mask.mclk_dpm_enable_mask & mask);
5427 break;
5428 case PP_PCIE:
5429 {
5430 uint32_t tmp = mask & data->dpm_level_enable_mask.pcie_dpm_enable_mask;
5431 uint32_t level = 0;
5432
5433 while (tmp >>= 1)
5434 level++;
5435
5436 if (!data->pcie_dpm_key_disabled)
5437 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
5438 PPSMC_MSG_PCIeDPM_ForceLevel,
5439 level);
5440 break;
5441 }
5442 default:
5443 break;
5444 }
5445
5446 return 0;
5447}
5448
5449static int iceland_print_clock_levels(struct pp_hwmgr *hwmgr,
5450 enum pp_clock_type type, char *buf)
5451{
5452 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5453 struct iceland_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
5454 struct iceland_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
5455 struct iceland_single_dpm_table *pcie_table = &(data->dpm_table.pcie_speed_table);
5456 int i, now, size = 0;
5457 uint32_t clock, pcie_speed;
5458
5459 switch (type) {
5460 case PP_SCLK:
5461 smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency);
5462 clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
5463
5464 for (i = 0; i < sclk_table->count; i++) {
5465 if (clock > sclk_table->dpm_levels[i].value)
5466 continue;
5467 break;
5468 }
5469 now = i;
5470
5471 for (i = 0; i < sclk_table->count; i++)
5472 size += sprintf(buf + size, "%d: %uMhz %s\n",
5473 i, sclk_table->dpm_levels[i].value / 100,
5474 (i == now) ? "*" : "");
5475 break;
5476 case PP_MCLK:
5477 smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency);
5478 clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
5479
5480 for (i = 0; i < mclk_table->count; i++) {
5481 if (clock > mclk_table->dpm_levels[i].value)
5482 continue;
5483 break;
5484 }
5485 now = i;
5486
5487 for (i = 0; i < mclk_table->count; i++)
5488 size += sprintf(buf + size, "%d: %uMhz %s\n",
5489 i, mclk_table->dpm_levels[i].value / 100,
5490 (i == now) ? "*" : "");
5491 break;
5492 case PP_PCIE:
5493 pcie_speed = iceland_get_current_pcie_speed(hwmgr);
5494 for (i = 0; i < pcie_table->count; i++) {
5495 if (pcie_speed != pcie_table->dpm_levels[i].value)
5496 continue;
5497 break;
5498 }
5499 now = i;
5500
5501 for (i = 0; i < pcie_table->count; i++)
5502 size += sprintf(buf + size, "%d: %s %s\n", i,
5503 (pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x8" :
5504 (pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" :
5505 (pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "",
5506 (i == now) ? "*" : "");
5507 break;
5508 default:
5509 break;
5510 }
5511 return size;
5512}
5513
5514static int iceland_get_sclk_od(struct pp_hwmgr *hwmgr)
5515{
5516 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5517 struct iceland_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
5518 struct iceland_single_dpm_table *golden_sclk_table =
5519 &(data->golden_dpm_table.sclk_table);
5520 int value;
5521
5522 value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
5523 golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) *
5524 100 /
5525 golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
5526
5527 return value;
5528}
5529
5530static int iceland_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
5531{
5532 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5533 struct iceland_single_dpm_table *golden_sclk_table =
5534 &(data->golden_dpm_table.sclk_table);
5535 struct pp_power_state *ps;
5536 struct iceland_power_state *iceland_ps;
5537
5538 if (value > 20)
5539 value = 20;
5540
5541 ps = hwmgr->request_ps;
5542
5543 if (ps == NULL)
5544 return -EINVAL;
5545
5546 iceland_ps = cast_phw_iceland_power_state(&ps->hardware);
5547
5548 iceland_ps->performance_levels[iceland_ps->performance_level_count - 1].engine_clock =
5549 golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value *
5550 value / 100 +
5551 golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
5552
5553 return 0;
5554}
5555
5556static int iceland_get_mclk_od(struct pp_hwmgr *hwmgr)
5557{
5558 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5559 struct iceland_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
5560 struct iceland_single_dpm_table *golden_mclk_table =
5561 &(data->golden_dpm_table.mclk_table);
5562 int value;
5563
5564 value = (mclk_table->dpm_levels[mclk_table->count - 1].value -
5565 golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) *
5566 100 /
5567 golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value;
5568
5569 return value;
5570}
5571
5572uint32_t iceland_get_xclk(struct pp_hwmgr *hwmgr)
5573{
5574 uint32_t reference_clock;
5575 uint32_t tc;
5576 uint32_t divide;
5577
5578 ATOM_FIRMWARE_INFO *fw_info;
5579 uint16_t size;
5580 uint8_t frev, crev;
5581 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
5582
5583 tc = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_CLKPIN_CNTL_2, MUX_TCLK_TO_XCLK);
5584
5585 if (tc)
5586 return TCLK;
5587
5588 fw_info = (ATOM_FIRMWARE_INFO *)cgs_atom_get_data_table(hwmgr->device, index,
5589 &size, &frev, &crev);
5590
5591 if (!fw_info)
5592 return 0;
5593
5594 reference_clock = le16_to_cpu(fw_info->usReferenceClock);
5595
5596 divide = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_CLKPIN_CNTL, XTALIN_DIVIDE);
5597
5598 if (0 != divide)
5599 return reference_clock / 4;
5600
5601 return reference_clock;
5602}
5603
5604static int iceland_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
5605{
5606 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
5607 struct iceland_single_dpm_table *golden_mclk_table =
5608 &(data->golden_dpm_table.mclk_table);
5609 struct pp_power_state *ps;
5610 struct iceland_power_state *iceland_ps;
5611
5612 if (value > 20)
5613 value = 20;
5614
5615 ps = hwmgr->request_ps;
5616
5617 if (ps == NULL)
5618 return -EINVAL;
5619
5620 iceland_ps = cast_phw_iceland_power_state(&ps->hardware);
5621
5622 iceland_ps->performance_levels[iceland_ps->performance_level_count - 1].memory_clock =
5623 golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value *
5624 value / 100 +
5625 golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value;
5626
5627 return 0;
5628}
5629
5630static const struct pp_hwmgr_func iceland_hwmgr_funcs = {
5631 .backend_init = &iceland_hwmgr_backend_init,
5632 .backend_fini = &iceland_hwmgr_backend_fini,
5633 .asic_setup = &iceland_setup_asic_task,
5634 .dynamic_state_management_enable = &iceland_enable_dpm_tasks,
5635 .apply_state_adjust_rules = iceland_apply_state_adjust_rules,
5636 .force_dpm_level = &iceland_force_dpm_level,
5637 .power_state_set = iceland_set_power_state_tasks,
5638 .get_power_state_size = iceland_get_power_state_size,
5639 .get_mclk = iceland_dpm_get_mclk,
5640 .get_sclk = iceland_dpm_get_sclk,
5641 .patch_boot_state = iceland_dpm_patch_boot_state,
5642 .get_pp_table_entry = iceland_get_pp_table_entry,
5643 .get_num_of_pp_table_entries = iceland_get_num_of_entries,
5644 .print_current_perforce_level = iceland_print_current_perforce_level,
5645 .powerdown_uvd = iceland_phm_powerdown_uvd,
5646 .powergate_uvd = iceland_phm_powergate_uvd,
5647 .powergate_vce = iceland_phm_powergate_vce,
5648 .disable_clock_power_gating = iceland_phm_disable_clock_power_gating,
5649 .update_clock_gatings = iceland_phm_update_clock_gatings,
5650 .notify_smc_display_config_after_ps_adjustment = iceland_notify_smc_display_config_after_ps_adjustment,
5651 .display_config_changed = iceland_display_configuration_changed_task,
5652 .set_max_fan_pwm_output = iceland_set_max_fan_pwm_output,
5653 .set_max_fan_rpm_output = iceland_set_max_fan_rpm_output,
5654 .get_temperature = iceland_thermal_get_temperature,
5655 .stop_thermal_controller = iceland_thermal_stop_thermal_controller,
5656 .get_fan_speed_info = iceland_fan_ctrl_get_fan_speed_info,
5657 .get_fan_speed_percent = iceland_fan_ctrl_get_fan_speed_percent,
5658 .set_fan_speed_percent = iceland_fan_ctrl_set_fan_speed_percent,
5659 .reset_fan_speed_to_default = iceland_fan_ctrl_reset_fan_speed_to_default,
5660 .get_fan_speed_rpm = iceland_fan_ctrl_get_fan_speed_rpm,
5661 .set_fan_speed_rpm = iceland_fan_ctrl_set_fan_speed_rpm,
5662 .uninitialize_thermal_controller = iceland_thermal_ctrl_uninitialize_thermal_controller,
5663 .register_internal_thermal_interrupt = iceland_register_internal_thermal_interrupt,
5664 .check_smc_update_required_for_display_configuration = iceland_check_smc_update_required_for_display_configuration,
5665 .check_states_equal = iceland_check_states_equal,
5666 .set_fan_control_mode = iceland_set_fan_control_mode,
5667 .get_fan_control_mode = iceland_get_fan_control_mode,
5668 .force_clock_level = iceland_force_clock_level,
5669 .print_clock_levels = iceland_print_clock_levels,
5670 .get_sclk_od = iceland_get_sclk_od,
5671 .set_sclk_od = iceland_set_sclk_od,
5672 .get_mclk_od = iceland_get_mclk_od,
5673 .set_mclk_od = iceland_set_mclk_od,
5674};
5675
5676int iceland_hwmgr_init(struct pp_hwmgr *hwmgr)
5677{
5678 iceland_hwmgr *data;
5679
5680 data = kzalloc (sizeof(iceland_hwmgr), GFP_KERNEL);
5681 if (data == NULL)
5682 return -ENOMEM;
5683 memset(data, 0x00, sizeof(iceland_hwmgr));
5684
5685 hwmgr->backend = data;
5686 hwmgr->hwmgr_func = &iceland_hwmgr_funcs;
5687 hwmgr->pptable_func = &pptable_funcs;
5688
5689 /* thermal */
5690 pp_iceland_thermal_initialize(hwmgr);
5691 return 0;
5692}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.h
new file mode 100644
index 000000000000..f253988de2d2
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_hwmgr.h
@@ -0,0 +1,424 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25#ifndef ICELAND_HWMGR_H
26#define ICELAND_HWMGR_H
27
28#include "hwmgr.h"
29#include "ppatomctrl.h"
30#include "ppinterrupt.h"
31#include "ppsmc.h"
32#include "iceland_powertune.h"
33#include "pp_endian.h"
34#include "smu71_discrete.h"
35
36#define ICELAND_MAX_HARDWARE_POWERLEVELS 2
37#define ICELAND_DYNCLK_NUMBER_OF_TREND_COEFFICIENTS 15
38
39struct iceland_performance_level {
40 uint32_t memory_clock;
41 uint32_t engine_clock;
42 uint16_t pcie_gen;
43 uint16_t pcie_lane;
44};
45
46struct _phw_iceland_bacos {
47 uint32_t best_match;
48 uint32_t baco_flags;
49 struct iceland_performance_level performance_level;
50};
51typedef struct _phw_iceland_bacos phw_iceland_bacos;
52
53struct _phw_iceland_uvd_clocks {
54 uint32_t VCLK;
55 uint32_t DCLK;
56};
57
58typedef struct _phw_iceland_uvd_clocks phw_iceland_uvd_clocks;
59
60struct _phw_iceland_vce_clocks {
61 uint32_t EVCLK;
62 uint32_t ECCLK;
63};
64
65typedef struct _phw_iceland_vce_clocks phw_iceland_vce_clocks;
66
67struct iceland_power_state {
68 uint32_t magic;
69 phw_iceland_uvd_clocks uvd_clocks;
70 phw_iceland_vce_clocks vce_clocks;
71 uint32_t sam_clk;
72 uint32_t acp_clk;
73 uint16_t performance_level_count;
74 bool dc_compatible;
75 uint32_t sclk_threshold;
76 struct iceland_performance_level performance_levels[ICELAND_MAX_HARDWARE_POWERLEVELS];
77};
78
79struct _phw_iceland_dpm_level {
80 bool enabled;
81 uint32_t value;
82 uint32_t param1;
83};
84typedef struct _phw_iceland_dpm_level phw_iceland_dpm_level;
85
86#define ICELAND_MAX_DEEPSLEEP_DIVIDER_ID 5
87#define MAX_REGULAR_DPM_NUMBER 8
88#define ICELAND_MINIMUM_ENGINE_CLOCK 5000
89
90struct iceland_single_dpm_table {
91 uint32_t count;
92 phw_iceland_dpm_level dpm_levels[MAX_REGULAR_DPM_NUMBER];
93};
94
95struct iceland_dpm_table {
96 struct iceland_single_dpm_table sclk_table;
97 struct iceland_single_dpm_table mclk_table;
98 struct iceland_single_dpm_table pcie_speed_table;
99 struct iceland_single_dpm_table vddc_table;
100 struct iceland_single_dpm_table vdd_gfx_table;
101 struct iceland_single_dpm_table vdd_ci_table;
102 struct iceland_single_dpm_table mvdd_table;
103};
104typedef struct _phw_iceland_dpm_table phw_iceland_dpm_table;
105
106
107struct _phw_iceland_clock_regisiters {
108 uint32_t vCG_SPLL_FUNC_CNTL;
109 uint32_t vCG_SPLL_FUNC_CNTL_2;
110 uint32_t vCG_SPLL_FUNC_CNTL_3;
111 uint32_t vCG_SPLL_FUNC_CNTL_4;
112 uint32_t vCG_SPLL_SPREAD_SPECTRUM;
113 uint32_t vCG_SPLL_SPREAD_SPECTRUM_2;
114 uint32_t vDLL_CNTL;
115 uint32_t vMCLK_PWRMGT_CNTL;
116 uint32_t vMPLL_AD_FUNC_CNTL;
117 uint32_t vMPLL_DQ_FUNC_CNTL;
118 uint32_t vMPLL_FUNC_CNTL;
119 uint32_t vMPLL_FUNC_CNTL_1;
120 uint32_t vMPLL_FUNC_CNTL_2;
121 uint32_t vMPLL_SS1;
122 uint32_t vMPLL_SS2;
123};
124typedef struct _phw_iceland_clock_regisiters phw_iceland_clock_registers;
125
126struct _phw_iceland_voltage_smio_registers {
127 uint32_t vs0_vid_lower_smio_cntl;
128};
129typedef struct _phw_iceland_voltage_smio_registers phw_iceland_voltage_smio_registers;
130
131
132struct _phw_iceland_mc_reg_entry {
133 uint32_t mclk_max;
134 uint32_t mc_data[SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE];
135};
136typedef struct _phw_iceland_mc_reg_entry phw_iceland_mc_reg_entry;
137
138struct _phw_iceland_mc_reg_table {
139 uint8_t last; /* number of registers*/
140 uint8_t num_entries; /* number of entries in mc_reg_table_entry used*/
141 uint16_t validflag; /* indicate the corresponding register is valid or not. 1: valid, 0: invalid. bit0->address[0], bit1->address[1], etc.*/
142 phw_iceland_mc_reg_entry mc_reg_table_entry[MAX_AC_TIMING_ENTRIES];
143 SMU71_Discrete_MCRegisterAddress mc_reg_address[SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE];
144};
145typedef struct _phw_iceland_mc_reg_table phw_iceland_mc_reg_table;
146
147#define DISABLE_MC_LOADMICROCODE 1
148#define DISABLE_MC_CFGPROGRAMMING 2
149
150
151/*Ultra Low Voltage parameter structure */
152struct phw_iceland_ulv_parm{
153 bool ulv_supported;
154 uint32_t ch_ulv_parameter;
155 uint32_t ulv_volt_change_delay;
156 struct iceland_performance_level ulv_power_level;
157};
158
159#define ICELAND_MAX_LEAKAGE_COUNT 8
160
161struct phw_iceland_leakage_voltage {
162 uint16_t count;
163 uint16_t leakage_id[ICELAND_MAX_LEAKAGE_COUNT];
164 uint16_t actual_voltage[ICELAND_MAX_LEAKAGE_COUNT];
165};
166
167struct _phw_iceland_display_timing {
168 uint32_t min_clock_insr;
169 uint32_t num_existing_displays;
170};
171typedef struct _phw_iceland_display_timing phw_iceland_display_timing;
172
173
174struct phw_iceland_thermal_temperature_setting
175{
176 long temperature_low;
177 long temperature_high;
178 long temperature_shutdown;
179};
180
181struct _phw_iceland_dpmlevel_enable_mask {
182 uint32_t uvd_dpm_enable_mask;
183 uint32_t vce_dpm_enable_mask;
184 uint32_t acp_dpm_enable_mask;
185 uint32_t samu_dpm_enable_mask;
186 uint32_t sclk_dpm_enable_mask;
187 uint32_t mclk_dpm_enable_mask;
188 uint32_t pcie_dpm_enable_mask;
189};
190typedef struct _phw_iceland_dpmlevel_enable_mask phw_iceland_dpmlevel_enable_mask;
191
192struct _phw_iceland_pcie_perf_range {
193 uint16_t max;
194 uint16_t min;
195};
196typedef struct _phw_iceland_pcie_perf_range phw_iceland_pcie_perf_range;
197
198struct _phw_iceland_vbios_boot_state {
199 uint16_t mvdd_bootup_value;
200 uint16_t vddc_bootup_value;
201 uint16_t vddci_bootup_value;
202 uint16_t vddgfx_bootup_value;
203 uint32_t sclk_bootup_value;
204 uint32_t mclk_bootup_value;
205 uint16_t pcie_gen_bootup_value;
206 uint16_t pcie_lane_bootup_value;
207};
208typedef struct _phw_iceland_vbios_boot_state phw_iceland_vbios_boot_state;
209
210#define DPMTABLE_OD_UPDATE_SCLK 0x00000001
211#define DPMTABLE_OD_UPDATE_MCLK 0x00000002
212#define DPMTABLE_UPDATE_SCLK 0x00000004
213#define DPMTABLE_UPDATE_MCLK 0x00000008
214
215/* We need to review which fields are needed. */
216/* This is mostly a copy of the RV7xx/Evergreen structure which is close, but not identical to the N.Islands one. */
217struct iceland_hwmgr {
218 struct iceland_dpm_table dpm_table;
219 struct iceland_dpm_table golden_dpm_table;
220
221 uint32_t voting_rights_clients0;
222 uint32_t voting_rights_clients1;
223 uint32_t voting_rights_clients2;
224 uint32_t voting_rights_clients3;
225 uint32_t voting_rights_clients4;
226 uint32_t voting_rights_clients5;
227 uint32_t voting_rights_clients6;
228 uint32_t voting_rights_clients7;
229 uint32_t static_screen_threshold_unit;
230 uint32_t static_screen_threshold;
231 uint32_t voltage_control;
232 uint32_t vdd_gfx_control;
233
234 uint32_t vddc_vddci_delta;
235 uint32_t vddc_vddgfx_delta;
236
237 struct pp_interrupt_registration_info internal_high_thermal_interrupt_info;
238 struct pp_interrupt_registration_info internal_low_thermal_interrupt_info;
239 struct pp_interrupt_registration_info smc_to_host_interrupt_info;
240 uint32_t active_auto_throttle_sources;
241
242 struct pp_interrupt_registration_info external_throttle_interrupt;
243 irq_handler_func_t external_throttle_callback;
244 void *external_throttle_context;
245
246 struct pp_interrupt_registration_info ctf_interrupt_info;
247 irq_handler_func_t ctf_callback;
248 void *ctf_context;
249
250 phw_iceland_clock_registers clock_registers;
251 phw_iceland_voltage_smio_registers voltage_smio_registers;
252
253 bool is_memory_GDDR5;
254 uint16_t acpi_vddc;
255 bool pspp_notify_required; /* Flag to indicate if PSPP notification to SBIOS is required */
256 uint16_t force_pcie_gen; /* The forced PCI-E speed if not 0xffff */
257 uint16_t acpi_pcie_gen; /* The PCI-E speed at ACPI time */
258 uint32_t pcie_gen_cap; /* The PCI-E speed capabilities bitmap from CAIL */
259 uint32_t pcie_lane_cap; /* The PCI-E lane capabilities bitmap from CAIL */
260 uint32_t pcie_spc_cap; /* Symbol Per Clock Capabilities from registry */
261 struct phw_iceland_leakage_voltage vddc_leakage; /* The Leakage VDDC supported (based on leakage ID).*/
262 struct phw_iceland_leakage_voltage vddcgfx_leakage; /* The Leakage VDDC supported (based on leakage ID). */
263 struct phw_iceland_leakage_voltage vddci_leakage; /* The Leakage VDDCI supported (based on leakage ID). */
264
265 uint32_t mvdd_control;
266 uint32_t vddc_mask_low;
267 uint32_t mvdd_mask_low;
268 uint16_t max_vddc_in_pp_table; /* the maximum VDDC value in the powerplay table*/
269 uint16_t min_vddc_in_pp_table;
270 uint16_t max_vddci_in_pp_table; /* the maximum VDDCI value in the powerplay table */
271 uint16_t min_vddci_in_pp_table;
272 uint32_t mclk_strobe_mode_threshold;
273 uint32_t mclk_stutter_mode_threshold;
274 uint32_t mclk_edc_enable_threshold;
275 uint32_t mclk_edc_wr_enable_threshold;
276 bool is_uvd_enabled;
277 bool is_xdma_enabled;
278 phw_iceland_vbios_boot_state vbios_boot_state;
279
280 bool battery_state;
281 bool is_tlu_enabled;
282 bool pcie_performance_request;
283
284 /* -------------- SMC SRAM Address of firmware header tables ----------------*/
285 uint32_t sram_end; /* The first address after the SMC SRAM. */
286 uint32_t dpm_table_start; /* The start of the dpm table in the SMC SRAM. */
287 uint32_t soft_regs_start; /* The start of the soft registers in the SMC SRAM. */
288 uint32_t mc_reg_table_start; /* The start of the mc register table in the SMC SRAM. */
289 uint32_t fan_table_start; /* The start of the fan table in the SMC SRAM. */
290 uint32_t arb_table_start; /* The start of the ARB setting table in the SMC SRAM. */
291 uint32_t ulv_settings_start;
292 SMU71_Discrete_DpmTable smc_state_table; /* The carbon copy of the SMC state table. */
293 SMU71_Discrete_MCRegisters mc_reg_table;
294 SMU71_Discrete_Ulv ulv_setting; /* The carbon copy of ULV setting. */
295
296 /* -------------- Stuff originally coming from Evergreen --------------------*/
297 phw_iceland_mc_reg_table iceland_mc_reg_table;
298 uint32_t vdd_ci_control;
299 pp_atomctrl_voltage_table vddc_voltage_table;
300 pp_atomctrl_voltage_table vddci_voltage_table;
301 pp_atomctrl_voltage_table vddgfx_voltage_table;
302 pp_atomctrl_voltage_table mvdd_voltage_table;
303
304 uint32_t mgcg_cgtt_local2;
305 uint32_t mgcg_cgtt_local3;
306 uint32_t gpio_debug;
307 uint32_t mc_micro_code_feature;
308 uint32_t highest_mclk;
309 uint16_t acpi_vdd_ci;
310 uint8_t mvdd_high_index;
311 uint8_t mvdd_low_index;
312 bool dll_defaule_on;
313 bool performance_request_registered;
314
315 /* ----------------- Low Power Features ---------------------*/
316 phw_iceland_bacos bacos;
317 struct phw_iceland_ulv_parm ulv;
318
319 /* ----------------- CAC Stuff ---------------------*/
320 uint32_t cac_table_start;
321 bool cac_configuration_required; /* TRUE if PP_CACConfigurationRequired == 1 */
322 bool driver_calculate_cac_leakage; /* TRUE if PP_DriverCalculateCACLeakage == 1 */
323 bool cac_enabled;
324
325 /* ----------------- DPM2 Parameters ---------------------*/
326 uint32_t power_containment_features;
327 bool enable_bapm_feature;
328 bool enable_dte_feature;
329 bool enable_tdc_limit_feature;
330 bool enable_pkg_pwr_tracking_feature;
331 bool disable_uvd_power_tune_feature;
332 struct iceland_pt_defaults *power_tune_defaults;
333 SMU71_Discrete_PmFuses power_tune_table;
334 uint32_t ul_dte_tj_offset; /* Fudge factor in DPM table to correct HW DTE errors */
335 uint32_t fast_watermark_threshold; /* use fast watermark if clock is equal or above this. In percentage of the target high sclk. */
336
337 /* ----------------- Phase Shedding ---------------------*/
338 bool vddc_phase_shed_control;
339
340 /* --------------------- DI/DT --------------------------*/
341 phw_iceland_display_timing display_timing;
342
343 /* --------- ReadRegistry data for memory and engine clock margins ---- */
344 uint32_t engine_clock_data;
345 uint32_t memory_clock_data;
346
347 /* -------- Thermal Temperature Setting --------------*/
348 struct phw_iceland_thermal_temperature_setting thermal_temp_setting;
349 phw_iceland_dpmlevel_enable_mask dpm_level_enable_mask;
350
351 uint32_t need_update_smu7_dpm_table;
352 uint32_t sclk_dpm_key_disabled;
353 uint32_t mclk_dpm_key_disabled;
354 uint32_t pcie_dpm_key_disabled;
355 /* used to store the previous dal min sclock */
356 uint32_t min_engine_clocks;
357 phw_iceland_pcie_perf_range pcie_gen_performance;
358 phw_iceland_pcie_perf_range pcie_lane_performance;
359 phw_iceland_pcie_perf_range pcie_gen_power_saving;
360 phw_iceland_pcie_perf_range pcie_lane_power_saving;
361 bool use_pcie_performance_levels;
362 bool use_pcie_power_saving_levels;
363 /* percentage value from 0-100, default 50 */
364 uint32_t activity_target[SMU71_MAX_LEVELS_GRAPHICS];
365 uint32_t mclk_activity_target;
366 uint32_t low_sclk_interrupt_threshold;
367 uint32_t last_mclk_dpm_enable_mask;
368 bool uvd_enabled;
369 uint32_t pcc_monitor_enabled;
370
371 /* --------- Power Gating States ------------*/
372 bool uvd_power_gated; /* 1: gated, 0:not gated */
373 bool vce_power_gated; /* 1: gated, 0:not gated */
374 bool samu_power_gated; /* 1: gated, 0:not gated */
375 bool acp_power_gated; /* 1: gated, 0:not gated */
376 bool pg_acp_init;
377
378 /* soft pptable for re-uploading into smu */
379 void *soft_pp_table;
380};
381
382typedef struct iceland_hwmgr iceland_hwmgr;
383
384int iceland_hwmgr_init(struct pp_hwmgr *hwmgr);
385int iceland_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate);
386uint32_t iceland_get_xclk(struct pp_hwmgr *hwmgr);
387int iceland_populate_bapm_vddc_vid_sidd(struct pp_hwmgr *hwmgr);
388int iceland_populate_vddc_vid(struct pp_hwmgr *hwmgr);
389
390#define ICELAND_DPM2_NEAR_TDP_DEC 10
391#define ICELAND_DPM2_ABOVE_SAFE_INC 5
392#define ICELAND_DPM2_BELOW_SAFE_INC 20
393
394/*
395 * Log2 of the LTA window size (l2numWin_TDP). Eg. If LTA windows size
396 * is 128, then this value should be Log2(128) = 7.
397 */
398#define ICELAND_DPM2_LTA_WINDOW_SIZE 7
399
400#define ICELAND_DPM2_LTS_TRUNCATE 0
401
402#define ICELAND_DPM2_TDP_SAFE_LIMIT_PERCENT 80 // Maximum 100
403
404#define ICELAND_DPM2_MAXPS_PERCENT_H 90 // Maximum 0xFF
405#define ICELAND_DPM2_MAXPS_PERCENT_M 90 // Maximum 0xFF
406
407#define ICELAND_DPM2_PWREFFICIENCYRATIO_MARGIN 50
408
409#define ICELAND_DPM2_SQ_RAMP_MAX_POWER 0x3FFF
410#define ICELAND_DPM2_SQ_RAMP_MIN_POWER 0x12
411#define ICELAND_DPM2_SQ_RAMP_MAX_POWER_DELTA 0x15
412#define ICELAND_DPM2_SQ_RAMP_SHORT_TERM_INTERVAL_SIZE 0x1E
413#define ICELAND_DPM2_SQ_RAMP_LONG_TERM_INTERVAL_RATIO 0xF
414
415#define ICELAND_VOLTAGE_CONTROL_NONE 0x0
416#define ICELAND_VOLTAGE_CONTROL_BY_GPIO 0x1
417#define ICELAND_VOLTAGE_CONTROL_BY_SVID2 0x2
418
419/* convert to Q8.8 format for firmware */
420#define ICELAND_Q88_FORMAT_CONVERSION_UNIT 256
421
422#define ICELAND_UNUSED_GPIO_PIN 0x7F
423
424#endif
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.c
new file mode 100644
index 000000000000..041e9648e592
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.c
@@ -0,0 +1,490 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25
26#include "amdgpu.h"
27#include "hwmgr.h"
28#include "smumgr.h"
29#include "iceland_hwmgr.h"
30#include "iceland_powertune.h"
31#include "iceland_smumgr.h"
32#include "smu71_discrete.h"
33#include "smu71.h"
34#include "pp_debug.h"
35#include "cgs_common.h"
36#include "pp_endian.h"
37
38#include "bif/bif_5_0_d.h"
39#include "bif/bif_5_0_sh_mask.h"
40
41#define VOLTAGE_SCALE 4
42#define POWERTUNE_DEFAULT_SET_MAX 1
43
44#define DEVICE_ID_VI_ICELAND_M_6900 0x6900
45#define DEVICE_ID_VI_ICELAND_M_6901 0x6901
46#define DEVICE_ID_VI_ICELAND_M_6902 0x6902
47#define DEVICE_ID_VI_ICELAND_M_6903 0x6903
48
49
50struct iceland_pt_defaults defaults_iceland =
51{
52 /*
53 * sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc,
54 * TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT
55 */
56 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000,
57 { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61 },
58 { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 }
59};
60
61/* 35W - XT, XTL */
62struct iceland_pt_defaults defaults_icelandxt =
63{
64 /*
65 * sviLoadLIneEn, SviLoadLineVddC,
66 * TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt,
67 * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac,
68 * BAPM_TEMP_GRADIENT
69 */
70 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0x0,
71 { 0xA7, 0x0, 0x0, 0xB5, 0x0, 0x0, 0x9F, 0x0, 0x0, 0xD6, 0x0, 0x0, 0xD7, 0x0, 0x0},
72 { 0x1EA, 0x0, 0x0, 0x224, 0x0, 0x0, 0x25E, 0x0, 0x0, 0x28E, 0x0, 0x0, 0x2AB, 0x0, 0x0}
73};
74
75/* 25W - PRO, LE */
76struct iceland_pt_defaults defaults_icelandpro =
77{
78 /*
79 * sviLoadLIneEn, SviLoadLineVddC,
80 * TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt,
81 * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac,
82 * BAPM_TEMP_GRADIENT
83 */
84 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0x0,
85 { 0xB7, 0x0, 0x0, 0xC3, 0x0, 0x0, 0xB5, 0x0, 0x0, 0xEA, 0x0, 0x0, 0xE6, 0x0, 0x0},
86 { 0x1EA, 0x0, 0x0, 0x224, 0x0, 0x0, 0x25E, 0x0, 0x0, 0x28E, 0x0, 0x0, 0x2AB, 0x0, 0x0}
87};
88
89void iceland_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
90{
91 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
92 uint32_t tmp = 0;
93 struct cgs_system_info sys_info = {0};
94 uint32_t pdev_id;
95
96 sys_info.size = sizeof(struct cgs_system_info);
97 sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV;
98 cgs_query_system_info(hwmgr->device, &sys_info);
99 pdev_id = (uint32_t)sys_info.value;
100
101 switch (pdev_id) {
102 case DEVICE_ID_VI_ICELAND_M_6900:
103 case DEVICE_ID_VI_ICELAND_M_6903:
104 data->power_tune_defaults = &defaults_icelandxt;
105 break;
106
107 case DEVICE_ID_VI_ICELAND_M_6901:
108 case DEVICE_ID_VI_ICELAND_M_6902:
109 data->power_tune_defaults = &defaults_icelandpro;
110 break;
111 default:
112 /* TODO: need to assign valid defaults */
113 data->power_tune_defaults = &defaults_iceland;
114 pr_warning("Unknown V.I. Device ID.\n");
115 break;
116 }
117
118 /* Assume disabled */
119 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
120 PHM_PlatformCaps_PowerContainment);
121 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
122 PHM_PlatformCaps_CAC);
123 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
124 PHM_PlatformCaps_SQRamping);
125 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
126 PHM_PlatformCaps_DBRamping);
127 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
128 PHM_PlatformCaps_TDRamping);
129 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
130 PHM_PlatformCaps_TCPRamping);
131
132 data->ul_dte_tj_offset = tmp;
133
134 if (!tmp) {
135 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
136 PHM_PlatformCaps_CAC);
137
138 data->fast_watermark_threshold = 100;
139
140 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
141 PHM_PlatformCaps_PowerContainment)) {
142 tmp = 1;
143 data->enable_dte_feature = tmp ? false : true;
144 data->enable_tdc_limit_feature = tmp ? true : false;
145 data->enable_pkg_pwr_tracking_feature = tmp ? true : false;
146 }
147 }
148}
149
150int iceland_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr)
151{
152 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
153 struct iceland_pt_defaults *defaults = data->power_tune_defaults;
154 SMU71_Discrete_DpmTable *dpm_table = &(data->smc_state_table);
155 struct phm_cac_tdp_table *cac_dtp_table = hwmgr->dyn_state.cac_dtp_table;
156 struct phm_ppm_table *ppm = hwmgr->dyn_state.ppm_parameter_table;
157 uint16_t *def1, *def2;
158 int i, j, k;
159
160 /*
161 * TDP number of fraction bits are changed from 8 to 7 for Iceland
162 * as requested by SMC team
163 */
164 dpm_table->DefaultTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usTDP * 256));
165 dpm_table->TargetTdp = PP_HOST_TO_SMC_US((uint16_t)(cac_dtp_table->usConfigurableTDP * 256));
166
167 dpm_table->DTETjOffset = (uint8_t)data->ul_dte_tj_offset;
168
169 dpm_table->GpuTjMax = (uint8_t)(data->thermal_temp_setting.temperature_high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES);
170 dpm_table->GpuTjHyst = 8;
171
172 dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base;
173
174 /* The following are for new Iceland Multi-input fan/thermal control */
175 if(NULL != ppm) {
176 dpm_table->PPM_PkgPwrLimit = (uint16_t)ppm->dgpu_tdp * 256 / 1000;
177 dpm_table->PPM_TemperatureLimit = (uint16_t)ppm->tj_max * 256;
178 } else {
179 dpm_table->PPM_PkgPwrLimit = 0;
180 dpm_table->PPM_TemperatureLimit = 0;
181 }
182
183 CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_PkgPwrLimit);
184 CONVERT_FROM_HOST_TO_SMC_US(dpm_table->PPM_TemperatureLimit);
185
186 dpm_table->BAPM_TEMP_GRADIENT = PP_HOST_TO_SMC_UL(defaults->bamp_temp_gradient);
187 def1 = defaults->bapmti_r;
188 def2 = defaults->bapmti_rc;
189
190 for (i = 0; i < SMU71_DTE_ITERATIONS; i++) {
191 for (j = 0; j < SMU71_DTE_SOURCES; j++) {
192 for (k = 0; k < SMU71_DTE_SINKS; k++) {
193 dpm_table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*def1);
194 dpm_table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*def2);
195 def1++;
196 def2++;
197 }
198 }
199 }
200
201 return 0;
202}
203
204static int iceland_populate_svi_load_line(struct pp_hwmgr *hwmgr)
205{
206 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
207 const struct iceland_pt_defaults *defaults = data->power_tune_defaults;
208
209 data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en;
210 data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddc;
211 data->power_tune_table.SviLoadLineTrimVddC = 3;
212 data->power_tune_table.SviLoadLineOffsetVddC = 0;
213
214 return 0;
215}
216
217static int iceland_populate_tdc_limit(struct pp_hwmgr *hwmgr)
218{
219 uint16_t tdc_limit;
220 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
221 const struct iceland_pt_defaults *defaults = data->power_tune_defaults;
222
223 /* TDC number of fraction bits are changed from 8 to 7
224 * for Iceland as requested by SMC team
225 */
226 tdc_limit = (uint16_t)(hwmgr->dyn_state.cac_dtp_table->usTDC * 256);
227 data->power_tune_table.TDC_VDDC_PkgLimit =
228 CONVERT_FROM_HOST_TO_SMC_US(tdc_limit);
229 data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc =
230 defaults->tdc_vddc_throttle_release_limit_perc;
231 data->power_tune_table.TDC_MAWt = defaults->tdc_mawt;
232
233 return 0;
234}
235
236static int iceland_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset)
237{
238 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
239 const struct iceland_pt_defaults *defaults = data->power_tune_defaults;
240 uint32_t temp;
241
242 if (iceland_read_smc_sram_dword(hwmgr->smumgr,
243 fuse_table_offset +
244 offsetof(SMU71_Discrete_PmFuses, TdcWaterfallCtl),
245 (uint32_t *)&temp, data->sram_end))
246 PP_ASSERT_WITH_CODE(false,
247 "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!",
248 return -EINVAL);
249 else
250 data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl;
251
252 return 0;
253}
254
255static int iceland_populate_temperature_scaler(struct pp_hwmgr *hwmgr)
256{
257 return 0;
258}
259
260static int iceland_populate_gnb_lpml(struct pp_hwmgr *hwmgr)
261{
262 int i;
263 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
264
265 /* Currently not used. Set all to zero. */
266 for (i = 0; i < 8; i++)
267 data->power_tune_table.GnbLPML[i] = 0;
268
269 return 0;
270}
271
272static int iceland_min_max_vgnb_lpml_id_from_bapm_vddc(struct pp_hwmgr *hwmgr)
273{
274 return 0;
275}
276
277static int iceland_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr)
278{
279 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
280 uint16_t HiSidd = data->power_tune_table.BapmVddCBaseLeakageHiSidd;
281 uint16_t LoSidd = data->power_tune_table.BapmVddCBaseLeakageLoSidd;
282 struct phm_cac_tdp_table *cac_table = hwmgr->dyn_state.cac_dtp_table;
283
284 HiSidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256);
285 LoSidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256);
286
287 data->power_tune_table.BapmVddCBaseLeakageHiSidd =
288 CONVERT_FROM_HOST_TO_SMC_US(HiSidd);
289 data->power_tune_table.BapmVddCBaseLeakageLoSidd =
290 CONVERT_FROM_HOST_TO_SMC_US(LoSidd);
291
292 return 0;
293}
294
295int iceland_populate_pm_fuses(struct pp_hwmgr *hwmgr)
296{
297 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
298 uint32_t pm_fuse_table_offset;
299
300 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
301 PHM_PlatformCaps_PowerContainment)) {
302 if (iceland_read_smc_sram_dword(hwmgr->smumgr,
303 SMU71_FIRMWARE_HEADER_LOCATION +
304 offsetof(SMU71_Firmware_Header, PmFuseTable),
305 &pm_fuse_table_offset, data->sram_end))
306 PP_ASSERT_WITH_CODE(false,
307 "Attempt to get pm_fuse_table_offset Failed!",
308 return -EINVAL);
309
310 /* DW0 - DW3 */
311 if (iceland_populate_bapm_vddc_vid_sidd(hwmgr))
312 PP_ASSERT_WITH_CODE(false,
313 "Attempt to populate bapm vddc vid Failed!",
314 return -EINVAL);
315
316 /* DW4 - DW5 */
317 if (iceland_populate_vddc_vid(hwmgr))
318 PP_ASSERT_WITH_CODE(false,
319 "Attempt to populate vddc vid Failed!",
320 return -EINVAL);
321
322 /* DW6 */
323 if (iceland_populate_svi_load_line(hwmgr))
324 PP_ASSERT_WITH_CODE(false,
325 "Attempt to populate SviLoadLine Failed!",
326 return -EINVAL);
327 /* DW7 */
328 if (iceland_populate_tdc_limit(hwmgr))
329 PP_ASSERT_WITH_CODE(false,
330 "Attempt to populate TDCLimit Failed!", return -EINVAL);
331 /* DW8 */
332 if (iceland_populate_dw8(hwmgr, pm_fuse_table_offset))
333 PP_ASSERT_WITH_CODE(false,
334 "Attempt to populate TdcWaterfallCtl, "
335 "LPMLTemperature Min and Max Failed!",
336 return -EINVAL);
337
338 /* DW9-DW12 */
339 if (0 != iceland_populate_temperature_scaler(hwmgr))
340 PP_ASSERT_WITH_CODE(false,
341 "Attempt to populate LPMLTemperatureScaler Failed!",
342 return -EINVAL);
343
344 /* DW13-DW16 */
345 if (iceland_populate_gnb_lpml(hwmgr))
346 PP_ASSERT_WITH_CODE(false,
347 "Attempt to populate GnbLPML Failed!",
348 return -EINVAL);
349
350 /* DW17 */
351 if (iceland_min_max_vgnb_lpml_id_from_bapm_vddc(hwmgr))
352 PP_ASSERT_WITH_CODE(false,
353 "Attempt to populate GnbLPML Min and Max Vid Failed!",
354 return -EINVAL);
355
356 /* DW18 */
357 if (iceland_populate_bapm_vddc_base_leakage_sidd(hwmgr))
358 PP_ASSERT_WITH_CODE(false,
359 "Attempt to populate BapmVddCBaseLeakage Hi and Lo Sidd Failed!",
360 return -EINVAL);
361
362 if (iceland_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset,
363 (uint8_t *)&data->power_tune_table,
364 sizeof(struct SMU71_Discrete_PmFuses), data->sram_end))
365 PP_ASSERT_WITH_CODE(false,
366 "Attempt to download PmFuseTable Failed!",
367 return -EINVAL);
368 }
369 return 0;
370}
371
372int iceland_enable_smc_cac(struct pp_hwmgr *hwmgr)
373{
374 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
375 int result = 0;
376
377 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
378 PHM_PlatformCaps_CAC)) {
379 int smc_result;
380 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
381 (uint16_t)(PPSMC_MSG_EnableCac));
382 PP_ASSERT_WITH_CODE((0 == smc_result),
383 "Failed to enable CAC in SMC.", result = -1);
384
385 data->cac_enabled = (0 == smc_result) ? true : false;
386 }
387 return result;
388}
389
390static int iceland_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
391{
392 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
393
394 if(data->power_containment_features &
395 POWERCONTAINMENT_FEATURE_PkgPwrLimit)
396 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
397 PPSMC_MSG_PkgPwrSetLimit, n);
398 return 0;
399}
400
401static int iceland_set_overdriver_target_tdp(struct pp_hwmgr *pHwMgr, uint32_t target_tdp)
402{
403 return smum_send_msg_to_smc_with_parameter(pHwMgr->smumgr,
404 PPSMC_MSG_OverDriveSetTargetTdp, target_tdp);
405}
406
407int iceland_enable_power_containment(struct pp_hwmgr *hwmgr)
408{
409 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
410 SMU71_Discrete_DpmTable *dpm_table = &data->smc_state_table;
411 int smc_result;
412 int result = 0;
413 uint32_t is_asic_kicker;
414
415 data->power_containment_features = 0;
416 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
417 PHM_PlatformCaps_PowerContainment)) {
418 is_asic_kicker = cgs_read_register(hwmgr->device, mmCC_BIF_BX_STRAP2);
419 is_asic_kicker = (is_asic_kicker >> 12) & 0x01;
420
421 if (data->enable_bapm_feature &&
422 (!is_asic_kicker ||
423 phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
424 PHM_PlatformCaps_DisableUsingActualTemperatureForPowerCalc))) {
425 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
426 (uint16_t)(PPSMC_MSG_EnableDTE));
427 PP_ASSERT_WITH_CODE((0 == smc_result),
428 "Failed to enable BAPM in SMC.", result = -1;);
429 if (0 == smc_result)
430 data->power_containment_features |= POWERCONTAINMENT_FEATURE_BAPM;
431 }
432
433 if (is_asic_kicker && !phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
434 PHM_PlatformCaps_DisableUsingActualTemperatureForPowerCalc))
435 dpm_table->DTEMode = 2;
436
437 if (data->enable_tdc_limit_feature) {
438 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
439 (uint16_t)(PPSMC_MSG_TDCLimitEnable));
440 PP_ASSERT_WITH_CODE((0 == smc_result),
441 "Failed to enable TDCLimit in SMC.", result = -1;);
442 if (0 == smc_result)
443 data->power_containment_features |=
444 POWERCONTAINMENT_FEATURE_TDCLimit;
445 }
446
447 if (data->enable_pkg_pwr_tracking_feature) {
448 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
449 (uint16_t)(PPSMC_MSG_PkgPwrLimitEnable));
450 PP_ASSERT_WITH_CODE((0 == smc_result),
451 "Failed to enable PkgPwrTracking in SMC.", result = -1;);
452 if (0 == smc_result) {
453 struct phm_cac_tdp_table *cac_table =
454 hwmgr->dyn_state.cac_dtp_table;
455 uint32_t default_limit =
456 (uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256);
457
458 data->power_containment_features |=
459 POWERCONTAINMENT_FEATURE_PkgPwrLimit;
460
461 if (iceland_set_power_limit(hwmgr, default_limit))
462 printk(KERN_ERR "Failed to set Default Power Limit in SMC!");
463 }
464 }
465 }
466 return result;
467}
468
469int iceland_power_control_set_level(struct pp_hwmgr *hwmgr)
470{
471 struct phm_cac_tdp_table *cac_table = hwmgr->dyn_state.cac_dtp_table;
472 int adjust_percent, target_tdp;
473 int result = 0;
474
475 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
476 PHM_PlatformCaps_PowerContainment)) {
477 /* adjustment percentage has already been validated */
478 adjust_percent = hwmgr->platform_descriptor.TDPAdjustmentPolarity ?
479 hwmgr->platform_descriptor.TDPAdjustment :
480 (-1 * hwmgr->platform_descriptor.TDPAdjustment);
481 /*
482 * SMC requested that target_tdp to be 7 bit fraction in DPM table
483 * but message to be 8 bit fraction for messages
484 */
485 target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 256)) / 100;
486 result = iceland_set_overdriver_target_tdp(hwmgr, (uint32_t)target_tdp);
487 }
488
489 return result;
490}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.h
new file mode 100644
index 000000000000..6c25ee139ca3
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_powertune.h
@@ -0,0 +1,74 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25#ifndef ICELAND_POWERTUNE_H
26#define ICELAND_POWERTUNE_H
27
28#include "smu71.h"
29
30enum iceland_pt_config_reg_type {
31 ICELAND_CONFIGREG_MMR = 0,
32 ICELAND_CONFIGREG_SMC_IND,
33 ICELAND_CONFIGREG_DIDT_IND,
34 ICELAND_CONFIGREG_CACHE,
35 ICELAND_CONFIGREG_MAX
36};
37
38/* PowerContainment Features */
39#define POWERCONTAINMENT_FEATURE_DTE 0x00000001
40#define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002
41#define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004
42#define POWERCONTAINMENT_FEATURE_BAPM 0x00000001
43
44struct iceland_pt_config_reg {
45 uint32_t offset;
46 uint32_t mask;
47 uint32_t shift;
48 uint32_t value;
49 enum iceland_pt_config_reg_type type;
50};
51
52struct iceland_pt_defaults
53{
54 uint8_t svi_load_line_en;
55 uint8_t svi_load_line_vddc;
56 uint8_t tdc_vddc_throttle_release_limit_perc;
57 uint8_t tdc_mawt;
58 uint8_t tdc_waterfall_ctl;
59 uint8_t dte_ambient_temp_base;
60 uint32_t display_cac;
61 uint32_t bamp_temp_gradient;
62 uint16_t bapmti_r[SMU71_DTE_ITERATIONS * SMU71_DTE_SOURCES * SMU71_DTE_SINKS];
63 uint16_t bapmti_rc[SMU71_DTE_ITERATIONS * SMU71_DTE_SOURCES * SMU71_DTE_SINKS];
64};
65
66void iceland_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr);
67int iceland_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr);
68int iceland_populate_pm_fuses(struct pp_hwmgr *hwmgr);
69int iceland_enable_smc_cac(struct pp_hwmgr *hwmgr);
70int iceland_enable_power_containment(struct pp_hwmgr *hwmgr);
71int iceland_power_control_set_level(struct pp_hwmgr *hwmgr);
72
73#endif /* ICELAND_POWERTUNE_H */
74
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.c
new file mode 100644
index 000000000000..527f37022424
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.c
@@ -0,0 +1,595 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25#include <asm/div64.h>
26#include "iceland_thermal.h"
27#include "iceland_hwmgr.h"
28#include "iceland_smumgr.h"
29#include "atombios.h"
30#include "ppsmc.h"
31
32#include "gmc/gmc_8_1_d.h"
33#include "gmc/gmc_8_1_sh_mask.h"
34
35#include "bif/bif_5_0_d.h"
36#include "bif/bif_5_0_sh_mask.h"
37
38#include "smu/smu_7_1_1_d.h"
39#include "smu/smu_7_1_1_sh_mask.h"
40
41
42/**
43* Get Fan Speed Control Parameters.
44* @param hwmgr the address of the powerplay hardware manager.
45* @param pSpeed is the address of the structure where the result is to be placed.
46* @exception Always succeeds except if we cannot zero out the output structure.
47*/
48int iceland_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
49 struct phm_fan_speed_info *fan_speed_info)
50{
51
52 if (hwmgr->thermal_controller.fanInfo.bNoFan)
53 return 0;
54
55 fan_speed_info->supports_percent_read = true;
56 fan_speed_info->supports_percent_write = true;
57 fan_speed_info->min_percent = 0;
58 fan_speed_info->max_percent = 100;
59
60 if (0 != hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution) {
61 fan_speed_info->supports_rpm_read = true;
62 fan_speed_info->supports_rpm_write = true;
63 fan_speed_info->min_rpm = hwmgr->thermal_controller.fanInfo.ulMinRPM;
64 fan_speed_info->max_rpm = hwmgr->thermal_controller.fanInfo.ulMaxRPM;
65 } else {
66 fan_speed_info->min_rpm = 0;
67 fan_speed_info->max_rpm = 0;
68 }
69
70 return 0;
71}
72
73/**
74* Get Fan Speed in percent.
75* @param hwmgr the address of the powerplay hardware manager.
76* @param pSpeed is the address of the structure where the result is to be placed.
77* @exception Fails is the 100% setting appears to be 0.
78*/
79int iceland_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t *speed)
80{
81 uint32_t duty100;
82 uint32_t duty;
83 uint64_t tmp64;
84
85 if (hwmgr->thermal_controller.fanInfo.bNoFan)
86 return 0;
87
88 duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
89 duty = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_STATUS, FDO_PWM_DUTY);
90
91 if (0 == duty100)
92 return -EINVAL;
93
94
95 tmp64 = (uint64_t)duty * 100;
96 do_div(tmp64, duty100);
97 *speed = (uint32_t)tmp64;
98
99 if (*speed > 100)
100 *speed = 100;
101
102 return 0;
103}
104
105/**
106* Get Fan Speed in RPM.
107* @param hwmgr the address of the powerplay hardware manager.
108* @param speed is the address of the structure where the result is to be placed.
109* @exception Returns not supported if no fan is found or if pulses per revolution are not set
110*/
111int iceland_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
112{
113 return 0;
114}
115
116/**
117* Set Fan Speed Control to static mode, so that the user can decide what speed to use.
118* @param hwmgr the address of the powerplay hardware manager.
119* mode the fan control mode, 0 default, 1 by percent, 5, by RPM
120* @exception Should always succeed.
121*/
122int iceland_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
123{
124
125 if (hwmgr->fan_ctrl_is_in_default_mode) {
126 hwmgr->fan_ctrl_default_mode = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE);
127 hwmgr->tmin = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN);
128 hwmgr->fan_ctrl_is_in_default_mode = false;
129 }
130
131 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN, 0);
132 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE, mode);
133
134 return 0;
135}
136
137/**
138* Reset Fan Speed Control to default mode.
139* @param hwmgr the address of the powerplay hardware manager.
140* @exception Should always succeed.
141*/
142static int iceland_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr)
143{
144 if (!hwmgr->fan_ctrl_is_in_default_mode) {
145 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, FDO_PWM_MODE, hwmgr->fan_ctrl_default_mode);
146 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TMIN, hwmgr->tmin);
147 hwmgr->fan_ctrl_is_in_default_mode = true;
148 }
149
150 return 0;
151}
152
153int iceland_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
154{
155 return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StartFanControl) == 0) ? 0 : -EINVAL;
156}
157
158
159int iceland_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
160{
161 return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_StopFanControl) == 0) ? 0 : -EINVAL;
162}
163
164/**
165* Set Fan Speed in percent.
166* @param hwmgr the address of the powerplay hardware manager.
167* @param speed is the percentage value (0% - 100%) to be set.
168* @exception Fails is the 100% setting appears to be 0.
169*/
170int iceland_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t speed)
171{
172 uint32_t duty100;
173 uint32_t duty;
174 uint64_t tmp64;
175
176 if (hwmgr->thermal_controller.fanInfo.bNoFan)
177 return -EINVAL;
178
179 if (speed > 100) {
180 pr_warning("Cannot set more than 100%% duty cycle. Set it to 100.\n");
181 speed = 100;
182 }
183
184 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl))
185 iceland_fan_ctrl_stop_smc_fan_control(hwmgr);
186
187 duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
188
189 if (0 == duty100)
190 return -EINVAL;
191
192 tmp64 = (uint64_t)speed * duty100;
193 do_div(tmp64, 100);
194 duty = (uint32_t)tmp64;
195
196 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL0, FDO_STATIC_DUTY, duty);
197
198 return iceland_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
199}
200
201/**
202* Reset Fan Speed to default.
203* @param hwmgr the address of the powerplay hardware manager.
204* @exception Always succeeds.
205*/
206int iceland_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
207{
208 int result;
209
210 if (hwmgr->thermal_controller.fanInfo.bNoFan)
211 return 0;
212
213 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) {
214 result = iceland_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
215 if (0 == result)
216 result = iceland_fan_ctrl_start_smc_fan_control(hwmgr);
217 } else
218 result = iceland_fan_ctrl_set_default_mode(hwmgr);
219
220 return result;
221}
222
223/**
224* Set Fan Speed in RPM.
225* @param hwmgr the address of the powerplay hardware manager.
226* @param speed is the percentage value (min - max) to be set.
227* @exception Fails is the speed not lie between min and max.
228*/
229int iceland_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
230{
231 return 0;
232}
233
234/**
235* Reads the remote temperature from the SIslands thermal controller.
236*
237* @param hwmgr The address of the hardware manager.
238*/
239int iceland_thermal_get_temperature(struct pp_hwmgr *hwmgr)
240{
241 int temp;
242
243 temp = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_STATUS, CTF_TEMP);
244
245 /*
246 * Bit 9 means the reading is lower than the lowest usable
247 * value.
248 */
249 if (0 != (0x200 & temp))
250 temp = ICELAND_THERMAL_MAXIMUM_TEMP_READING;
251 else
252 temp = (temp & 0x1ff);
253
254 temp = temp * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
255
256 return temp;
257}
258
259/**
260* Set the requested temperature range for high and low alert signals
261*
262* @param hwmgr The address of the hardware manager.
263* @param range Temperature range to be programmed for high and low alert signals
264* @exception PP_Result_BadInput if the input data is not valid.
265*/
266static int iceland_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, uint32_t low_temp, uint32_t high_temp)
267{
268 uint32_t low = ICELAND_THERMAL_MINIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
269 uint32_t high = ICELAND_THERMAL_MAXIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
270
271 if (low < low_temp)
272 low = low_temp;
273 if (high > high_temp)
274 high = high_temp;
275
276 if (low > high)
277 return -EINVAL;
278
279 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
280 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
281 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_CTRL, DIG_THERM_DPM, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
282
283 return 0;
284}
285
286/**
287* Programs thermal controller one-time setting registers
288*
289* @param hwmgr The address of the hardware manager.
290*/
291static int iceland_thermal_initialize(struct pp_hwmgr *hwmgr)
292{
293 if (0 != hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution)
294 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
295 CG_TACH_CTRL, EDGE_PER_REV,
296 hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution - 1);
297
298 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL2, TACH_PWM_RESP_RATE, 0x28);
299
300 return 0;
301}
302
303/**
304* Enable thermal alerts on the RV770 thermal controller.
305*
306* @param hwmgr The address of the hardware manager.
307*/
308static int iceland_thermal_enable_alert(struct pp_hwmgr *hwmgr)
309{
310 uint32_t alert;
311
312 alert = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK);
313 alert &= ~(ICELAND_THERMAL_HIGH_ALERT_MASK | ICELAND_THERMAL_LOW_ALERT_MASK);
314 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK, alert);
315
316 /* send message to SMU to enable internal thermal interrupts */
317 return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Thermal_Cntl_Enable) == 0) ? 0 : -1;
318}
319
320/**
321* Disable thermal alerts on the RV770 thermal controller.
322* @param hwmgr The address of the hardware manager.
323*/
324static int iceland_thermal_disable_alert(struct pp_hwmgr *hwmgr)
325{
326 uint32_t alert;
327
328 alert = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK);
329 alert |= (ICELAND_THERMAL_HIGH_ALERT_MASK | ICELAND_THERMAL_LOW_ALERT_MASK);
330 PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_THERMAL_INT, THERM_INT_MASK, alert);
331
332 /* send message to SMU to disable internal thermal interrupts */
333 return (smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Thermal_Cntl_Disable) == 0) ? 0 : -1;
334}
335
336/**
337* Uninitialize the thermal controller.
338* Currently just disables alerts.
339* @param hwmgr The address of the hardware manager.
340*/
341int iceland_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr)
342{
343 int result = iceland_thermal_disable_alert(hwmgr);
344
345 if (result)
346 pr_warning("Failed to disable thermal alerts!\n");
347
348 if (hwmgr->thermal_controller.fanInfo.bNoFan)
349 iceland_fan_ctrl_set_default_mode(hwmgr);
350
351 return result;
352}
353
354/**
355* Set up the fan table to control the fan using the SMC.
356* @param hwmgr the address of the powerplay hardware manager.
357* @param pInput the pointer to input data
358* @param pOutput the pointer to output data
359* @param pStorage the pointer to temporary storage
360* @param Result the last failure code
361* @return result from set temperature range routine
362*/
363int tf_iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
364{
365 struct iceland_hwmgr *data = (struct iceland_hwmgr *)(hwmgr->backend);
366 SMU71_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE };
367 uint32_t duty100;
368 uint32_t t_diff1, t_diff2, pwm_diff1, pwm_diff2;
369 uint16_t fdo_min, slope1, slope2;
370 uint32_t reference_clock;
371 int res;
372 uint64_t tmp64;
373
374 if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl))
375 return 0;
376
377 if (0 == data->fan_table_start) {
378 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
379 return 0;
380 }
381
382 duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_FDO_CTRL1, FMAX_DUTY100);
383
384 if (0 == duty100) {
385 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
386 return 0;
387 }
388
389 tmp64 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin * duty100;
390 do_div(tmp64, 10000);
391 fdo_min = (uint16_t)tmp64;
392
393 t_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usTMed - hwmgr->thermal_controller.advanceFanControlParameters.usTMin;
394 t_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usTHigh - hwmgr->thermal_controller.advanceFanControlParameters.usTMed;
395
396 pwm_diff1 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMin;
397 pwm_diff2 = hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh - hwmgr->thermal_controller.advanceFanControlParameters.usPWMMed;
398
399 slope1 = (uint16_t)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
400 slope2 = (uint16_t)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
401
402 fan_table.TempMin = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMin) / 100);
403 fan_table.TempMed = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMed) / 100);
404 fan_table.TempMax = cpu_to_be16((50 + hwmgr->thermal_controller.advanceFanControlParameters.usTMax) / 100);
405
406 fan_table.Slope1 = cpu_to_be16(slope1);
407 fan_table.Slope2 = cpu_to_be16(slope2);
408
409 fan_table.FdoMin = cpu_to_be16(fdo_min);
410
411 fan_table.HystDown = cpu_to_be16(hwmgr->thermal_controller.advanceFanControlParameters.ucTHyst);
412
413 fan_table.HystUp = cpu_to_be16(1);
414
415 fan_table.HystSlope = cpu_to_be16(1);
416
417 fan_table.TempRespLim = cpu_to_be16(5);
418
419 reference_clock = iceland_get_xclk(hwmgr);
420
421 fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600);
422
423 fan_table.FdoMax = cpu_to_be16((uint16_t)duty100);
424
425 fan_table.TempSrc = (uint8_t)PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_MULT_THERMAL_CTRL, TEMP_SEL);
426
427 //fan_table.FanControl_GL_Flag = 1;
428
429 res = iceland_copy_bytes_to_smc(hwmgr->smumgr, data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), data->sram_end);
430/* TO DO FOR SOME DEVICE ID 0X692b, send this msg return invalid command.
431 if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit != 0)
432 res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanMinPwm, \
433 hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit) ? 0 : -1);
434
435 if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit != 0)
436 res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanSclkTarget, \
437 hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit) ? 0 : -1);
438
439 if (0 != res)
440 phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
441*/
442 return 0;
443}
444
445/**
446* Start the fan control on the SMC.
447* @param hwmgr the address of the powerplay hardware manager.
448* @param pInput the pointer to input data
449* @param pOutput the pointer to output data
450* @param pStorage the pointer to temporary storage
451* @param Result the last failure code
452* @return result from set temperature range routine
453*/
454int tf_iceland_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
455{
456/* If the fantable setup has failed we could have disabled PHM_PlatformCaps_MicrocodeFanControl even after this function was included in the table.
457 * Make sure that we still think controlling the fan is OK.
458*/
459 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl)) {
460 iceland_fan_ctrl_start_smc_fan_control(hwmgr);
461 iceland_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
462 }
463
464 return 0;
465}
466
467/**
468* Set temperature range for high and low alerts
469* @param hwmgr the address of the powerplay hardware manager.
470* @param pInput the pointer to input data
471* @param pOutput the pointer to output data
472* @param pStorage the pointer to temporary storage
473* @param Result the last failure code
474* @return result from set temperature range routine
475*/
476static int tf_iceland_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
477 void *input, void *output, void *storage, int result)
478{
479 struct PP_TemperatureRange *range = (struct PP_TemperatureRange *)input;
480
481 if (range == NULL)
482 return -EINVAL;
483
484 return iceland_thermal_set_temperature_range(hwmgr, range->min, range->max);
485}
486
487/**
488* Programs one-time setting registers
489* @param hwmgr the address of the powerplay hardware manager.
490* @param pInput the pointer to input data
491* @param pOutput the pointer to output data
492* @param pStorage the pointer to temporary storage
493* @param Result the last failure code
494* @return result from initialize thermal controller routine
495*/
496static int tf_iceland_thermal_initialize(struct pp_hwmgr *hwmgr, void *input,
497 void *output, void *storage, int result)
498{
499 return iceland_thermal_initialize(hwmgr);
500}
501
502/**
503* Enable high and low alerts
504* @param hwmgr the address of the powerplay hardware manager.
505* @param pInput the pointer to input data
506* @param pOutput the pointer to output data
507* @param pStorage the pointer to temporary storage
508* @param Result the last failure code
509* @return result from enable alert routine
510*/
511static int tf_iceland_thermal_enable_alert(struct pp_hwmgr *hwmgr,
512 void *input, void *output, void *storage, int result)
513{
514 return iceland_thermal_enable_alert(hwmgr);
515}
516
517/**
518* Disable high and low alerts
519* @param hwmgr the address of the powerplay hardware manager.
520* @param pInput the pointer to input data
521* @param pOutput the pointer to output data
522* @param pStorage the pointer to temporary storage
523* @param Result the last failure code
524* @return result from disable alert routine
525*/
526static int tf_iceland_thermal_disable_alert(struct pp_hwmgr *hwmgr, void *input, void *output, void *storage, int result)
527{
528 return iceland_thermal_disable_alert(hwmgr);
529}
530
531static const struct phm_master_table_item iceland_thermal_start_thermal_controller_master_list[] = {
532 { NULL, tf_iceland_thermal_initialize },
533 { NULL, tf_iceland_thermal_set_temperature_range },
534 { NULL, tf_iceland_thermal_enable_alert },
535 /*
536 * We should restrict performance levels to low before we halt
537 * the SMC. On the other hand we are still in boot state when
538 * we do this so it would be pointless. If this assumption
539 * changes we have to revisit this table.
540 */
541 { NULL, tf_iceland_thermal_setup_fan_table},
542 { NULL, tf_iceland_thermal_start_smc_fan_control},
543 { NULL, NULL }
544};
545
546static const struct phm_master_table_header iceland_thermal_start_thermal_controller_master = {
547 0,
548 PHM_MasterTableFlag_None,
549 iceland_thermal_start_thermal_controller_master_list
550};
551
552static const struct phm_master_table_item iceland_thermal_set_temperature_range_master_list[] = {
553 { NULL, tf_iceland_thermal_disable_alert},
554 { NULL, tf_iceland_thermal_set_temperature_range},
555 { NULL, tf_iceland_thermal_enable_alert},
556 { NULL, NULL }
557};
558
559static const struct phm_master_table_header iceland_thermal_set_temperature_range_master = {
560 0,
561 PHM_MasterTableFlag_None,
562 iceland_thermal_set_temperature_range_master_list
563};
564
565int iceland_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr)
566{
567 if (!hwmgr->thermal_controller.fanInfo.bNoFan)
568 iceland_fan_ctrl_set_default_mode(hwmgr);
569 return 0;
570}
571
572/**
573* Initializes the thermal controller related functions in the Hardware Manager structure.
574* @param hwmgr The address of the hardware manager.
575* @exception Any error code from the low-level communication.
576*/
577int pp_iceland_thermal_initialize(struct pp_hwmgr *hwmgr)
578{
579 int result;
580
581 result = phm_construct_table(hwmgr, &iceland_thermal_set_temperature_range_master, &(hwmgr->set_temperature_range));
582
583 if (0 == result) {
584 result = phm_construct_table(hwmgr,
585 &iceland_thermal_start_thermal_controller_master,
586 &(hwmgr->start_thermal_controller));
587 if (0 != result)
588 phm_destroy_table(hwmgr, &(hwmgr->set_temperature_range));
589 }
590
591 if (0 == result)
592 hwmgr->fan_ctrl_is_in_default_mode = true;
593 return result;
594}
595
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.h b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.h
new file mode 100644
index 000000000000..267945f4df71
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/iceland_thermal.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25
26#ifndef ICELAND_THERMAL_H
27#define ICELAND_THERMAL_H
28
29#include "hwmgr.h"
30
31#define ICELAND_THERMAL_HIGH_ALERT_MASK 0x1
32#define ICELAND_THERMAL_LOW_ALERT_MASK 0x2
33
34#define ICELAND_THERMAL_MINIMUM_TEMP_READING -256
35#define ICELAND_THERMAL_MAXIMUM_TEMP_READING 255
36
37#define ICELAND_THERMAL_MINIMUM_ALERT_TEMP 0
38#define ICELAND_THERMAL_MAXIMUM_ALERT_TEMP 255
39
40#define FDO_PWM_MODE_STATIC 1
41#define FDO_PWM_MODE_STATIC_RPM 5
42
43
44extern int iceland_thermal_get_temperature(struct pp_hwmgr *hwmgr);
45extern int iceland_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr);
46extern int iceland_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, struct phm_fan_speed_info *fan_speed_info);
47extern int iceland_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t *speed);
48extern int iceland_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode);
49extern int iceland_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, uint32_t speed);
50extern int iceland_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr);
51extern int pp_iceland_thermal_initialize(struct pp_hwmgr *hwmgr);
52extern int iceland_thermal_ctrl_uninitialize_thermal_controller(struct pp_hwmgr *hwmgr);
53extern int iceland_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed);
54extern int iceland_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed);
55extern int iceland_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);
56
57#endif
58
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c
index 783dcc3384f1..b69132296672 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c
@@ -97,19 +97,6 @@
97#define PCIE_BUS_CLK 10000 97#define PCIE_BUS_CLK 10000
98#define TCLK (PCIE_BUS_CLK / 10) 98#define TCLK (PCIE_BUS_CLK / 10)
99 99
100
101static const uint16_t polaris10_clock_stretcher_lookup_table[2][4] =
102{ {600, 1050, 3, 0}, {600, 1050, 6, 1} };
103
104/* [FF, SS] type, [] 4 voltage ranges, and [Floor Freq, Boundary Freq, VID min , VID max] */
105static const uint32_t polaris10_clock_stretcher_ddt_table[2][4][4] =
106{ { {265, 529, 120, 128}, {325, 650, 96, 119}, {430, 860, 32, 95}, {0, 0, 0, 31} },
107 { {275, 550, 104, 112}, {319, 638, 96, 103}, {360, 720, 64, 95}, {384, 768, 32, 63} } };
108
109/* [Use_For_Low_freq] value, [0%, 5%, 10%, 7.14%, 14.28%, 20%] (coming from PWR_CKS_CNTL.stretch_amount reg spec) */
110static const uint8_t polaris10_clock_stretch_amount_conversion[2][6] =
111{ {0, 1, 3, 2, 4, 5}, {0, 2, 4, 5, 6, 5} };
112
113/** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */ 100/** Values for the CG_THERMAL_CTRL::DPM_EVENT_SRC field. */
114enum DPM_EVENT_SRC { 101enum DPM_EVENT_SRC {
115 DPM_EVENT_SRC_ANALOG = 0, 102 DPM_EVENT_SRC_ANALOG = 0,
@@ -2772,9 +2759,6 @@ int polaris10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
2772 struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); 2759 struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
2773 2760
2774 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 2761 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2775 PHM_PlatformCaps_SclkDeepSleep);
2776
2777 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2778 PHM_PlatformCaps_DynamicPatchPowerState); 2762 PHM_PlatformCaps_DynamicPatchPowerState);
2779 2763
2780 if (data->mvdd_control == POLARIS10_VOLTAGE_CONTROL_NONE) 2764 if (data->mvdd_control == POLARIS10_VOLTAGE_CONTROL_NONE)
@@ -2819,13 +2803,6 @@ int polaris10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
2819 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 2803 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2820 PHM_PlatformCaps_TCPRamping); 2804 PHM_PlatformCaps_TCPRamping);
2821 2805
2822 if (hwmgr->powercontainment_enabled)
2823 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2824 PHM_PlatformCaps_PowerContainment);
2825 else
2826 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
2827 PHM_PlatformCaps_PowerContainment);
2828
2829 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 2806 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
2830 PHM_PlatformCaps_CAC); 2807 PHM_PlatformCaps_CAC);
2831 2808
@@ -2904,8 +2881,8 @@ static int polaris10_get_evv_voltages(struct pp_hwmgr *hwmgr)
2904 continue; 2881 continue;
2905 } 2882 }
2906 2883
2907 /* need to make sure vddc is less than 2v or else, it could burn the ASIC. 2884 /* need to make sure vddc is less than 2V or else, it could burn the ASIC.
2908 * real voltage level in unit of 0.01mv */ 2885 * real voltage level in unit of 0.01mV */
2909 PP_ASSERT_WITH_CODE((vddc < 200000 && vddc != 0), 2886 PP_ASSERT_WITH_CODE((vddc < 200000 && vddc != 0),
2910 "Invalid VDDC value", result = -EINVAL;); 2887 "Invalid VDDC value", result = -EINVAL;);
2911 2888
@@ -3142,7 +3119,10 @@ int polaris10_patch_voltage_workaround(struct pp_hwmgr *hwmgr)
3142 table_info->vddc_lookup_table; 3119 table_info->vddc_lookup_table;
3143 uint32_t i; 3120 uint32_t i;
3144 3121
3145 if (hwmgr->chip_id == CHIP_POLARIS10 && hwmgr->hw_revision == 0xC7) { 3122 if (hwmgr->chip_id == CHIP_POLARIS10 && hwmgr->hw_revision == 0xC7 &&
3123 ((hwmgr->sub_sys_id == 0xb37 && hwmgr->sub_vendor_id == 0x1002) ||
3124 (hwmgr->sub_sys_id == 0x4a8 && hwmgr->sub_vendor_id == 0x1043) ||
3125 (hwmgr->sub_sys_id == 0x9480 && hwmgr->sub_vendor_id == 0x1682))) {
3146 if (lookup_table->entries[dep_mclk_table->entries[dep_mclk_table->count-1].vddInd].us_vdd >= 1000) 3126 if (lookup_table->entries[dep_mclk_table->entries[dep_mclk_table->count-1].vddInd].us_vdd >= 1000)
3147 return 0; 3127 return 0;
3148 3128
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
index 7dc4afd19d26..7f9ba7f15e19 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
@@ -301,6 +301,8 @@ void tonga_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
301 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 301 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
302 PHM_PlatformCaps_DisableMemoryTransition); 302 PHM_PlatformCaps_DisableMemoryTransition);
303 303
304 tonga_initialize_power_tune_defaults(hwmgr);
305
304 data->mclk_strobe_mode_threshold = 40000; 306 data->mclk_strobe_mode_threshold = 40000;
305 data->mclk_stutter_mode_threshold = 30000; 307 data->mclk_stutter_mode_threshold = 30000;
306 data->mclk_edc_enable_threshold = 40000; 308 data->mclk_edc_enable_threshold = 40000;
@@ -2478,7 +2480,7 @@ static int tonga_populate_single_graphic_level(struct pp_hwmgr *hwmgr, uint32_t
2478 graphic_level->VoltageDownHyst = 0; 2480 graphic_level->VoltageDownHyst = 0;
2479 graphic_level->PowerThrottle = 0; 2481 graphic_level->PowerThrottle = 0;
2480 2482
2481 threshold = engine_clock * data->fast_watemark_threshold / 100; 2483 threshold = engine_clock * data->fast_watermark_threshold / 100;
2482/* 2484/*
2483 *get the DAL clock. do it in funture. 2485 *get the DAL clock. do it in funture.
2484 PECI_GetMinClockSettings(hwmgr->peci, &minClocks); 2486 PECI_GetMinClockSettings(hwmgr->peci, &minClocks);
@@ -2981,6 +2983,10 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr)
2981 PP_ASSERT_WITH_CODE(0 == result, 2983 PP_ASSERT_WITH_CODE(0 == result,
2982 "Failed to initialize Boot Level!", return result;); 2984 "Failed to initialize Boot Level!", return result;);
2983 2985
2986 result = tonga_populate_bapm_parameters_in_dpm_table(hwmgr);
2987 PP_ASSERT_WITH_CODE(result == 0,
2988 "Failed to populate BAPM Parameters!", return result);
2989
2984 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 2990 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
2985 PHM_PlatformCaps_ClockStretcher)) { 2991 PHM_PlatformCaps_ClockStretcher)) {
2986 result = tonga_populate_clock_stretcher_data_table(hwmgr); 2992 result = tonga_populate_clock_stretcher_data_table(hwmgr);
@@ -4369,6 +4375,10 @@ int tonga_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
4369 PP_ASSERT_WITH_CODE((0 == tmp_result), 4375 PP_ASSERT_WITH_CODE((0 == tmp_result),
4370 "Failed to initialize ARB table index!", result = tmp_result); 4376 "Failed to initialize ARB table index!", result = tmp_result);
4371 4377
4378 tmp_result = tonga_populate_pm_fuses(hwmgr);
4379 PP_ASSERT_WITH_CODE((tmp_result == 0),
4380 "Failed to populate PM fuses!", result = tmp_result);
4381
4372 tmp_result = tonga_populate_initial_mc_reg_table(hwmgr); 4382 tmp_result = tonga_populate_initial_mc_reg_table(hwmgr);
4373 PP_ASSERT_WITH_CODE((0 == tmp_result), 4383 PP_ASSERT_WITH_CODE((0 == tmp_result),
4374 "Failed to populate initialize MC Reg table!", result = tmp_result); 4384 "Failed to populate initialize MC Reg table!", result = tmp_result);
@@ -4387,6 +4397,18 @@ int tonga_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
4387 PP_ASSERT_WITH_CODE((0 == tmp_result), 4397 PP_ASSERT_WITH_CODE((0 == tmp_result),
4388 "Failed to start DPM!", result = tmp_result); 4398 "Failed to start DPM!", result = tmp_result);
4389 4399
4400 tmp_result = tonga_enable_smc_cac(hwmgr);
4401 PP_ASSERT_WITH_CODE((tmp_result == 0),
4402 "Failed to enable SMC CAC!", result = tmp_result);
4403
4404 tmp_result = tonga_enable_power_containment(hwmgr);
4405 PP_ASSERT_WITH_CODE((tmp_result == 0),
4406 "Failed to enable power containment!", result = tmp_result);
4407
4408 tmp_result = tonga_power_control_set_level(hwmgr);
4409 PP_ASSERT_WITH_CODE((tmp_result == 0),
4410 "Failed to power control set level!", result = tmp_result);
4411
4390 return result; 4412 return result;
4391} 4413}
4392 4414
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h
index 3961884bfa9b..fcad9426d3c1 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h
@@ -300,6 +300,7 @@ struct tonga_hwmgr {
300 bool dll_defaule_on; 300 bool dll_defaule_on;
301 bool performance_request_registered; 301 bool performance_request_registered;
302 302
303
303 /* ----------------- Low Power Features ---------------------*/ 304 /* ----------------- Low Power Features ---------------------*/
304 phw_tonga_bacos bacos; 305 phw_tonga_bacos bacos;
305 phw_tonga_ulv_parm ulv; 306 phw_tonga_ulv_parm ulv;
@@ -314,10 +315,14 @@ struct tonga_hwmgr {
314 bool enable_tdc_limit_feature; 315 bool enable_tdc_limit_feature;
315 bool enable_pkg_pwr_tracking_feature; 316 bool enable_pkg_pwr_tracking_feature;
316 bool disable_uvd_power_tune_feature; 317 bool disable_uvd_power_tune_feature;
317 phw_tonga_pt_defaults *power_tune_defaults; 318 struct tonga_pt_defaults *power_tune_defaults;
318 SMU72_Discrete_PmFuses power_tune_table; 319 SMU72_Discrete_PmFuses power_tune_table;
319 uint32_t ul_dte_tj_offset; /* Fudge factor in DPM table to correct HW DTE errors */ 320 uint32_t dte_tj_offset; /* Fudge factor in DPM table to correct HW DTE errors */
320 uint32_t fast_watemark_threshold; /* use fast watermark if clock is equal or above this. In percentage of the target high sclk. */ 321 uint32_t fast_watermark_threshold; /* use fast watermark if clock is equal or above this. In percentage of the target high sclk. */
322
323
324 bool enable_dte_feature;
325
321 326
322 /* ----------------- Phase Shedding ---------------------*/ 327 /* ----------------- Phase Shedding ---------------------*/
323 bool vddc_phase_shed_control; 328 bool vddc_phase_shed_control;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c
new file mode 100644
index 000000000000..9496ade3247e
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c
@@ -0,0 +1,498 @@
1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "hwmgr.h"
25#include "smumgr.h"
26#include "tonga_hwmgr.h"
27#include "tonga_powertune.h"
28#include "tonga_smumgr.h"
29#include "smu72_discrete.h"
30#include "pp_debug.h"
31#include "tonga_ppsmc.h"
32
33#define VOLTAGE_SCALE 4
34#define POWERTUNE_DEFAULT_SET_MAX 1
35
36struct tonga_pt_defaults tonga_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = {
37/* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */
38 {1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000,
39 {0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61},
40 {0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } },
41};
42
43void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
44{
45 struct tonga_hwmgr *tonga_hwmgr = (struct tonga_hwmgr *)(hwmgr->backend);
46 struct phm_ppt_v1_information *table_info =
47 (struct phm_ppt_v1_information *)(hwmgr->pptable);
48 uint32_t tmp = 0;
49
50 if (table_info &&
51 table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX &&
52 table_info->cac_dtp_table->usPowerTuneDataSetID)
53 tonga_hwmgr->power_tune_defaults =
54 &tonga_power_tune_data_set_array
55 [table_info->cac_dtp_table->usPowerTuneDataSetID - 1];
56 else
57 tonga_hwmgr->power_tune_defaults = &tonga_power_tune_data_set_array[0];
58
59 /* Assume disabled */
60 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
61 PHM_PlatformCaps_PowerContainment);
62 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
63 PHM_PlatformCaps_CAC);
64 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
65 PHM_PlatformCaps_SQRamping);
66 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
67 PHM_PlatformCaps_DBRamping);
68 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
69 PHM_PlatformCaps_TDRamping);
70 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
71 PHM_PlatformCaps_TCPRamping);
72
73 tonga_hwmgr->dte_tj_offset = tmp;
74
75 if (!tmp) {
76 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
77 PHM_PlatformCaps_CAC);
78
79 tonga_hwmgr->fast_watermark_threshold = 100;
80
81 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
82 PHM_PlatformCaps_PowerContainment)) {
83 tmp = 1;
84 tonga_hwmgr->enable_dte_feature = tmp ? false : true;
85 tonga_hwmgr->enable_tdc_limit_feature = tmp ? true : false;
86 tonga_hwmgr->enable_pkg_pwr_tracking_feature = tmp ? true : false;
87 }
88 }
89}
90
91
92int tonga_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr)
93{
94 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
95 struct tonga_pt_defaults *defaults = data->power_tune_defaults;
96 SMU72_Discrete_DpmTable *dpm_table = &(data->smc_state_table);
97 struct phm_ppt_v1_information *table_info =
98 (struct phm_ppt_v1_information *)(hwmgr->pptable);
99 struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table;
100 int i, j, k;
101 uint16_t *pdef1;
102 uint16_t *pdef2;
103
104
105 /* TDP number of fraction bits are changed from 8 to 7 for Fiji
106 * as requested by SMC team
107 */
108 dpm_table->DefaultTdp = PP_HOST_TO_SMC_US(
109 (uint16_t)(cac_dtp_table->usTDP * 256));
110 dpm_table->TargetTdp = PP_HOST_TO_SMC_US(
111 (uint16_t)(cac_dtp_table->usConfigurableTDP * 256));
112
113 PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255,
114 "Target Operating Temp is out of Range!",
115 );
116
117 dpm_table->GpuTjMax = (uint8_t)(cac_dtp_table->usTargetOperatingTemp);
118 dpm_table->GpuTjHyst = 8;
119
120 dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base;
121
122 dpm_table->BAPM_TEMP_GRADIENT = PP_HOST_TO_SMC_UL(defaults->bamp_temp_gradient);
123 pdef1 = defaults->bapmti_r;
124 pdef2 = defaults->bapmti_rc;
125
126 for (i = 0; i < SMU72_DTE_ITERATIONS; i++) {
127 for (j = 0; j < SMU72_DTE_SOURCES; j++) {
128 for (k = 0; k < SMU72_DTE_SINKS; k++) {
129 dpm_table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*pdef1);
130 dpm_table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*pdef2);
131 pdef1++;
132 pdef2++;
133 }
134 }
135 }
136
137 return 0;
138}
139
140static int tonga_populate_svi_load_line(struct pp_hwmgr *hwmgr)
141{
142 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
143 const struct tonga_pt_defaults *defaults = data->power_tune_defaults;
144
145 data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en;
146 data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddC;
147 data->power_tune_table.SviLoadLineTrimVddC = 3;
148 data->power_tune_table.SviLoadLineOffsetVddC = 0;
149
150 return 0;
151}
152
153static int tonga_populate_tdc_limit(struct pp_hwmgr *hwmgr)
154{
155 uint16_t tdc_limit;
156 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
157 struct phm_ppt_v1_information *table_info =
158 (struct phm_ppt_v1_information *)(hwmgr->pptable);
159 const struct tonga_pt_defaults *defaults = data->power_tune_defaults;
160
161 /* TDC number of fraction bits are changed from 8 to 7
162 * for Fiji as requested by SMC team
163 */
164 tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 256);
165 data->power_tune_table.TDC_VDDC_PkgLimit =
166 CONVERT_FROM_HOST_TO_SMC_US(tdc_limit);
167 data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc =
168 defaults->tdc_vddc_throttle_release_limit_perc;
169 data->power_tune_table.TDC_MAWt = defaults->tdc_mawt;
170
171 return 0;
172}
173
174static int tonga_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset)
175{
176 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
177 const struct tonga_pt_defaults *defaults = data->power_tune_defaults;
178 uint32_t temp;
179
180 if (tonga_read_smc_sram_dword(hwmgr->smumgr,
181 fuse_table_offset +
182 offsetof(SMU72_Discrete_PmFuses, TdcWaterfallCtl),
183 (uint32_t *)&temp, data->sram_end))
184 PP_ASSERT_WITH_CODE(false,
185 "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!",
186 return -EINVAL);
187 else
188 data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl;
189
190 return 0;
191}
192
193static int tonga_populate_temperature_scaler(struct pp_hwmgr *hwmgr)
194{
195 int i;
196 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
197
198 /* Currently not used. Set all to zero. */
199 for (i = 0; i < 16; i++)
200 data->power_tune_table.LPMLTemperatureScaler[i] = 0;
201
202 return 0;
203}
204
205static int tonga_populate_fuzzy_fan(struct pp_hwmgr *hwmgr)
206{
207 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
208
209 if ((hwmgr->thermal_controller.advanceFanControlParameters.
210 usFanOutputSensitivity & (1 << 15)) ||
211 (hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity == 0))
212 hwmgr->thermal_controller.advanceFanControlParameters.
213 usFanOutputSensitivity = hwmgr->thermal_controller.
214 advanceFanControlParameters.usDefaultFanOutputSensitivity;
215
216 data->power_tune_table.FuzzyFan_PwmSetDelta =
217 PP_HOST_TO_SMC_US(hwmgr->thermal_controller.
218 advanceFanControlParameters.usFanOutputSensitivity);
219 return 0;
220}
221
222static int tonga_populate_gnb_lpml(struct pp_hwmgr *hwmgr)
223{
224 int i;
225 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
226
227 /* Currently not used. Set all to zero. */
228 for (i = 0; i < 16; i++)
229 data->power_tune_table.GnbLPML[i] = 0;
230
231 return 0;
232}
233
234static int tonga_min_max_vgnb_lpml_id_from_bapm_vddc(struct pp_hwmgr *hwmgr)
235{
236 return 0;
237}
238
239static int tonga_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr)
240{
241 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
242 struct phm_ppt_v1_information *table_info =
243 (struct phm_ppt_v1_information *)(hwmgr->pptable);
244 uint16_t hi_sidd = data->power_tune_table.BapmVddCBaseLeakageHiSidd;
245 uint16_t lo_sidd = data->power_tune_table.BapmVddCBaseLeakageLoSidd;
246 struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table;
247
248 hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256);
249 lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256);
250
251 data->power_tune_table.BapmVddCBaseLeakageHiSidd =
252 CONVERT_FROM_HOST_TO_SMC_US(hi_sidd);
253 data->power_tune_table.BapmVddCBaseLeakageLoSidd =
254 CONVERT_FROM_HOST_TO_SMC_US(lo_sidd);
255
256 return 0;
257}
258
259int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr)
260{
261 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
262 uint32_t pm_fuse_table_offset;
263
264 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
265 PHM_PlatformCaps_PowerContainment)) {
266 if (tonga_read_smc_sram_dword(hwmgr->smumgr,
267 SMU72_FIRMWARE_HEADER_LOCATION +
268 offsetof(SMU72_Firmware_Header, PmFuseTable),
269 &pm_fuse_table_offset, data->sram_end))
270 PP_ASSERT_WITH_CODE(false,
271 "Attempt to get pm_fuse_table_offset Failed!",
272 return -EINVAL);
273
274 /* DW6 */
275 if (tonga_populate_svi_load_line(hwmgr))
276 PP_ASSERT_WITH_CODE(false,
277 "Attempt to populate SviLoadLine Failed!",
278 return -EINVAL);
279 /* DW7 */
280 if (tonga_populate_tdc_limit(hwmgr))
281 PP_ASSERT_WITH_CODE(false,
282 "Attempt to populate TDCLimit Failed!", return -EINVAL);
283 /* DW8 */
284 if (tonga_populate_dw8(hwmgr, pm_fuse_table_offset))
285 PP_ASSERT_WITH_CODE(false,
286 "Attempt to populate TdcWaterfallCtl Failed !",
287 return -EINVAL);
288
289 /* DW9-DW12 */
290 if (tonga_populate_temperature_scaler(hwmgr) != 0)
291 PP_ASSERT_WITH_CODE(false,
292 "Attempt to populate LPMLTemperatureScaler Failed!",
293 return -EINVAL);
294
295 /* DW13-DW14 */
296 if (tonga_populate_fuzzy_fan(hwmgr))
297 PP_ASSERT_WITH_CODE(false,
298 "Attempt to populate Fuzzy Fan Control parameters Failed!",
299 return -EINVAL);
300
301 /* DW15-DW18 */
302 if (tonga_populate_gnb_lpml(hwmgr))
303 PP_ASSERT_WITH_CODE(false,
304 "Attempt to populate GnbLPML Failed!",
305 return -EINVAL);
306
307 /* DW19 */
308 if (tonga_min_max_vgnb_lpml_id_from_bapm_vddc(hwmgr))
309 PP_ASSERT_WITH_CODE(false,
310 "Attempt to populate GnbLPML Min and Max Vid Failed!",
311 return -EINVAL);
312
313 /* DW20 */
314 if (tonga_populate_bapm_vddc_base_leakage_sidd(hwmgr))
315 PP_ASSERT_WITH_CODE(false,
316 "Attempt to populate BapmVddCBaseLeakage Hi and Lo Sidd Failed!",
317 return -EINVAL);
318
319 if (tonga_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset,
320 (uint8_t *)&data->power_tune_table,
321 sizeof(struct SMU72_Discrete_PmFuses), data->sram_end))
322 PP_ASSERT_WITH_CODE(false,
323 "Attempt to download PmFuseTable Failed!",
324 return -EINVAL);
325 }
326 return 0;
327}
328
329int tonga_enable_smc_cac(struct pp_hwmgr *hwmgr)
330{
331 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
332 int result = 0;
333
334 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
335 PHM_PlatformCaps_CAC)) {
336 int smc_result;
337
338 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
339 (uint16_t)(PPSMC_MSG_EnableCac));
340 PP_ASSERT_WITH_CODE((smc_result == 0),
341 "Failed to enable CAC in SMC.", result = -1);
342
343 data->cac_enabled = (smc_result == 0) ? true : false;
344 }
345 return result;
346}
347
348int tonga_disable_smc_cac(struct pp_hwmgr *hwmgr)
349{
350 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
351 int result = 0;
352
353 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
354 PHM_PlatformCaps_CAC) && data->cac_enabled) {
355 int smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
356 (uint16_t)(PPSMC_MSG_DisableCac));
357 PP_ASSERT_WITH_CODE((smc_result == 0),
358 "Failed to disable CAC in SMC.", result = -1);
359
360 data->cac_enabled = false;
361 }
362 return result;
363}
364
365int tonga_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
366{
367 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
368
369 if (data->power_containment_features &
370 POWERCONTAINMENT_FEATURE_PkgPwrLimit)
371 return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
372 PPSMC_MSG_PkgPwrSetLimit, n);
373 return 0;
374}
375
376static int tonga_set_overdriver_target_tdp(struct pp_hwmgr *pHwMgr, uint32_t target_tdp)
377{
378 return smum_send_msg_to_smc_with_parameter(pHwMgr->smumgr,
379 PPSMC_MSG_OverDriveSetTargetTdp, target_tdp);
380}
381
382int tonga_enable_power_containment(struct pp_hwmgr *hwmgr)
383{
384 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
385 struct phm_ppt_v1_information *table_info =
386 (struct phm_ppt_v1_information *)(hwmgr->pptable);
387 int smc_result;
388 int result = 0;
389
390 data->power_containment_features = 0;
391 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
392 PHM_PlatformCaps_PowerContainment)) {
393 if (data->enable_dte_feature) {
394 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
395 (uint16_t)(PPSMC_MSG_EnableDTE));
396 PP_ASSERT_WITH_CODE((smc_result == 0),
397 "Failed to enable DTE in SMC.", result = -1;);
398 if (smc_result == 0)
399 data->power_containment_features |= POWERCONTAINMENT_FEATURE_DTE;
400 }
401
402 if (data->enable_tdc_limit_feature) {
403 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
404 (uint16_t)(PPSMC_MSG_TDCLimitEnable));
405 PP_ASSERT_WITH_CODE((smc_result == 0),
406 "Failed to enable TDCLimit in SMC.", result = -1;);
407 if (smc_result == 0)
408 data->power_containment_features |=
409 POWERCONTAINMENT_FEATURE_TDCLimit;
410 }
411
412 if (data->enable_pkg_pwr_tracking_feature) {
413 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
414 (uint16_t)(PPSMC_MSG_PkgPwrLimitEnable));
415 PP_ASSERT_WITH_CODE((smc_result == 0),
416 "Failed to enable PkgPwrTracking in SMC.", result = -1;);
417 if (smc_result == 0) {
418 struct phm_cac_tdp_table *cac_table =
419 table_info->cac_dtp_table;
420 uint32_t default_limit =
421 (uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256);
422
423 data->power_containment_features |=
424 POWERCONTAINMENT_FEATURE_PkgPwrLimit;
425
426 if (tonga_set_power_limit(hwmgr, default_limit))
427 printk(KERN_ERR "Failed to set Default Power Limit in SMC!");
428 }
429 }
430 }
431 return result;
432}
433
434int tonga_disable_power_containment(struct pp_hwmgr *hwmgr)
435{
436 struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
437 int result = 0;
438
439 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
440 PHM_PlatformCaps_PowerContainment) &&
441 data->power_containment_features) {
442 int smc_result;
443
444 if (data->power_containment_features &
445 POWERCONTAINMENT_FEATURE_TDCLimit) {
446 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
447 (uint16_t)(PPSMC_MSG_TDCLimitDisable));
448 PP_ASSERT_WITH_CODE((smc_result == 0),
449 "Failed to disable TDCLimit in SMC.",
450 result = smc_result);
451 }
452
453 if (data->power_containment_features &
454 POWERCONTAINMENT_FEATURE_DTE) {
455 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
456 (uint16_t)(PPSMC_MSG_DisableDTE));
457 PP_ASSERT_WITH_CODE((smc_result == 0),
458 "Failed to disable DTE in SMC.",
459 result = smc_result);
460 }
461
462 if (data->power_containment_features &
463 POWERCONTAINMENT_FEATURE_PkgPwrLimit) {
464 smc_result = smum_send_msg_to_smc(hwmgr->smumgr,
465 (uint16_t)(PPSMC_MSG_PkgPwrLimitDisable));
466 PP_ASSERT_WITH_CODE((smc_result == 0),
467 "Failed to disable PkgPwrTracking in SMC.",
468 result = smc_result);
469 }
470 data->power_containment_features = 0;
471 }
472
473 return result;
474}
475
476int tonga_power_control_set_level(struct pp_hwmgr *hwmgr)
477{
478 struct phm_ppt_v1_information *table_info =
479 (struct phm_ppt_v1_information *)(hwmgr->pptable);
480 struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table;
481 int adjust_percent, target_tdp;
482 int result = 0;
483
484 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
485 PHM_PlatformCaps_PowerContainment)) {
486 /* adjustment percentage has already been validated */
487 adjust_percent = hwmgr->platform_descriptor.TDPAdjustmentPolarity ?
488 hwmgr->platform_descriptor.TDPAdjustment :
489 (-1 * hwmgr->platform_descriptor.TDPAdjustment);
490 /* SMC requested that target_tdp to be 7 bit fraction in DPM table
491 * but message to be 8 bit fraction for messages
492 */
493 target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 256)) / 100;
494 result = tonga_set_overdriver_target_tdp(hwmgr, (uint32_t)target_tdp);
495 }
496
497 return result;
498}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h
index 8e6670b3cb67..c8bdb92d81f4 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h
@@ -35,20 +35,23 @@ enum _phw_tonga_ptc_config_reg_type {
35typedef enum _phw_tonga_ptc_config_reg_type phw_tonga_ptc_config_reg_type; 35typedef enum _phw_tonga_ptc_config_reg_type phw_tonga_ptc_config_reg_type;
36 36
37/* PowerContainment Features */ 37/* PowerContainment Features */
38#define POWERCONTAINMENT_FEATURE_DTE 0x00000001
39
40
41/* PowerContainment Features */
38#define POWERCONTAINMENT_FEATURE_BAPM 0x00000001 42#define POWERCONTAINMENT_FEATURE_BAPM 0x00000001
39#define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002 43#define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002
40#define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004 44#define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004
41 45
42struct _phw_tonga_pt_config_reg { 46struct tonga_pt_config_reg {
43 uint32_t Offset; 47 uint32_t Offset;
44 uint32_t Mask; 48 uint32_t Mask;
45 uint32_t Shift; 49 uint32_t Shift;
46 uint32_t Value; 50 uint32_t Value;
47 phw_tonga_ptc_config_reg_type Type; 51 phw_tonga_ptc_config_reg_type Type;
48}; 52};
49typedef struct _phw_tonga_pt_config_reg phw_tonga_pt_config_reg;
50 53
51struct _phw_tonga_pt_defaults { 54struct tonga_pt_defaults {
52 uint8_t svi_load_line_en; 55 uint8_t svi_load_line_en;
53 uint8_t svi_load_line_vddC; 56 uint8_t svi_load_line_vddC;
54 uint8_t tdc_vddc_throttle_release_limit_perc; 57 uint8_t tdc_vddc_throttle_release_limit_perc;
@@ -60,7 +63,18 @@ struct _phw_tonga_pt_defaults {
60 uint16_t bapmti_r[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; 63 uint16_t bapmti_r[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS];
61 uint16_t bapmti_rc[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; 64 uint16_t bapmti_rc[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS];
62}; 65};
63typedef struct _phw_tonga_pt_defaults phw_tonga_pt_defaults; 66
67
68
69void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr);
70int tonga_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr);
71int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr);
72int tonga_enable_smc_cac(struct pp_hwmgr *hwmgr);
73int tonga_disable_smc_cac(struct pp_hwmgr *hwmgr);
74int tonga_enable_power_containment(struct pp_hwmgr *hwmgr);
75int tonga_disable_power_containment(struct pp_hwmgr *hwmgr);
76int tonga_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n);
77int tonga_power_control_set_level(struct pp_hwmgr *hwmgr);
64 78
65#endif 79#endif
66 80
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
index b764c8c05ec8..3f8172f545b0 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
@@ -132,8 +132,10 @@ struct amd_pp_init {
132 uint32_t chip_family; 132 uint32_t chip_family;
133 uint32_t chip_id; 133 uint32_t chip_id;
134 uint32_t rev_id; 134 uint32_t rev_id;
135 bool powercontainment_enabled; 135 uint16_t sub_sys_id;
136 uint16_t sub_vendor_id;
136}; 137};
138
137enum amd_pp_display_config_type{ 139enum amd_pp_display_config_type{
138 AMD_PP_DisplayConfigType_None = 0, 140 AMD_PP_DisplayConfigType_None = 0,
139 AMD_PP_DisplayConfigType_DP54 , 141 AMD_PP_DisplayConfigType_DP54 ,
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index bf0d2accf7bf..36b4ec9c9cb1 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -41,6 +41,9 @@ struct phm_fan_speed_info;
41struct pp_atomctrl_voltage_table; 41struct pp_atomctrl_voltage_table;
42 42
43 43
44extern int amdgpu_powercontainment;
45extern int amdgpu_sclk_deep_sleep_en;
46
44enum DISPLAY_GAP { 47enum DISPLAY_GAP {
45 DISPLAY_GAP_VBLANK_OR_WM = 0, /* Wait for vblank or MCHG watermark. */ 48 DISPLAY_GAP_VBLANK_OR_WM = 0, /* Wait for vblank or MCHG watermark. */
46 DISPLAY_GAP_VBLANK = 1, /* Wait for vblank. */ 49 DISPLAY_GAP_VBLANK = 1, /* Wait for vblank. */
@@ -614,7 +617,6 @@ struct pp_hwmgr {
614 uint32_t num_ps; 617 uint32_t num_ps;
615 struct pp_thermal_controller_info thermal_controller; 618 struct pp_thermal_controller_info thermal_controller;
616 bool fan_ctrl_is_in_default_mode; 619 bool fan_ctrl_is_in_default_mode;
617 bool powercontainment_enabled;
618 uint32_t fan_ctrl_default_mode; 620 uint32_t fan_ctrl_default_mode;
619 uint32_t tmin; 621 uint32_t tmin;
620 struct phm_microcode_version_info microcode_version_info; 622 struct phm_microcode_version_info microcode_version_info;
@@ -637,16 +639,7 @@ extern int hw_init_power_state_table(struct pp_hwmgr *hwmgr);
637extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index, 639extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
638 uint32_t value, uint32_t mask); 640 uint32_t value, uint32_t mask);
639 641
640extern int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
641 uint32_t index, uint32_t value, uint32_t mask);
642
643extern uint32_t phm_read_indirect_register(struct pp_hwmgr *hwmgr,
644 uint32_t indirect_port, uint32_t index);
645 642
646extern void phm_write_indirect_register(struct pp_hwmgr *hwmgr,
647 uint32_t indirect_port,
648 uint32_t index,
649 uint32_t value);
650 643
651extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr, 644extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
652 uint32_t indirect_port, 645 uint32_t indirect_port,
@@ -654,12 +647,7 @@ extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
654 uint32_t value, 647 uint32_t value,
655 uint32_t mask); 648 uint32_t mask);
656 649
657extern void phm_wait_for_indirect_register_unequal( 650
658 struct pp_hwmgr *hwmgr,
659 uint32_t indirect_port,
660 uint32_t index,
661 uint32_t value,
662 uint32_t mask);
663 651
664extern bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr); 652extern bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr);
665extern bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr); 653extern bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr);
@@ -697,43 +685,7 @@ extern void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr);
697 PHM_FIELD_SHIFT(reg, field)) 685 PHM_FIELD_SHIFT(reg, field))
698 686
699 687
700#define PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, index, value, mask) \
701 phm_wait_on_register(hwmgr, index, value, mask)
702
703#define PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, index, value, mask) \
704 phm_wait_for_register_unequal(hwmgr, index, value, mask)
705
706#define PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask) \
707 phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX, index, value, mask)
708
709#define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask) \
710 phm_wait_for_indirect_register_unequal(hwmgr, mm##port##_INDEX, index, value, mask)
711 688
712#define PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask) \
713 phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX_0, index, value, mask)
714
715#define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask) \
716 phm_wait_for_indirect_register_unequal(hwmgr, mm##port##_INDEX_0, index, value, mask)
717
718/* Operations on named registers. */
719
720#define PHM_WAIT_REGISTER(hwmgr, reg, value, mask) \
721 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg, value, mask)
722
723#define PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, value, mask) \
724 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg, value, mask)
725
726#define PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, value, mask) \
727 PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
728
729#define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask) \
730 PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
731
732#define PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, value, mask) \
733 PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
734
735#define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask) \
736 PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
737 689
738/* Operations on named fields. */ 690/* Operations on named fields. */
739 691
@@ -762,60 +714,16 @@ extern void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr);
762 PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \ 714 PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
763 reg, field, fieldval)) 715 reg, field, fieldval))
764 716
765#define PHM_WAIT_FIELD(hwmgr, reg, field, fieldval) \ 717#define PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask) \
766 PHM_WAIT_REGISTER(hwmgr, reg, (fieldval) \ 718 phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX, index, value, mask)
767 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
768 719
769#define PHM_WAIT_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval) \
770 PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval) \
771 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
772 720
773#define PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval) \ 721#define PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, value, mask) \
774 PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval) \ 722 PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
775 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
776 723
777#define PHM_WAIT_FIELD_UNEQUAL(hwmgr, reg, field, fieldval) \ 724#define PHM_WAIT_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval) \
778 PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, (fieldval) \ 725 PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval) \
779 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
780
781#define PHM_WAIT_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval) \
782 PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, (fieldval) \
783 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
784
785#define PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval) \
786 PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, (fieldval) \
787 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field)) 726 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
788 727
789/* Operations on arrays of registers & fields. */
790
791#define PHM_READ_ARRAY_REGISTER(device, reg, offset) \
792 cgs_read_register(device, mm##reg + (offset))
793
794#define PHM_WRITE_ARRAY_REGISTER(device, reg, offset, value) \
795 cgs_write_register(device, mm##reg + (offset), value)
796
797#define PHM_WAIT_ARRAY_REGISTER(hwmgr, reg, offset, value, mask) \
798 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg + (offset), value, mask)
799
800#define PHM_WAIT_ARRAY_REGISTER_UNEQUAL(hwmgr, reg, offset, value, mask) \
801 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg + (offset), value, mask)
802
803#define PHM_READ_ARRAY_FIELD(hwmgr, reg, offset, field) \
804 PHM_GET_FIELD(PHM_READ_ARRAY_REGISTER(hwmgr->device, reg, offset), reg, field)
805
806#define PHM_WRITE_ARRAY_FIELD(hwmgr, reg, offset, field, fieldvalue) \
807 PHM_WRITE_ARRAY_REGISTER(hwmgr->device, reg, offset, \
808 PHM_SET_FIELD(PHM_READ_ARRAY_REGISTER(hwmgr->device, reg, offset), \
809 reg, field, fieldvalue))
810
811#define PHM_WAIT_ARRAY_FIELD(hwmgr, reg, offset, field, fieldvalue) \
812 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg + (offset), \
813 (fieldvalue) << PHM_FIELD_SHIFT(reg, field), \
814 PHM_FIELD_MASK(reg, field))
815
816#define PHM_WAIT_ARRAY_FIELD_UNEQUAL(hwmgr, reg, offset, field, fieldvalue) \
817 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg + (offset), \
818 (fieldvalue) << PHM_FIELD_SHIFT(reg, field), \
819 PHM_FIELD_MASK(reg, field))
820 728
821#endif /* _HWMGR_H_ */ 729#endif /* _HWMGR_H_ */
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu71.h b/drivers/gpu/drm/amd/powerplay/inc/smu71.h
new file mode 100644
index 000000000000..71c9b2d28640
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu71.h
@@ -0,0 +1,510 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef SMU71_H
24#define SMU71_H
25
26#if !defined(SMC_MICROCODE)
27#pragma pack(push, 1)
28#endif
29
30#define SMU__NUM_PCIE_DPM_LEVELS 8
31#define SMU__NUM_SCLK_DPM_STATE 8
32#define SMU__NUM_MCLK_DPM_LEVELS 4
33#define SMU__VARIANT__ICELAND 1
34#define SMU__DGPU_ONLY 1
35#define SMU__DYNAMIC_MCARB_SETTINGS 1
36
37enum SID_OPTION {
38 SID_OPTION_HI,
39 SID_OPTION_LO,
40 SID_OPTION_COUNT
41};
42
43typedef struct {
44 uint32_t high;
45 uint32_t low;
46} data_64_t;
47
48typedef struct {
49 data_64_t high;
50 data_64_t low;
51} data_128_t;
52
53#define SMU7_CONTEXT_ID_SMC 1
54#define SMU7_CONTEXT_ID_VBIOS 2
55
56#define SMU71_MAX_LEVELS_VDDC 8
57#define SMU71_MAX_LEVELS_VDDCI 4
58#define SMU71_MAX_LEVELS_MVDD 4
59#define SMU71_MAX_LEVELS_VDDNB 8
60
61#define SMU71_MAX_LEVELS_GRAPHICS SMU__NUM_SCLK_DPM_STATE
62#define SMU71_MAX_LEVELS_MEMORY SMU__NUM_MCLK_DPM_LEVELS
63#define SMU71_MAX_LEVELS_GIO SMU__NUM_LCLK_DPM_LEVELS
64#define SMU71_MAX_LEVELS_LINK SMU__NUM_PCIE_DPM_LEVELS
65#define SMU71_MAX_ENTRIES_SMIO 32
66
67#define DPM_NO_LIMIT 0
68#define DPM_NO_UP 1
69#define DPM_GO_DOWN 2
70#define DPM_GO_UP 3
71
72#define SMU7_FIRST_DPM_GRAPHICS_LEVEL 0
73#define SMU7_FIRST_DPM_MEMORY_LEVEL 0
74
75#define GPIO_CLAMP_MODE_VRHOT 1
76#define GPIO_CLAMP_MODE_THERM 2
77#define GPIO_CLAMP_MODE_DC 4
78
79#define SCRATCH_B_TARG_PCIE_INDEX_SHIFT 0
80#define SCRATCH_B_TARG_PCIE_INDEX_MASK (0x7<<SCRATCH_B_TARG_PCIE_INDEX_SHIFT)
81#define SCRATCH_B_CURR_PCIE_INDEX_SHIFT 3
82#define SCRATCH_B_CURR_PCIE_INDEX_MASK (0x7<<SCRATCH_B_CURR_PCIE_INDEX_SHIFT)
83#define SCRATCH_B_TARG_UVD_INDEX_SHIFT 6
84#define SCRATCH_B_TARG_UVD_INDEX_MASK (0x7<<SCRATCH_B_TARG_UVD_INDEX_SHIFT)
85#define SCRATCH_B_CURR_UVD_INDEX_SHIFT 9
86#define SCRATCH_B_CURR_UVD_INDEX_MASK (0x7<<SCRATCH_B_CURR_UVD_INDEX_SHIFT)
87#define SCRATCH_B_TARG_VCE_INDEX_SHIFT 12
88#define SCRATCH_B_TARG_VCE_INDEX_MASK (0x7<<SCRATCH_B_TARG_VCE_INDEX_SHIFT)
89#define SCRATCH_B_CURR_VCE_INDEX_SHIFT 15
90#define SCRATCH_B_CURR_VCE_INDEX_MASK (0x7<<SCRATCH_B_CURR_VCE_INDEX_SHIFT)
91#define SCRATCH_B_TARG_ACP_INDEX_SHIFT 18
92#define SCRATCH_B_TARG_ACP_INDEX_MASK (0x7<<SCRATCH_B_TARG_ACP_INDEX_SHIFT)
93#define SCRATCH_B_CURR_ACP_INDEX_SHIFT 21
94#define SCRATCH_B_CURR_ACP_INDEX_MASK (0x7<<SCRATCH_B_CURR_ACP_INDEX_SHIFT)
95#define SCRATCH_B_TARG_SAMU_INDEX_SHIFT 24
96#define SCRATCH_B_TARG_SAMU_INDEX_MASK (0x7<<SCRATCH_B_TARG_SAMU_INDEX_SHIFT)
97#define SCRATCH_B_CURR_SAMU_INDEX_SHIFT 27
98#define SCRATCH_B_CURR_SAMU_INDEX_MASK (0x7<<SCRATCH_B_CURR_SAMU_INDEX_SHIFT)
99
100
101#if defined SMU__DGPU_ONLY
102#define SMU71_DTE_ITERATIONS 5
103#define SMU71_DTE_SOURCES 3
104#define SMU71_DTE_SINKS 1
105#define SMU71_NUM_CPU_TES 0
106#define SMU71_NUM_GPU_TES 1
107#define SMU71_NUM_NON_TES 2
108
109#endif
110
111#if defined SMU__FUSION_ONLY
112#define SMU7_DTE_ITERATIONS 5
113#define SMU7_DTE_SOURCES 5
114#define SMU7_DTE_SINKS 3
115#define SMU7_NUM_CPU_TES 2
116#define SMU7_NUM_GPU_TES 1
117#define SMU7_NUM_NON_TES 2
118
119#endif
120
121struct SMU71_PIDController
122{
123 uint32_t Ki;
124 int32_t LFWindupUpperLim;
125 int32_t LFWindupLowerLim;
126 uint32_t StatePrecision;
127 uint32_t LfPrecision;
128 uint32_t LfOffset;
129 uint32_t MaxState;
130 uint32_t MaxLfFraction;
131 uint32_t StateShift;
132};
133
134typedef struct SMU71_PIDController SMU71_PIDController;
135
136struct SMU7_LocalDpmScoreboard
137{
138 uint32_t PercentageBusy;
139
140 int32_t PIDError;
141 int32_t PIDIntegral;
142 int32_t PIDOutput;
143
144 uint32_t SigmaDeltaAccum;
145 uint32_t SigmaDeltaOutput;
146 uint32_t SigmaDeltaLevel;
147
148 uint32_t UtilizationSetpoint;
149
150 uint8_t TdpClampMode;
151 uint8_t TdcClampMode;
152 uint8_t ThermClampMode;
153 uint8_t VoltageBusy;
154
155 int8_t CurrLevel;
156 int8_t TargLevel;
157 uint8_t LevelChangeInProgress;
158 uint8_t UpHyst;
159
160 uint8_t DownHyst;
161 uint8_t VoltageDownHyst;
162 uint8_t DpmEnable;
163 uint8_t DpmRunning;
164
165 uint8_t DpmForce;
166 uint8_t DpmForceLevel;
167 uint8_t DisplayWatermark;
168 uint8_t McArbIndex;
169
170 uint32_t MinimumPerfSclk;
171
172 uint8_t AcpiReq;
173 uint8_t AcpiAck;
174 uint8_t GfxClkSlow;
175 uint8_t GpioClampMode;
176
177 uint8_t FpsFilterWeight;
178 uint8_t EnabledLevelsChange;
179 uint8_t DteClampMode;
180 uint8_t FpsClampMode;
181
182 uint16_t LevelResidencyCounters [SMU71_MAX_LEVELS_GRAPHICS];
183 uint16_t LevelSwitchCounters [SMU71_MAX_LEVELS_GRAPHICS];
184
185 void (*TargetStateCalculator)(uint8_t);
186 void (*SavedTargetStateCalculator)(uint8_t);
187
188 uint16_t AutoDpmInterval;
189 uint16_t AutoDpmRange;
190
191 uint8_t FpsEnabled;
192 uint8_t MaxPerfLevel;
193 uint8_t AllowLowClkInterruptToHost;
194 uint8_t FpsRunning;
195
196 uint32_t MaxAllowedFrequency;
197};
198
199typedef struct SMU7_LocalDpmScoreboard SMU7_LocalDpmScoreboard;
200
201#define SMU7_MAX_VOLTAGE_CLIENTS 12
202
203struct SMU7_VoltageScoreboard
204{
205 uint16_t CurrentVoltage;
206 uint16_t HighestVoltage;
207 uint16_t MaxVid;
208 uint8_t HighestVidOffset;
209 uint8_t CurrentVidOffset;
210#if defined (SMU__DGPU_ONLY)
211 uint8_t CurrentPhases;
212 uint8_t HighestPhases;
213#else
214 uint8_t AvsOffset;
215 uint8_t AvsOffsetApplied;
216#endif
217 uint8_t ControllerBusy;
218 uint8_t CurrentVid;
219 uint16_t RequestedVoltage[SMU7_MAX_VOLTAGE_CLIENTS];
220#if defined (SMU__DGPU_ONLY)
221 uint8_t RequestedPhases[SMU7_MAX_VOLTAGE_CLIENTS];
222#endif
223 uint8_t EnabledRequest[SMU7_MAX_VOLTAGE_CLIENTS];
224 uint8_t TargetIndex;
225 uint8_t Delay;
226 uint8_t ControllerEnable;
227 uint8_t ControllerRunning;
228 uint16_t CurrentStdVoltageHiSidd;
229 uint16_t CurrentStdVoltageLoSidd;
230#if defined (SMU__DGPU_ONLY)
231 uint16_t RequestedVddci;
232 uint16_t CurrentVddci;
233 uint16_t HighestVddci;
234 uint8_t CurrentVddciVid;
235 uint8_t TargetVddciIndex;
236#endif
237};
238
239typedef struct SMU7_VoltageScoreboard SMU7_VoltageScoreboard;
240
241// -------------------------------------------------------------------------------------------------------------------------
242#define SMU7_MAX_PCIE_LINK_SPEEDS 3 /* 0:Gen1 1:Gen2 2:Gen3 */
243
244struct SMU7_PCIeLinkSpeedScoreboard
245{
246 uint8_t DpmEnable;
247 uint8_t DpmRunning;
248 uint8_t DpmForce;
249 uint8_t DpmForceLevel;
250
251 uint8_t CurrentLinkSpeed;
252 uint8_t EnabledLevelsChange;
253 uint16_t AutoDpmInterval;
254
255 uint16_t AutoDpmRange;
256 uint16_t AutoDpmCount;
257
258 uint8_t DpmMode;
259 uint8_t AcpiReq;
260 uint8_t AcpiAck;
261 uint8_t CurrentLinkLevel;
262
263};
264
265typedef struct SMU7_PCIeLinkSpeedScoreboard SMU7_PCIeLinkSpeedScoreboard;
266
267// -------------------------------------------------------- CAC table ------------------------------------------------------
268#define SMU7_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
269#define SMU7_LKGE_LUT_NUM_OF_VOLT_ENTRIES 16
270
271#define SMU7_SCALE_I 7
272#define SMU7_SCALE_R 12
273
274struct SMU7_PowerScoreboard
275{
276 uint16_t MinVoltage;
277 uint16_t MaxVoltage;
278
279 uint32_t AvgGpuPower;
280
281 uint16_t VddcLeakagePower[SID_OPTION_COUNT];
282 uint16_t VddcSclkConstantPower[SID_OPTION_COUNT];
283 uint16_t VddcSclkDynamicPower[SID_OPTION_COUNT];
284 uint16_t VddcNonSclkDynamicPower[SID_OPTION_COUNT];
285 uint16_t VddcTotalPower[SID_OPTION_COUNT];
286 uint16_t VddcTotalCurrent[SID_OPTION_COUNT];
287 uint16_t VddcLoadVoltage[SID_OPTION_COUNT];
288 uint16_t VddcNoLoadVoltage[SID_OPTION_COUNT];
289
290 uint16_t DisplayPhyPower;
291 uint16_t PciePhyPower;
292
293 uint16_t VddciTotalPower;
294 uint16_t Vddr1TotalPower;
295
296 uint32_t RocPower;
297
298 uint32_t last_power;
299 uint32_t enableWinAvg;
300
301 uint32_t lkg_acc;
302 uint16_t VoltLkgeScaler;
303 uint16_t TempLkgeScaler;
304
305 uint32_t uvd_cac_dclk;
306 uint32_t uvd_cac_vclk;
307 uint32_t vce_cac_eclk;
308 uint32_t samu_cac_samclk;
309 uint32_t display_cac_dispclk;
310 uint32_t acp_cac_aclk;
311 uint32_t unb_cac;
312
313 uint32_t WinTime;
314
315 uint16_t GpuPwr_MAWt;
316 uint16_t FilteredVddcTotalPower;
317
318 uint8_t CalculationRepeats;
319 uint8_t WaterfallUp;
320 uint8_t WaterfallDown;
321 uint8_t WaterfallLimit;
322};
323
324typedef struct SMU7_PowerScoreboard SMU7_PowerScoreboard;
325
326// --------------------------------------------------------------------------------------------------
327
328struct SMU7_ThermalScoreboard
329{
330 int16_t GpuLimit;
331 int16_t GpuHyst;
332 uint16_t CurrGnbTemp;
333 uint16_t FilteredGnbTemp;
334 uint8_t ControllerEnable;
335 uint8_t ControllerRunning;
336 uint8_t WaterfallUp;
337 uint8_t WaterfallDown;
338 uint8_t WaterfallLimit;
339 uint8_t padding[3];
340};
341
342typedef struct SMU7_ThermalScoreboard SMU7_ThermalScoreboard;
343
344// For FeatureEnables:
345#define SMU7_SCLK_DPM_CONFIG_MASK 0x01
346#define SMU7_VOLTAGE_CONTROLLER_CONFIG_MASK 0x02
347#define SMU7_THERMAL_CONTROLLER_CONFIG_MASK 0x04
348#define SMU7_MCLK_DPM_CONFIG_MASK 0x08
349#define SMU7_UVD_DPM_CONFIG_MASK 0x10
350#define SMU7_VCE_DPM_CONFIG_MASK 0x20
351#define SMU7_ACP_DPM_CONFIG_MASK 0x40
352#define SMU7_SAMU_DPM_CONFIG_MASK 0x80
353#define SMU7_PCIEGEN_DPM_CONFIG_MASK 0x100
354
355#define SMU7_ACP_MCLK_HANDSHAKE_DISABLE 0x00000001
356#define SMU7_ACP_SCLK_HANDSHAKE_DISABLE 0x00000002
357#define SMU7_UVD_MCLK_HANDSHAKE_DISABLE 0x00000100
358#define SMU7_UVD_SCLK_HANDSHAKE_DISABLE 0x00000200
359#define SMU7_VCE_MCLK_HANDSHAKE_DISABLE 0x00010000
360#define SMU7_VCE_SCLK_HANDSHAKE_DISABLE 0x00020000
361
362// All 'soft registers' should be uint32_t.
363struct SMU71_SoftRegisters
364{
365 uint32_t RefClockFrequency;
366 uint32_t PmTimerPeriod;
367 uint32_t FeatureEnables;
368#if defined (SMU__DGPU_ONLY)
369 uint32_t PreVBlankGap;
370 uint32_t VBlankTimeout;
371 uint32_t TrainTimeGap;
372 uint32_t MvddSwitchTime;
373 uint32_t LongestAcpiTrainTime;
374 uint32_t AcpiDelay;
375 uint32_t G5TrainTime;
376 uint32_t DelayMpllPwron;
377 uint32_t VoltageChangeTimeout;
378#endif
379 uint32_t HandshakeDisables;
380
381 uint8_t DisplayPhy1Config;
382 uint8_t DisplayPhy2Config;
383 uint8_t DisplayPhy3Config;
384 uint8_t DisplayPhy4Config;
385
386 uint8_t DisplayPhy5Config;
387 uint8_t DisplayPhy6Config;
388 uint8_t DisplayPhy7Config;
389 uint8_t DisplayPhy8Config;
390
391 uint32_t AverageGraphicsActivity;
392 uint32_t AverageMemoryActivity;
393 uint32_t AverageGioActivity;
394
395 uint8_t SClkDpmEnabledLevels;
396 uint8_t MClkDpmEnabledLevels;
397 uint8_t LClkDpmEnabledLevels;
398 uint8_t PCIeDpmEnabledLevels;
399
400 uint32_t DRAM_LOG_ADDR_H;
401 uint32_t DRAM_LOG_ADDR_L;
402 uint32_t DRAM_LOG_PHY_ADDR_H;
403 uint32_t DRAM_LOG_PHY_ADDR_L;
404 uint32_t DRAM_LOG_BUFF_SIZE;
405 uint32_t UlvEnterCount;
406 uint32_t UlvTime;
407 uint32_t UcodeLoadStatus;
408 uint8_t DPMFreezeAndForced;
409 uint8_t Activity_Weight;
410 uint8_t Reserved8[2];
411 uint32_t Reserved;
412};
413
414typedef struct SMU71_SoftRegisters SMU71_SoftRegisters;
415
416struct SMU71_Firmware_Header
417{
418 uint32_t Digest[5];
419 uint32_t Version;
420 uint32_t HeaderSize;
421 uint32_t Flags;
422 uint32_t EntryPoint;
423 uint32_t CodeSize;
424 uint32_t ImageSize;
425
426 uint32_t Rtos;
427 uint32_t SoftRegisters;
428 uint32_t DpmTable;
429 uint32_t FanTable;
430 uint32_t CacConfigTable;
431 uint32_t CacStatusTable;
432
433 uint32_t mcRegisterTable;
434
435 uint32_t mcArbDramTimingTable;
436
437 uint32_t PmFuseTable;
438 uint32_t Globals;
439 uint32_t UvdDpmTable;
440 uint32_t AcpDpmTable;
441 uint32_t VceDpmTable;
442 uint32_t SamuDpmTable;
443 uint32_t UlvSettings;
444 uint32_t Reserved[37];
445 uint32_t Signature;
446};
447
448typedef struct SMU71_Firmware_Header SMU71_Firmware_Header;
449
450struct SMU7_HystController_Data
451{
452 uint8_t waterfall_up;
453 uint8_t waterfall_down;
454 uint8_t pstate;
455 uint8_t clamp_mode;
456};
457
458typedef struct SMU7_HystController_Data SMU7_HystController_Data;
459
460#define SMU71_FIRMWARE_HEADER_LOCATION 0x20000
461
462enum DisplayConfig {
463 PowerDown = 1,
464 DP54x4,
465 DP54x2,
466 DP54x1,
467 DP27x4,
468 DP27x2,
469 DP27x1,
470 HDMI297,
471 HDMI162,
472 LVDS,
473 DP324x4,
474 DP324x2,
475 DP324x1
476};
477
478//#define SX_BLOCK_COUNT 8
479//#define MC_BLOCK_COUNT 1
480//#define CPL_BLOCK_COUNT 27
481
482#if defined SMU__VARIANT__ICELAND
483 #define SX_BLOCK_COUNT 8
484 #define MC_BLOCK_COUNT 1
485 #define CPL_BLOCK_COUNT 29
486#endif
487
488struct SMU7_Local_Cac {
489 uint8_t BlockId;
490 uint8_t SignalId;
491 uint8_t Threshold;
492 uint8_t Padding;
493};
494
495typedef struct SMU7_Local_Cac SMU7_Local_Cac;
496
497struct SMU7_Local_Cac_Table {
498 SMU7_Local_Cac SxLocalCac[SX_BLOCK_COUNT];
499 SMU7_Local_Cac CplLocalCac[CPL_BLOCK_COUNT];
500 SMU7_Local_Cac McLocalCac[MC_BLOCK_COUNT];
501};
502
503typedef struct SMU7_Local_Cac_Table SMU7_Local_Cac_Table;
504
505#if !defined(SMC_MICROCODE)
506#pragma pack(pop)
507#endif
508
509#endif
510
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu71_discrete.h b/drivers/gpu/drm/amd/powerplay/inc/smu71_discrete.h
new file mode 100644
index 000000000000..c0e3936d5c2e
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu71_discrete.h
@@ -0,0 +1,631 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef SMU71_DISCRETE_H
24#define SMU71_DISCRETE_H
25
26#include "smu71.h"
27
28#if !defined(SMC_MICROCODE)
29#pragma pack(push, 1)
30#endif
31
32#define VDDC_ON_SVI2 0x1
33#define VDDCI_ON_SVI2 0x2
34#define MVDD_ON_SVI2 0x4
35
36struct SMU71_Discrete_VoltageLevel
37{
38 uint16_t Voltage;
39 uint16_t StdVoltageHiSidd;
40 uint16_t StdVoltageLoSidd;
41 uint8_t Smio;
42 uint8_t padding;
43};
44
45typedef struct SMU71_Discrete_VoltageLevel SMU71_Discrete_VoltageLevel;
46
47struct SMU71_Discrete_GraphicsLevel
48{
49 uint32_t MinVddc;
50 uint32_t MinVddcPhases;
51
52 uint32_t SclkFrequency;
53
54 uint8_t pcieDpmLevel;
55 uint8_t DeepSleepDivId;
56 uint16_t ActivityLevel;
57
58 uint32_t CgSpllFuncCntl3;
59 uint32_t CgSpllFuncCntl4;
60 uint32_t SpllSpreadSpectrum;
61 uint32_t SpllSpreadSpectrum2;
62 uint32_t CcPwrDynRm;
63 uint32_t CcPwrDynRm1;
64 uint8_t SclkDid;
65 uint8_t DisplayWatermark;
66 uint8_t EnabledForActivity;
67 uint8_t EnabledForThrottle;
68 uint8_t UpHyst;
69 uint8_t DownHyst;
70 uint8_t VoltageDownHyst;
71 uint8_t PowerThrottle;
72};
73
74typedef struct SMU71_Discrete_GraphicsLevel SMU71_Discrete_GraphicsLevel;
75
76struct SMU71_Discrete_ACPILevel
77{
78 uint32_t Flags;
79 uint32_t MinVddc;
80 uint32_t MinVddcPhases;
81 uint32_t SclkFrequency;
82 uint8_t SclkDid;
83 uint8_t DisplayWatermark;
84 uint8_t DeepSleepDivId;
85 uint8_t padding;
86 uint32_t CgSpllFuncCntl;
87 uint32_t CgSpllFuncCntl2;
88 uint32_t CgSpllFuncCntl3;
89 uint32_t CgSpllFuncCntl4;
90 uint32_t SpllSpreadSpectrum;
91 uint32_t SpllSpreadSpectrum2;
92 uint32_t CcPwrDynRm;
93 uint32_t CcPwrDynRm1;
94};
95
96typedef struct SMU71_Discrete_ACPILevel SMU71_Discrete_ACPILevel;
97
98struct SMU71_Discrete_Ulv
99{
100 uint32_t CcPwrDynRm;
101 uint32_t CcPwrDynRm1;
102 uint16_t VddcOffset;
103 uint8_t VddcOffsetVid;
104 uint8_t VddcPhase;
105 uint32_t Reserved;
106};
107
108typedef struct SMU71_Discrete_Ulv SMU71_Discrete_Ulv;
109
110struct SMU71_Discrete_MemoryLevel
111{
112 uint32_t MinVddc;
113 uint32_t MinVddcPhases;
114 uint32_t MinVddci;
115 uint32_t MinMvdd;
116
117 uint32_t MclkFrequency;
118
119 uint8_t EdcReadEnable;
120 uint8_t EdcWriteEnable;
121 uint8_t RttEnable;
122 uint8_t StutterEnable;
123
124 uint8_t StrobeEnable;
125 uint8_t StrobeRatio;
126 uint8_t EnabledForThrottle;
127 uint8_t EnabledForActivity;
128
129 uint8_t UpHyst;
130 uint8_t DownHyst;
131 uint8_t VoltageDownHyst;
132 uint8_t padding;
133
134 uint16_t ActivityLevel;
135 uint8_t DisplayWatermark;
136 uint8_t padding1;
137
138 uint32_t MpllFuncCntl;
139 uint32_t MpllFuncCntl_1;
140 uint32_t MpllFuncCntl_2;
141 uint32_t MpllAdFuncCntl;
142 uint32_t MpllDqFuncCntl;
143 uint32_t MclkPwrmgtCntl;
144 uint32_t DllCntl;
145 uint32_t MpllSs1;
146 uint32_t MpllSs2;
147};
148
149typedef struct SMU71_Discrete_MemoryLevel SMU71_Discrete_MemoryLevel;
150
151struct SMU71_Discrete_LinkLevel
152{
153 uint8_t PcieGenSpeed; ///< 0:PciE-gen1 1:PciE-gen2 2:PciE-gen3
154 uint8_t PcieLaneCount; ///< 1=x1, 2=x2, 3=x4, 4=x8, 5=x12, 6=x16
155 uint8_t EnabledForActivity;
156 uint8_t SPC;
157 uint32_t DownThreshold;
158 uint32_t UpThreshold;
159 uint32_t Reserved;
160};
161
162typedef struct SMU71_Discrete_LinkLevel SMU71_Discrete_LinkLevel;
163
164
165#ifdef SMU__DYNAMIC_MCARB_SETTINGS
166// MC ARB DRAM Timing registers.
167struct SMU71_Discrete_MCArbDramTimingTableEntry
168{
169 uint32_t McArbDramTiming;
170 uint32_t McArbDramTiming2;
171 uint8_t McArbBurstTime;
172 uint8_t padding[3];
173};
174
175typedef struct SMU71_Discrete_MCArbDramTimingTableEntry SMU71_Discrete_MCArbDramTimingTableEntry;
176
177struct SMU71_Discrete_MCArbDramTimingTable
178{
179 SMU71_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS];
180};
181
182typedef struct SMU71_Discrete_MCArbDramTimingTable SMU71_Discrete_MCArbDramTimingTable;
183#endif
184
185// UVD VCLK/DCLK state (level) definition.
186struct SMU71_Discrete_UvdLevel
187{
188 uint32_t VclkFrequency;
189 uint32_t DclkFrequency;
190 uint16_t MinVddc;
191 uint8_t MinVddcPhases;
192 uint8_t VclkDivider;
193 uint8_t DclkDivider;
194 uint8_t padding[3];
195};
196
197typedef struct SMU71_Discrete_UvdLevel SMU71_Discrete_UvdLevel;
198
199// Clocks for other external blocks (VCE, ACP, SAMU).
200struct SMU71_Discrete_ExtClkLevel
201{
202 uint32_t Frequency;
203 uint16_t MinVoltage;
204 uint8_t MinPhases;
205 uint8_t Divider;
206};
207
208typedef struct SMU71_Discrete_ExtClkLevel SMU71_Discrete_ExtClkLevel;
209
210// Everything that we need to keep track of about the current state.
211// Use this instead of copies of the GraphicsLevel and MemoryLevel structures to keep track of state parameters
212// that need to be checked later.
213// We don't need to cache everything about a state, just a few parameters.
214struct SMU71_Discrete_StateInfo
215{
216 uint32_t SclkFrequency;
217 uint32_t MclkFrequency;
218 uint32_t VclkFrequency;
219 uint32_t DclkFrequency;
220 uint32_t SamclkFrequency;
221 uint32_t AclkFrequency;
222 uint32_t EclkFrequency;
223 uint16_t MvddVoltage;
224 uint16_t padding16;
225 uint8_t DisplayWatermark;
226 uint8_t McArbIndex;
227 uint8_t McRegIndex;
228 uint8_t SeqIndex;
229 uint8_t SclkDid;
230 int8_t SclkIndex;
231 int8_t MclkIndex;
232 uint8_t PCIeGen;
233
234};
235
236typedef struct SMU71_Discrete_StateInfo SMU71_Discrete_StateInfo;
237
238
239struct SMU71_Discrete_DpmTable
240{
241 // Multi-DPM controller settings
242 SMU71_PIDController GraphicsPIDController;
243 SMU71_PIDController MemoryPIDController;
244 SMU71_PIDController LinkPIDController;
245
246 uint32_t SystemFlags;
247
248 // SMIO masks for voltage and phase controls
249 uint32_t SmioMaskVddcVid;
250 uint32_t SmioMaskVddcPhase;
251 uint32_t SmioMaskVddciVid;
252 uint32_t SmioMaskMvddVid;
253
254 uint32_t VddcLevelCount;
255 uint32_t VddciLevelCount;
256 uint32_t MvddLevelCount;
257
258 SMU71_Discrete_VoltageLevel VddcLevel [SMU71_MAX_LEVELS_VDDC];
259 SMU71_Discrete_VoltageLevel VddciLevel [SMU71_MAX_LEVELS_VDDCI];
260 SMU71_Discrete_VoltageLevel MvddLevel [SMU71_MAX_LEVELS_MVDD];
261
262 uint8_t GraphicsDpmLevelCount;
263 uint8_t MemoryDpmLevelCount;
264 uint8_t LinkLevelCount;
265 uint8_t MasterDeepSleepControl;
266
267 uint32_t Reserved[5];
268
269 // State table entries for each DPM state
270 SMU71_Discrete_GraphicsLevel GraphicsLevel [SMU71_MAX_LEVELS_GRAPHICS];
271 SMU71_Discrete_MemoryLevel MemoryACPILevel;
272 SMU71_Discrete_MemoryLevel MemoryLevel [SMU71_MAX_LEVELS_MEMORY];
273 SMU71_Discrete_LinkLevel LinkLevel [SMU71_MAX_LEVELS_LINK];
274 SMU71_Discrete_ACPILevel ACPILevel;
275
276 uint32_t SclkStepSize;
277 uint32_t Smio [SMU71_MAX_ENTRIES_SMIO];
278
279 uint8_t GraphicsBootLevel;
280 uint8_t GraphicsVoltageChangeEnable;
281 uint8_t GraphicsThermThrottleEnable;
282 uint8_t GraphicsInterval;
283
284 uint8_t VoltageInterval;
285 uint8_t ThermalInterval;
286 uint16_t TemperatureLimitHigh;
287
288 uint16_t TemperatureLimitLow;
289 uint8_t MemoryBootLevel;
290 uint8_t MemoryVoltageChangeEnable;
291
292 uint8_t MemoryInterval;
293 uint8_t MemoryThermThrottleEnable;
294 uint8_t MergedVddci;
295 uint8_t padding2;
296
297 uint16_t VoltageResponseTime;
298 uint16_t PhaseResponseTime;
299
300 uint8_t PCIeBootLinkLevel;
301 uint8_t PCIeGenInterval;
302 uint8_t DTEInterval;
303 uint8_t DTEMode;
304
305 uint8_t SVI2Enable;
306 uint8_t VRHotGpio;
307 uint8_t AcDcGpio;
308 uint8_t ThermGpio;
309
310 uint32_t DisplayCac;
311
312 uint16_t MaxPwr;
313 uint16_t NomPwr;
314
315 uint16_t FpsHighThreshold;
316 uint16_t FpsLowThreshold;
317
318 uint16_t BAPMTI_R [SMU71_DTE_ITERATIONS][SMU71_DTE_SOURCES][SMU71_DTE_SINKS];
319 uint16_t BAPMTI_RC [SMU71_DTE_ITERATIONS][SMU71_DTE_SOURCES][SMU71_DTE_SINKS];
320
321 uint8_t DTEAmbientTempBase;
322 uint8_t DTETjOffset;
323 uint8_t GpuTjMax;
324 uint8_t GpuTjHyst;
325
326 uint16_t BootVddc;
327 uint16_t BootVddci;
328
329 uint16_t BootMVdd;
330 uint16_t padding;
331
332 uint32_t BAPM_TEMP_GRADIENT;
333
334 uint32_t LowSclkInterruptThreshold;
335 uint32_t VddGfxReChkWait;
336
337 uint16_t PPM_PkgPwrLimit;
338 uint16_t PPM_TemperatureLimit;
339
340 uint16_t DefaultTdp;
341 uint16_t TargetTdp;
342};
343
344typedef struct SMU71_Discrete_DpmTable SMU71_Discrete_DpmTable;
345
346// --------------------------------------------------- AC Timing Parameters ------------------------------------------------
347#define SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE 16
348#define SMU71_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT SMU71_MAX_LEVELS_MEMORY
349
350struct SMU71_Discrete_MCRegisterAddress
351{
352 uint16_t s0;
353 uint16_t s1;
354};
355
356typedef struct SMU71_Discrete_MCRegisterAddress SMU71_Discrete_MCRegisterAddress;
357
358struct SMU71_Discrete_MCRegisterSet
359{
360 uint32_t value[SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE];
361};
362
363typedef struct SMU71_Discrete_MCRegisterSet SMU71_Discrete_MCRegisterSet;
364
365struct SMU71_Discrete_MCRegisters
366{
367 uint8_t last;
368 uint8_t reserved[3];
369 SMU71_Discrete_MCRegisterAddress address[SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE];
370 SMU71_Discrete_MCRegisterSet data[SMU71_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT];
371};
372
373typedef struct SMU71_Discrete_MCRegisters SMU71_Discrete_MCRegisters;
374
375
376// --------------------------------------------------- Fan Table -----------------------------------------------------------
377struct SMU71_Discrete_FanTable
378{
379 uint16_t FdoMode;
380 int16_t TempMin;
381 int16_t TempMed;
382 int16_t TempMax;
383 int16_t Slope1;
384 int16_t Slope2;
385 int16_t FdoMin;
386 int16_t HystUp;
387 int16_t HystDown;
388 int16_t HystSlope;
389 int16_t TempRespLim;
390 int16_t TempCurr;
391 int16_t SlopeCurr;
392 int16_t PwmCurr;
393 uint32_t RefreshPeriod;
394 int16_t FdoMax;
395 uint8_t TempSrc;
396 int8_t Padding;
397};
398
399typedef struct SMU71_Discrete_FanTable SMU71_Discrete_FanTable;
400
401#define SMU7_DISCRETE_GPIO_SCLK_DEBUG 4
402#define SMU7_DISCRETE_GPIO_SCLK_DEBUG_BIT (0x1 << SMU7_DISCRETE_GPIO_SCLK_DEBUG)
403
404struct SMU71_MclkDpmScoreboard
405{
406
407 uint32_t PercentageBusy;
408
409 int32_t PIDError;
410 int32_t PIDIntegral;
411 int32_t PIDOutput;
412
413 uint32_t SigmaDeltaAccum;
414 uint32_t SigmaDeltaOutput;
415 uint32_t SigmaDeltaLevel;
416
417 uint32_t UtilizationSetpoint;
418
419 uint8_t TdpClampMode;
420 uint8_t TdcClampMode;
421 uint8_t ThermClampMode;
422 uint8_t VoltageBusy;
423
424 int8_t CurrLevel;
425 int8_t TargLevel;
426 uint8_t LevelChangeInProgress;
427 uint8_t UpHyst;
428
429 uint8_t DownHyst;
430 uint8_t VoltageDownHyst;
431 uint8_t DpmEnable;
432 uint8_t DpmRunning;
433
434 uint8_t DpmForce;
435 uint8_t DpmForceLevel;
436 uint8_t DisplayWatermark;
437 uint8_t McArbIndex;
438
439 uint32_t MinimumPerfMclk;
440
441 uint8_t AcpiReq;
442 uint8_t AcpiAck;
443 uint8_t MclkSwitchInProgress;
444 uint8_t MclkSwitchCritical;
445
446 uint8_t TargetMclkIndex;
447 uint8_t TargetMvddIndex;
448 uint8_t MclkSwitchResult;
449
450 uint8_t EnabledLevelsChange;
451
452 uint16_t LevelResidencyCounters [SMU71_MAX_LEVELS_MEMORY];
453 uint16_t LevelSwitchCounters [SMU71_MAX_LEVELS_MEMORY];
454
455 void (*TargetStateCalculator)(uint8_t);
456 void (*SavedTargetStateCalculator)(uint8_t);
457
458 uint16_t AutoDpmInterval;
459 uint16_t AutoDpmRange;
460
461 uint16_t MclkSwitchingTime;
462 uint8_t padding[2];
463};
464
465typedef struct SMU71_MclkDpmScoreboard SMU71_MclkDpmScoreboard;
466
467struct SMU71_UlvScoreboard
468{
469 uint8_t EnterUlv;
470 uint8_t ExitUlv;
471 uint8_t UlvActive;
472 uint8_t WaitingForUlv;
473 uint8_t UlvEnable;
474 uint8_t UlvRunning;
475 uint8_t UlvMasterEnable;
476 uint8_t padding;
477 uint32_t UlvAbortedCount;
478 uint32_t UlvTimeStamp;
479};
480
481typedef struct SMU71_UlvScoreboard SMU71_UlvScoreboard;
482
483struct SMU71_VddGfxScoreboard
484{
485 uint8_t VddGfxEnable;
486 uint8_t VddGfxActive;
487 uint8_t padding[2];
488
489 uint32_t VddGfxEnteredCount;
490 uint32_t VddGfxAbortedCount;
491};
492
493typedef struct SMU71_VddGfxScoreboard SMU71_VddGfxScoreboard;
494
495struct SMU71_AcpiScoreboard {
496 uint32_t SavedInterruptMask[2];
497 uint8_t LastACPIRequest;
498 uint8_t CgBifResp;
499 uint8_t RequestType;
500 uint8_t Padding;
501 SMU71_Discrete_ACPILevel D0Level;
502};
503
504typedef struct SMU71_AcpiScoreboard SMU71_AcpiScoreboard;
505
506
507struct SMU71_Discrete_PmFuses {
508 // dw0-dw1
509 uint8_t BapmVddCVidHiSidd[8];
510
511 // dw2-dw3
512 uint8_t BapmVddCVidLoSidd[8];
513
514 // dw4-dw5
515 uint8_t VddCVid[8];
516
517 // dw6
518 uint8_t SviLoadLineEn;
519 uint8_t SviLoadLineVddC;
520 uint8_t SviLoadLineTrimVddC;
521 uint8_t SviLoadLineOffsetVddC;
522
523 // dw7
524 uint16_t TDC_VDDC_PkgLimit;
525 uint8_t TDC_VDDC_ThrottleReleaseLimitPerc;
526 uint8_t TDC_MAWt;
527
528 // dw8
529 uint8_t TdcWaterfallCtl;
530 uint8_t LPMLTemperatureMin;
531 uint8_t LPMLTemperatureMax;
532 uint8_t Reserved;
533
534 // dw9-dw12
535 uint8_t LPMLTemperatureScaler[16];
536
537 // dw13-dw14
538 int16_t FuzzyFan_ErrorSetDelta;
539 int16_t FuzzyFan_ErrorRateSetDelta;
540 int16_t FuzzyFan_PwmSetDelta;
541 uint16_t Reserved6;
542
543 // dw15
544 uint8_t GnbLPML[16];
545
546 // dw15
547 uint8_t GnbLPMLMaxVid;
548 uint8_t GnbLPMLMinVid;
549 uint8_t Reserved1[2];
550
551 // dw16
552 uint16_t BapmVddCBaseLeakageHiSidd;
553 uint16_t BapmVddCBaseLeakageLoSidd;
554};
555
556typedef struct SMU71_Discrete_PmFuses SMU71_Discrete_PmFuses;
557
558struct SMU71_Discrete_Log_Header_Table {
559 uint32_t version;
560 uint32_t asic_id;
561 uint16_t flags;
562 uint16_t entry_size;
563 uint32_t total_size;
564 uint32_t num_of_entries;
565 uint8_t type;
566 uint8_t mode;
567 uint8_t filler_0[2];
568 uint32_t filler_1[2];
569};
570
571typedef struct SMU71_Discrete_Log_Header_Table SMU71_Discrete_Log_Header_Table;
572
573struct SMU71_Discrete_Log_Cntl {
574 uint8_t Enabled;
575 uint8_t Type;
576 uint8_t padding[2];
577 uint32_t BufferSize;
578 uint32_t SamplesLogged;
579 uint32_t SampleSize;
580 uint32_t AddrL;
581 uint32_t AddrH;
582};
583
584typedef struct SMU71_Discrete_Log_Cntl SMU71_Discrete_Log_Cntl;
585
586#if defined SMU__DGPU_ONLY
587 #define CAC_ACC_NW_NUM_OF_SIGNALS 83
588#endif
589
590
591struct SMU71_Discrete_Cac_Collection_Table {
592 uint32_t temperature;
593 uint32_t cac_acc_nw[CAC_ACC_NW_NUM_OF_SIGNALS];
594 uint32_t filler[4];
595};
596
597typedef struct SMU71_Discrete_Cac_Collection_Table SMU71_Discrete_Cac_Collection_Table;
598
599struct SMU71_Discrete_Cac_Verification_Table {
600 uint32_t VddcTotalPower;
601 uint32_t VddcLeakagePower;
602 uint32_t VddcConstantPower;
603 uint32_t VddcGfxDynamicPower;
604 uint32_t VddcUvdDynamicPower;
605 uint32_t VddcVceDynamicPower;
606 uint32_t VddcAcpDynamicPower;
607 uint32_t VddcPcieDynamicPower;
608 uint32_t VddcDceDynamicPower;
609 uint32_t VddcCurrent;
610 uint32_t VddcVoltage;
611 uint32_t VddciTotalPower;
612 uint32_t VddciLeakagePower;
613 uint32_t VddciConstantPower;
614 uint32_t VddciDynamicPower;
615 uint32_t Vddr1TotalPower;
616 uint32_t Vddr1LeakagePower;
617 uint32_t Vddr1ConstantPower;
618 uint32_t Vddr1DynamicPower;
619 uint32_t spare[8];
620 uint32_t temperature;
621};
622
623typedef struct SMU71_Discrete_Cac_Verification_Table SMU71_Discrete_Cac_Verification_Table;
624
625#if !defined(SMC_MICROCODE)
626#pragma pack(pop)
627#endif
628
629
630#endif
631
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile
index f10fb64ef981..19e79469f6bc 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile
@@ -2,7 +2,8 @@
2# Makefile for the 'smu manager' sub-component of powerplay. 2# Makefile for the 'smu manager' sub-component of powerplay.
3# It provides the smu management services for the driver. 3# It provides the smu management services for the driver.
4 4
5SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o polaris10_smumgr.o 5SMU_MGR = smumgr.o cz_smumgr.o tonga_smumgr.o fiji_smumgr.o \
6 polaris10_smumgr.o iceland_smumgr.o
6 7
7AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR)) 8AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR))
8 9
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
new file mode 100644
index 000000000000..f50658332d9d
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
@@ -0,0 +1,713 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25#include <linux/types.h>
26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/gfp.h>
29
30#include "smumgr.h"
31#include "iceland_smumgr.h"
32#include "pp_debug.h"
33#include "smu_ucode_xfer_vi.h"
34#include "ppsmc.h"
35#include "smu/smu_7_1_1_d.h"
36#include "smu/smu_7_1_1_sh_mask.h"
37#include "cgs_common.h"
38
39#define ICELAND_SMC_SIZE 0x20000
40#define BUFFER_SIZE 80000
41#define MAX_STRING_SIZE 15
42#define BUFFER_SIZETWO 131072 /*128 *1024*/
43
44/**
45 * Set the address for reading/writing the SMC SRAM space.
46 * @param smumgr the address of the powerplay hardware manager.
47 * @param smcAddress the address in the SMC RAM to access.
48 */
49static int iceland_set_smc_sram_address(struct pp_smumgr *smumgr,
50 uint32_t smcAddress, uint32_t limit)
51{
52 if (smumgr == NULL || smumgr->device == NULL)
53 return -EINVAL;
54 PP_ASSERT_WITH_CODE((0 == (3 & smcAddress)),
55 "SMC address must be 4 byte aligned.",
56 return -1;);
57
58 PP_ASSERT_WITH_CODE((limit > (smcAddress + 3)),
59 "SMC address is beyond the SMC RAM area.",
60 return -1;);
61
62 cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, smcAddress);
63 SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
64
65 return 0;
66}
67
68/**
69 * Copy bytes from an array into the SMC RAM space.
70 *
71 * @param smumgr the address of the powerplay SMU manager.
72 * @param smcStartAddress the start address in the SMC RAM to copy bytes to.
73 * @param src the byte array to copy the bytes from.
74 * @param byteCount the number of bytes to copy.
75 */
76int iceland_copy_bytes_to_smc(struct pp_smumgr *smumgr,
77 uint32_t smcStartAddress, const uint8_t *src,
78 uint32_t byteCount, uint32_t limit)
79{
80 uint32_t addr;
81 uint32_t data, orig_data;
82 int result = 0;
83 uint32_t extra_shift;
84
85 if (smumgr == NULL || smumgr->device == NULL)
86 return -EINVAL;
87 PP_ASSERT_WITH_CODE((0 == (3 & smcStartAddress)),
88 "SMC address must be 4 byte aligned.",
89 return 0;);
90
91 PP_ASSERT_WITH_CODE((limit > (smcStartAddress + byteCount)),
92 "SMC address is beyond the SMC RAM area.",
93 return 0;);
94
95 addr = smcStartAddress;
96
97 while (byteCount >= 4) {
98 /*
99 * Bytes are written into the
100 * SMC address space with the MSB first
101 */
102 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
103
104 result = iceland_set_smc_sram_address(smumgr, addr, limit);
105
106 if (result)
107 goto out;
108
109 cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
110
111 src += 4;
112 byteCount -= 4;
113 addr += 4;
114 }
115
116 if (0 != byteCount) {
117 /* Now write odd bytes left, do a read modify write cycle */
118 data = 0;
119
120 result = iceland_set_smc_sram_address(smumgr, addr, limit);
121 if (result)
122 goto out;
123
124 orig_data = cgs_read_register(smumgr->device,
125 mmSMC_IND_DATA_0);
126 extra_shift = 8 * (4 - byteCount);
127
128 while (byteCount > 0) {
129 data = (data << 8) + *src++;
130 byteCount--;
131 }
132
133 data <<= extra_shift;
134 data |= (orig_data & ~((~0UL) << extra_shift));
135
136 result = iceland_set_smc_sram_address(smumgr, addr, limit);
137 if (result)
138 goto out;
139
140 cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
141 }
142
143out:
144 return result;
145}
146
147/**
148 * Deassert the reset'pin' (set it to high).
149 *
150 * @param smumgr the address of the powerplay hardware manager.
151 */
152static int iceland_start_smc(struct pp_smumgr *smumgr)
153{
154 SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
155 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
156
157 return 0;
158}
159
160static void iceland_pp_reset_smc(struct pp_smumgr *smumgr)
161{
162 SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
163 SMC_SYSCON_RESET_CNTL,
164 rst_reg, 1);
165}
166
167int iceland_program_jump_on_start(struct pp_smumgr *smumgr)
168{
169 static const unsigned char pData[] = { 0xE0, 0x00, 0x80, 0x40 };
170
171 iceland_copy_bytes_to_smc(smumgr, 0x0, pData, 4, sizeof(pData)+1);
172
173 return 0;
174}
175
176/**
177 * Return if the SMC is currently running.
178 *
179 * @param smumgr the address of the powerplay hardware manager.
180 */
181bool iceland_is_smc_ram_running(struct pp_smumgr *smumgr)
182{
183 uint32_t val1, val2;
184
185 val1 = SMUM_READ_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
186 SMC_SYSCON_CLOCK_CNTL_0, ck_disable);
187 val2 = cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC,
188 ixSMC_PC_C);
189
190 return ((0 == val1) && (0x20100 <= val2));
191}
192
193/**
194 * Send a message to the SMC, and wait for its response.
195 *
196 * @param smumgr the address of the powerplay hardware manager.
197 * @param msg the message to send.
198 * @return The response that came from the SMC.
199 */
200static int iceland_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
201{
202 if (smumgr == NULL || smumgr->device == NULL)
203 return -EINVAL;
204
205 if (!iceland_is_smc_ram_running(smumgr))
206 return -EINVAL;
207
208 SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
209 PP_ASSERT_WITH_CODE(
210 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP),
211 "Failed to send Previous Message.",
212 );
213
214 cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
215
216 SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
217 PP_ASSERT_WITH_CODE(
218 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP),
219 "Failed to send Message.",
220 );
221
222 return 0;
223}
224
225/**
226 * Send a message to the SMC with parameter
227 *
228 * @param smumgr: the address of the powerplay hardware manager.
229 * @param msg: the message to send.
230 * @param parameter: the parameter to send
231 * @return The response that came from the SMC.
232 */
233static int iceland_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
234 uint16_t msg, uint32_t parameter)
235{
236 if (smumgr == NULL || smumgr->device == NULL)
237 return -EINVAL;
238
239 cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter);
240
241 return iceland_send_msg_to_smc(smumgr, msg);
242}
243
244/*
245 * Read a 32bit value from the SMC SRAM space.
246 * ALL PARAMETERS ARE IN HOST BYTE ORDER.
247 * @param smumgr the address of the powerplay hardware manager.
248 * @param smcAddress the address in the SMC RAM to access.
249 * @param value and output parameter for the data read from the SMC SRAM.
250 */
251int iceland_read_smc_sram_dword(struct pp_smumgr *smumgr,
252 uint32_t smcAddress, uint32_t *value,
253 uint32_t limit)
254{
255 int result;
256
257 result = iceland_set_smc_sram_address(smumgr, smcAddress, limit);
258
259 if (0 != result)
260 return result;
261
262 *value = cgs_read_register(smumgr->device, mmSMC_IND_DATA_0);
263
264 return 0;
265}
266
267/*
268 * Write a 32bit value to the SMC SRAM space.
269 * ALL PARAMETERS ARE IN HOST BYTE ORDER.
270 * @param smumgr the address of the powerplay hardware manager.
271 * @param smcAddress the address in the SMC RAM to access.
272 * @param value to write to the SMC SRAM.
273 */
274int iceland_write_smc_sram_dword(struct pp_smumgr *smumgr,
275 uint32_t smcAddress, uint32_t value,
276 uint32_t limit)
277{
278 int result;
279
280 result = iceland_set_smc_sram_address(smumgr, smcAddress, limit);
281
282 if (0 != result)
283 return result;
284
285 cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, value);
286
287 return 0;
288}
289
290static int iceland_smu_fini(struct pp_smumgr *smumgr)
291{
292 struct iceland_smumgr *priv = (struct iceland_smumgr *)(smumgr->backend);
293
294 smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle);
295
296 if (smumgr->backend != NULL) {
297 kfree(smumgr->backend);
298 smumgr->backend = NULL;
299 }
300
301 cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU);
302 return 0;
303}
304
305static enum cgs_ucode_id iceland_convert_fw_type_to_cgs(uint32_t fw_type)
306{
307 enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM;
308
309 switch (fw_type) {
310 case UCODE_ID_SMU:
311 result = CGS_UCODE_ID_SMU;
312 break;
313 case UCODE_ID_SDMA0:
314 result = CGS_UCODE_ID_SDMA0;
315 break;
316 case UCODE_ID_SDMA1:
317 result = CGS_UCODE_ID_SDMA1;
318 break;
319 case UCODE_ID_CP_CE:
320 result = CGS_UCODE_ID_CP_CE;
321 break;
322 case UCODE_ID_CP_PFP:
323 result = CGS_UCODE_ID_CP_PFP;
324 break;
325 case UCODE_ID_CP_ME:
326 result = CGS_UCODE_ID_CP_ME;
327 break;
328 case UCODE_ID_CP_MEC:
329 result = CGS_UCODE_ID_CP_MEC;
330 break;
331 case UCODE_ID_CP_MEC_JT1:
332 result = CGS_UCODE_ID_CP_MEC_JT1;
333 break;
334 case UCODE_ID_CP_MEC_JT2:
335 result = CGS_UCODE_ID_CP_MEC_JT2;
336 break;
337 case UCODE_ID_RLC_G:
338 result = CGS_UCODE_ID_RLC_G;
339 break;
340 default:
341 break;
342 }
343
344 return result;
345}
346
347/**
348 * Convert the PPIRI firmware type to SMU type mask.
349 * For MEC, we need to check all MEC related type
350 */
351static uint16_t iceland_get_mask_for_firmware_type(uint16_t firmwareType)
352{
353 uint16_t result = 0;
354
355 switch (firmwareType) {
356 case UCODE_ID_SDMA0:
357 result = UCODE_ID_SDMA0_MASK;
358 break;
359 case UCODE_ID_SDMA1:
360 result = UCODE_ID_SDMA1_MASK;
361 break;
362 case UCODE_ID_CP_CE:
363 result = UCODE_ID_CP_CE_MASK;
364 break;
365 case UCODE_ID_CP_PFP:
366 result = UCODE_ID_CP_PFP_MASK;
367 break;
368 case UCODE_ID_CP_ME:
369 result = UCODE_ID_CP_ME_MASK;
370 break;
371 case UCODE_ID_CP_MEC:
372 case UCODE_ID_CP_MEC_JT1:
373 case UCODE_ID_CP_MEC_JT2:
374 result = UCODE_ID_CP_MEC_MASK;
375 break;
376 case UCODE_ID_RLC_G:
377 result = UCODE_ID_RLC_G_MASK;
378 break;
379 default:
380 break;
381 }
382
383 return result;
384}
385
386/**
387 * Check if the FW has been loaded,
388 * SMU will not return if loading has not finished.
389*/
390static int iceland_check_fw_load_finish(struct pp_smumgr *smumgr, uint32_t fwType)
391{
392 uint16_t fwMask = iceland_get_mask_for_firmware_type(fwType);
393
394 if (0 != SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, SMC_IND,
395 SOFT_REGISTERS_TABLE_27, fwMask, fwMask)) {
396 pr_err("[ powerplay ] check firmware loading failed\n");
397 return -EINVAL;
398 }
399
400 return 0;
401}
402
403/* Populate one firmware image to the data structure */
404static int iceland_populate_single_firmware_entry(struct pp_smumgr *smumgr,
405 uint16_t firmware_type,
406 struct SMU_Entry *pentry)
407{
408 int result;
409 struct cgs_firmware_info info = {0};
410
411 result = cgs_get_firmware_info(
412 smumgr->device,
413 iceland_convert_fw_type_to_cgs(firmware_type),
414 &info);
415
416 if (result == 0) {
417 pentry->version = 0;
418 pentry->id = (uint16_t)firmware_type;
419 pentry->image_addr_high = smu_upper_32_bits(info.mc_addr);
420 pentry->image_addr_low = smu_lower_32_bits(info.mc_addr);
421 pentry->meta_data_addr_high = 0;
422 pentry->meta_data_addr_low = 0;
423 pentry->data_size_byte = info.image_size;
424 pentry->num_register_entries = 0;
425
426 if (firmware_type == UCODE_ID_RLC_G)
427 pentry->flags = 1;
428 else
429 pentry->flags = 0;
430 } else {
431 return result;
432 }
433
434 return result;
435}
436
437static void iceland_pp_stop_smc_clock(struct pp_smumgr *smumgr)
438{
439 SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
440 SMC_SYSCON_CLOCK_CNTL_0,
441 ck_disable, 1);
442}
443
444static void iceland_start_smc_clock(struct pp_smumgr *smumgr)
445{
446 SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
447 SMC_SYSCON_CLOCK_CNTL_0,
448 ck_disable, 0);
449}
450
451int iceland_smu_start_smc(struct pp_smumgr *smumgr)
452{
453 /* set smc instruct start point at 0x0 */
454 iceland_program_jump_on_start(smumgr);
455
456 /* enable smc clock */
457 iceland_start_smc_clock(smumgr);
458
459 /* de-assert reset */
460 iceland_start_smc(smumgr);
461
462 SMUM_WAIT_INDIRECT_FIELD(smumgr, SMC_IND, FIRMWARE_FLAGS,
463 INTERRUPTS_ENABLED, 1);
464
465 return 0;
466}
467
468/**
469 * Upload the SMC firmware to the SMC microcontroller.
470 *
471 * @param smumgr the address of the powerplay hardware manager.
472 * @param pFirmware the data structure containing the various sections of the firmware.
473 */
474int iceland_smu_upload_firmware_image(struct pp_smumgr *smumgr)
475{
476 const uint8_t *src;
477 uint32_t byte_count, val;
478 uint32_t data;
479 struct cgs_firmware_info info = {0};
480
481 if (smumgr == NULL || smumgr->device == NULL)
482 return -EINVAL;
483
484 /* load SMC firmware */
485 cgs_get_firmware_info(smumgr->device,
486 iceland_convert_fw_type_to_cgs(UCODE_ID_SMU), &info);
487
488 if (info.image_size & 3) {
489 pr_err("[ powerplay ] SMC ucode is not 4 bytes aligned\n");
490 return -EINVAL;
491 }
492
493 if (info.image_size > ICELAND_SMC_SIZE) {
494 pr_err("[ powerplay ] SMC address is beyond the SMC RAM area\n");
495 return -EINVAL;
496 }
497
498 /* wait for smc boot up */
499 SMUM_WAIT_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
500 RCU_UC_EVENTS, boot_seq_done, 0);
501
502 /* clear firmware interrupt enable flag */
503 val = cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC,
504 ixSMC_SYSCON_MISC_CNTL);
505 cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
506 ixSMC_SYSCON_MISC_CNTL, val | 1);
507
508 /* stop smc clock */
509 iceland_pp_stop_smc_clock(smumgr);
510
511 /* reset smc */
512 iceland_pp_reset_smc(smumgr);
513
514 cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0,
515 info.ucode_start_address);
516
517 SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL,
518 AUTO_INCREMENT_IND_0, 1);
519
520 byte_count = info.image_size;
521 src = (const uint8_t *)info.kptr;
522
523 while (byte_count >= 4) {
524 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
525 cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
526 src += 4;
527 byte_count -= 4;
528 }
529
530 SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL,
531 AUTO_INCREMENT_IND_0, 0);
532
533 return 0;
534}
535
536static int iceland_request_smu_reload_fw(struct pp_smumgr *smumgr)
537{
538 struct iceland_smumgr *iceland_smu =
539 (struct iceland_smumgr *)(smumgr->backend);
540 uint16_t fw_to_load;
541 int result = 0;
542 struct SMU_DRAMData_TOC *toc;
543
544 toc = (struct SMU_DRAMData_TOC *)iceland_smu->pHeader;
545 toc->num_entries = 0;
546 toc->structure_version = 1;
547
548 PP_ASSERT_WITH_CODE(
549 0 == iceland_populate_single_firmware_entry(smumgr,
550 UCODE_ID_RLC_G,
551 &toc->entry[toc->num_entries++]),
552 "Failed to Get Firmware Entry.\n",
553 return -1);
554 PP_ASSERT_WITH_CODE(
555 0 == iceland_populate_single_firmware_entry(smumgr,
556 UCODE_ID_CP_CE,
557 &toc->entry[toc->num_entries++]),
558 "Failed to Get Firmware Entry.\n",
559 return -1);
560 PP_ASSERT_WITH_CODE(
561 0 == iceland_populate_single_firmware_entry
562 (smumgr, UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]),
563 "Failed to Get Firmware Entry.\n", return -1);
564 PP_ASSERT_WITH_CODE(
565 0 == iceland_populate_single_firmware_entry
566 (smumgr, UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]),
567 "Failed to Get Firmware Entry.\n", return -1);
568 PP_ASSERT_WITH_CODE(
569 0 == iceland_populate_single_firmware_entry
570 (smumgr, UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]),
571 "Failed to Get Firmware Entry.\n", return -1);
572 PP_ASSERT_WITH_CODE(
573 0 == iceland_populate_single_firmware_entry
574 (smumgr, UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]),
575 "Failed to Get Firmware Entry.\n", return -1);
576 PP_ASSERT_WITH_CODE(
577 0 == iceland_populate_single_firmware_entry
578 (smumgr, UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]),
579 "Failed to Get Firmware Entry.\n", return -1);
580 PP_ASSERT_WITH_CODE(
581 0 == iceland_populate_single_firmware_entry
582 (smumgr, UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]),
583 "Failed to Get Firmware Entry.\n", return -1);
584 PP_ASSERT_WITH_CODE(
585 0 == iceland_populate_single_firmware_entry
586 (smumgr, UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]),
587 "Failed to Get Firmware Entry.\n", return -1);
588
589 if (!iceland_is_smc_ram_running(smumgr)) {
590 result = iceland_smu_upload_firmware_image(smumgr);
591 if (result)
592 return result;
593
594 result = iceland_smu_start_smc(smumgr);
595 if (result)
596 return result;
597 }
598
599 iceland_send_msg_to_smc_with_parameter(smumgr,
600 PPSMC_MSG_DRV_DRAM_ADDR_HI,
601 iceland_smu->header_buffer.mc_addr_high);
602
603 iceland_send_msg_to_smc_with_parameter(smumgr,
604 PPSMC_MSG_DRV_DRAM_ADDR_LO,
605 iceland_smu->header_buffer.mc_addr_low);
606
607 fw_to_load = UCODE_ID_RLC_G_MASK
608 + UCODE_ID_SDMA0_MASK
609 + UCODE_ID_SDMA1_MASK
610 + UCODE_ID_CP_CE_MASK
611 + UCODE_ID_CP_ME_MASK
612 + UCODE_ID_CP_PFP_MASK
613 + UCODE_ID_CP_MEC_MASK
614 + UCODE_ID_CP_MEC_JT1_MASK
615 + UCODE_ID_CP_MEC_JT2_MASK;
616
617 PP_ASSERT_WITH_CODE(
618 0 == iceland_send_msg_to_smc_with_parameter(
619 smumgr, PPSMC_MSG_LoadUcodes, fw_to_load),
620 "Fail to Request SMU Load uCode", return 0);
621
622 return result;
623}
624
625static int iceland_request_smu_load_specific_fw(struct pp_smumgr *smumgr,
626 uint32_t firmwareType)
627{
628 return 0;
629}
630
631static int iceland_start_smu(struct pp_smumgr *smumgr)
632{
633 int result;
634
635 result = iceland_smu_upload_firmware_image(smumgr);
636 if (result)
637 return result;
638
639 result = iceland_smu_start_smc(smumgr);
640 if (result)
641 return result;
642
643 result = iceland_request_smu_reload_fw(smumgr);
644
645 return result;
646}
647
648/**
649 * Write a 32bit value to the SMC SRAM space.
650 * ALL PARAMETERS ARE IN HOST BYTE ORDER.
651 * @param smumgr the address of the powerplay hardware manager.
652 * @param smcAddress the address in the SMC RAM to access.
653 * @param value to write to the SMC SRAM.
654 */
655static int iceland_smu_init(struct pp_smumgr *smumgr)
656{
657 struct iceland_smumgr *iceland_smu;
658 uint64_t mc_addr = 0;
659
660 /* Allocate memory for backend private data */
661 iceland_smu = (struct iceland_smumgr *)(smumgr->backend);
662 iceland_smu->header_buffer.data_size =
663 ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
664
665 smu_allocate_memory(smumgr->device,
666 iceland_smu->header_buffer.data_size,
667 CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB,
668 PAGE_SIZE,
669 &mc_addr,
670 &iceland_smu->header_buffer.kaddr,
671 &iceland_smu->header_buffer.handle);
672
673 iceland_smu->pHeader = iceland_smu->header_buffer.kaddr;
674 iceland_smu->header_buffer.mc_addr_high = smu_upper_32_bits(mc_addr);
675 iceland_smu->header_buffer.mc_addr_low = smu_lower_32_bits(mc_addr);
676
677 PP_ASSERT_WITH_CODE((NULL != iceland_smu->pHeader),
678 "Out of memory.",
679 kfree(smumgr->backend);
680 cgs_free_gpu_mem(smumgr->device,
681 (cgs_handle_t)iceland_smu->header_buffer.handle);
682 return -1);
683
684 return 0;
685}
686
687static const struct pp_smumgr_func iceland_smu_funcs = {
688 .smu_init = &iceland_smu_init,
689 .smu_fini = &iceland_smu_fini,
690 .start_smu = &iceland_start_smu,
691 .check_fw_load_finish = &iceland_check_fw_load_finish,
692 .request_smu_load_fw = &iceland_request_smu_reload_fw,
693 .request_smu_load_specific_fw = &iceland_request_smu_load_specific_fw,
694 .send_msg_to_smc = &iceland_send_msg_to_smc,
695 .send_msg_to_smc_with_parameter = &iceland_send_msg_to_smc_with_parameter,
696 .download_pptable_settings = NULL,
697 .upload_pptable_settings = NULL,
698};
699
700int iceland_smum_init(struct pp_smumgr *smumgr)
701{
702 struct iceland_smumgr *iceland_smu = NULL;
703
704 iceland_smu = kzalloc(sizeof(struct iceland_smumgr), GFP_KERNEL);
705
706 if (iceland_smu == NULL)
707 return -ENOMEM;
708
709 smumgr->backend = iceland_smu;
710 smumgr->smumgr_funcs = &iceland_smu_funcs;
711
712 return 0;
713}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.h
new file mode 100644
index 000000000000..62009a7ae827
--- /dev/null
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25
26#ifndef _ICELAND_SMUMGR_H_
27#define _ICELAND_SMUMGR_H_
28
29struct iceland_buffer_entry {
30 uint32_t data_size;
31 uint32_t mc_addr_low;
32 uint32_t mc_addr_high;
33 void *kaddr;
34 unsigned long handle;
35};
36
37/* Iceland only has header_buffer, don't have smu buffer. */
38struct iceland_smumgr {
39 uint8_t *pHeader;
40 uint8_t *pMecImage;
41 uint32_t ulSoftRegsStart;
42
43 struct iceland_buffer_entry header_buffer;
44};
45
46extern int iceland_smum_init(struct pp_smumgr *smumgr);
47extern int iceland_copy_bytes_to_smc(struct pp_smumgr *smumgr,
48 uint32_t smcStartAddress,
49 const uint8_t *src,
50 uint32_t byteCount, uint32_t limit);
51
52extern int iceland_smu_start_smc(struct pp_smumgr *smumgr);
53
54extern int iceland_read_smc_sram_dword(struct pp_smumgr *smumgr,
55 uint32_t smcAddress,
56 uint32_t *value, uint32_t limit);
57extern int iceland_write_smc_sram_dword(struct pp_smumgr *smumgr,
58 uint32_t smcAddress,
59 uint32_t value, uint32_t limit);
60
61extern bool iceland_is_smc_ram_running(struct pp_smumgr *smumgr);
62extern int iceland_smu_upload_firmware_image(struct pp_smumgr *smumgr);
63
64#endif
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index 5dba7c509710..704ff4cc0023 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -978,7 +978,7 @@ static int polaris10_smu_init(struct pp_smumgr *smumgr)
978 return 0; 978 return 0;
979} 979}
980 980
981static const struct pp_smumgr_func ellsemere_smu_funcs = { 981static const struct pp_smumgr_func polaris10_smu_funcs = {
982 .smu_init = polaris10_smu_init, 982 .smu_init = polaris10_smu_init,
983 .smu_fini = polaris10_smu_fini, 983 .smu_fini = polaris10_smu_fini,
984 .start_smu = polaris10_start_smu, 984 .start_smu = polaris10_start_smu,
@@ -1001,7 +1001,7 @@ int polaris10_smum_init(struct pp_smumgr *smumgr)
1001 return -1; 1001 return -1;
1002 1002
1003 smumgr->backend = polaris10_smu; 1003 smumgr->backend = polaris10_smu;
1004 smumgr->smumgr_funcs = &ellsemere_smu_funcs; 1004 smumgr->smumgr_funcs = &polaris10_smu_funcs;
1005 1005
1006 return 0; 1006 return 0;
1007} 1007}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
index 7723473e51a0..cf3cabee8918 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
@@ -30,6 +30,7 @@
30#include "linux/delay.h" 30#include "linux/delay.h"
31#include "cz_smumgr.h" 31#include "cz_smumgr.h"
32#include "tonga_smumgr.h" 32#include "tonga_smumgr.h"
33#include "iceland_smumgr.h"
33#include "fiji_smumgr.h" 34#include "fiji_smumgr.h"
34#include "polaris10_smumgr.h" 35#include "polaris10_smumgr.h"
35 36
@@ -58,6 +59,9 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
58 break; 59 break;
59 case AMDGPU_FAMILY_VI: 60 case AMDGPU_FAMILY_VI:
60 switch (smumgr->chip_id) { 61 switch (smumgr->chip_id) {
62 case CHIP_TOPAZ:
63 iceland_smum_init(smumgr);
64 break;
61 case CHIP_TONGA: 65 case CHIP_TONGA:
62 tonga_smum_init(smumgr); 66 tonga_smum_init(smumgr);
63 break; 67 break;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 7f2510524f09..7b21281c4b78 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3480,14 +3480,23 @@ out:
3480int drm_mode_page_flip_ioctl(struct drm_device *dev, 3480int drm_mode_page_flip_ioctl(struct drm_device *dev,
3481 void *data, struct drm_file *file_priv) 3481 void *data, struct drm_file *file_priv)
3482{ 3482{
3483 struct drm_mode_crtc_page_flip *page_flip = data; 3483 struct drm_mode_crtc_page_flip_target *page_flip = data;
3484 struct drm_crtc *crtc; 3484 struct drm_crtc *crtc;
3485 struct drm_framebuffer *fb = NULL; 3485 struct drm_framebuffer *fb = NULL;
3486 struct drm_pending_vblank_event *e = NULL; 3486 struct drm_pending_vblank_event *e = NULL;
3487 u32 target_vblank = page_flip->sequence;
3487 int ret = -EINVAL; 3488 int ret = -EINVAL;
3488 3489
3489 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || 3490 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS)
3490 page_flip->reserved != 0) 3491 return -EINVAL;
3492
3493 if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET))
3494 return -EINVAL;
3495
3496 /* Only one of the DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags
3497 * can be specified
3498 */
3499 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET)
3491 return -EINVAL; 3500 return -EINVAL;
3492 3501
3493 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip) 3502 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
@@ -3497,6 +3506,45 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
3497 if (!crtc) 3506 if (!crtc)
3498 return -ENOENT; 3507 return -ENOENT;
3499 3508
3509 if (crtc->funcs->page_flip_target) {
3510 u32 current_vblank;
3511 int r;
3512
3513 r = drm_crtc_vblank_get(crtc);
3514 if (r)
3515 return r;
3516
3517 current_vblank = drm_crtc_vblank_count(crtc);
3518
3519 switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) {
3520 case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE:
3521 if ((int)(target_vblank - current_vblank) > 1) {
3522 DRM_DEBUG("Invalid absolute flip target %u, "
3523 "must be <= %u\n", target_vblank,
3524 current_vblank + 1);
3525 drm_crtc_vblank_put(crtc);
3526 return -EINVAL;
3527 }
3528 break;
3529 case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE:
3530 if (target_vblank != 0 && target_vblank != 1) {
3531 DRM_DEBUG("Invalid relative flip target %u, "
3532 "must be 0 or 1\n", target_vblank);
3533 drm_crtc_vblank_put(crtc);
3534 return -EINVAL;
3535 }
3536 target_vblank += current_vblank;
3537 break;
3538 default:
3539 target_vblank = current_vblank +
3540 !(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC);
3541 break;
3542 }
3543 } else if (crtc->funcs->page_flip == NULL ||
3544 (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) {
3545 return -EINVAL;
3546 }
3547
3500 drm_modeset_lock_crtc(crtc, crtc->primary); 3548 drm_modeset_lock_crtc(crtc, crtc->primary);
3501 if (crtc->primary->fb == NULL) { 3549 if (crtc->primary->fb == NULL) {
3502 /* The framebuffer is currently unbound, presumably 3550 /* The framebuffer is currently unbound, presumably
@@ -3507,9 +3555,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
3507 goto out; 3555 goto out;
3508 } 3556 }
3509 3557
3510 if (crtc->funcs->page_flip == NULL)
3511 goto out;
3512
3513 fb = drm_framebuffer_lookup(dev, page_flip->fb_id); 3558 fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
3514 if (!fb) { 3559 if (!fb) {
3515 ret = -ENOENT; 3560 ret = -ENOENT;
@@ -3550,7 +3595,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
3550 } 3595 }
3551 3596
3552 crtc->primary->old_fb = crtc->primary->fb; 3597 crtc->primary->old_fb = crtc->primary->fb;
3553 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); 3598 if (crtc->funcs->page_flip_target)
3599 ret = crtc->funcs->page_flip_target(crtc, fb, e,
3600 page_flip->flags,
3601 target_vblank);
3602 else
3603 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
3554 if (ret) { 3604 if (ret) {
3555 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) 3605 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
3556 drm_event_cancel_free(dev, &e->base); 3606 drm_event_cancel_free(dev, &e->base);
@@ -3563,6 +3613,8 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
3563 } 3613 }
3564 3614
3565out: 3615out:
3616 if (ret)
3617 drm_crtc_vblank_put(crtc);
3566 if (fb) 3618 if (fb)
3567 drm_framebuffer_unreference(fb); 3619 drm_framebuffer_unreference(fb);
3568 if (crtc->primary->old_fb) 3620 if (crtc->primary->old_fb)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index bb51ee97956d..12b7753a0d27 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -228,6 +228,7 @@ static int drm_getstats(struct drm_device *dev, void *data,
228static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) 228static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
229{ 229{
230 struct drm_get_cap *req = data; 230 struct drm_get_cap *req = data;
231 struct drm_crtc *crtc;
231 232
232 req->value = 0; 233 req->value = 0;
233 switch (req->capability) { 234 switch (req->capability) {
@@ -254,6 +255,13 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
254 case DRM_CAP_ASYNC_PAGE_FLIP: 255 case DRM_CAP_ASYNC_PAGE_FLIP:
255 req->value = dev->mode_config.async_page_flip; 256 req->value = dev->mode_config.async_page_flip;
256 break; 257 break;
258 case DRM_CAP_PAGE_FLIP_TARGET:
259 req->value = 1;
260 drm_for_each_crtc(crtc, dev) {
261 if (!crtc->funcs->page_flip_target)
262 req->value = 0;
263 }
264 break;
257 case DRM_CAP_CURSOR_WIDTH: 265 case DRM_CAP_CURSOR_WIDTH:
258 if (dev->mode_config.cursor_width) 266 if (dev->mode_config.cursor_width)
259 req->value = dev->mode_config.cursor_width; 267 req->value = dev->mode_config.cursor_width;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 6190035edfea..8ab9ce5089fe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1151,7 +1151,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
1151 if (ret) 1151 if (ret)
1152 goto out; 1152 goto out;
1153 1153
1154 ret = ttm_bo_move_ttm(bo, true, intr, no_wait_gpu, new_mem); 1154 ret = ttm_bo_move_ttm(bo, intr, no_wait_gpu, new_mem);
1155out: 1155out:
1156 ttm_bo_mem_put(bo, &tmp_mem); 1156 ttm_bo_mem_put(bo, &tmp_mem);
1157 return ret; 1157 return ret;
@@ -1179,7 +1179,7 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr,
1179 if (ret) 1179 if (ret)
1180 return ret; 1180 return ret;
1181 1181
1182 ret = ttm_bo_move_ttm(bo, true, intr, no_wait_gpu, &tmp_mem); 1182 ret = ttm_bo_move_ttm(bo, intr, no_wait_gpu, &tmp_mem);
1183 if (ret) 1183 if (ret)
1184 goto out; 1184 goto out;
1185 1185
@@ -1297,7 +1297,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
1297 /* Fallback to software copy. */ 1297 /* Fallback to software copy. */
1298 ret = ttm_bo_wait(bo, intr, no_wait_gpu); 1298 ret = ttm_bo_wait(bo, intr, no_wait_gpu);
1299 if (ret == 0) 1299 if (ret == 0)
1300 ret = ttm_bo_move_memcpy(bo, evict, intr, no_wait_gpu, new_mem); 1300 ret = ttm_bo_move_memcpy(bo, intr, no_wait_gpu, new_mem);
1301 1301
1302out: 1302out:
1303 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 1303 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index d50c9679e631..6a22de045cb5 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -361,8 +361,8 @@ static int qxl_bo_move(struct ttm_buffer_object *bo,
361 qxl_move_null(bo, new_mem); 361 qxl_move_null(bo, new_mem);
362 return 0; 362 return 0;
363 } 363 }
364 return ttm_bo_move_memcpy(bo, evict, interruptible, 364 return ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu,
365 no_wait_gpu, new_mem); 365 new_mem);
366} 366}
367 367
368static void qxl_bo_move_notify(struct ttm_buffer_object *bo, 368static void qxl_bo_move_notify(struct ttm_buffer_object *bo,
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index a89c4803aced..4824f70b0258 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1435,8 +1435,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
1435 WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, 1435 WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1436 (viewport_w << 16) | viewport_h); 1436 (viewport_w << 16) | viewport_h);
1437 1437
1438 /* set pageflip to happen only at start of vblank interval (front porch) */ 1438 /* set pageflip to happen anywhere in vblank interval */
1439 WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3); 1439 WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
1440 1440
1441 if (!atomic && fb && fb != crtc->primary->fb) { 1441 if (!atomic && fb && fb != crtc->primary->fb) {
1442 radeon_fb = to_radeon_framebuffer(fb); 1442 radeon_fb = to_radeon_framebuffer(fb);
@@ -1636,8 +1636,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
1636 WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, 1636 WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1637 (viewport_w << 16) | viewport_h); 1637 (viewport_w << 16) | viewport_h);
1638 1638
1639 /* set pageflip to happen only at start of vblank interval (front porch) */ 1639 /* set pageflip to happen anywhere in vblank interval */
1640 WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3); 1640 WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
1641 1641
1642 if (!atomic && fb && fb != crtc->primary->fb) { 1642 if (!atomic && fb && fb != crtc->primary->fb) {
1643 radeon_fb = to_radeon_framebuffer(fb); 1643 radeon_fb = to_radeon_framebuffer(fb);
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index cead089a9e7d..432cb46f6a34 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -389,22 +389,21 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
389{ 389{
390 struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; 390 struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
391 u8 msg[DP_DPCD_SIZE]; 391 u8 msg[DP_DPCD_SIZE];
392 int ret, i; 392 int ret;
393 393
394 for (i = 0; i < 7; i++) { 394 ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
395 ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, 395 DP_DPCD_SIZE);
396 DP_DPCD_SIZE); 396 if (ret == DP_DPCD_SIZE) {
397 if (ret == DP_DPCD_SIZE) { 397 memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
398 memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
399 398
400 DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd), 399 DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd),
401 dig_connector->dpcd); 400 dig_connector->dpcd);
402 401
403 radeon_dp_probe_oui(radeon_connector); 402 radeon_dp_probe_oui(radeon_connector);
404 403
405 return true; 404 return true;
406 }
407 } 405 }
406
408 dig_connector->dpcd[0] = 0; 407 dig_connector->dpcd[0] = 0;
409 return false; 408 return false;
410} 409}
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 0c1b9ff433af..b1784a1b482a 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -1871,7 +1871,7 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
1871{ 1871{
1872 const __be32 *fw_data = NULL; 1872 const __be32 *fw_data = NULL;
1873 const __le32 *new_fw_data = NULL; 1873 const __le32 *new_fw_data = NULL;
1874 u32 running, blackout = 0, tmp; 1874 u32 running, tmp;
1875 u32 *io_mc_regs = NULL; 1875 u32 *io_mc_regs = NULL;
1876 const __le32 *new_io_mc_regs = NULL; 1876 const __le32 *new_io_mc_regs = NULL;
1877 int i, regs_size, ucode_size; 1877 int i, regs_size, ucode_size;
@@ -1912,11 +1912,6 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
1912 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; 1912 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
1913 1913
1914 if (running == 0) { 1914 if (running == 0) {
1915 if (running) {
1916 blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
1917 WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
1918 }
1919
1920 /* reset the engine and set to writable */ 1915 /* reset the engine and set to writable */
1921 WREG32(MC_SEQ_SUP_CNTL, 0x00000008); 1916 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1922 WREG32(MC_SEQ_SUP_CNTL, 0x00000010); 1917 WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
@@ -1964,9 +1959,6 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
1964 break; 1959 break;
1965 udelay(1); 1960 udelay(1);
1966 } 1961 }
1967
1968 if (running)
1969 WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
1970 } 1962 }
1971 1963
1972 return 0; 1964 return 0;
@@ -8215,7 +8207,7 @@ static void cik_uvd_resume(struct radeon_device *rdev)
8215 return; 8207 return;
8216 8208
8217 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 8209 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
8218 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); 8210 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
8219 if (r) { 8211 if (r) {
8220 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 8212 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
8221 return; 8213 return;
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index cead2284fd79..48db93577c1d 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -2069,6 +2069,7 @@
2069#define UVD_UDEC_ADDR_CONFIG 0xef4c 2069#define UVD_UDEC_ADDR_CONFIG 0xef4c
2070#define UVD_UDEC_DB_ADDR_CONFIG 0xef50 2070#define UVD_UDEC_DB_ADDR_CONFIG 0xef50
2071#define UVD_UDEC_DBW_ADDR_CONFIG 0xef54 2071#define UVD_UDEC_DBW_ADDR_CONFIG 0xef54
2072#define UVD_NO_OP 0xeffc
2072 2073
2073#define UVD_LMI_EXT40_ADDR 0xf498 2074#define UVD_LMI_EXT40_ADDR 0xf498
2074#define UVD_GP_SCRATCH4 0xf4e0 2075#define UVD_GP_SCRATCH4 0xf4e0
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index db275b7ed34a..0b6b5766216f 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2878,9 +2878,8 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
2878 for (i = 0; i < rdev->num_crtc; i++) { 2878 for (i = 0; i < rdev->num_crtc; i++) {
2879 if (save->crtc_enabled[i]) { 2879 if (save->crtc_enabled[i]) {
2880 tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]); 2880 tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]);
2881 if ((tmp & 0x7) != 3) { 2881 if ((tmp & 0x7) != 0) {
2882 tmp &= ~0x7; 2882 tmp &= ~0x7;
2883 tmp |= 0x3;
2884 WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp); 2883 WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
2885 } 2884 }
2886 tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]); 2885 tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
@@ -5580,7 +5579,7 @@ static void evergreen_uvd_resume(struct radeon_device *rdev)
5580 return; 5579 return;
5581 5580
5582 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 5581 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
5583 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); 5582 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
5584 if (r) { 5583 if (r) {
5585 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 5584 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
5586 return; 5585 return;
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index c8e3d394cde7..f3d88ca2aa8f 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -1523,6 +1523,7 @@
1523#define UVD_UDEC_ADDR_CONFIG 0xef4c 1523#define UVD_UDEC_ADDR_CONFIG 0xef4c
1524#define UVD_UDEC_DB_ADDR_CONFIG 0xef50 1524#define UVD_UDEC_DB_ADDR_CONFIG 0xef50
1525#define UVD_UDEC_DBW_ADDR_CONFIG 0xef54 1525#define UVD_UDEC_DBW_ADDR_CONFIG 0xef54
1526#define UVD_NO_OP 0xeffc
1526#define UVD_RBC_RB_RPTR 0xf690 1527#define UVD_RBC_RB_RPTR 0xf690
1527#define UVD_RBC_RB_WPTR 0xf694 1528#define UVD_RBC_RB_WPTR 0xf694
1528#define UVD_STATUS 0xf6bc 1529#define UVD_STATUS 0xf6bc
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 4a3d7cab83f7..103fc8650197 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -2062,7 +2062,7 @@ static void cayman_uvd_resume(struct radeon_device *rdev)
2062 return; 2062 return;
2063 2063
2064 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 2064 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2065 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); 2065 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
2066 if (r) { 2066 if (r) {
2067 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 2067 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
2068 return; 2068 return;
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 47eb49b77d32..3c9fec88ea44 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -1137,6 +1137,7 @@
1137#define UVD_UDEC_ADDR_CONFIG 0xEF4C 1137#define UVD_UDEC_ADDR_CONFIG 0xEF4C
1138#define UVD_UDEC_DB_ADDR_CONFIG 0xEF50 1138#define UVD_UDEC_DB_ADDR_CONFIG 0xEF50
1139#define UVD_UDEC_DBW_ADDR_CONFIG 0xEF54 1139#define UVD_UDEC_DBW_ADDR_CONFIG 0xEF54
1140#define UVD_NO_OP 0xEFFC
1140#define UVD_RBC_RB_RPTR 0xF690 1141#define UVD_RBC_RB_RPTR 0xF690
1141#define UVD_RBC_RB_WPTR 0xF694 1142#define UVD_RBC_RB_WPTR 0xF694
1142#define UVD_STATUS 0xf6bc 1143#define UVD_STATUS 0xf6bc
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 9247e7d207fe..640653606f86 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -3097,7 +3097,7 @@ static void r600_uvd_resume(struct radeon_device *rdev)
3097 return; 3097 return;
3098 3098
3099 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 3099 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
3100 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); 3100 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
3101 if (r) { 3101 if (r) {
3102 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 3102 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
3103 return; 3103 return;
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 1e8495cca41e..2e00a5287bd2 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -1490,6 +1490,7 @@
1490#define UVD_GPCOM_VCPU_DATA0 0xef10 1490#define UVD_GPCOM_VCPU_DATA0 0xef10
1491#define UVD_GPCOM_VCPU_DATA1 0xef14 1491#define UVD_GPCOM_VCPU_DATA1 0xef14
1492#define UVD_ENGINE_CNTL 0xef18 1492#define UVD_ENGINE_CNTL 0xef18
1493#define UVD_NO_OP 0xeffc
1493 1494
1494#define UVD_SEMA_CNTL 0xf400 1495#define UVD_SEMA_CNTL 0xf400
1495#define UVD_RB_ARB_CTRL 0xf480 1496#define UVD_RB_ARB_CTRL 0xf480
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 5633ee3eb46e..1b0dcad916b0 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -742,6 +742,7 @@ struct radeon_flip_work {
742 struct work_struct unpin_work; 742 struct work_struct unpin_work;
743 struct radeon_device *rdev; 743 struct radeon_device *rdev;
744 int crtc_id; 744 int crtc_id;
745 u32 target_vblank;
745 uint64_t base; 746 uint64_t base;
746 struct drm_pending_vblank_event *event; 747 struct drm_pending_vblank_event *event;
747 struct radeon_bo *old_rbo; 748 struct radeon_bo *old_rbo;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index c3206fb8f4cf..890171f08987 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -400,14 +400,13 @@ static void radeon_flip_work_func(struct work_struct *__work)
400 struct radeon_flip_work *work = 400 struct radeon_flip_work *work =
401 container_of(__work, struct radeon_flip_work, flip_work); 401 container_of(__work, struct radeon_flip_work, flip_work);
402 struct radeon_device *rdev = work->rdev; 402 struct radeon_device *rdev = work->rdev;
403 struct drm_device *dev = rdev->ddev;
403 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id]; 404 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
404 405
405 struct drm_crtc *crtc = &radeon_crtc->base; 406 struct drm_crtc *crtc = &radeon_crtc->base;
406 unsigned long flags; 407 unsigned long flags;
407 int r; 408 int r;
408 int vpos, hpos, stat, min_udelay = 0; 409 int vpos, hpos;
409 unsigned repcnt = 4;
410 struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
411 410
412 down_read(&rdev->exclusive_lock); 411 down_read(&rdev->exclusive_lock);
413 if (work->fence) { 412 if (work->fence) {
@@ -438,59 +437,25 @@ static void radeon_flip_work_func(struct work_struct *__work)
438 work->fence = NULL; 437 work->fence = NULL;
439 } 438 }
440 439
440 /* Wait until we're out of the vertical blank period before the one
441 * targeted by the flip
442 */
443 while (radeon_crtc->enabled &&
444 (radeon_get_crtc_scanoutpos(dev, work->crtc_id, 0,
445 &vpos, &hpos, NULL, NULL,
446 &crtc->hwmode)
447 & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) ==
448 (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) &&
449 (int)(work->target_vblank -
450 dev->driver->get_vblank_counter(dev, work->crtc_id)) > 0)
451 usleep_range(1000, 2000);
452
441 /* We borrow the event spin lock for protecting flip_status */ 453 /* We borrow the event spin lock for protecting flip_status */
442 spin_lock_irqsave(&crtc->dev->event_lock, flags); 454 spin_lock_irqsave(&crtc->dev->event_lock, flags);
443 455
444 /* set the proper interrupt */ 456 /* set the proper interrupt */
445 radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id); 457 radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
446 458
447 /* If this happens to execute within the "virtually extended" vblank
448 * interval before the start of the real vblank interval then it needs
449 * to delay programming the mmio flip until the real vblank is entered.
450 * This prevents completing a flip too early due to the way we fudge
451 * our vblank counter and vblank timestamps in order to work around the
452 * problem that the hw fires vblank interrupts before actual start of
453 * vblank (when line buffer refilling is done for a frame). It
454 * complements the fudging logic in radeon_get_crtc_scanoutpos() for
455 * timestamping and radeon_get_vblank_counter_kms() for vblank counts.
456 *
457 * In practice this won't execute very often unless on very fast
458 * machines because the time window for this to happen is very small.
459 */
460 while (radeon_crtc->enabled && --repcnt) {
461 /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
462 * start in hpos, and to the "fudged earlier" vblank start in
463 * vpos.
464 */
465 stat = radeon_get_crtc_scanoutpos(rdev->ddev, work->crtc_id,
466 GET_DISTANCE_TO_VBLANKSTART,
467 &vpos, &hpos, NULL, NULL,
468 &crtc->hwmode);
469
470 if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
471 (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) ||
472 !(vpos >= 0 && hpos <= 0))
473 break;
474
475 /* Sleep at least until estimated real start of hw vblank */
476 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
477 if (min_udelay > vblank->framedur_ns / 2000) {
478 /* Don't wait ridiculously long - something is wrong */
479 repcnt = 0;
480 break;
481 }
482 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
483 usleep_range(min_udelay, 2 * min_udelay);
484 spin_lock_irqsave(&crtc->dev->event_lock, flags);
485 };
486
487 if (!repcnt)
488 DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, "
489 "framedur %d, linedur %d, stat %d, vpos %d, "
490 "hpos %d\n", work->crtc_id, min_udelay,
491 vblank->framedur_ns / 1000,
492 vblank->linedur_ns / 1000, stat, vpos, hpos);
493
494 /* do the flip (mmio) */ 459 /* do the flip (mmio) */
495 radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base, work->async); 460 radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base, work->async);
496 461
@@ -499,10 +464,11 @@ static void radeon_flip_work_func(struct work_struct *__work)
499 up_read(&rdev->exclusive_lock); 464 up_read(&rdev->exclusive_lock);
500} 465}
501 466
502static int radeon_crtc_page_flip(struct drm_crtc *crtc, 467static int radeon_crtc_page_flip_target(struct drm_crtc *crtc,
503 struct drm_framebuffer *fb, 468 struct drm_framebuffer *fb,
504 struct drm_pending_vblank_event *event, 469 struct drm_pending_vblank_event *event,
505 uint32_t page_flip_flags) 470 uint32_t page_flip_flags,
471 uint32_t target)
506{ 472{
507 struct drm_device *dev = crtc->dev; 473 struct drm_device *dev = crtc->dev;
508 struct radeon_device *rdev = dev->dev_private; 474 struct radeon_device *rdev = dev->dev_private;
@@ -599,12 +565,8 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
599 base &= ~7; 565 base &= ~7;
600 } 566 }
601 work->base = base; 567 work->base = base;
602 568 work->target_vblank = target - drm_crtc_vblank_count(crtc) +
603 r = drm_crtc_vblank_get(crtc); 569 dev->driver->get_vblank_counter(dev, work->crtc_id);
604 if (r) {
605 DRM_ERROR("failed to get vblank before flip\n");
606 goto pflip_cleanup;
607 }
608 570
609 /* We borrow the event spin lock for protecting flip_work */ 571 /* We borrow the event spin lock for protecting flip_work */
610 spin_lock_irqsave(&crtc->dev->event_lock, flags); 572 spin_lock_irqsave(&crtc->dev->event_lock, flags);
@@ -613,7 +575,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
613 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); 575 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
614 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 576 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
615 r = -EBUSY; 577 r = -EBUSY;
616 goto vblank_cleanup; 578 goto pflip_cleanup;
617 } 579 }
618 radeon_crtc->flip_status = RADEON_FLIP_PENDING; 580 radeon_crtc->flip_status = RADEON_FLIP_PENDING;
619 radeon_crtc->flip_work = work; 581 radeon_crtc->flip_work = work;
@@ -626,9 +588,6 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
626 queue_work(radeon_crtc->flip_queue, &work->flip_work); 588 queue_work(radeon_crtc->flip_queue, &work->flip_work);
627 return 0; 589 return 0;
628 590
629vblank_cleanup:
630 drm_crtc_vblank_put(crtc);
631
632pflip_cleanup: 591pflip_cleanup:
633 if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) { 592 if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) {
634 DRM_ERROR("failed to reserve new rbo in error path\n"); 593 DRM_ERROR("failed to reserve new rbo in error path\n");
@@ -697,7 +656,7 @@ static const struct drm_crtc_funcs radeon_crtc_funcs = {
697 .gamma_set = radeon_crtc_gamma_set, 656 .gamma_set = radeon_crtc_gamma_set,
698 .set_config = radeon_crtc_set_config, 657 .set_config = radeon_crtc_set_config,
699 .destroy = radeon_crtc_destroy, 658 .destroy = radeon_crtc_destroy,
700 .page_flip = radeon_crtc_page_flip, 659 .page_flip_target = radeon_crtc_page_flip_target,
701}; 660};
702 661
703static void radeon_crtc_init(struct drm_device *dev, int index) 662static void radeon_crtc_init(struct drm_device *dev, int index)
diff --git a/drivers/gpu/drm/radeon/radeon_dp_auxch.c b/drivers/gpu/drm/radeon/radeon_dp_auxch.c
index db64e0062689..2d465648856a 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_auxch.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_auxch.c
@@ -164,7 +164,6 @@ radeon_dp_aux_transfer_native(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg
164 } 164 }
165 165
166 if (tmp & AUX_SW_RX_TIMEOUT) { 166 if (tmp & AUX_SW_RX_TIMEOUT) {
167 DRM_DEBUG_KMS("dp_aux_ch timed out\n");
168 ret = -ETIMEDOUT; 167 ret = -ETIMEDOUT;
169 goto done; 168 goto done;
170 } 169 }
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 90f2ff217b31..07e44931f1f1 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -95,9 +95,10 @@
95 * 2.44.0 - SET_APPEND_CNT packet3 support 95 * 2.44.0 - SET_APPEND_CNT packet3 support
96 * 2.45.0 - Allow setting shader registers using DMA/COPY packet3 on SI 96 * 2.45.0 - Allow setting shader registers using DMA/COPY packet3 on SI
97 * 2.46.0 - Add PFP_SYNC_ME support on evergreen 97 * 2.46.0 - Add PFP_SYNC_ME support on evergreen
98 * 2.47.0 - Add UVD_NO_OP register support
98 */ 99 */
99#define KMS_DRIVER_MAJOR 2 100#define KMS_DRIVER_MAJOR 2
100#define KMS_DRIVER_MINOR 46 101#define KMS_DRIVER_MINOR 47
101#define KMS_DRIVER_PATCHLEVEL 0 102#define KMS_DRIVER_PATCHLEVEL 0
102int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); 103int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
103int radeon_driver_unload_kms(struct drm_device *dev); 104int radeon_driver_unload_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 9590bcd321c0..021aa005623f 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -938,10 +938,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
938 "Radeon i2c hw bus %s", name); 938 "Radeon i2c hw bus %s", name);
939 i2c->adapter.algo = &radeon_i2c_algo; 939 i2c->adapter.algo = &radeon_i2c_algo;
940 ret = i2c_add_adapter(&i2c->adapter); 940 ret = i2c_add_adapter(&i2c->adapter);
941 if (ret) { 941 if (ret)
942 DRM_ERROR("Failed to register hw i2c %s\n", name);
943 goto out_free; 942 goto out_free;
944 }
945 } else if (rec->hw_capable && 943 } else if (rec->hw_capable &&
946 radeon_hw_i2c && 944 radeon_hw_i2c &&
947 ASIC_IS_DCE3(rdev)) { 945 ASIC_IS_DCE3(rdev)) {
@@ -950,10 +948,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
950 "Radeon i2c hw bus %s", name); 948 "Radeon i2c hw bus %s", name);
951 i2c->adapter.algo = &radeon_atom_i2c_algo; 949 i2c->adapter.algo = &radeon_atom_i2c_algo;
952 ret = i2c_add_adapter(&i2c->adapter); 950 ret = i2c_add_adapter(&i2c->adapter);
953 if (ret) { 951 if (ret)
954 DRM_ERROR("Failed to register hw i2c %s\n", name);
955 goto out_free; 952 goto out_free;
956 }
957 } else { 953 } else {
958 /* set the radeon bit adapter */ 954 /* set the radeon bit adapter */
959 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), 955 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 0c00e192c845..93414aca60d6 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -346,7 +346,7 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
346 if (unlikely(r)) { 346 if (unlikely(r)) {
347 goto out_cleanup; 347 goto out_cleanup;
348 } 348 }
349 r = ttm_bo_move_ttm(bo, true, interruptible, no_wait_gpu, new_mem); 349 r = ttm_bo_move_ttm(bo, interruptible, no_wait_gpu, new_mem);
350out_cleanup: 350out_cleanup:
351 ttm_bo_mem_put(bo, &tmp_mem); 351 ttm_bo_mem_put(bo, &tmp_mem);
352 return r; 352 return r;
@@ -379,7 +379,7 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo,
379 if (unlikely(r)) { 379 if (unlikely(r)) {
380 return r; 380 return r;
381 } 381 }
382 r = ttm_bo_move_ttm(bo, true, interruptible, no_wait_gpu, &tmp_mem); 382 r = ttm_bo_move_ttm(bo, interruptible, no_wait_gpu, &tmp_mem);
383 if (unlikely(r)) { 383 if (unlikely(r)) {
384 goto out_cleanup; 384 goto out_cleanup;
385 } 385 }
@@ -444,8 +444,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo,
444 444
445 if (r) { 445 if (r) {
446memcpy: 446memcpy:
447 r = ttm_bo_move_memcpy(bo, evict, interruptible, 447 r = ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu, new_mem);
448 no_wait_gpu, new_mem);
449 if (r) { 448 if (r) {
450 return r; 449 return r;
451 } 450 }
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c
index 73dfe01435ea..0cd0e7bdee55 100644
--- a/drivers/gpu/drm/radeon/radeon_uvd.c
+++ b/drivers/gpu/drm/radeon/radeon_uvd.c
@@ -669,6 +669,7 @@ static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
669 return r; 669 return r;
670 break; 670 break;
671 case UVD_ENGINE_CNTL: 671 case UVD_ENGINE_CNTL:
672 case UVD_NO_OP:
672 break; 673 break;
673 default: 674 default:
674 DRM_ERROR("Invalid reg 0x%X!\n", 675 DRM_ERROR("Invalid reg 0x%X!\n",
@@ -753,8 +754,10 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev,
753 ib.ptr[3] = addr >> 32; 754 ib.ptr[3] = addr >> 32;
754 ib.ptr[4] = PACKET0(UVD_GPCOM_VCPU_CMD, 0); 755 ib.ptr[4] = PACKET0(UVD_GPCOM_VCPU_CMD, 0);
755 ib.ptr[5] = 0; 756 ib.ptr[5] = 0;
756 for (i = 6; i < 16; ++i) 757 for (i = 6; i < 16; i += 2) {
757 ib.ptr[i] = PACKET2(0); 758 ib.ptr[i] = PACKET0(UVD_NO_OP, 0);
759 ib.ptr[i+1] = 0;
760 }
758 ib.length_dw = 16; 761 ib.length_dw = 16;
759 762
760 r = radeon_ib_schedule(rdev, &ib, NULL, false); 763 r = radeon_ib_schedule(rdev, &ib, NULL, false);
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index c55d653aaf5f..76c55c5d11ec 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -406,9 +406,8 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
406 for (i = 0; i < rdev->num_crtc; i++) { 406 for (i = 0; i < rdev->num_crtc; i++) {
407 if (save->crtc_enabled[i]) { 407 if (save->crtc_enabled[i]) {
408 tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]); 408 tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]);
409 if ((tmp & 0x7) != 3) { 409 if ((tmp & 0x7) != 0) {
410 tmp &= ~0x7; 410 tmp &= ~0x7;
411 tmp |= 0x3;
412 WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp); 411 WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
413 } 412 }
414 tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]); 413 tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 1c120a4c3c97..729ae588c970 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1738,7 +1738,7 @@ static void rv770_uvd_resume(struct radeon_device *rdev)
1738 return; 1738 return;
1739 1739
1740 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 1740 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
1741 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); 1741 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
1742 if (r) { 1742 if (r) {
1743 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 1743 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
1744 return; 1744 return;
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
index 9ef2064b1c9c..0271f4c559ae 100644
--- a/drivers/gpu/drm/radeon/rv770d.h
+++ b/drivers/gpu/drm/radeon/rv770d.h
@@ -387,6 +387,7 @@
387#define UVD_UDEC_TILING_CONFIG 0xef40 387#define UVD_UDEC_TILING_CONFIG 0xef40
388#define UVD_UDEC_DB_TILING_CONFIG 0xef44 388#define UVD_UDEC_DB_TILING_CONFIG 0xef44
389#define UVD_UDEC_DBW_TILING_CONFIG 0xef48 389#define UVD_UDEC_DBW_TILING_CONFIG 0xef48
390#define UVD_NO_OP 0xeffc
390 391
391#define GC_USER_SHADER_PIPE_CONFIG 0x8954 392#define GC_USER_SHADER_PIPE_CONFIG 0x8954
392#define INACTIVE_QD_PIPES(x) ((x) << 8) 393#define INACTIVE_QD_PIPES(x) ((x) << 8)
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 2523ca96c6c7..7ee9aafbdf74 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -1547,7 +1547,7 @@ int si_mc_load_microcode(struct radeon_device *rdev)
1547{ 1547{
1548 const __be32 *fw_data = NULL; 1548 const __be32 *fw_data = NULL;
1549 const __le32 *new_fw_data = NULL; 1549 const __le32 *new_fw_data = NULL;
1550 u32 running, blackout = 0; 1550 u32 running;
1551 u32 *io_mc_regs = NULL; 1551 u32 *io_mc_regs = NULL;
1552 const __le32 *new_io_mc_regs = NULL; 1552 const __le32 *new_io_mc_regs = NULL;
1553 int i, regs_size, ucode_size; 1553 int i, regs_size, ucode_size;
@@ -1598,11 +1598,6 @@ int si_mc_load_microcode(struct radeon_device *rdev)
1598 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; 1598 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
1599 1599
1600 if (running == 0) { 1600 if (running == 0) {
1601 if (running) {
1602 blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
1603 WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
1604 }
1605
1606 /* reset the engine and set to writable */ 1601 /* reset the engine and set to writable */
1607 WREG32(MC_SEQ_SUP_CNTL, 0x00000008); 1602 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1608 WREG32(MC_SEQ_SUP_CNTL, 0x00000010); 1603 WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
@@ -1641,9 +1636,6 @@ int si_mc_load_microcode(struct radeon_device *rdev)
1641 break; 1636 break;
1642 udelay(1); 1637 udelay(1);
1643 } 1638 }
1644
1645 if (running)
1646 WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
1647 } 1639 }
1648 1640
1649 return 0; 1641 return 0;
@@ -6928,7 +6920,7 @@ static void si_uvd_resume(struct radeon_device *rdev)
6928 return; 6920 return;
6929 6921
6930 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 6922 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
6931 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); 6923 r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
6932 if (r) { 6924 if (r) {
6933 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 6925 dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
6934 return; 6926 return;
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index d1a7b58dd291..eb220eecba78 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -1559,6 +1559,7 @@
1559#define UVD_UDEC_ADDR_CONFIG 0xEF4C 1559#define UVD_UDEC_ADDR_CONFIG 0xEF4C
1560#define UVD_UDEC_DB_ADDR_CONFIG 0xEF50 1560#define UVD_UDEC_DB_ADDR_CONFIG 0xEF50
1561#define UVD_UDEC_DBW_ADDR_CONFIG 0xEF54 1561#define UVD_UDEC_DBW_ADDR_CONFIG 0xEF54
1562#define UVD_NO_OP 0xEFFC
1562#define UVD_RBC_RB_RPTR 0xF690 1563#define UVD_RBC_RB_RPTR 0xF690
1563#define UVD_RBC_RB_WPTR 0xF694 1564#define UVD_RBC_RB_WPTR 0xF694
1564#define UVD_STATUS 0xf6bc 1565#define UVD_STATUS 0xf6bc
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 42c074a9c955..c2a30bdc8a01 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -354,14 +354,12 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
354 354
355 if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && 355 if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
356 !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) 356 !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED))
357 ret = ttm_bo_move_ttm(bo, evict, interruptible, no_wait_gpu, 357 ret = ttm_bo_move_ttm(bo, interruptible, no_wait_gpu, mem);
358 mem);
359 else if (bdev->driver->move) 358 else if (bdev->driver->move)
360 ret = bdev->driver->move(bo, evict, interruptible, 359 ret = bdev->driver->move(bo, evict, interruptible,
361 no_wait_gpu, mem); 360 no_wait_gpu, mem);
362 else 361 else
363 ret = ttm_bo_move_memcpy(bo, evict, interruptible, 362 ret = ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu, mem);
364 no_wait_gpu, mem);
365 363
366 if (ret) { 364 if (ret) {
367 if (bdev->driver->move_notify) { 365 if (bdev->driver->move_notify) {
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index f157a9efd220..bf6e21655c57 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -45,8 +45,8 @@ void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
45} 45}
46 46
47int ttm_bo_move_ttm(struct ttm_buffer_object *bo, 47int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
48 bool evict, bool interruptible, 48 bool interruptible, bool no_wait_gpu,
49 bool no_wait_gpu, struct ttm_mem_reg *new_mem) 49 struct ttm_mem_reg *new_mem)
50{ 50{
51 struct ttm_tt *ttm = bo->ttm; 51 struct ttm_tt *ttm = bo->ttm;
52 struct ttm_mem_reg *old_mem = &bo->mem; 52 struct ttm_mem_reg *old_mem = &bo->mem;
@@ -329,8 +329,7 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
329} 329}
330 330
331int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, 331int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
332 bool evict, bool interruptible, 332 bool interruptible, bool no_wait_gpu,
333 bool no_wait_gpu,
334 struct ttm_mem_reg *new_mem) 333 struct ttm_mem_reg *new_mem)
335{ 334{
336 struct ttm_bo_device *bdev = bo->bdev; 335 struct ttm_bo_device *bdev = bo->bdev;
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index a1803fbcc898..29855be96be0 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -600,3 +600,9 @@ size_t ttm_round_pot(size_t size)
600 return 0; 600 return 0;
601} 601}
602EXPORT_SYMBOL(ttm_round_pot); 602EXPORT_SYMBOL(ttm_round_pot);
603
604uint64_t ttm_get_kernel_zone_memory_size(struct ttm_mem_global *glob)
605{
606 return glob->zone_kernel->max_mem;
607}
608EXPORT_SYMBOL(ttm_get_kernel_zone_memory_size);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3fa0275e509f..7c8a77b181c2 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -391,6 +391,24 @@ struct drm_crtc_funcs {
391 uint32_t flags); 391 uint32_t flags);
392 392
393 /** 393 /**
394 * @page_flip_target:
395 *
396 * Same as @page_flip but with an additional parameter specifying the
397 * absolute target vertical blank period (as reported by
398 * drm_crtc_vblank_count()) when the flip should take effect.
399 *
400 * Note that the core code calls drm_crtc_vblank_get before this entry
401 * point, and will call drm_crtc_vblank_put if this entry point returns
402 * any non-0 error code. It's the driver's responsibility to call
403 * drm_crtc_vblank_put after this entry point returns 0, typically when
404 * the flip completes.
405 */
406 int (*page_flip_target)(struct drm_crtc *crtc,
407 struct drm_framebuffer *fb,
408 struct drm_pending_vblank_event *event,
409 uint32_t flags, uint32_t target);
410
411 /**
394 * @set_property: 412 * @set_property:
395 * 413 *
396 * This is the legacy entry point to update a property attached to the 414 * This is the legacy entry point to update a property attached to the
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 99c6d01d24f2..c986fa7effd2 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -961,7 +961,6 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev,
961 * ttm_bo_move_ttm 961 * ttm_bo_move_ttm
962 * 962 *
963 * @bo: A pointer to a struct ttm_buffer_object. 963 * @bo: A pointer to a struct ttm_buffer_object.
964 * @evict: 1: This is an eviction. Don't try to pipeline.
965 * @interruptible: Sleep interruptible if waiting. 964 * @interruptible: Sleep interruptible if waiting.
966 * @no_wait_gpu: Return immediately if the GPU is busy. 965 * @no_wait_gpu: Return immediately if the GPU is busy.
967 * @new_mem: struct ttm_mem_reg indicating where to move. 966 * @new_mem: struct ttm_mem_reg indicating where to move.
@@ -977,14 +976,13 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev,
977 */ 976 */
978 977
979extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, 978extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
980 bool evict, bool interruptible, bool no_wait_gpu, 979 bool interruptible, bool no_wait_gpu,
981 struct ttm_mem_reg *new_mem); 980 struct ttm_mem_reg *new_mem);
982 981
983/** 982/**
984 * ttm_bo_move_memcpy 983 * ttm_bo_move_memcpy
985 * 984 *
986 * @bo: A pointer to a struct ttm_buffer_object. 985 * @bo: A pointer to a struct ttm_buffer_object.
987 * @evict: 1: This is an eviction. Don't try to pipeline.
988 * @interruptible: Sleep interruptible if waiting. 986 * @interruptible: Sleep interruptible if waiting.
989 * @no_wait_gpu: Return immediately if the GPU is busy. 987 * @no_wait_gpu: Return immediately if the GPU is busy.
990 * @new_mem: struct ttm_mem_reg indicating where to move. 988 * @new_mem: struct ttm_mem_reg indicating where to move.
@@ -1000,8 +998,7 @@ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
1000 */ 998 */
1001 999
1002extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, 1000extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
1003 bool evict, bool interruptible, 1001 bool interruptible, bool no_wait_gpu,
1004 bool no_wait_gpu,
1005 struct ttm_mem_reg *new_mem); 1002 struct ttm_mem_reg *new_mem);
1006 1003
1007/** 1004/**
diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
index 72dcbe81dd07..c4520890f267 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -155,4 +155,5 @@ extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
155extern void ttm_mem_global_free_page(struct ttm_mem_global *glob, 155extern void ttm_mem_global_free_page(struct ttm_mem_global *glob,
156 struct page *page); 156 struct page *page);
157extern size_t ttm_round_pot(size_t size); 157extern size_t ttm_round_pot(size_t size);
158extern uint64_t ttm_get_kernel_zone_memory_size(struct ttm_mem_global *glob);
158#endif 159#endif
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 462246aa200e..ae2845fdcb5f 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -77,6 +77,10 @@ extern "C" {
77#define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1) 77#define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1)
78/* Flag that USWC attributes should be used for GTT */ 78/* Flag that USWC attributes should be used for GTT */
79#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2) 79#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
80/* Flag that the memory should be in VRAM and cleared */
81#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
82/* Flag that create shadow bo(GTT) while allocating vram bo */
83#define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
80 84
81struct drm_amdgpu_gem_create_in { 85struct drm_amdgpu_gem_create_in {
82 /** the requested memory size */ 86 /** the requested memory size */
@@ -481,6 +485,8 @@ struct drm_amdgpu_cs_chunk_data {
481#define AMDGPU_INFO_DEV_INFO 0x16 485#define AMDGPU_INFO_DEV_INFO 0x16
482/* visible vram usage */ 486/* visible vram usage */
483#define AMDGPU_INFO_VIS_VRAM_USAGE 0x17 487#define AMDGPU_INFO_VIS_VRAM_USAGE 0x17
488/* number of TTM buffer evictions */
489#define AMDGPU_INFO_NUM_EVICTIONS 0x18
484 490
485#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 491#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
486#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff 492#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 452675fb55d9..b2c52843bc70 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -646,6 +646,7 @@ struct drm_gem_open {
646#define DRM_CAP_CURSOR_WIDTH 0x8 646#define DRM_CAP_CURSOR_WIDTH 0x8
647#define DRM_CAP_CURSOR_HEIGHT 0x9 647#define DRM_CAP_CURSOR_HEIGHT 0x9
648#define DRM_CAP_ADDFB2_MODIFIERS 0x10 648#define DRM_CAP_ADDFB2_MODIFIERS 0x10
649#define DRM_CAP_PAGE_FLIP_TARGET 0x11
649 650
650/** DRM_IOCTL_GET_CAP ioctl argument type */ 651/** DRM_IOCTL_GET_CAP ioctl argument type */
651struct drm_get_cap { 652struct drm_get_cap {
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 49a72659b801..df0e3504c349 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -520,7 +520,13 @@ struct drm_color_lut {
520 520
521#define DRM_MODE_PAGE_FLIP_EVENT 0x01 521#define DRM_MODE_PAGE_FLIP_EVENT 0x01
522#define DRM_MODE_PAGE_FLIP_ASYNC 0x02 522#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
523#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT|DRM_MODE_PAGE_FLIP_ASYNC) 523#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
524#define DRM_MODE_PAGE_FLIP_TARGET_RELATIVE 0x8
525#define DRM_MODE_PAGE_FLIP_TARGET (DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE | \
526 DRM_MODE_PAGE_FLIP_TARGET_RELATIVE)
527#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | \
528 DRM_MODE_PAGE_FLIP_ASYNC | \
529 DRM_MODE_PAGE_FLIP_TARGET)
524 530
525/* 531/*
526 * Request a page flip on the specified crtc. 532 * Request a page flip on the specified crtc.
@@ -543,8 +549,7 @@ struct drm_color_lut {
543 * 'as soon as possible', meaning that it not delay waiting for vblank. 549 * 'as soon as possible', meaning that it not delay waiting for vblank.
544 * This may cause tearing on the screen. 550 * This may cause tearing on the screen.
545 * 551 *
546 * The reserved field must be zero until we figure out something 552 * The reserved field must be zero.
547 * clever to use it for.
548 */ 553 */
549 554
550struct drm_mode_crtc_page_flip { 555struct drm_mode_crtc_page_flip {
@@ -555,6 +560,34 @@ struct drm_mode_crtc_page_flip {
555 __u64 user_data; 560 __u64 user_data;
556}; 561};
557 562
563/*
564 * Request a page flip on the specified crtc.
565 *
566 * Same as struct drm_mode_crtc_page_flip, but supports new flags and
567 * re-purposes the reserved field:
568 *
569 * The sequence field must be zero unless either of the
570 * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is specified. When
571 * the ABSOLUTE flag is specified, the sequence field denotes the absolute
572 * vblank sequence when the flip should take effect. When the RELATIVE
573 * flag is specified, the sequence field denotes the relative (to the
574 * current one when the ioctl is called) vblank sequence when the flip
575 * should take effect. NOTE: DRM_IOCTL_WAIT_VBLANK must still be used to
576 * make sure the vblank sequence before the target one has passed before
577 * calling this ioctl. The purpose of the
578 * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is merely to clarify
579 * the target for when code dealing with a page flip runs during a
580 * vertical blank period.
581 */
582
583struct drm_mode_crtc_page_flip_target {
584 __u32 crtc_id;
585 __u32 fb_id;
586 __u32 flags;
587 __u32 sequence;
588 __u64 user_data;
589};
590
558/* create a dumb scanout buffer */ 591/* create a dumb scanout buffer */
559struct drm_mode_create_dumb { 592struct drm_mode_create_dumb {
560 __u32 height; 593 __u32 height;