diff options
author | Dave Airlie <airlied@redhat.com> | 2016-07-07 23:42:41 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-07-07 23:42:41 -0400 |
commit | 6f6e68b383314ab10189f983fead55437c149f32 (patch) | |
tree | a9254f00bb2053aa567981c8979c9713d648346c | |
parent | b33e07731c13f2a9ec5c345b8542cae5adf74235 (diff) | |
parent | b1814a1def0564a2a1d3be7fa5bf7243ff899a28 (diff) |
Merge branch 'drm-next-4.8' of git://people.freedesktop.org/~agd5f/linux into drm-next
This is the main 4.8 pull for radeon and amdgpu. Sorry for the delay,
I meant to send this out last week, but I was moving house. Lots of
changes here:
- ATPX improvements for better dGPU power control on PX systems
- New power features for CZ/BR/ST
- Pipelined BO moves and evictions in TTM
- GPU scheduler improvements
- GPU reset improvements
- Overclocking on dGPUs with amdgpu
- Lots of code cleanup
- Bug fixes
* 'drm-next-4.8' of git://people.freedesktop.org/~agd5f/linux: (191 commits)
drm/amd/powerplay: don't add invalid voltage.
drm/amdgpu: add read/write function for GC CAC programming
drm/amd/powerplay: add definitions related to di/dt feature for fiji and polaris.
drm/amd/powerplay: add shared definitions for di/dt feature.
drm/amdgpu: remove gfx8 registers that vary between asics
drm/amd/powerplay: add mvdd dpm support.
drm/amdgpu: get number of shade engine by cgs interface.
drm/amdgpu: remove more of the ring backup code
drm/amd/powerplay: Unify family defines
drm/amdgpu: clean up ring_backup code, no need more
drm/amdgpu: ib test first after gpu reset
drm/amdgpu: recovery hw jobs when gpu reset V3
drm/amdgpu: abstract amdgpu_vm_is_gpu_reset
drm/amdgpu: add a bool to specify if needing vm flush V2
drm/amdgpu: add amd_sched_job_recovery
drm/amdgpu: force completion for gpu reset
drm/amdgpu: block ttm first before parking scheduler
drm/amd: add amd_sched_hw_job_reset
drm/amd: add parent for sched fence
drm/amdgpu: remove evict vram
...
103 files changed, 3924 insertions, 1596 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index ac8e02f9105a..eb09037a7161 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -85,8 +85,12 @@ extern int amdgpu_vm_debug; | |||
85 | extern int amdgpu_sched_jobs; | 85 | extern int amdgpu_sched_jobs; |
86 | extern int amdgpu_sched_hw_submission; | 86 | extern int amdgpu_sched_hw_submission; |
87 | extern int amdgpu_powerplay; | 87 | extern int amdgpu_powerplay; |
88 | extern int amdgpu_powercontainment; | ||
88 | extern unsigned amdgpu_pcie_gen_cap; | 89 | extern unsigned amdgpu_pcie_gen_cap; |
89 | extern unsigned amdgpu_pcie_lane_cap; | 90 | extern unsigned amdgpu_pcie_lane_cap; |
91 | extern unsigned amdgpu_cg_mask; | ||
92 | extern unsigned amdgpu_pg_mask; | ||
93 | extern char *amdgpu_disable_cu; | ||
90 | 94 | ||
91 | #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 | 95 | #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 |
92 | #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ | 96 | #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ |
@@ -183,6 +187,10 @@ int amdgpu_set_clockgating_state(struct amdgpu_device *adev, | |||
183 | int amdgpu_set_powergating_state(struct amdgpu_device *adev, | 187 | int amdgpu_set_powergating_state(struct amdgpu_device *adev, |
184 | enum amd_ip_block_type block_type, | 188 | enum amd_ip_block_type block_type, |
185 | enum amd_powergating_state state); | 189 | enum amd_powergating_state state); |
190 | int amdgpu_wait_for_idle(struct amdgpu_device *adev, | ||
191 | enum amd_ip_block_type block_type); | ||
192 | bool amdgpu_is_idle(struct amdgpu_device *adev, | ||
193 | enum amd_ip_block_type block_type); | ||
186 | 194 | ||
187 | struct amdgpu_ip_block_version { | 195 | struct amdgpu_ip_block_version { |
188 | enum amd_ip_block_type type; | 196 | enum amd_ip_block_type type; |
@@ -594,11 +602,9 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, | |||
594 | struct amdgpu_sync *sync, | 602 | struct amdgpu_sync *sync, |
595 | struct reservation_object *resv, | 603 | struct reservation_object *resv, |
596 | void *owner); | 604 | void *owner); |
597 | bool amdgpu_sync_is_idle(struct amdgpu_sync *sync); | 605 | struct fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync, |
598 | int amdgpu_sync_cycle_fences(struct amdgpu_sync *dst, struct amdgpu_sync *src, | 606 | struct amdgpu_ring *ring); |
599 | struct fence *fence); | ||
600 | struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync); | 607 | struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync); |
601 | int amdgpu_sync_wait(struct amdgpu_sync *sync); | ||
602 | void amdgpu_sync_free(struct amdgpu_sync *sync); | 608 | void amdgpu_sync_free(struct amdgpu_sync *sync); |
603 | int amdgpu_sync_init(void); | 609 | int amdgpu_sync_init(void); |
604 | void amdgpu_sync_fini(void); | 610 | void amdgpu_sync_fini(void); |
@@ -754,12 +760,11 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, | |||
754 | int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, | 760 | int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, |
755 | struct amdgpu_job **job); | 761 | struct amdgpu_job **job); |
756 | 762 | ||
763 | void amdgpu_job_free_resources(struct amdgpu_job *job); | ||
757 | void amdgpu_job_free(struct amdgpu_job *job); | 764 | void amdgpu_job_free(struct amdgpu_job *job); |
758 | void amdgpu_job_free_func(struct kref *refcount); | ||
759 | int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, | 765 | int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, |
760 | struct amd_sched_entity *entity, void *owner, | 766 | struct amd_sched_entity *entity, void *owner, |
761 | struct fence **f); | 767 | struct fence **f); |
762 | void amdgpu_job_timeout_func(struct work_struct *work); | ||
763 | 768 | ||
764 | struct amdgpu_ring { | 769 | struct amdgpu_ring { |
765 | struct amdgpu_device *adev; | 770 | struct amdgpu_device *adev; |
@@ -771,8 +776,6 @@ struct amdgpu_ring { | |||
771 | struct amdgpu_bo *ring_obj; | 776 | struct amdgpu_bo *ring_obj; |
772 | volatile uint32_t *ring; | 777 | volatile uint32_t *ring; |
773 | unsigned rptr_offs; | 778 | unsigned rptr_offs; |
774 | u64 next_rptr_gpu_addr; | ||
775 | volatile u32 *next_rptr_cpu_addr; | ||
776 | unsigned wptr; | 779 | unsigned wptr; |
777 | unsigned wptr_old; | 780 | unsigned wptr_old; |
778 | unsigned ring_size; | 781 | unsigned ring_size; |
@@ -791,7 +794,6 @@ struct amdgpu_ring { | |||
791 | u32 doorbell_index; | 794 | u32 doorbell_index; |
792 | bool use_doorbell; | 795 | bool use_doorbell; |
793 | unsigned wptr_offs; | 796 | unsigned wptr_offs; |
794 | unsigned next_rptr_offs; | ||
795 | unsigned fence_offs; | 797 | unsigned fence_offs; |
796 | uint64_t current_ctx; | 798 | uint64_t current_ctx; |
797 | enum amdgpu_ring_type type; | 799 | enum amdgpu_ring_type type; |
@@ -799,6 +801,9 @@ struct amdgpu_ring { | |||
799 | unsigned cond_exe_offs; | 801 | unsigned cond_exe_offs; |
800 | u64 cond_exe_gpu_addr; | 802 | u64 cond_exe_gpu_addr; |
801 | volatile u32 *cond_exe_cpu_addr; | 803 | volatile u32 *cond_exe_cpu_addr; |
804 | #if defined(CONFIG_DEBUG_FS) | ||
805 | struct dentry *ent; | ||
806 | #endif | ||
802 | }; | 807 | }; |
803 | 808 | ||
804 | /* | 809 | /* |
@@ -861,6 +866,7 @@ struct amdgpu_vm { | |||
861 | struct amdgpu_bo *page_directory; | 866 | struct amdgpu_bo *page_directory; |
862 | unsigned max_pde_used; | 867 | unsigned max_pde_used; |
863 | struct fence *page_directory_fence; | 868 | struct fence *page_directory_fence; |
869 | uint64_t last_eviction_counter; | ||
864 | 870 | ||
865 | /* array of page tables, one for each page directory entry */ | 871 | /* array of page tables, one for each page directory entry */ |
866 | struct amdgpu_vm_pt *page_tables; | 872 | struct amdgpu_vm_pt *page_tables; |
@@ -883,13 +889,14 @@ struct amdgpu_vm_id { | |||
883 | struct fence *first; | 889 | struct fence *first; |
884 | struct amdgpu_sync active; | 890 | struct amdgpu_sync active; |
885 | struct fence *last_flush; | 891 | struct fence *last_flush; |
886 | struct amdgpu_ring *last_user; | ||
887 | atomic64_t owner; | 892 | atomic64_t owner; |
888 | 893 | ||
889 | uint64_t pd_gpu_addr; | 894 | uint64_t pd_gpu_addr; |
890 | /* last flushed PD/PT update */ | 895 | /* last flushed PD/PT update */ |
891 | struct fence *flushed_updates; | 896 | struct fence *flushed_updates; |
892 | 897 | ||
898 | uint32_t current_gpu_reset_count; | ||
899 | |||
893 | uint32_t gds_base; | 900 | uint32_t gds_base; |
894 | uint32_t gds_size; | 901 | uint32_t gds_size; |
895 | uint32_t gws_base; | 902 | uint32_t gws_base; |
@@ -905,6 +912,10 @@ struct amdgpu_vm_manager { | |||
905 | struct list_head ids_lru; | 912 | struct list_head ids_lru; |
906 | struct amdgpu_vm_id ids[AMDGPU_NUM_VM]; | 913 | struct amdgpu_vm_id ids[AMDGPU_NUM_VM]; |
907 | 914 | ||
915 | /* Handling of VM fences */ | ||
916 | u64 fence_context; | ||
917 | unsigned seqno[AMDGPU_MAX_RINGS]; | ||
918 | |||
908 | uint32_t max_pfn; | 919 | uint32_t max_pfn; |
909 | /* vram base address for page table entry */ | 920 | /* vram base address for page table entry */ |
910 | u64 vram_base_offset; | 921 | u64 vram_base_offset; |
@@ -926,17 +937,14 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); | |||
926 | void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, | 937 | void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, |
927 | struct list_head *validated, | 938 | struct list_head *validated, |
928 | struct amdgpu_bo_list_entry *entry); | 939 | struct amdgpu_bo_list_entry *entry); |
929 | void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates); | 940 | void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
941 | struct list_head *duplicates); | ||
930 | void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, | 942 | void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, |
931 | struct amdgpu_vm *vm); | 943 | struct amdgpu_vm *vm); |
932 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | 944 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, |
933 | struct amdgpu_sync *sync, struct fence *fence, | 945 | struct amdgpu_sync *sync, struct fence *fence, |
934 | unsigned *vm_id, uint64_t *vm_pd_addr); | 946 | struct amdgpu_job *job); |
935 | int amdgpu_vm_flush(struct amdgpu_ring *ring, | 947 | int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job); |
936 | unsigned vm_id, uint64_t pd_addr, | ||
937 | uint32_t gds_base, uint32_t gds_size, | ||
938 | uint32_t gws_base, uint32_t gws_size, | ||
939 | uint32_t oa_base, uint32_t oa_size); | ||
940 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); | 948 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); |
941 | uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); | 949 | uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); |
942 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | 950 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, |
@@ -1142,6 +1150,12 @@ struct amdgpu_cu_info { | |||
1142 | uint32_t bitmap[4][4]; | 1150 | uint32_t bitmap[4][4]; |
1143 | }; | 1151 | }; |
1144 | 1152 | ||
1153 | struct amdgpu_gfx_funcs { | ||
1154 | /* get the gpu clock counter */ | ||
1155 | uint64_t (*get_gpu_clock_counter)(struct amdgpu_device *adev); | ||
1156 | void (*select_se_sh)(struct amdgpu_device *adev, u32 se_num, u32 sh_num, u32 instance); | ||
1157 | }; | ||
1158 | |||
1145 | struct amdgpu_gfx { | 1159 | struct amdgpu_gfx { |
1146 | struct mutex gpu_clock_mutex; | 1160 | struct mutex gpu_clock_mutex; |
1147 | struct amdgpu_gca_config config; | 1161 | struct amdgpu_gca_config config; |
@@ -1178,6 +1192,7 @@ struct amdgpu_gfx { | |||
1178 | /* ce ram size*/ | 1192 | /* ce ram size*/ |
1179 | unsigned ce_ram_size; | 1193 | unsigned ce_ram_size; |
1180 | struct amdgpu_cu_info cu_info; | 1194 | struct amdgpu_cu_info cu_info; |
1195 | const struct amdgpu_gfx_funcs *funcs; | ||
1181 | }; | 1196 | }; |
1182 | 1197 | ||
1183 | int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 1198 | int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
@@ -1195,10 +1210,6 @@ void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count); | |||
1195 | void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); | 1210 | void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); |
1196 | void amdgpu_ring_commit(struct amdgpu_ring *ring); | 1211 | void amdgpu_ring_commit(struct amdgpu_ring *ring); |
1197 | void amdgpu_ring_undo(struct amdgpu_ring *ring); | 1212 | void amdgpu_ring_undo(struct amdgpu_ring *ring); |
1198 | unsigned amdgpu_ring_backup(struct amdgpu_ring *ring, | ||
1199 | uint32_t **data); | ||
1200 | int amdgpu_ring_restore(struct amdgpu_ring *ring, | ||
1201 | unsigned size, uint32_t *data); | ||
1202 | int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | 1213 | int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, |
1203 | unsigned ring_size, u32 nop, u32 align_mask, | 1214 | unsigned ring_size, u32 nop, u32 align_mask, |
1204 | struct amdgpu_irq_src *irq_src, unsigned irq_type, | 1215 | struct amdgpu_irq_src *irq_src, unsigned irq_type, |
@@ -1250,6 +1261,7 @@ struct amdgpu_job { | |||
1250 | uint32_t num_ibs; | 1261 | uint32_t num_ibs; |
1251 | void *owner; | 1262 | void *owner; |
1252 | uint64_t ctx; | 1263 | uint64_t ctx; |
1264 | bool vm_needs_flush; | ||
1253 | unsigned vm_id; | 1265 | unsigned vm_id; |
1254 | uint64_t vm_pd_addr; | 1266 | uint64_t vm_pd_addr; |
1255 | uint32_t gds_base, gds_size; | 1267 | uint32_t gds_base, gds_size; |
@@ -1257,8 +1269,7 @@ struct amdgpu_job { | |||
1257 | uint32_t oa_base, oa_size; | 1269 | uint32_t oa_base, oa_size; |
1258 | 1270 | ||
1259 | /* user fence handling */ | 1271 | /* user fence handling */ |
1260 | struct amdgpu_bo *uf_bo; | 1272 | uint64_t uf_addr; |
1261 | uint32_t uf_offset; | ||
1262 | uint64_t uf_sequence; | 1273 | uint64_t uf_sequence; |
1263 | 1274 | ||
1264 | }; | 1275 | }; |
@@ -1560,6 +1571,12 @@ struct amdgpu_dpm_funcs { | |||
1560 | u32 (*get_fan_control_mode)(struct amdgpu_device *adev); | 1571 | u32 (*get_fan_control_mode)(struct amdgpu_device *adev); |
1561 | int (*set_fan_speed_percent)(struct amdgpu_device *adev, u32 speed); | 1572 | int (*set_fan_speed_percent)(struct amdgpu_device *adev, u32 speed); |
1562 | int (*get_fan_speed_percent)(struct amdgpu_device *adev, u32 *speed); | 1573 | int (*get_fan_speed_percent)(struct amdgpu_device *adev, u32 *speed); |
1574 | int (*force_clock_level)(struct amdgpu_device *adev, enum pp_clock_type type, uint32_t mask); | ||
1575 | int (*print_clock_levels)(struct amdgpu_device *adev, enum pp_clock_type type, char *buf); | ||
1576 | int (*get_sclk_od)(struct amdgpu_device *adev); | ||
1577 | int (*set_sclk_od)(struct amdgpu_device *adev, uint32_t value); | ||
1578 | int (*get_mclk_od)(struct amdgpu_device *adev); | ||
1579 | int (*set_mclk_od)(struct amdgpu_device *adev, uint32_t value); | ||
1563 | }; | 1580 | }; |
1564 | 1581 | ||
1565 | struct amdgpu_dpm { | 1582 | struct amdgpu_dpm { |
@@ -1767,6 +1784,8 @@ int amdgpu_debugfs_init(struct drm_minor *minor); | |||
1767 | void amdgpu_debugfs_cleanup(struct drm_minor *minor); | 1784 | void amdgpu_debugfs_cleanup(struct drm_minor *minor); |
1768 | #endif | 1785 | #endif |
1769 | 1786 | ||
1787 | int amdgpu_debugfs_firmware_init(struct amdgpu_device *adev); | ||
1788 | |||
1770 | /* | 1789 | /* |
1771 | * amdgpu smumgr functions | 1790 | * amdgpu smumgr functions |
1772 | */ | 1791 | */ |
@@ -1811,12 +1830,8 @@ struct amdgpu_asic_funcs { | |||
1811 | u32 sh_num, u32 reg_offset, u32 *value); | 1830 | u32 sh_num, u32 reg_offset, u32 *value); |
1812 | void (*set_vga_state)(struct amdgpu_device *adev, bool state); | 1831 | void (*set_vga_state)(struct amdgpu_device *adev, bool state); |
1813 | int (*reset)(struct amdgpu_device *adev); | 1832 | int (*reset)(struct amdgpu_device *adev); |
1814 | /* wait for mc_idle */ | ||
1815 | int (*wait_for_mc_idle)(struct amdgpu_device *adev); | ||
1816 | /* get the reference clock */ | 1833 | /* get the reference clock */ |
1817 | u32 (*get_xclk)(struct amdgpu_device *adev); | 1834 | u32 (*get_xclk)(struct amdgpu_device *adev); |
1818 | /* get the gpu clock counter */ | ||
1819 | uint64_t (*get_gpu_clock_counter)(struct amdgpu_device *adev); | ||
1820 | /* MM block clocks */ | 1835 | /* MM block clocks */ |
1821 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); | 1836 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); |
1822 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); | 1837 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); |
@@ -2003,6 +2018,10 @@ struct amdgpu_device { | |||
2003 | spinlock_t didt_idx_lock; | 2018 | spinlock_t didt_idx_lock; |
2004 | amdgpu_rreg_t didt_rreg; | 2019 | amdgpu_rreg_t didt_rreg; |
2005 | amdgpu_wreg_t didt_wreg; | 2020 | amdgpu_wreg_t didt_wreg; |
2021 | /* protects concurrent gc_cac register access */ | ||
2022 | spinlock_t gc_cac_idx_lock; | ||
2023 | amdgpu_rreg_t gc_cac_rreg; | ||
2024 | amdgpu_wreg_t gc_cac_wreg; | ||
2006 | /* protects concurrent ENDPOINT (audio) register access */ | 2025 | /* protects concurrent ENDPOINT (audio) register access */ |
2007 | spinlock_t audio_endpt_idx_lock; | 2026 | spinlock_t audio_endpt_idx_lock; |
2008 | amdgpu_block_rreg_t audio_endpt_rreg; | 2027 | amdgpu_block_rreg_t audio_endpt_rreg; |
@@ -2028,6 +2047,7 @@ struct amdgpu_device { | |||
2028 | atomic64_t vram_vis_usage; | 2047 | atomic64_t vram_vis_usage; |
2029 | atomic64_t gtt_usage; | 2048 | atomic64_t gtt_usage; |
2030 | atomic64_t num_bytes_moved; | 2049 | atomic64_t num_bytes_moved; |
2050 | atomic64_t num_evictions; | ||
2031 | atomic_t gpu_reset_counter; | 2051 | atomic_t gpu_reset_counter; |
2032 | 2052 | ||
2033 | /* display */ | 2053 | /* display */ |
@@ -2131,6 +2151,8 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v); | |||
2131 | #define WREG32_UVD_CTX(reg, v) adev->uvd_ctx_wreg(adev, (reg), (v)) | 2151 | #define WREG32_UVD_CTX(reg, v) adev->uvd_ctx_wreg(adev, (reg), (v)) |
2132 | #define RREG32_DIDT(reg) adev->didt_rreg(adev, (reg)) | 2152 | #define RREG32_DIDT(reg) adev->didt_rreg(adev, (reg)) |
2133 | #define WREG32_DIDT(reg, v) adev->didt_wreg(adev, (reg), (v)) | 2153 | #define WREG32_DIDT(reg, v) adev->didt_wreg(adev, (reg), (v)) |
2154 | #define RREG32_GC_CAC(reg) adev->gc_cac_rreg(adev, (reg)) | ||
2155 | #define WREG32_GC_CAC(reg, v) adev->gc_cac_wreg(adev, (reg), (v)) | ||
2134 | #define RREG32_AUDIO_ENDPT(block, reg) adev->audio_endpt_rreg(adev, (block), (reg)) | 2156 | #define RREG32_AUDIO_ENDPT(block, reg) adev->audio_endpt_rreg(adev, (block), (reg)) |
2135 | #define WREG32_AUDIO_ENDPT(block, reg, v) adev->audio_endpt_wreg(adev, (block), (reg), (v)) | 2157 | #define WREG32_AUDIO_ENDPT(block, reg, v) adev->audio_endpt_wreg(adev, (block), (reg), (v)) |
2136 | #define WREG32_P(reg, val, mask) \ | 2158 | #define WREG32_P(reg, val, mask) \ |
@@ -2206,12 +2228,10 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
2206 | */ | 2228 | */ |
2207 | #define amdgpu_asic_set_vga_state(adev, state) (adev)->asic_funcs->set_vga_state((adev), (state)) | 2229 | #define amdgpu_asic_set_vga_state(adev, state) (adev)->asic_funcs->set_vga_state((adev), (state)) |
2208 | #define amdgpu_asic_reset(adev) (adev)->asic_funcs->reset((adev)) | 2230 | #define amdgpu_asic_reset(adev) (adev)->asic_funcs->reset((adev)) |
2209 | #define amdgpu_asic_wait_for_mc_idle(adev) (adev)->asic_funcs->wait_for_mc_idle((adev)) | ||
2210 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) | 2231 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) |
2211 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) | 2232 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) |
2212 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) | 2233 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) |
2213 | #define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev))) | 2234 | #define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev))) |
2214 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) | ||
2215 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) | 2235 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) |
2216 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) | 2236 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) |
2217 | #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v))) | 2237 | #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v))) |
@@ -2264,6 +2284,8 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
2264 | #define amdgpu_dpm_print_power_state(adev, ps) (adev)->pm.funcs->print_power_state((adev), (ps)) | 2284 | #define amdgpu_dpm_print_power_state(adev, ps) (adev)->pm.funcs->print_power_state((adev), (ps)) |
2265 | #define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev)) | 2285 | #define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev)) |
2266 | #define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e)) | 2286 | #define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e)) |
2287 | #define amdgpu_gfx_get_gpu_clock_counter(adev) (adev)->gfx.funcs->get_gpu_clock_counter((adev)) | ||
2288 | #define amdgpu_gfx_select_se_sh(adev, se, sh, instance) (adev)->gfx.funcs->select_se_sh((adev), (se), (sh), (instance)) | ||
2267 | 2289 | ||
2268 | #define amdgpu_dpm_get_temperature(adev) \ | 2290 | #define amdgpu_dpm_get_temperature(adev) \ |
2269 | ((adev)->pp_enabled ? \ | 2291 | ((adev)->pp_enabled ? \ |
@@ -2342,6 +2364,18 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
2342 | #define amdgpu_dpm_force_clock_level(adev, type, level) \ | 2364 | #define amdgpu_dpm_force_clock_level(adev, type, level) \ |
2343 | (adev)->powerplay.pp_funcs->force_clock_level((adev)->powerplay.pp_handle, type, level) | 2365 | (adev)->powerplay.pp_funcs->force_clock_level((adev)->powerplay.pp_handle, type, level) |
2344 | 2366 | ||
2367 | #define amdgpu_dpm_get_sclk_od(adev) \ | ||
2368 | (adev)->powerplay.pp_funcs->get_sclk_od((adev)->powerplay.pp_handle) | ||
2369 | |||
2370 | #define amdgpu_dpm_set_sclk_od(adev, value) \ | ||
2371 | (adev)->powerplay.pp_funcs->set_sclk_od((adev)->powerplay.pp_handle, value) | ||
2372 | |||
2373 | #define amdgpu_dpm_get_mclk_od(adev) \ | ||
2374 | ((adev)->powerplay.pp_funcs->get_mclk_od((adev)->powerplay.pp_handle)) | ||
2375 | |||
2376 | #define amdgpu_dpm_set_mclk_od(adev, value) \ | ||
2377 | ((adev)->powerplay.pp_funcs->set_mclk_od((adev)->powerplay.pp_handle, value)) | ||
2378 | |||
2345 | #define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \ | 2379 | #define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \ |
2346 | (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output)) | 2380 | (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output)) |
2347 | 2381 | ||
@@ -2383,9 +2417,13 @@ bool amdgpu_device_is_px(struct drm_device *dev); | |||
2383 | #if defined(CONFIG_VGA_SWITCHEROO) | 2417 | #if defined(CONFIG_VGA_SWITCHEROO) |
2384 | void amdgpu_register_atpx_handler(void); | 2418 | void amdgpu_register_atpx_handler(void); |
2385 | void amdgpu_unregister_atpx_handler(void); | 2419 | void amdgpu_unregister_atpx_handler(void); |
2420 | bool amdgpu_has_atpx_dgpu_power_cntl(void); | ||
2421 | bool amdgpu_is_atpx_hybrid(void); | ||
2386 | #else | 2422 | #else |
2387 | static inline void amdgpu_register_atpx_handler(void) {} | 2423 | static inline void amdgpu_register_atpx_handler(void) {} |
2388 | static inline void amdgpu_unregister_atpx_handler(void) {} | 2424 | static inline void amdgpu_unregister_atpx_handler(void) {} |
2425 | static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } | ||
2426 | static inline bool amdgpu_is_atpx_hybrid(void) { return false; } | ||
2389 | #endif | 2427 | #endif |
2390 | 2428 | ||
2391 | /* | 2429 | /* |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 32809f749903..d080d0807a5b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | |||
@@ -240,8 +240,8 @@ uint64_t get_gpu_clock_counter(struct kgd_dev *kgd) | |||
240 | { | 240 | { |
241 | struct amdgpu_device *rdev = (struct amdgpu_device *)kgd; | 241 | struct amdgpu_device *rdev = (struct amdgpu_device *)kgd; |
242 | 242 | ||
243 | if (rdev->asic_funcs->get_gpu_clock_counter) | 243 | if (rdev->gfx.funcs->get_gpu_clock_counter) |
244 | return rdev->asic_funcs->get_gpu_clock_counter(rdev); | 244 | return rdev->gfx.funcs->get_gpu_clock_counter(rdev); |
245 | return 0; | 245 | return 0; |
246 | } | 246 | } |
247 | 247 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 35a1248aaa77..0494fe7b62c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/acpi.h> | 11 | #include <linux/acpi.h> |
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/delay.h> | ||
13 | 14 | ||
14 | #include "amd_acpi.h" | 15 | #include "amd_acpi.h" |
15 | 16 | ||
@@ -27,6 +28,7 @@ struct amdgpu_atpx_functions { | |||
27 | struct amdgpu_atpx { | 28 | struct amdgpu_atpx { |
28 | acpi_handle handle; | 29 | acpi_handle handle; |
29 | struct amdgpu_atpx_functions functions; | 30 | struct amdgpu_atpx_functions functions; |
31 | bool is_hybrid; | ||
30 | }; | 32 | }; |
31 | 33 | ||
32 | static struct amdgpu_atpx_priv { | 34 | static struct amdgpu_atpx_priv { |
@@ -63,6 +65,14 @@ bool amdgpu_has_atpx(void) { | |||
63 | return amdgpu_atpx_priv.atpx_detected; | 65 | return amdgpu_atpx_priv.atpx_detected; |
64 | } | 66 | } |
65 | 67 | ||
68 | bool amdgpu_has_atpx_dgpu_power_cntl(void) { | ||
69 | return amdgpu_atpx_priv.atpx.functions.power_cntl; | ||
70 | } | ||
71 | |||
72 | bool amdgpu_is_atpx_hybrid(void) { | ||
73 | return amdgpu_atpx_priv.atpx.is_hybrid; | ||
74 | } | ||
75 | |||
66 | /** | 76 | /** |
67 | * amdgpu_atpx_call - call an ATPX method | 77 | * amdgpu_atpx_call - call an ATPX method |
68 | * | 78 | * |
@@ -142,18 +152,12 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas | |||
142 | */ | 152 | */ |
143 | static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) | 153 | static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) |
144 | { | 154 | { |
145 | /* make sure required functions are enabled */ | 155 | u32 valid_bits = 0; |
146 | /* dGPU power control is required */ | ||
147 | if (atpx->functions.power_cntl == false) { | ||
148 | printk("ATPX dGPU power cntl not present, forcing\n"); | ||
149 | atpx->functions.power_cntl = true; | ||
150 | } | ||
151 | 156 | ||
152 | if (atpx->functions.px_params) { | 157 | if (atpx->functions.px_params) { |
153 | union acpi_object *info; | 158 | union acpi_object *info; |
154 | struct atpx_px_params output; | 159 | struct atpx_px_params output; |
155 | size_t size; | 160 | size_t size; |
156 | u32 valid_bits; | ||
157 | 161 | ||
158 | info = amdgpu_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); | 162 | info = amdgpu_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); |
159 | if (!info) | 163 | if (!info) |
@@ -172,19 +176,43 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) | |||
172 | memcpy(&output, info->buffer.pointer, size); | 176 | memcpy(&output, info->buffer.pointer, size); |
173 | 177 | ||
174 | valid_bits = output.flags & output.valid_flags; | 178 | valid_bits = output.flags & output.valid_flags; |
175 | /* if separate mux flag is set, mux controls are required */ | ||
176 | if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { | ||
177 | atpx->functions.i2c_mux_cntl = true; | ||
178 | atpx->functions.disp_mux_cntl = true; | ||
179 | } | ||
180 | /* if any outputs are muxed, mux controls are required */ | ||
181 | if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | | ||
182 | ATPX_TV_SIGNAL_MUXED | | ||
183 | ATPX_DFP_SIGNAL_MUXED)) | ||
184 | atpx->functions.disp_mux_cntl = true; | ||
185 | 179 | ||
186 | kfree(info); | 180 | kfree(info); |
187 | } | 181 | } |
182 | |||
183 | /* if separate mux flag is set, mux controls are required */ | ||
184 | if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { | ||
185 | atpx->functions.i2c_mux_cntl = true; | ||
186 | atpx->functions.disp_mux_cntl = true; | ||
187 | } | ||
188 | /* if any outputs are muxed, mux controls are required */ | ||
189 | if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | | ||
190 | ATPX_TV_SIGNAL_MUXED | | ||
191 | ATPX_DFP_SIGNAL_MUXED)) | ||
192 | atpx->functions.disp_mux_cntl = true; | ||
193 | |||
194 | |||
195 | /* some bioses set these bits rather than flagging power_cntl as supported */ | ||
196 | if (valid_bits & (ATPX_DYNAMIC_PX_SUPPORTED | | ||
197 | ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED)) | ||
198 | atpx->functions.power_cntl = true; | ||
199 | |||
200 | atpx->is_hybrid = false; | ||
201 | if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { | ||
202 | printk("ATPX Hybrid Graphics\n"); | ||
203 | #if 1 | ||
204 | /* This is a temporary hack until the D3 cold support | ||
205 | * makes it upstream. The ATPX power_control method seems | ||
206 | * to still work on even if the system should be using | ||
207 | * the new standardized hybrid D3 cold ACPI interface. | ||
208 | */ | ||
209 | atpx->functions.power_cntl = true; | ||
210 | #else | ||
211 | atpx->functions.power_cntl = false; | ||
212 | #endif | ||
213 | atpx->is_hybrid = true; | ||
214 | } | ||
215 | |||
188 | return 0; | 216 | return 0; |
189 | } | 217 | } |
190 | 218 | ||
@@ -259,6 +287,10 @@ static int amdgpu_atpx_set_discrete_state(struct amdgpu_atpx *atpx, u8 state) | |||
259 | if (!info) | 287 | if (!info) |
260 | return -EIO; | 288 | return -EIO; |
261 | kfree(info); | 289 | kfree(info); |
290 | |||
291 | /* 200ms delay is required after off */ | ||
292 | if (state == 0) | ||
293 | msleep(200); | ||
262 | } | 294 | } |
263 | return 0; | 295 | return 0; |
264 | } | 296 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 823bf5e0b0c8..651115dcce12 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | |||
@@ -94,6 +94,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, | |||
94 | unsigned last_entry = 0, first_userptr = num_entries; | 94 | unsigned last_entry = 0, first_userptr = num_entries; |
95 | unsigned i; | 95 | unsigned i; |
96 | int r; | 96 | int r; |
97 | unsigned long total_size = 0; | ||
97 | 98 | ||
98 | array = drm_malloc_ab(num_entries, sizeof(struct amdgpu_bo_list_entry)); | 99 | array = drm_malloc_ab(num_entries, sizeof(struct amdgpu_bo_list_entry)); |
99 | if (!array) | 100 | if (!array) |
@@ -140,6 +141,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, | |||
140 | if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_OA) | 141 | if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_OA) |
141 | oa_obj = entry->robj; | 142 | oa_obj = entry->robj; |
142 | 143 | ||
144 | total_size += amdgpu_bo_size(entry->robj); | ||
143 | trace_amdgpu_bo_list_set(list, entry->robj); | 145 | trace_amdgpu_bo_list_set(list, entry->robj); |
144 | } | 146 | } |
145 | 147 | ||
@@ -155,6 +157,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, | |||
155 | list->array = array; | 157 | list->array = array; |
156 | list->num_entries = num_entries; | 158 | list->num_entries = num_entries; |
157 | 159 | ||
160 | trace_amdgpu_cs_bo_status(list->num_entries, total_size); | ||
158 | return 0; | 161 | return 0; |
159 | 162 | ||
160 | error_free: | 163 | error_free: |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index cf6f49fc1c75..5556ce979199 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
@@ -312,6 +312,8 @@ static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device, | |||
312 | return RREG32_UVD_CTX(index); | 312 | return RREG32_UVD_CTX(index); |
313 | case CGS_IND_REG__DIDT: | 313 | case CGS_IND_REG__DIDT: |
314 | return RREG32_DIDT(index); | 314 | return RREG32_DIDT(index); |
315 | case CGS_IND_REG_GC_CAC: | ||
316 | return RREG32_GC_CAC(index); | ||
315 | case CGS_IND_REG__AUDIO_ENDPT: | 317 | case CGS_IND_REG__AUDIO_ENDPT: |
316 | DRM_ERROR("audio endpt register access not implemented.\n"); | 318 | DRM_ERROR("audio endpt register access not implemented.\n"); |
317 | return 0; | 319 | return 0; |
@@ -336,6 +338,8 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device, | |||
336 | return WREG32_UVD_CTX(index, value); | 338 | return WREG32_UVD_CTX(index, value); |
337 | case CGS_IND_REG__DIDT: | 339 | case CGS_IND_REG__DIDT: |
338 | return WREG32_DIDT(index, value); | 340 | return WREG32_DIDT(index, value); |
341 | case CGS_IND_REG_GC_CAC: | ||
342 | return WREG32_GC_CAC(index, value); | ||
339 | case CGS_IND_REG__AUDIO_ENDPT: | 343 | case CGS_IND_REG__AUDIO_ENDPT: |
340 | DRM_ERROR("audio endpt register access not implemented.\n"); | 344 | DRM_ERROR("audio endpt register access not implemented.\n"); |
341 | return; | 345 | return; |
@@ -787,6 +791,7 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
787 | } | 791 | } |
788 | 792 | ||
789 | hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; | 793 | hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; |
794 | amdgpu_ucode_print_smc_hdr(&hdr->header); | ||
790 | adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); | 795 | adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); |
791 | ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); | 796 | ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); |
792 | ucode_start_address = le32_to_cpu(hdr->ucode_start_addr); | 797 | ucode_start_address = le32_to_cpu(hdr->ucode_start_addr); |
@@ -830,6 +835,9 @@ static int amdgpu_cgs_query_system_info(struct cgs_device *cgs_device, | |||
830 | case CGS_SYSTEM_INFO_GFX_CU_INFO: | 835 | case CGS_SYSTEM_INFO_GFX_CU_INFO: |
831 | sys_info->value = adev->gfx.cu_info.number; | 836 | sys_info->value = adev->gfx.cu_info.number; |
832 | break; | 837 | break; |
838 | case CGS_SYSTEM_INFO_GFX_SE_INFO: | ||
839 | sys_info->value = adev->gfx.config.max_shader_engines; | ||
840 | break; | ||
833 | default: | 841 | default: |
834 | return -ENODEV; | 842 | return -ENODEV; |
835 | } | 843 | } |
@@ -972,11 +980,11 @@ static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device, | |||
972 | params->integer.value = argument->value; | 980 | params->integer.value = argument->value; |
973 | break; | 981 | break; |
974 | case ACPI_TYPE_STRING: | 982 | case ACPI_TYPE_STRING: |
975 | params->string.length = argument->method_length; | 983 | params->string.length = argument->data_length; |
976 | params->string.pointer = argument->pointer; | 984 | params->string.pointer = argument->pointer; |
977 | break; | 985 | break; |
978 | case ACPI_TYPE_BUFFER: | 986 | case ACPI_TYPE_BUFFER: |
979 | params->buffer.length = argument->method_length; | 987 | params->buffer.length = argument->data_length; |
980 | params->buffer.pointer = argument->pointer; | 988 | params->buffer.pointer = argument->pointer; |
981 | break; | 989 | break; |
982 | default: | 990 | default: |
@@ -1079,17 +1087,14 @@ int amdgpu_cgs_call_acpi_method(struct cgs_device *cgs_device, | |||
1079 | struct cgs_acpi_method_info info = {0}; | 1087 | struct cgs_acpi_method_info info = {0}; |
1080 | 1088 | ||
1081 | acpi_input[0].type = CGS_ACPI_TYPE_INTEGER; | 1089 | acpi_input[0].type = CGS_ACPI_TYPE_INTEGER; |
1082 | acpi_input[0].method_length = sizeof(uint32_t); | ||
1083 | acpi_input[0].data_length = sizeof(uint32_t); | 1090 | acpi_input[0].data_length = sizeof(uint32_t); |
1084 | acpi_input[0].value = acpi_function; | 1091 | acpi_input[0].value = acpi_function; |
1085 | 1092 | ||
1086 | acpi_input[1].type = CGS_ACPI_TYPE_BUFFER; | 1093 | acpi_input[1].type = CGS_ACPI_TYPE_BUFFER; |
1087 | acpi_input[1].method_length = CGS_ACPI_MAX_BUFFER_SIZE; | ||
1088 | acpi_input[1].data_length = input_size; | 1094 | acpi_input[1].data_length = input_size; |
1089 | acpi_input[1].pointer = pinput; | 1095 | acpi_input[1].pointer = pinput; |
1090 | 1096 | ||
1091 | acpi_output.type = CGS_ACPI_TYPE_BUFFER; | 1097 | acpi_output.type = CGS_ACPI_TYPE_BUFFER; |
1092 | acpi_output.method_length = CGS_ACPI_MAX_BUFFER_SIZE; | ||
1093 | acpi_output.data_length = output_size; | 1098 | acpi_output.data_length = output_size; |
1094 | acpi_output.pointer = poutput; | 1099 | acpi_output.pointer = poutput; |
1095 | 1100 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index cb07da41152b..ff0b55a65ca3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | |||
@@ -1690,7 +1690,6 @@ amdgpu_connector_add(struct amdgpu_device *adev, | |||
1690 | DRM_MODE_SCALE_NONE); | 1690 | DRM_MODE_SCALE_NONE); |
1691 | /* no HPD on analog connectors */ | 1691 | /* no HPD on analog connectors */ |
1692 | amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE; | 1692 | amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE; |
1693 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
1694 | connector->interlace_allowed = true; | 1693 | connector->interlace_allowed = true; |
1695 | connector->doublescan_allowed = true; | 1694 | connector->doublescan_allowed = true; |
1696 | break; | 1695 | break; |
@@ -1893,8 +1892,10 @@ amdgpu_connector_add(struct amdgpu_device *adev, | |||
1893 | } | 1892 | } |
1894 | 1893 | ||
1895 | if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE) { | 1894 | if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE) { |
1896 | if (i2c_bus->valid) | 1895 | if (i2c_bus->valid) { |
1897 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 1896 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | |
1897 | DRM_CONNECTOR_POLL_DISCONNECT; | ||
1898 | } | ||
1898 | } else | 1899 | } else |
1899 | connector->polled = DRM_CONNECTOR_POLL_HPD; | 1900 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
1900 | 1901 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 9bc8f1d99733..0307ff5887c5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -216,11 +216,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
216 | if (ret) | 216 | if (ret) |
217 | goto free_all_kdata; | 217 | goto free_all_kdata; |
218 | 218 | ||
219 | if (p->uf_entry.robj) { | 219 | if (p->uf_entry.robj) |
220 | p->job->uf_bo = amdgpu_bo_ref(p->uf_entry.robj); | 220 | p->job->uf_addr = uf_offset; |
221 | p->job->uf_offset = uf_offset; | ||
222 | } | ||
223 | |||
224 | kfree(chunk_array); | 221 | kfree(chunk_array); |
225 | return 0; | 222 | return 0; |
226 | 223 | ||
@@ -459,7 +456,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
459 | list_splice(&need_pages, &p->validated); | 456 | list_splice(&need_pages, &p->validated); |
460 | } | 457 | } |
461 | 458 | ||
462 | amdgpu_vm_get_pt_bos(&fpriv->vm, &duplicates); | 459 | amdgpu_vm_get_pt_bos(p->adev, &fpriv->vm, &duplicates); |
463 | 460 | ||
464 | p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev); | 461 | p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev); |
465 | p->bytes_moved = 0; | 462 | p->bytes_moved = 0; |
@@ -472,6 +469,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
472 | if (r) | 469 | if (r) |
473 | goto error_validate; | 470 | goto error_validate; |
474 | 471 | ||
472 | fpriv->vm.last_eviction_counter = | ||
473 | atomic64_read(&p->adev->num_evictions); | ||
474 | |||
475 | if (p->bo_list) { | 475 | if (p->bo_list) { |
476 | struct amdgpu_bo *gds = p->bo_list->gds_obj; | 476 | struct amdgpu_bo *gds = p->bo_list->gds_obj; |
477 | struct amdgpu_bo *gws = p->bo_list->gws_obj; | 477 | struct amdgpu_bo *gws = p->bo_list->gws_obj; |
@@ -499,6 +499,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
499 | } | 499 | } |
500 | } | 500 | } |
501 | 501 | ||
502 | if (p->uf_entry.robj) | ||
503 | p->job->uf_addr += amdgpu_bo_gpu_offset(p->uf_entry.robj); | ||
504 | |||
502 | error_validate: | 505 | error_validate: |
503 | if (r) { | 506 | if (r) { |
504 | amdgpu_vm_move_pt_bos_in_lru(p->adev, &fpriv->vm); | 507 | amdgpu_vm_move_pt_bos_in_lru(p->adev, &fpriv->vm); |
@@ -653,18 +656,21 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, | |||
653 | 656 | ||
654 | /* Only for UVD/VCE VM emulation */ | 657 | /* Only for UVD/VCE VM emulation */ |
655 | if (ring->funcs->parse_cs) { | 658 | if (ring->funcs->parse_cs) { |
659 | p->job->vm = NULL; | ||
656 | for (i = 0; i < p->job->num_ibs; i++) { | 660 | for (i = 0; i < p->job->num_ibs; i++) { |
657 | r = amdgpu_ring_parse_cs(ring, p, i); | 661 | r = amdgpu_ring_parse_cs(ring, p, i); |
658 | if (r) | 662 | if (r) |
659 | return r; | 663 | return r; |
660 | } | 664 | } |
661 | } | 665 | } else { |
666 | p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); | ||
662 | 667 | ||
663 | r = amdgpu_bo_vm_update_pte(p, vm); | 668 | r = amdgpu_bo_vm_update_pte(p, vm); |
664 | if (!r) | 669 | if (r) |
665 | amdgpu_cs_sync_rings(p); | 670 | return r; |
671 | } | ||
666 | 672 | ||
667 | return r; | 673 | return amdgpu_cs_sync_rings(p); |
668 | } | 674 | } |
669 | 675 | ||
670 | static int amdgpu_cs_handle_lockup(struct amdgpu_device *adev, int r) | 676 | static int amdgpu_cs_handle_lockup(struct amdgpu_device *adev, int r) |
@@ -761,7 +767,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
761 | } | 767 | } |
762 | 768 | ||
763 | /* UVD & VCE fw doesn't support user fences */ | 769 | /* UVD & VCE fw doesn't support user fences */ |
764 | if (parser->job->uf_bo && ( | 770 | if (parser->job->uf_addr && ( |
765 | parser->job->ring->type == AMDGPU_RING_TYPE_UVD || | 771 | parser->job->ring->type == AMDGPU_RING_TYPE_UVD || |
766 | parser->job->ring->type == AMDGPU_RING_TYPE_VCE)) | 772 | parser->job->ring->type == AMDGPU_RING_TYPE_VCE)) |
767 | return -EINVAL; | 773 | return -EINVAL; |
@@ -830,17 +836,13 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
830 | { | 836 | { |
831 | struct amdgpu_ring *ring = p->job->ring; | 837 | struct amdgpu_ring *ring = p->job->ring; |
832 | struct amd_sched_entity *entity = &p->ctx->rings[ring->idx].entity; | 838 | struct amd_sched_entity *entity = &p->ctx->rings[ring->idx].entity; |
833 | struct fence *fence; | ||
834 | struct amdgpu_job *job; | 839 | struct amdgpu_job *job; |
835 | int r; | 840 | int r; |
836 | 841 | ||
837 | job = p->job; | 842 | job = p->job; |
838 | p->job = NULL; | 843 | p->job = NULL; |
839 | 844 | ||
840 | r = amd_sched_job_init(&job->base, &ring->sched, | 845 | r = amd_sched_job_init(&job->base, &ring->sched, entity, p->filp); |
841 | entity, amdgpu_job_timeout_func, | ||
842 | amdgpu_job_free_func, | ||
843 | p->filp, &fence); | ||
844 | if (r) { | 846 | if (r) { |
845 | amdgpu_job_free(job); | 847 | amdgpu_job_free(job); |
846 | return r; | 848 | return r; |
@@ -848,9 +850,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
848 | 850 | ||
849 | job->owner = p->filp; | 851 | job->owner = p->filp; |
850 | job->ctx = entity->fence_context; | 852 | job->ctx = entity->fence_context; |
851 | p->fence = fence_get(fence); | 853 | p->fence = fence_get(&job->base.s_fence->finished); |
852 | cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, fence); | 854 | cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, p->fence); |
853 | job->uf_sequence = cs->out.handle; | 855 | job->uf_sequence = cs->out.handle; |
856 | amdgpu_job_free_resources(job); | ||
854 | 857 | ||
855 | trace_amdgpu_cs_ioctl(job); | 858 | trace_amdgpu_cs_ioctl(job); |
856 | amd_sched_entity_push_job(&job->base); | 859 | amd_sched_entity_push_job(&job->base); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 6e920086af46..9c9f28c1ce84 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * Alex Deucher | 25 | * Alex Deucher |
26 | * Jerome Glisse | 26 | * Jerome Glisse |
27 | */ | 27 | */ |
28 | #include <linux/kthread.h> | ||
28 | #include <linux/console.h> | 29 | #include <linux/console.h> |
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/debugfs.h> | 31 | #include <linux/debugfs.h> |
@@ -35,6 +36,7 @@ | |||
35 | #include <linux/vga_switcheroo.h> | 36 | #include <linux/vga_switcheroo.h> |
36 | #include <linux/efi.h> | 37 | #include <linux/efi.h> |
37 | #include "amdgpu.h" | 38 | #include "amdgpu.h" |
39 | #include "amdgpu_trace.h" | ||
38 | #include "amdgpu_i2c.h" | 40 | #include "amdgpu_i2c.h" |
39 | #include "atom.h" | 41 | #include "atom.h" |
40 | #include "amdgpu_atombios.h" | 42 | #include "amdgpu_atombios.h" |
@@ -79,24 +81,27 @@ bool amdgpu_device_is_px(struct drm_device *dev) | |||
79 | uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, | 81 | uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, |
80 | bool always_indirect) | 82 | bool always_indirect) |
81 | { | 83 | { |
84 | uint32_t ret; | ||
85 | |||
82 | if ((reg * 4) < adev->rmmio_size && !always_indirect) | 86 | if ((reg * 4) < adev->rmmio_size && !always_indirect) |
83 | return readl(((void __iomem *)adev->rmmio) + (reg * 4)); | 87 | ret = readl(((void __iomem *)adev->rmmio) + (reg * 4)); |
84 | else { | 88 | else { |
85 | unsigned long flags; | 89 | unsigned long flags; |
86 | uint32_t ret; | ||
87 | 90 | ||
88 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); | 91 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); |
89 | writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4)); | 92 | writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4)); |
90 | ret = readl(((void __iomem *)adev->rmmio) + (mmMM_DATA * 4)); | 93 | ret = readl(((void __iomem *)adev->rmmio) + (mmMM_DATA * 4)); |
91 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); | 94 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); |
92 | |||
93 | return ret; | ||
94 | } | 95 | } |
96 | trace_amdgpu_mm_rreg(adev->pdev->device, reg, ret); | ||
97 | return ret; | ||
95 | } | 98 | } |
96 | 99 | ||
97 | void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, | 100 | void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, |
98 | bool always_indirect) | 101 | bool always_indirect) |
99 | { | 102 | { |
103 | trace_amdgpu_mm_wreg(adev->pdev->device, reg, v); | ||
104 | |||
100 | if ((reg * 4) < adev->rmmio_size && !always_indirect) | 105 | if ((reg * 4) < adev->rmmio_size && !always_indirect) |
101 | writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); | 106 | writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); |
102 | else { | 107 | else { |
@@ -1070,11 +1075,14 @@ int amdgpu_set_clockgating_state(struct amdgpu_device *adev, | |||
1070 | int i, r = 0; | 1075 | int i, r = 0; |
1071 | 1076 | ||
1072 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1077 | for (i = 0; i < adev->num_ip_blocks; i++) { |
1078 | if (!adev->ip_block_status[i].valid) | ||
1079 | continue; | ||
1073 | if (adev->ip_blocks[i].type == block_type) { | 1080 | if (adev->ip_blocks[i].type == block_type) { |
1074 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | 1081 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, |
1075 | state); | 1082 | state); |
1076 | if (r) | 1083 | if (r) |
1077 | return r; | 1084 | return r; |
1085 | break; | ||
1078 | } | 1086 | } |
1079 | } | 1087 | } |
1080 | return r; | 1088 | return r; |
@@ -1087,16 +1095,53 @@ int amdgpu_set_powergating_state(struct amdgpu_device *adev, | |||
1087 | int i, r = 0; | 1095 | int i, r = 0; |
1088 | 1096 | ||
1089 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1097 | for (i = 0; i < adev->num_ip_blocks; i++) { |
1098 | if (!adev->ip_block_status[i].valid) | ||
1099 | continue; | ||
1090 | if (adev->ip_blocks[i].type == block_type) { | 1100 | if (adev->ip_blocks[i].type == block_type) { |
1091 | r = adev->ip_blocks[i].funcs->set_powergating_state((void *)adev, | 1101 | r = adev->ip_blocks[i].funcs->set_powergating_state((void *)adev, |
1092 | state); | 1102 | state); |
1093 | if (r) | 1103 | if (r) |
1094 | return r; | 1104 | return r; |
1105 | break; | ||
1095 | } | 1106 | } |
1096 | } | 1107 | } |
1097 | return r; | 1108 | return r; |
1098 | } | 1109 | } |
1099 | 1110 | ||
1111 | int amdgpu_wait_for_idle(struct amdgpu_device *adev, | ||
1112 | enum amd_ip_block_type block_type) | ||
1113 | { | ||
1114 | int i, r; | ||
1115 | |||
1116 | for (i = 0; i < adev->num_ip_blocks; i++) { | ||
1117 | if (!adev->ip_block_status[i].valid) | ||
1118 | continue; | ||
1119 | if (adev->ip_blocks[i].type == block_type) { | ||
1120 | r = adev->ip_blocks[i].funcs->wait_for_idle((void *)adev); | ||
1121 | if (r) | ||
1122 | return r; | ||
1123 | break; | ||
1124 | } | ||
1125 | } | ||
1126 | return 0; | ||
1127 | |||
1128 | } | ||
1129 | |||
1130 | bool amdgpu_is_idle(struct amdgpu_device *adev, | ||
1131 | enum amd_ip_block_type block_type) | ||
1132 | { | ||
1133 | int i; | ||
1134 | |||
1135 | for (i = 0; i < adev->num_ip_blocks; i++) { | ||
1136 | if (!adev->ip_block_status[i].valid) | ||
1137 | continue; | ||
1138 | if (adev->ip_blocks[i].type == block_type) | ||
1139 | return adev->ip_blocks[i].funcs->is_idle((void *)adev); | ||
1140 | } | ||
1141 | return true; | ||
1142 | |||
1143 | } | ||
1144 | |||
1100 | const struct amdgpu_ip_block_version * amdgpu_get_ip_block( | 1145 | const struct amdgpu_ip_block_version * amdgpu_get_ip_block( |
1101 | struct amdgpu_device *adev, | 1146 | struct amdgpu_device *adev, |
1102 | enum amd_ip_block_type type) | 1147 | enum amd_ip_block_type type) |
@@ -1209,6 +1254,9 @@ static int amdgpu_early_init(struct amdgpu_device *adev) | |||
1209 | } | 1254 | } |
1210 | } | 1255 | } |
1211 | 1256 | ||
1257 | adev->cg_flags &= amdgpu_cg_mask; | ||
1258 | adev->pg_flags &= amdgpu_pg_mask; | ||
1259 | |||
1212 | return 0; | 1260 | return 0; |
1213 | } | 1261 | } |
1214 | 1262 | ||
@@ -1440,9 +1488,12 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1440 | adev->uvd_ctx_wreg = &amdgpu_invalid_wreg; | 1488 | adev->uvd_ctx_wreg = &amdgpu_invalid_wreg; |
1441 | adev->didt_rreg = &amdgpu_invalid_rreg; | 1489 | adev->didt_rreg = &amdgpu_invalid_rreg; |
1442 | adev->didt_wreg = &amdgpu_invalid_wreg; | 1490 | adev->didt_wreg = &amdgpu_invalid_wreg; |
1491 | adev->gc_cac_rreg = &amdgpu_invalid_rreg; | ||
1492 | adev->gc_cac_wreg = &amdgpu_invalid_wreg; | ||
1443 | adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg; | 1493 | adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg; |
1444 | adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg; | 1494 | adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg; |
1445 | 1495 | ||
1496 | |||
1446 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", | 1497 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", |
1447 | amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device, | 1498 | amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device, |
1448 | pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); | 1499 | pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); |
@@ -1467,6 +1518,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1467 | spin_lock_init(&adev->pcie_idx_lock); | 1518 | spin_lock_init(&adev->pcie_idx_lock); |
1468 | spin_lock_init(&adev->uvd_ctx_idx_lock); | 1519 | spin_lock_init(&adev->uvd_ctx_idx_lock); |
1469 | spin_lock_init(&adev->didt_idx_lock); | 1520 | spin_lock_init(&adev->didt_idx_lock); |
1521 | spin_lock_init(&adev->gc_cac_idx_lock); | ||
1470 | spin_lock_init(&adev->audio_endpt_idx_lock); | 1522 | spin_lock_init(&adev->audio_endpt_idx_lock); |
1471 | 1523 | ||
1472 | adev->rmmio_base = pci_resource_start(adev->pdev, 5); | 1524 | adev->rmmio_base = pci_resource_start(adev->pdev, 5); |
@@ -1511,17 +1563,20 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1511 | vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain); | 1563 | vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain); |
1512 | 1564 | ||
1513 | /* Read BIOS */ | 1565 | /* Read BIOS */ |
1514 | if (!amdgpu_get_bios(adev)) | 1566 | if (!amdgpu_get_bios(adev)) { |
1515 | return -EINVAL; | 1567 | r = -EINVAL; |
1568 | goto failed; | ||
1569 | } | ||
1516 | /* Must be an ATOMBIOS */ | 1570 | /* Must be an ATOMBIOS */ |
1517 | if (!adev->is_atom_bios) { | 1571 | if (!adev->is_atom_bios) { |
1518 | dev_err(adev->dev, "Expecting atombios for GPU\n"); | 1572 | dev_err(adev->dev, "Expecting atombios for GPU\n"); |
1519 | return -EINVAL; | 1573 | r = -EINVAL; |
1574 | goto failed; | ||
1520 | } | 1575 | } |
1521 | r = amdgpu_atombios_init(adev); | 1576 | r = amdgpu_atombios_init(adev); |
1522 | if (r) { | 1577 | if (r) { |
1523 | dev_err(adev->dev, "amdgpu_atombios_init failed\n"); | 1578 | dev_err(adev->dev, "amdgpu_atombios_init failed\n"); |
1524 | return r; | 1579 | goto failed; |
1525 | } | 1580 | } |
1526 | 1581 | ||
1527 | /* See if the asic supports SR-IOV */ | 1582 | /* See if the asic supports SR-IOV */ |
@@ -1538,7 +1593,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1538 | !(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) { | 1593 | !(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) { |
1539 | if (!adev->bios) { | 1594 | if (!adev->bios) { |
1540 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); | 1595 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); |
1541 | return -EINVAL; | 1596 | r = -EINVAL; |
1597 | goto failed; | ||
1542 | } | 1598 | } |
1543 | DRM_INFO("GPU not posted. posting now...\n"); | 1599 | DRM_INFO("GPU not posted. posting now...\n"); |
1544 | amdgpu_atom_asic_init(adev->mode_info.atom_context); | 1600 | amdgpu_atom_asic_init(adev->mode_info.atom_context); |
@@ -1548,7 +1604,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1548 | r = amdgpu_atombios_get_clock_info(adev); | 1604 | r = amdgpu_atombios_get_clock_info(adev); |
1549 | if (r) { | 1605 | if (r) { |
1550 | dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n"); | 1606 | dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n"); |
1551 | return r; | 1607 | goto failed; |
1552 | } | 1608 | } |
1553 | /* init i2c buses */ | 1609 | /* init i2c buses */ |
1554 | amdgpu_atombios_i2c_init(adev); | 1610 | amdgpu_atombios_i2c_init(adev); |
@@ -1557,7 +1613,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1557 | r = amdgpu_fence_driver_init(adev); | 1613 | r = amdgpu_fence_driver_init(adev); |
1558 | if (r) { | 1614 | if (r) { |
1559 | dev_err(adev->dev, "amdgpu_fence_driver_init failed\n"); | 1615 | dev_err(adev->dev, "amdgpu_fence_driver_init failed\n"); |
1560 | return r; | 1616 | goto failed; |
1561 | } | 1617 | } |
1562 | 1618 | ||
1563 | /* init the mode config */ | 1619 | /* init the mode config */ |
@@ -1567,7 +1623,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1567 | if (r) { | 1623 | if (r) { |
1568 | dev_err(adev->dev, "amdgpu_init failed\n"); | 1624 | dev_err(adev->dev, "amdgpu_init failed\n"); |
1569 | amdgpu_fini(adev); | 1625 | amdgpu_fini(adev); |
1570 | return r; | 1626 | goto failed; |
1571 | } | 1627 | } |
1572 | 1628 | ||
1573 | adev->accel_working = true; | 1629 | adev->accel_working = true; |
@@ -1577,7 +1633,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1577 | r = amdgpu_ib_pool_init(adev); | 1633 | r = amdgpu_ib_pool_init(adev); |
1578 | if (r) { | 1634 | if (r) { |
1579 | dev_err(adev->dev, "IB initialization failed (%d).\n", r); | 1635 | dev_err(adev->dev, "IB initialization failed (%d).\n", r); |
1580 | return r; | 1636 | goto failed; |
1581 | } | 1637 | } |
1582 | 1638 | ||
1583 | r = amdgpu_ib_ring_tests(adev); | 1639 | r = amdgpu_ib_ring_tests(adev); |
@@ -1594,6 +1650,12 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1594 | DRM_ERROR("registering register debugfs failed (%d).\n", r); | 1650 | DRM_ERROR("registering register debugfs failed (%d).\n", r); |
1595 | } | 1651 | } |
1596 | 1652 | ||
1653 | r = amdgpu_debugfs_firmware_init(adev); | ||
1654 | if (r) { | ||
1655 | DRM_ERROR("registering firmware debugfs failed (%d).\n", r); | ||
1656 | return r; | ||
1657 | } | ||
1658 | |||
1597 | if ((amdgpu_testing & 1)) { | 1659 | if ((amdgpu_testing & 1)) { |
1598 | if (adev->accel_working) | 1660 | if (adev->accel_working) |
1599 | amdgpu_test_moves(adev); | 1661 | amdgpu_test_moves(adev); |
@@ -1619,10 +1681,15 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1619 | r = amdgpu_late_init(adev); | 1681 | r = amdgpu_late_init(adev); |
1620 | if (r) { | 1682 | if (r) { |
1621 | dev_err(adev->dev, "amdgpu_late_init failed\n"); | 1683 | dev_err(adev->dev, "amdgpu_late_init failed\n"); |
1622 | return r; | 1684 | goto failed; |
1623 | } | 1685 | } |
1624 | 1686 | ||
1625 | return 0; | 1687 | return 0; |
1688 | |||
1689 | failed: | ||
1690 | if (runtime) | ||
1691 | vga_switcheroo_fini_domain_pm_ops(adev->dev); | ||
1692 | return r; | ||
1626 | } | 1693 | } |
1627 | 1694 | ||
1628 | static void amdgpu_debugfs_remove_files(struct amdgpu_device *adev); | 1695 | static void amdgpu_debugfs_remove_files(struct amdgpu_device *adev); |
@@ -1656,6 +1723,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
1656 | kfree(adev->bios); | 1723 | kfree(adev->bios); |
1657 | adev->bios = NULL; | 1724 | adev->bios = NULL; |
1658 | vga_switcheroo_unregister_client(adev->pdev); | 1725 | vga_switcheroo_unregister_client(adev->pdev); |
1726 | if (adev->flags & AMD_IS_PX) | ||
1727 | vga_switcheroo_fini_domain_pm_ops(adev->dev); | ||
1659 | vga_client_register(adev->pdev, NULL, NULL, NULL); | 1728 | vga_client_register(adev->pdev, NULL, NULL, NULL); |
1660 | if (adev->rio_mem) | 1729 | if (adev->rio_mem) |
1661 | pci_iounmap(adev->pdev, adev->rio_mem); | 1730 | pci_iounmap(adev->pdev, adev->rio_mem); |
@@ -1861,11 +1930,6 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon) | |||
1861 | */ | 1930 | */ |
1862 | int amdgpu_gpu_reset(struct amdgpu_device *adev) | 1931 | int amdgpu_gpu_reset(struct amdgpu_device *adev) |
1863 | { | 1932 | { |
1864 | unsigned ring_sizes[AMDGPU_MAX_RINGS]; | ||
1865 | uint32_t *ring_data[AMDGPU_MAX_RINGS]; | ||
1866 | |||
1867 | bool saved = false; | ||
1868 | |||
1869 | int i, r; | 1933 | int i, r; |
1870 | int resched; | 1934 | int resched; |
1871 | 1935 | ||
@@ -1874,22 +1938,30 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) | |||
1874 | /* block TTM */ | 1938 | /* block TTM */ |
1875 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); | 1939 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); |
1876 | 1940 | ||
1877 | r = amdgpu_suspend(adev); | 1941 | /* block scheduler */ |
1878 | |||
1879 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 1942 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
1880 | struct amdgpu_ring *ring = adev->rings[i]; | 1943 | struct amdgpu_ring *ring = adev->rings[i]; |
1944 | |||
1881 | if (!ring) | 1945 | if (!ring) |
1882 | continue; | 1946 | continue; |
1883 | 1947 | kthread_park(ring->sched.thread); | |
1884 | ring_sizes[i] = amdgpu_ring_backup(ring, &ring_data[i]); | 1948 | amd_sched_hw_job_reset(&ring->sched); |
1885 | if (ring_sizes[i]) { | ||
1886 | saved = true; | ||
1887 | dev_info(adev->dev, "Saved %d dwords of commands " | ||
1888 | "on ring %d.\n", ring_sizes[i], i); | ||
1889 | } | ||
1890 | } | 1949 | } |
1950 | /* after all hw jobs are reset, hw fence is meaningless, so force_completion */ | ||
1951 | amdgpu_fence_driver_force_completion(adev); | ||
1952 | |||
1953 | /* save scratch */ | ||
1954 | amdgpu_atombios_scratch_regs_save(adev); | ||
1955 | r = amdgpu_suspend(adev); | ||
1891 | 1956 | ||
1892 | retry: | 1957 | retry: |
1958 | /* Disable fb access */ | ||
1959 | if (adev->mode_info.num_crtc) { | ||
1960 | struct amdgpu_mode_mc_save save; | ||
1961 | amdgpu_display_stop_mc_access(adev, &save); | ||
1962 | amdgpu_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GMC); | ||
1963 | } | ||
1964 | |||
1893 | r = amdgpu_asic_reset(adev); | 1965 | r = amdgpu_asic_reset(adev); |
1894 | /* post card */ | 1966 | /* post card */ |
1895 | amdgpu_atom_asic_init(adev->mode_info.atom_context); | 1967 | amdgpu_atom_asic_init(adev->mode_info.atom_context); |
@@ -1898,32 +1970,29 @@ retry: | |||
1898 | dev_info(adev->dev, "GPU reset succeeded, trying to resume\n"); | 1970 | dev_info(adev->dev, "GPU reset succeeded, trying to resume\n"); |
1899 | r = amdgpu_resume(adev); | 1971 | r = amdgpu_resume(adev); |
1900 | } | 1972 | } |
1901 | 1973 | /* restore scratch */ | |
1974 | amdgpu_atombios_scratch_regs_restore(adev); | ||
1902 | if (!r) { | 1975 | if (!r) { |
1976 | r = amdgpu_ib_ring_tests(adev); | ||
1977 | if (r) { | ||
1978 | dev_err(adev->dev, "ib ring test failed (%d).\n", r); | ||
1979 | r = amdgpu_suspend(adev); | ||
1980 | goto retry; | ||
1981 | } | ||
1982 | |||
1903 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 1983 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
1904 | struct amdgpu_ring *ring = adev->rings[i]; | 1984 | struct amdgpu_ring *ring = adev->rings[i]; |
1905 | if (!ring) | 1985 | if (!ring) |
1906 | continue; | 1986 | continue; |
1907 | 1987 | amd_sched_job_recovery(&ring->sched); | |
1908 | amdgpu_ring_restore(ring, ring_sizes[i], ring_data[i]); | 1988 | kthread_unpark(ring->sched.thread); |
1909 | ring_sizes[i] = 0; | ||
1910 | ring_data[i] = NULL; | ||
1911 | } | ||
1912 | |||
1913 | r = amdgpu_ib_ring_tests(adev); | ||
1914 | if (r) { | ||
1915 | dev_err(adev->dev, "ib ring test failed (%d).\n", r); | ||
1916 | if (saved) { | ||
1917 | saved = false; | ||
1918 | r = amdgpu_suspend(adev); | ||
1919 | goto retry; | ||
1920 | } | ||
1921 | } | 1989 | } |
1922 | } else { | 1990 | } else { |
1923 | amdgpu_fence_driver_force_completion(adev); | 1991 | dev_err(adev->dev, "asic resume failed (%d).\n", r); |
1924 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 1992 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
1925 | if (adev->rings[i]) | 1993 | if (adev->rings[i]) { |
1926 | kfree(ring_data[i]); | 1994 | kthread_unpark(adev->rings[i]->sched.thread); |
1995 | } | ||
1927 | } | 1996 | } |
1928 | } | 1997 | } |
1929 | 1998 | ||
@@ -1934,13 +2003,11 @@ retry: | |||
1934 | /* bad news, how to tell it to userspace ? */ | 2003 | /* bad news, how to tell it to userspace ? */ |
1935 | dev_info(adev->dev, "GPU reset failed\n"); | 2004 | dev_info(adev->dev, "GPU reset failed\n"); |
1936 | } | 2005 | } |
2006 | amdgpu_irq_gpu_reset_resume_helper(adev); | ||
1937 | 2007 | ||
1938 | return r; | 2008 | return r; |
1939 | } | 2009 | } |
1940 | 2010 | ||
1941 | #define AMDGPU_DEFAULT_PCIE_GEN_MASK 0x30007 /* gen: chipset 1/2, asic 1/2/3 */ | ||
1942 | #define AMDGPU_DEFAULT_PCIE_MLW_MASK 0x2f0000 /* 1/2/4/8/16 lanes */ | ||
1943 | |||
1944 | void amdgpu_get_pcie_info(struct amdgpu_device *adev) | 2011 | void amdgpu_get_pcie_info(struct amdgpu_device *adev) |
1945 | { | 2012 | { |
1946 | u32 mask; | 2013 | u32 mask; |
@@ -2094,20 +2161,43 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | |||
2094 | struct amdgpu_device *adev = f->f_inode->i_private; | 2161 | struct amdgpu_device *adev = f->f_inode->i_private; |
2095 | ssize_t result = 0; | 2162 | ssize_t result = 0; |
2096 | int r; | 2163 | int r; |
2164 | bool use_bank; | ||
2165 | unsigned instance_bank, sh_bank, se_bank; | ||
2097 | 2166 | ||
2098 | if (size & 0x3 || *pos & 0x3) | 2167 | if (size & 0x3 || *pos & 0x3) |
2099 | return -EINVAL; | 2168 | return -EINVAL; |
2100 | 2169 | ||
2170 | if (*pos & (1ULL << 62)) { | ||
2171 | se_bank = (*pos >> 24) & 0x3FF; | ||
2172 | sh_bank = (*pos >> 34) & 0x3FF; | ||
2173 | instance_bank = (*pos >> 44) & 0x3FF; | ||
2174 | use_bank = 1; | ||
2175 | *pos &= 0xFFFFFF; | ||
2176 | } else { | ||
2177 | use_bank = 0; | ||
2178 | } | ||
2179 | |||
2180 | if (use_bank) { | ||
2181 | if (sh_bank >= adev->gfx.config.max_sh_per_se || | ||
2182 | se_bank >= adev->gfx.config.max_shader_engines) | ||
2183 | return -EINVAL; | ||
2184 | mutex_lock(&adev->grbm_idx_mutex); | ||
2185 | amdgpu_gfx_select_se_sh(adev, se_bank, | ||
2186 | sh_bank, instance_bank); | ||
2187 | } | ||
2188 | |||
2101 | while (size) { | 2189 | while (size) { |
2102 | uint32_t value; | 2190 | uint32_t value; |
2103 | 2191 | ||
2104 | if (*pos > adev->rmmio_size) | 2192 | if (*pos > adev->rmmio_size) |
2105 | return result; | 2193 | goto end; |
2106 | 2194 | ||
2107 | value = RREG32(*pos >> 2); | 2195 | value = RREG32(*pos >> 2); |
2108 | r = put_user(value, (uint32_t *)buf); | 2196 | r = put_user(value, (uint32_t *)buf); |
2109 | if (r) | 2197 | if (r) { |
2110 | return r; | 2198 | result = r; |
2199 | goto end; | ||
2200 | } | ||
2111 | 2201 | ||
2112 | result += 4; | 2202 | result += 4; |
2113 | buf += 4; | 2203 | buf += 4; |
@@ -2115,6 +2205,12 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | |||
2115 | size -= 4; | 2205 | size -= 4; |
2116 | } | 2206 | } |
2117 | 2207 | ||
2208 | end: | ||
2209 | if (use_bank) { | ||
2210 | amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); | ||
2211 | mutex_unlock(&adev->grbm_idx_mutex); | ||
2212 | } | ||
2213 | |||
2118 | return result; | 2214 | return result; |
2119 | } | 2215 | } |
2120 | 2216 | ||
@@ -2314,6 +2410,68 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * | |||
2314 | return result; | 2410 | return result; |
2315 | } | 2411 | } |
2316 | 2412 | ||
2413 | static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, | ||
2414 | size_t size, loff_t *pos) | ||
2415 | { | ||
2416 | struct amdgpu_device *adev = f->f_inode->i_private; | ||
2417 | ssize_t result = 0; | ||
2418 | int r; | ||
2419 | uint32_t *config, no_regs = 0; | ||
2420 | |||
2421 | if (size & 0x3 || *pos & 0x3) | ||
2422 | return -EINVAL; | ||
2423 | |||
2424 | config = kmalloc(256 * sizeof(*config), GFP_KERNEL); | ||
2425 | if (!config) | ||
2426 | return -ENOMEM; | ||
2427 | |||
2428 | /* version, increment each time something is added */ | ||
2429 | config[no_regs++] = 0; | ||
2430 | config[no_regs++] = adev->gfx.config.max_shader_engines; | ||
2431 | config[no_regs++] = adev->gfx.config.max_tile_pipes; | ||
2432 | config[no_regs++] = adev->gfx.config.max_cu_per_sh; | ||
2433 | config[no_regs++] = adev->gfx.config.max_sh_per_se; | ||
2434 | config[no_regs++] = adev->gfx.config.max_backends_per_se; | ||
2435 | config[no_regs++] = adev->gfx.config.max_texture_channel_caches; | ||
2436 | config[no_regs++] = adev->gfx.config.max_gprs; | ||
2437 | config[no_regs++] = adev->gfx.config.max_gs_threads; | ||
2438 | config[no_regs++] = adev->gfx.config.max_hw_contexts; | ||
2439 | config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend; | ||
2440 | config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend; | ||
2441 | config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size; | ||
2442 | config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size; | ||
2443 | config[no_regs++] = adev->gfx.config.num_tile_pipes; | ||
2444 | config[no_regs++] = adev->gfx.config.backend_enable_mask; | ||
2445 | config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes; | ||
2446 | config[no_regs++] = adev->gfx.config.mem_row_size_in_kb; | ||
2447 | config[no_regs++] = adev->gfx.config.shader_engine_tile_size; | ||
2448 | config[no_regs++] = adev->gfx.config.num_gpus; | ||
2449 | config[no_regs++] = adev->gfx.config.multi_gpu_tile_size; | ||
2450 | config[no_regs++] = adev->gfx.config.mc_arb_ramcfg; | ||
2451 | config[no_regs++] = adev->gfx.config.gb_addr_config; | ||
2452 | config[no_regs++] = adev->gfx.config.num_rbs; | ||
2453 | |||
2454 | while (size && (*pos < no_regs * 4)) { | ||
2455 | uint32_t value; | ||
2456 | |||
2457 | value = config[*pos >> 2]; | ||
2458 | r = put_user(value, (uint32_t *)buf); | ||
2459 | if (r) { | ||
2460 | kfree(config); | ||
2461 | return r; | ||
2462 | } | ||
2463 | |||
2464 | result += 4; | ||
2465 | buf += 4; | ||
2466 | *pos += 4; | ||
2467 | size -= 4; | ||
2468 | } | ||
2469 | |||
2470 | kfree(config); | ||
2471 | return result; | ||
2472 | } | ||
2473 | |||
2474 | |||
2317 | static const struct file_operations amdgpu_debugfs_regs_fops = { | 2475 | static const struct file_operations amdgpu_debugfs_regs_fops = { |
2318 | .owner = THIS_MODULE, | 2476 | .owner = THIS_MODULE, |
2319 | .read = amdgpu_debugfs_regs_read, | 2477 | .read = amdgpu_debugfs_regs_read, |
@@ -2339,11 +2497,18 @@ static const struct file_operations amdgpu_debugfs_regs_smc_fops = { | |||
2339 | .llseek = default_llseek | 2497 | .llseek = default_llseek |
2340 | }; | 2498 | }; |
2341 | 2499 | ||
2500 | static const struct file_operations amdgpu_debugfs_gca_config_fops = { | ||
2501 | .owner = THIS_MODULE, | ||
2502 | .read = amdgpu_debugfs_gca_config_read, | ||
2503 | .llseek = default_llseek | ||
2504 | }; | ||
2505 | |||
2342 | static const struct file_operations *debugfs_regs[] = { | 2506 | static const struct file_operations *debugfs_regs[] = { |
2343 | &amdgpu_debugfs_regs_fops, | 2507 | &amdgpu_debugfs_regs_fops, |
2344 | &amdgpu_debugfs_regs_didt_fops, | 2508 | &amdgpu_debugfs_regs_didt_fops, |
2345 | &amdgpu_debugfs_regs_pcie_fops, | 2509 | &amdgpu_debugfs_regs_pcie_fops, |
2346 | &amdgpu_debugfs_regs_smc_fops, | 2510 | &amdgpu_debugfs_regs_smc_fops, |
2511 | &amdgpu_debugfs_gca_config_fops, | ||
2347 | }; | 2512 | }; |
2348 | 2513 | ||
2349 | static const char *debugfs_regs_names[] = { | 2514 | static const char *debugfs_regs_names[] = { |
@@ -2351,6 +2516,7 @@ static const char *debugfs_regs_names[] = { | |||
2351 | "amdgpu_regs_didt", | 2516 | "amdgpu_regs_didt", |
2352 | "amdgpu_regs_pcie", | 2517 | "amdgpu_regs_pcie", |
2353 | "amdgpu_regs_smc", | 2518 | "amdgpu_regs_smc", |
2519 | "amdgpu_gca_config", | ||
2354 | }; | 2520 | }; |
2355 | 2521 | ||
2356 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) | 2522 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index a6eecf6f9065..7dbe8d02c5a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |||
@@ -220,19 +220,17 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, | |||
220 | 220 | ||
221 | r = amdgpu_bo_pin_restricted(new_rbo, AMDGPU_GEM_DOMAIN_VRAM, 0, 0, &base); | 221 | r = amdgpu_bo_pin_restricted(new_rbo, AMDGPU_GEM_DOMAIN_VRAM, 0, 0, &base); |
222 | if (unlikely(r != 0)) { | 222 | if (unlikely(r != 0)) { |
223 | amdgpu_bo_unreserve(new_rbo); | ||
224 | r = -EINVAL; | 223 | r = -EINVAL; |
225 | DRM_ERROR("failed to pin new rbo buffer before flip\n"); | 224 | DRM_ERROR("failed to pin new rbo buffer before flip\n"); |
226 | goto cleanup; | 225 | goto unreserve; |
227 | } | 226 | } |
228 | 227 | ||
229 | r = reservation_object_get_fences_rcu(new_rbo->tbo.resv, &work->excl, | 228 | r = reservation_object_get_fences_rcu(new_rbo->tbo.resv, &work->excl, |
230 | &work->shared_count, | 229 | &work->shared_count, |
231 | &work->shared); | 230 | &work->shared); |
232 | if (unlikely(r != 0)) { | 231 | if (unlikely(r != 0)) { |
233 | amdgpu_bo_unreserve(new_rbo); | ||
234 | DRM_ERROR("failed to get fences for buffer\n"); | 232 | DRM_ERROR("failed to get fences for buffer\n"); |
235 | goto cleanup; | 233 | goto unpin; |
236 | } | 234 | } |
237 | 235 | ||
238 | amdgpu_bo_get_tiling_flags(new_rbo, &tiling_flags); | 236 | amdgpu_bo_get_tiling_flags(new_rbo, &tiling_flags); |
@@ -275,9 +273,11 @@ pflip_cleanup: | |||
275 | DRM_ERROR("failed to reserve new rbo in error path\n"); | 273 | DRM_ERROR("failed to reserve new rbo in error path\n"); |
276 | goto cleanup; | 274 | goto cleanup; |
277 | } | 275 | } |
276 | unpin: | ||
278 | if (unlikely(amdgpu_bo_unpin(new_rbo) != 0)) { | 277 | if (unlikely(amdgpu_bo_unpin(new_rbo) != 0)) { |
279 | DRM_ERROR("failed to unpin new rbo in error path\n"); | 278 | DRM_ERROR("failed to unpin new rbo in error path\n"); |
280 | } | 279 | } |
280 | unreserve: | ||
281 | amdgpu_bo_unreserve(new_rbo); | 281 | amdgpu_bo_unreserve(new_rbo); |
282 | 282 | ||
283 | cleanup: | 283 | cleanup: |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index f888c015f76c..015f1f4aae53 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
@@ -82,8 +82,12 @@ int amdgpu_exp_hw_support = 0; | |||
82 | int amdgpu_sched_jobs = 32; | 82 | int amdgpu_sched_jobs = 32; |
83 | int amdgpu_sched_hw_submission = 2; | 83 | int amdgpu_sched_hw_submission = 2; |
84 | int amdgpu_powerplay = -1; | 84 | int amdgpu_powerplay = -1; |
85 | int amdgpu_powercontainment = 1; | ||
85 | unsigned amdgpu_pcie_gen_cap = 0; | 86 | unsigned amdgpu_pcie_gen_cap = 0; |
86 | unsigned amdgpu_pcie_lane_cap = 0; | 87 | unsigned amdgpu_pcie_lane_cap = 0; |
88 | unsigned amdgpu_cg_mask = 0xffffffff; | ||
89 | unsigned amdgpu_pg_mask = 0xffffffff; | ||
90 | char *amdgpu_disable_cu = NULL; | ||
87 | 91 | ||
88 | MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); | 92 | MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); |
89 | module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); | 93 | module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); |
@@ -160,6 +164,9 @@ module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); | |||
160 | #ifdef CONFIG_DRM_AMD_POWERPLAY | 164 | #ifdef CONFIG_DRM_AMD_POWERPLAY |
161 | MODULE_PARM_DESC(powerplay, "Powerplay component (1 = enable, 0 = disable, -1 = auto (default))"); | 165 | MODULE_PARM_DESC(powerplay, "Powerplay component (1 = enable, 0 = disable, -1 = auto (default))"); |
162 | module_param_named(powerplay, amdgpu_powerplay, int, 0444); | 166 | module_param_named(powerplay, amdgpu_powerplay, int, 0444); |
167 | |||
168 | MODULE_PARM_DESC(powercontainment, "Power Containment (1 = enable (default), 0 = disable)"); | ||
169 | module_param_named(powercontainment, amdgpu_powercontainment, int, 0444); | ||
163 | #endif | 170 | #endif |
164 | 171 | ||
165 | MODULE_PARM_DESC(pcie_gen_cap, "PCIE Gen Caps (0: autodetect (default))"); | 172 | MODULE_PARM_DESC(pcie_gen_cap, "PCIE Gen Caps (0: autodetect (default))"); |
@@ -168,6 +175,15 @@ module_param_named(pcie_gen_cap, amdgpu_pcie_gen_cap, uint, 0444); | |||
168 | MODULE_PARM_DESC(pcie_lane_cap, "PCIE Lane Caps (0: autodetect (default))"); | 175 | MODULE_PARM_DESC(pcie_lane_cap, "PCIE Lane Caps (0: autodetect (default))"); |
169 | module_param_named(pcie_lane_cap, amdgpu_pcie_lane_cap, uint, 0444); | 176 | module_param_named(pcie_lane_cap, amdgpu_pcie_lane_cap, uint, 0444); |
170 | 177 | ||
178 | MODULE_PARM_DESC(cg_mask, "Clockgating flags mask (0 = disable clock gating)"); | ||
179 | module_param_named(cg_mask, amdgpu_cg_mask, uint, 0444); | ||
180 | |||
181 | MODULE_PARM_DESC(pg_mask, "Powergating flags mask (0 = disable power gating)"); | ||
182 | module_param_named(pg_mask, amdgpu_pg_mask, uint, 0444); | ||
183 | |||
184 | MODULE_PARM_DESC(disable_cu, "Disable CUs (se.sh.cu,...)"); | ||
185 | module_param_named(disable_cu, amdgpu_disable_cu, charp, 0444); | ||
186 | |||
171 | static const struct pci_device_id pciidlist[] = { | 187 | static const struct pci_device_id pciidlist[] = { |
172 | #ifdef CONFIG_DRM_AMDGPU_CIK | 188 | #ifdef CONFIG_DRM_AMDGPU_CIK |
173 | /* Kaveri */ | 189 | /* Kaveri */ |
@@ -413,7 +429,10 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev) | |||
413 | pci_save_state(pdev); | 429 | pci_save_state(pdev); |
414 | pci_disable_device(pdev); | 430 | pci_disable_device(pdev); |
415 | pci_ignore_hotplug(pdev); | 431 | pci_ignore_hotplug(pdev); |
416 | pci_set_power_state(pdev, PCI_D3cold); | 432 | if (amdgpu_is_atpx_hybrid()) |
433 | pci_set_power_state(pdev, PCI_D3cold); | ||
434 | else if (!amdgpu_has_atpx_dgpu_power_cntl()) | ||
435 | pci_set_power_state(pdev, PCI_D3hot); | ||
417 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; | 436 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; |
418 | 437 | ||
419 | return 0; | 438 | return 0; |
@@ -430,7 +449,9 @@ static int amdgpu_pmops_runtime_resume(struct device *dev) | |||
430 | 449 | ||
431 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 450 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
432 | 451 | ||
433 | pci_set_power_state(pdev, PCI_D0); | 452 | if (amdgpu_is_atpx_hybrid() || |
453 | !amdgpu_has_atpx_dgpu_power_cntl()) | ||
454 | pci_set_power_state(pdev, PCI_D0); | ||
434 | pci_restore_state(pdev); | 455 | pci_restore_state(pdev); |
435 | ret = pci_enable_device(pdev); | 456 | ret = pci_enable_device(pdev); |
436 | if (ret) | 457 | if (ret) |
@@ -515,7 +536,7 @@ static struct drm_driver kms_driver = { | |||
515 | .driver_features = | 536 | .driver_features = |
516 | DRIVER_USE_AGP | | 537 | DRIVER_USE_AGP | |
517 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | | 538 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | |
518 | DRIVER_PRIME | DRIVER_RENDER, | 539 | DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET, |
519 | .dev_priv_size = 0, | 540 | .dev_priv_size = 0, |
520 | .load = amdgpu_driver_load_kms, | 541 | .load = amdgpu_driver_load_kms, |
521 | .open = amdgpu_driver_open_kms, | 542 | .open = amdgpu_driver_open_kms, |
@@ -590,7 +611,6 @@ static int __init amdgpu_init(void) | |||
590 | DRM_INFO("amdgpu kernel modesetting enabled.\n"); | 611 | DRM_INFO("amdgpu kernel modesetting enabled.\n"); |
591 | driver = &kms_driver; | 612 | driver = &kms_driver; |
592 | pdriver = &amdgpu_kms_pci_driver; | 613 | pdriver = &amdgpu_kms_pci_driver; |
593 | driver->driver_features |= DRIVER_MODESET; | ||
594 | driver->num_ioctls = amdgpu_max_kms_ioctl; | 614 | driver->num_ioctls = amdgpu_max_kms_ioctl; |
595 | amdgpu_register_atpx_handler(); | 615 | amdgpu_register_atpx_handler(); |
596 | /* let modprobe override vga console setting */ | 616 | /* let modprobe override vga console setting */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 8fab6486064f..88fbed2389c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |||
@@ -503,7 +503,7 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | |||
503 | if (r) | 503 | if (r) |
504 | goto error_print; | 504 | goto error_print; |
505 | 505 | ||
506 | amdgpu_vm_get_pt_bos(bo_va->vm, &duplicates); | 506 | amdgpu_vm_get_pt_bos(adev, bo_va->vm, &duplicates); |
507 | list_for_each_entry(entry, &list, head) { | 507 | list_for_each_entry(entry, &list, head) { |
508 | domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); | 508 | domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); |
509 | /* if anything is swapped out don't swap it in here, | 509 | /* if anything is swapped out don't swap it in here, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 9f95da4f0536..a074edd95c70 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | |||
@@ -70,3 +70,47 @@ void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg) | |||
70 | } | 70 | } |
71 | } | 71 | } |
72 | } | 72 | } |
73 | |||
74 | /** | ||
75 | * amdgpu_gfx_parse_disable_cu - Parse the disable_cu module parameter | ||
76 | * | ||
77 | * @mask: array in which the per-shader array disable masks will be stored | ||
78 | * @max_se: number of SEs | ||
79 | * @max_sh: number of SHs | ||
80 | * | ||
81 | * The bitmask of CUs to be disabled in the shader array determined by se and | ||
82 | * sh is stored in mask[se * max_sh + sh]. | ||
83 | */ | ||
84 | void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se, unsigned max_sh) | ||
85 | { | ||
86 | unsigned se, sh, cu; | ||
87 | const char *p; | ||
88 | |||
89 | memset(mask, 0, sizeof(*mask) * max_se * max_sh); | ||
90 | |||
91 | if (!amdgpu_disable_cu || !*amdgpu_disable_cu) | ||
92 | return; | ||
93 | |||
94 | p = amdgpu_disable_cu; | ||
95 | for (;;) { | ||
96 | char *next; | ||
97 | int ret = sscanf(p, "%u.%u.%u", &se, &sh, &cu); | ||
98 | if (ret < 3) { | ||
99 | DRM_ERROR("amdgpu: could not parse disable_cu\n"); | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | if (se < max_se && sh < max_sh && cu < 16) { | ||
104 | DRM_INFO("amdgpu: disabling CU %u.%u.%u\n", se, sh, cu); | ||
105 | mask[se * max_sh + sh] |= 1u << cu; | ||
106 | } else { | ||
107 | DRM_ERROR("amdgpu: disable_cu %u.%u.%u is out of range\n", | ||
108 | se, sh, cu); | ||
109 | } | ||
110 | |||
111 | next = strchr(p, ','); | ||
112 | if (!next) | ||
113 | break; | ||
114 | p = next + 1; | ||
115 | } | ||
116 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h index dc06cbda7be6..51321e154c09 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | |||
@@ -27,4 +27,6 @@ | |||
27 | int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg); | 27 | int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg); |
28 | void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg); | 28 | void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg); |
29 | 29 | ||
30 | unsigned amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se, unsigned max_sh); | ||
31 | |||
30 | #endif | 32 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 34e35423b78e..46c3097c5224 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
@@ -160,10 +160,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
160 | patch_offset = amdgpu_ring_init_cond_exec(ring); | 160 | patch_offset = amdgpu_ring_init_cond_exec(ring); |
161 | 161 | ||
162 | if (vm) { | 162 | if (vm) { |
163 | r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr, | 163 | r = amdgpu_vm_flush(ring, job); |
164 | job->gds_base, job->gds_size, | ||
165 | job->gws_base, job->gws_size, | ||
166 | job->oa_base, job->oa_size); | ||
167 | if (r) { | 164 | if (r) { |
168 | amdgpu_ring_undo(ring); | 165 | amdgpu_ring_undo(ring); |
169 | return r; | 166 | return r; |
@@ -203,11 +200,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
203 | } | 200 | } |
204 | 201 | ||
205 | /* wrap the last IB with fence */ | 202 | /* wrap the last IB with fence */ |
206 | if (job && job->uf_bo) { | 203 | if (job && job->uf_addr) { |
207 | uint64_t addr = amdgpu_bo_gpu_offset(job->uf_bo); | 204 | amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence, |
208 | |||
209 | addr += job->uf_offset; | ||
210 | amdgpu_ring_emit_fence(ring, addr, job->uf_sequence, | ||
211 | AMDGPU_FENCE_FLAG_64BIT); | 205 | AMDGPU_FENCE_FLAG_64BIT); |
212 | } | 206 | } |
213 | 207 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 835a3fa8d8df..278708f5a744 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | |||
@@ -383,6 +383,18 @@ int amdgpu_irq_update(struct amdgpu_device *adev, | |||
383 | return r; | 383 | return r; |
384 | } | 384 | } |
385 | 385 | ||
386 | void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev) | ||
387 | { | ||
388 | int i, j; | ||
389 | for (i = 0; i < AMDGPU_MAX_IRQ_SRC_ID; i++) { | ||
390 | struct amdgpu_irq_src *src = adev->irq.sources[i]; | ||
391 | if (!src) | ||
392 | continue; | ||
393 | for (j = 0; j < src->num_types; j++) | ||
394 | amdgpu_irq_update(adev, src, j); | ||
395 | } | ||
396 | } | ||
397 | |||
386 | /** | 398 | /** |
387 | * amdgpu_irq_get - enable interrupt | 399 | * amdgpu_irq_get - enable interrupt |
388 | * | 400 | * |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index e124b59f39c1..7ef09352e534 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | |||
@@ -94,6 +94,7 @@ int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src, | |||
94 | unsigned type); | 94 | unsigned type); |
95 | bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src, | 95 | bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src, |
96 | unsigned type); | 96 | unsigned type); |
97 | void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev); | ||
97 | 98 | ||
98 | int amdgpu_irq_add_domain(struct amdgpu_device *adev); | 99 | int amdgpu_irq_add_domain(struct amdgpu_device *adev); |
99 | void amdgpu_irq_remove_domain(struct amdgpu_device *adev); | 100 | void amdgpu_irq_remove_domain(struct amdgpu_device *adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index f0dafa514fe4..aaee0c8f6731 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | |||
@@ -28,21 +28,15 @@ | |||
28 | #include "amdgpu.h" | 28 | #include "amdgpu.h" |
29 | #include "amdgpu_trace.h" | 29 | #include "amdgpu_trace.h" |
30 | 30 | ||
31 | static void amdgpu_job_free_handler(struct work_struct *ws) | 31 | static void amdgpu_job_timedout(struct amd_sched_job *s_job) |
32 | { | 32 | { |
33 | struct amdgpu_job *job = container_of(ws, struct amdgpu_job, base.work_free_job); | 33 | struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); |
34 | amd_sched_job_put(&job->base); | ||
35 | } | ||
36 | 34 | ||
37 | void amdgpu_job_timeout_func(struct work_struct *work) | ||
38 | { | ||
39 | struct amdgpu_job *job = container_of(work, struct amdgpu_job, base.work_tdr.work); | ||
40 | DRM_ERROR("ring %s timeout, last signaled seq=%u, last emitted seq=%u\n", | 35 | DRM_ERROR("ring %s timeout, last signaled seq=%u, last emitted seq=%u\n", |
41 | job->base.sched->name, | 36 | job->base.sched->name, |
42 | (uint32_t)atomic_read(&job->ring->fence_drv.last_seq), | 37 | atomic_read(&job->ring->fence_drv.last_seq), |
43 | job->ring->fence_drv.sync_seq); | 38 | job->ring->fence_drv.sync_seq); |
44 | 39 | amdgpu_gpu_reset(job->adev); | |
45 | amd_sched_job_put(&job->base); | ||
46 | } | 40 | } |
47 | 41 | ||
48 | int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, | 42 | int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, |
@@ -63,7 +57,6 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, | |||
63 | (*job)->vm = vm; | 57 | (*job)->vm = vm; |
64 | (*job)->ibs = (void *)&(*job)[1]; | 58 | (*job)->ibs = (void *)&(*job)[1]; |
65 | (*job)->num_ibs = num_ibs; | 59 | (*job)->num_ibs = num_ibs; |
66 | INIT_WORK(&(*job)->base.work_free_job, amdgpu_job_free_handler); | ||
67 | 60 | ||
68 | amdgpu_sync_create(&(*job)->sync); | 61 | amdgpu_sync_create(&(*job)->sync); |
69 | 62 | ||
@@ -86,27 +79,33 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, | |||
86 | return r; | 79 | return r; |
87 | } | 80 | } |
88 | 81 | ||
89 | void amdgpu_job_free(struct amdgpu_job *job) | 82 | void amdgpu_job_free_resources(struct amdgpu_job *job) |
90 | { | 83 | { |
91 | unsigned i; | ||
92 | struct fence *f; | 84 | struct fence *f; |
85 | unsigned i; | ||
86 | |||
93 | /* use sched fence if available */ | 87 | /* use sched fence if available */ |
94 | f = (job->base.s_fence)? &job->base.s_fence->base : job->fence; | 88 | f = job->base.s_fence ? &job->base.s_fence->finished : job->fence; |
95 | 89 | ||
96 | for (i = 0; i < job->num_ibs; ++i) | 90 | for (i = 0; i < job->num_ibs; ++i) |
97 | amdgpu_sa_bo_free(job->adev, &job->ibs[i].sa_bo, f); | 91 | amdgpu_ib_free(job->adev, &job->ibs[i], f); |
98 | fence_put(job->fence); | 92 | } |
99 | 93 | ||
100 | amdgpu_bo_unref(&job->uf_bo); | 94 | void amdgpu_job_free_cb(struct amd_sched_job *s_job) |
101 | amdgpu_sync_free(&job->sync); | 95 | { |
96 | struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); | ||
102 | 97 | ||
103 | if (!job->base.use_sched) | 98 | fence_put(job->fence); |
104 | kfree(job); | 99 | amdgpu_sync_free(&job->sync); |
100 | kfree(job); | ||
105 | } | 101 | } |
106 | 102 | ||
107 | void amdgpu_job_free_func(struct kref *refcount) | 103 | void amdgpu_job_free(struct amdgpu_job *job) |
108 | { | 104 | { |
109 | struct amdgpu_job *job = container_of(refcount, struct amdgpu_job, base.refcount); | 105 | amdgpu_job_free_resources(job); |
106 | |||
107 | fence_put(job->fence); | ||
108 | amdgpu_sync_free(&job->sync); | ||
110 | kfree(job); | 109 | kfree(job); |
111 | } | 110 | } |
112 | 111 | ||
@@ -114,22 +113,20 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, | |||
114 | struct amd_sched_entity *entity, void *owner, | 113 | struct amd_sched_entity *entity, void *owner, |
115 | struct fence **f) | 114 | struct fence **f) |
116 | { | 115 | { |
117 | struct fence *fence; | ||
118 | int r; | 116 | int r; |
119 | job->ring = ring; | 117 | job->ring = ring; |
120 | 118 | ||
121 | if (!f) | 119 | if (!f) |
122 | return -EINVAL; | 120 | return -EINVAL; |
123 | 121 | ||
124 | r = amd_sched_job_init(&job->base, &ring->sched, | 122 | r = amd_sched_job_init(&job->base, &ring->sched, entity, owner); |
125 | entity, amdgpu_job_timeout_func, | ||
126 | amdgpu_job_free_func, owner, &fence); | ||
127 | if (r) | 123 | if (r) |
128 | return r; | 124 | return r; |
129 | 125 | ||
130 | job->owner = owner; | 126 | job->owner = owner; |
131 | job->ctx = entity->fence_context; | 127 | job->ctx = entity->fence_context; |
132 | *f = fence_get(fence); | 128 | *f = fence_get(&job->base.s_fence->finished); |
129 | amdgpu_job_free_resources(job); | ||
133 | amd_sched_entity_push_job(&job->base); | 130 | amd_sched_entity_push_job(&job->base); |
134 | 131 | ||
135 | return 0; | 132 | return 0; |
@@ -147,8 +144,8 @@ static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) | |||
147 | int r; | 144 | int r; |
148 | 145 | ||
149 | r = amdgpu_vm_grab_id(vm, ring, &job->sync, | 146 | r = amdgpu_vm_grab_id(vm, ring, &job->sync, |
150 | &job->base.s_fence->base, | 147 | &job->base.s_fence->finished, |
151 | &job->vm_id, &job->vm_pd_addr); | 148 | job); |
152 | if (r) | 149 | if (r) |
153 | DRM_ERROR("Error getting VM ID (%d)\n", r); | 150 | DRM_ERROR("Error getting VM ID (%d)\n", r); |
154 | 151 | ||
@@ -170,11 +167,7 @@ static struct fence *amdgpu_job_run(struct amd_sched_job *sched_job) | |||
170 | } | 167 | } |
171 | job = to_amdgpu_job(sched_job); | 168 | job = to_amdgpu_job(sched_job); |
172 | 169 | ||
173 | r = amdgpu_sync_wait(&job->sync); | 170 | BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL)); |
174 | if (r) { | ||
175 | DRM_ERROR("failed to sync wait (%d)\n", r); | ||
176 | return NULL; | ||
177 | } | ||
178 | 171 | ||
179 | trace_amdgpu_sched_run_job(job); | 172 | trace_amdgpu_sched_run_job(job); |
180 | r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, | 173 | r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, |
@@ -185,14 +178,15 @@ static struct fence *amdgpu_job_run(struct amd_sched_job *sched_job) | |||
185 | } | 178 | } |
186 | 179 | ||
187 | err: | 180 | err: |
181 | /* if gpu reset, hw fence will be replaced here */ | ||
182 | fence_put(job->fence); | ||
188 | job->fence = fence; | 183 | job->fence = fence; |
189 | amdgpu_job_free(job); | ||
190 | return fence; | 184 | return fence; |
191 | } | 185 | } |
192 | 186 | ||
193 | const struct amd_sched_backend_ops amdgpu_sched_ops = { | 187 | const struct amd_sched_backend_ops amdgpu_sched_ops = { |
194 | .dependency = amdgpu_job_dependency, | 188 | .dependency = amdgpu_job_dependency, |
195 | .run_job = amdgpu_job_run, | 189 | .run_job = amdgpu_job_run, |
196 | .begin_job = amd_sched_job_begin, | 190 | .timedout_job = amdgpu_job_timedout, |
197 | .finish_job = amd_sched_job_finish, | 191 | .free_job = amdgpu_job_free_cb |
198 | }; | 192 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index d851ea15059f..b464aaa1da3e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -142,6 +142,65 @@ out: | |||
142 | return r; | 142 | return r; |
143 | } | 143 | } |
144 | 144 | ||
145 | static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, | ||
146 | struct drm_amdgpu_query_fw *query_fw, | ||
147 | struct amdgpu_device *adev) | ||
148 | { | ||
149 | switch (query_fw->fw_type) { | ||
150 | case AMDGPU_INFO_FW_VCE: | ||
151 | fw_info->ver = adev->vce.fw_version; | ||
152 | fw_info->feature = adev->vce.fb_version; | ||
153 | break; | ||
154 | case AMDGPU_INFO_FW_UVD: | ||
155 | fw_info->ver = adev->uvd.fw_version; | ||
156 | fw_info->feature = 0; | ||
157 | break; | ||
158 | case AMDGPU_INFO_FW_GMC: | ||
159 | fw_info->ver = adev->mc.fw_version; | ||
160 | fw_info->feature = 0; | ||
161 | break; | ||
162 | case AMDGPU_INFO_FW_GFX_ME: | ||
163 | fw_info->ver = adev->gfx.me_fw_version; | ||
164 | fw_info->feature = adev->gfx.me_feature_version; | ||
165 | break; | ||
166 | case AMDGPU_INFO_FW_GFX_PFP: | ||
167 | fw_info->ver = adev->gfx.pfp_fw_version; | ||
168 | fw_info->feature = adev->gfx.pfp_feature_version; | ||
169 | break; | ||
170 | case AMDGPU_INFO_FW_GFX_CE: | ||
171 | fw_info->ver = adev->gfx.ce_fw_version; | ||
172 | fw_info->feature = adev->gfx.ce_feature_version; | ||
173 | break; | ||
174 | case AMDGPU_INFO_FW_GFX_RLC: | ||
175 | fw_info->ver = adev->gfx.rlc_fw_version; | ||
176 | fw_info->feature = adev->gfx.rlc_feature_version; | ||
177 | break; | ||
178 | case AMDGPU_INFO_FW_GFX_MEC: | ||
179 | if (query_fw->index == 0) { | ||
180 | fw_info->ver = adev->gfx.mec_fw_version; | ||
181 | fw_info->feature = adev->gfx.mec_feature_version; | ||
182 | } else if (query_fw->index == 1) { | ||
183 | fw_info->ver = adev->gfx.mec2_fw_version; | ||
184 | fw_info->feature = adev->gfx.mec2_feature_version; | ||
185 | } else | ||
186 | return -EINVAL; | ||
187 | break; | ||
188 | case AMDGPU_INFO_FW_SMC: | ||
189 | fw_info->ver = adev->pm.fw_version; | ||
190 | fw_info->feature = 0; | ||
191 | break; | ||
192 | case AMDGPU_INFO_FW_SDMA: | ||
193 | if (query_fw->index >= adev->sdma.num_instances) | ||
194 | return -EINVAL; | ||
195 | fw_info->ver = adev->sdma.instance[query_fw->index].fw_version; | ||
196 | fw_info->feature = adev->sdma.instance[query_fw->index].feature_version; | ||
197 | break; | ||
198 | default: | ||
199 | return -EINVAL; | ||
200 | } | ||
201 | return 0; | ||
202 | } | ||
203 | |||
145 | /* | 204 | /* |
146 | * Userspace get information ioctl | 205 | * Userspace get information ioctl |
147 | */ | 206 | */ |
@@ -288,67 +347,20 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
288 | return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0; | 347 | return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0; |
289 | } | 348 | } |
290 | case AMDGPU_INFO_TIMESTAMP: | 349 | case AMDGPU_INFO_TIMESTAMP: |
291 | ui64 = amdgpu_asic_get_gpu_clock_counter(adev); | 350 | ui64 = amdgpu_gfx_get_gpu_clock_counter(adev); |
292 | return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; | 351 | return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; |
293 | case AMDGPU_INFO_FW_VERSION: { | 352 | case AMDGPU_INFO_FW_VERSION: { |
294 | struct drm_amdgpu_info_firmware fw_info; | 353 | struct drm_amdgpu_info_firmware fw_info; |
354 | int ret; | ||
295 | 355 | ||
296 | /* We only support one instance of each IP block right now. */ | 356 | /* We only support one instance of each IP block right now. */ |
297 | if (info->query_fw.ip_instance != 0) | 357 | if (info->query_fw.ip_instance != 0) |
298 | return -EINVAL; | 358 | return -EINVAL; |
299 | 359 | ||
300 | switch (info->query_fw.fw_type) { | 360 | ret = amdgpu_firmware_info(&fw_info, &info->query_fw, adev); |
301 | case AMDGPU_INFO_FW_VCE: | 361 | if (ret) |
302 | fw_info.ver = adev->vce.fw_version; | 362 | return ret; |
303 | fw_info.feature = adev->vce.fb_version; | 363 | |
304 | break; | ||
305 | case AMDGPU_INFO_FW_UVD: | ||
306 | fw_info.ver = adev->uvd.fw_version; | ||
307 | fw_info.feature = 0; | ||
308 | break; | ||
309 | case AMDGPU_INFO_FW_GMC: | ||
310 | fw_info.ver = adev->mc.fw_version; | ||
311 | fw_info.feature = 0; | ||
312 | break; | ||
313 | case AMDGPU_INFO_FW_GFX_ME: | ||
314 | fw_info.ver = adev->gfx.me_fw_version; | ||
315 | fw_info.feature = adev->gfx.me_feature_version; | ||
316 | break; | ||
317 | case AMDGPU_INFO_FW_GFX_PFP: | ||
318 | fw_info.ver = adev->gfx.pfp_fw_version; | ||
319 | fw_info.feature = adev->gfx.pfp_feature_version; | ||
320 | break; | ||
321 | case AMDGPU_INFO_FW_GFX_CE: | ||
322 | fw_info.ver = adev->gfx.ce_fw_version; | ||
323 | fw_info.feature = adev->gfx.ce_feature_version; | ||
324 | break; | ||
325 | case AMDGPU_INFO_FW_GFX_RLC: | ||
326 | fw_info.ver = adev->gfx.rlc_fw_version; | ||
327 | fw_info.feature = adev->gfx.rlc_feature_version; | ||
328 | break; | ||
329 | case AMDGPU_INFO_FW_GFX_MEC: | ||
330 | if (info->query_fw.index == 0) { | ||
331 | fw_info.ver = adev->gfx.mec_fw_version; | ||
332 | fw_info.feature = adev->gfx.mec_feature_version; | ||
333 | } else if (info->query_fw.index == 1) { | ||
334 | fw_info.ver = adev->gfx.mec2_fw_version; | ||
335 | fw_info.feature = adev->gfx.mec2_feature_version; | ||
336 | } else | ||
337 | return -EINVAL; | ||
338 | break; | ||
339 | case AMDGPU_INFO_FW_SMC: | ||
340 | fw_info.ver = adev->pm.fw_version; | ||
341 | fw_info.feature = 0; | ||
342 | break; | ||
343 | case AMDGPU_INFO_FW_SDMA: | ||
344 | if (info->query_fw.index >= adev->sdma.num_instances) | ||
345 | return -EINVAL; | ||
346 | fw_info.ver = adev->sdma.instance[info->query_fw.index].fw_version; | ||
347 | fw_info.feature = adev->sdma.instance[info->query_fw.index].feature_version; | ||
348 | break; | ||
349 | default: | ||
350 | return -EINVAL; | ||
351 | } | ||
352 | return copy_to_user(out, &fw_info, | 364 | return copy_to_user(out, &fw_info, |
353 | min((size_t)size, sizeof(fw_info))) ? -EFAULT : 0; | 365 | min((size_t)size, sizeof(fw_info))) ? -EFAULT : 0; |
354 | } | 366 | } |
@@ -756,3 +768,130 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { | |||
756 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 768 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
757 | }; | 769 | }; |
758 | const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms); | 770 | const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms); |
771 | |||
772 | /* | ||
773 | * Debugfs info | ||
774 | */ | ||
775 | #if defined(CONFIG_DEBUG_FS) | ||
776 | |||
777 | static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data) | ||
778 | { | ||
779 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
780 | struct drm_device *dev = node->minor->dev; | ||
781 | struct amdgpu_device *adev = dev->dev_private; | ||
782 | struct drm_amdgpu_info_firmware fw_info; | ||
783 | struct drm_amdgpu_query_fw query_fw; | ||
784 | int ret, i; | ||
785 | |||
786 | /* VCE */ | ||
787 | query_fw.fw_type = AMDGPU_INFO_FW_VCE; | ||
788 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
789 | if (ret) | ||
790 | return ret; | ||
791 | seq_printf(m, "VCE feature version: %u, firmware version: 0x%08x\n", | ||
792 | fw_info.feature, fw_info.ver); | ||
793 | |||
794 | /* UVD */ | ||
795 | query_fw.fw_type = AMDGPU_INFO_FW_UVD; | ||
796 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
797 | if (ret) | ||
798 | return ret; | ||
799 | seq_printf(m, "UVD feature version: %u, firmware version: 0x%08x\n", | ||
800 | fw_info.feature, fw_info.ver); | ||
801 | |||
802 | /* GMC */ | ||
803 | query_fw.fw_type = AMDGPU_INFO_FW_GMC; | ||
804 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
805 | if (ret) | ||
806 | return ret; | ||
807 | seq_printf(m, "MC feature version: %u, firmware version: 0x%08x\n", | ||
808 | fw_info.feature, fw_info.ver); | ||
809 | |||
810 | /* ME */ | ||
811 | query_fw.fw_type = AMDGPU_INFO_FW_GFX_ME; | ||
812 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
813 | if (ret) | ||
814 | return ret; | ||
815 | seq_printf(m, "ME feature version: %u, firmware version: 0x%08x\n", | ||
816 | fw_info.feature, fw_info.ver); | ||
817 | |||
818 | /* PFP */ | ||
819 | query_fw.fw_type = AMDGPU_INFO_FW_GFX_PFP; | ||
820 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
821 | if (ret) | ||
822 | return ret; | ||
823 | seq_printf(m, "PFP feature version: %u, firmware version: 0x%08x\n", | ||
824 | fw_info.feature, fw_info.ver); | ||
825 | |||
826 | /* CE */ | ||
827 | query_fw.fw_type = AMDGPU_INFO_FW_GFX_CE; | ||
828 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
829 | if (ret) | ||
830 | return ret; | ||
831 | seq_printf(m, "CE feature version: %u, firmware version: 0x%08x\n", | ||
832 | fw_info.feature, fw_info.ver); | ||
833 | |||
834 | /* RLC */ | ||
835 | query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC; | ||
836 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
837 | if (ret) | ||
838 | return ret; | ||
839 | seq_printf(m, "RLC feature version: %u, firmware version: 0x%08x\n", | ||
840 | fw_info.feature, fw_info.ver); | ||
841 | |||
842 | /* MEC */ | ||
843 | query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC; | ||
844 | query_fw.index = 0; | ||
845 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
846 | if (ret) | ||
847 | return ret; | ||
848 | seq_printf(m, "MEC feature version: %u, firmware version: 0x%08x\n", | ||
849 | fw_info.feature, fw_info.ver); | ||
850 | |||
851 | /* MEC2 */ | ||
852 | if (adev->asic_type == CHIP_KAVERI || | ||
853 | (adev->asic_type > CHIP_TOPAZ && adev->asic_type != CHIP_STONEY)) { | ||
854 | query_fw.index = 1; | ||
855 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
856 | if (ret) | ||
857 | return ret; | ||
858 | seq_printf(m, "MEC2 feature version: %u, firmware version: 0x%08x\n", | ||
859 | fw_info.feature, fw_info.ver); | ||
860 | } | ||
861 | |||
862 | /* SMC */ | ||
863 | query_fw.fw_type = AMDGPU_INFO_FW_SMC; | ||
864 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
865 | if (ret) | ||
866 | return ret; | ||
867 | seq_printf(m, "SMC feature version: %u, firmware version: 0x%08x\n", | ||
868 | fw_info.feature, fw_info.ver); | ||
869 | |||
870 | /* SDMA */ | ||
871 | query_fw.fw_type = AMDGPU_INFO_FW_SDMA; | ||
872 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
873 | query_fw.index = i; | ||
874 | ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); | ||
875 | if (ret) | ||
876 | return ret; | ||
877 | seq_printf(m, "SDMA%d feature version: %u, firmware version: 0x%08x\n", | ||
878 | i, fw_info.feature, fw_info.ver); | ||
879 | } | ||
880 | |||
881 | return 0; | ||
882 | } | ||
883 | |||
884 | static const struct drm_info_list amdgpu_firmware_info_list[] = { | ||
885 | {"amdgpu_firmware_info", amdgpu_debugfs_firmware_info, 0, NULL}, | ||
886 | }; | ||
887 | #endif | ||
888 | |||
889 | int amdgpu_debugfs_firmware_init(struct amdgpu_device *adev) | ||
890 | { | ||
891 | #if defined(CONFIG_DEBUG_FS) | ||
892 | return amdgpu_debugfs_add_files(adev, amdgpu_firmware_info_list, | ||
893 | ARRAY_SIZE(amdgpu_firmware_info_list)); | ||
894 | #else | ||
895 | return 0; | ||
896 | #endif | ||
897 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 7ecea83ce453..6f0873c75a25 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
@@ -589,6 +589,7 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, | |||
589 | struct ttm_mem_reg *new_mem) | 589 | struct ttm_mem_reg *new_mem) |
590 | { | 590 | { |
591 | struct amdgpu_bo *rbo; | 591 | struct amdgpu_bo *rbo; |
592 | struct ttm_mem_reg *old_mem = &bo->mem; | ||
592 | 593 | ||
593 | if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) | 594 | if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) |
594 | return; | 595 | return; |
@@ -602,6 +603,8 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, | |||
602 | 603 | ||
603 | /* move_notify is called before move happens */ | 604 | /* move_notify is called before move happens */ |
604 | amdgpu_update_memory_usage(rbo->adev, &bo->mem, new_mem); | 605 | amdgpu_update_memory_usage(rbo->adev, &bo->mem, new_mem); |
606 | |||
607 | trace_amdgpu_ttm_bo_move(rbo, new_mem->mem_type, old_mem->mem_type); | ||
605 | } | 608 | } |
606 | 609 | ||
607 | int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) | 610 | int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 0e13d80d2a95..ff63b88b0ffa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
@@ -347,6 +347,8 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, | |||
347 | 347 | ||
348 | if (adev->pp_enabled) | 348 | if (adev->pp_enabled) |
349 | size = amdgpu_dpm_print_clock_levels(adev, PP_SCLK, buf); | 349 | size = amdgpu_dpm_print_clock_levels(adev, PP_SCLK, buf); |
350 | else if (adev->pm.funcs->print_clock_levels) | ||
351 | size = adev->pm.funcs->print_clock_levels(adev, PP_SCLK, buf); | ||
350 | 352 | ||
351 | return size; | 353 | return size; |
352 | } | 354 | } |
@@ -363,7 +365,9 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, | |||
363 | uint32_t i, mask = 0; | 365 | uint32_t i, mask = 0; |
364 | char sub_str[2]; | 366 | char sub_str[2]; |
365 | 367 | ||
366 | for (i = 0; i < strlen(buf) - 1; i++) { | 368 | for (i = 0; i < strlen(buf); i++) { |
369 | if (*(buf + i) == '\n') | ||
370 | continue; | ||
367 | sub_str[0] = *(buf + i); | 371 | sub_str[0] = *(buf + i); |
368 | sub_str[1] = '\0'; | 372 | sub_str[1] = '\0'; |
369 | ret = kstrtol(sub_str, 0, &level); | 373 | ret = kstrtol(sub_str, 0, &level); |
@@ -377,6 +381,8 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, | |||
377 | 381 | ||
378 | if (adev->pp_enabled) | 382 | if (adev->pp_enabled) |
379 | amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); | 383 | amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); |
384 | else if (adev->pm.funcs->force_clock_level) | ||
385 | adev->pm.funcs->force_clock_level(adev, PP_SCLK, mask); | ||
380 | fail: | 386 | fail: |
381 | return count; | 387 | return count; |
382 | } | 388 | } |
@@ -391,6 +397,8 @@ static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev, | |||
391 | 397 | ||
392 | if (adev->pp_enabled) | 398 | if (adev->pp_enabled) |
393 | size = amdgpu_dpm_print_clock_levels(adev, PP_MCLK, buf); | 399 | size = amdgpu_dpm_print_clock_levels(adev, PP_MCLK, buf); |
400 | else if (adev->pm.funcs->print_clock_levels) | ||
401 | size = adev->pm.funcs->print_clock_levels(adev, PP_MCLK, buf); | ||
394 | 402 | ||
395 | return size; | 403 | return size; |
396 | } | 404 | } |
@@ -407,7 +415,9 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, | |||
407 | uint32_t i, mask = 0; | 415 | uint32_t i, mask = 0; |
408 | char sub_str[2]; | 416 | char sub_str[2]; |
409 | 417 | ||
410 | for (i = 0; i < strlen(buf) - 1; i++) { | 418 | for (i = 0; i < strlen(buf); i++) { |
419 | if (*(buf + i) == '\n') | ||
420 | continue; | ||
411 | sub_str[0] = *(buf + i); | 421 | sub_str[0] = *(buf + i); |
412 | sub_str[1] = '\0'; | 422 | sub_str[1] = '\0'; |
413 | ret = kstrtol(sub_str, 0, &level); | 423 | ret = kstrtol(sub_str, 0, &level); |
@@ -421,6 +431,8 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, | |||
421 | 431 | ||
422 | if (adev->pp_enabled) | 432 | if (adev->pp_enabled) |
423 | amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); | 433 | amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); |
434 | else if (adev->pm.funcs->force_clock_level) | ||
435 | adev->pm.funcs->force_clock_level(adev, PP_MCLK, mask); | ||
424 | fail: | 436 | fail: |
425 | return count; | 437 | return count; |
426 | } | 438 | } |
@@ -435,6 +447,8 @@ static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev, | |||
435 | 447 | ||
436 | if (adev->pp_enabled) | 448 | if (adev->pp_enabled) |
437 | size = amdgpu_dpm_print_clock_levels(adev, PP_PCIE, buf); | 449 | size = amdgpu_dpm_print_clock_levels(adev, PP_PCIE, buf); |
450 | else if (adev->pm.funcs->print_clock_levels) | ||
451 | size = adev->pm.funcs->print_clock_levels(adev, PP_PCIE, buf); | ||
438 | 452 | ||
439 | return size; | 453 | return size; |
440 | } | 454 | } |
@@ -451,7 +465,9 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, | |||
451 | uint32_t i, mask = 0; | 465 | uint32_t i, mask = 0; |
452 | char sub_str[2]; | 466 | char sub_str[2]; |
453 | 467 | ||
454 | for (i = 0; i < strlen(buf) - 1; i++) { | 468 | for (i = 0; i < strlen(buf); i++) { |
469 | if (*(buf + i) == '\n') | ||
470 | continue; | ||
455 | sub_str[0] = *(buf + i); | 471 | sub_str[0] = *(buf + i); |
456 | sub_str[1] = '\0'; | 472 | sub_str[1] = '\0'; |
457 | ret = kstrtol(sub_str, 0, &level); | 473 | ret = kstrtol(sub_str, 0, &level); |
@@ -465,6 +481,100 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, | |||
465 | 481 | ||
466 | if (adev->pp_enabled) | 482 | if (adev->pp_enabled) |
467 | amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); | 483 | amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); |
484 | else if (adev->pm.funcs->force_clock_level) | ||
485 | adev->pm.funcs->force_clock_level(adev, PP_PCIE, mask); | ||
486 | fail: | ||
487 | return count; | ||
488 | } | ||
489 | |||
490 | static ssize_t amdgpu_get_pp_sclk_od(struct device *dev, | ||
491 | struct device_attribute *attr, | ||
492 | char *buf) | ||
493 | { | ||
494 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
495 | struct amdgpu_device *adev = ddev->dev_private; | ||
496 | uint32_t value = 0; | ||
497 | |||
498 | if (adev->pp_enabled) | ||
499 | value = amdgpu_dpm_get_sclk_od(adev); | ||
500 | else if (adev->pm.funcs->get_sclk_od) | ||
501 | value = adev->pm.funcs->get_sclk_od(adev); | ||
502 | |||
503 | return snprintf(buf, PAGE_SIZE, "%d\n", value); | ||
504 | } | ||
505 | |||
506 | static ssize_t amdgpu_set_pp_sclk_od(struct device *dev, | ||
507 | struct device_attribute *attr, | ||
508 | const char *buf, | ||
509 | size_t count) | ||
510 | { | ||
511 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
512 | struct amdgpu_device *adev = ddev->dev_private; | ||
513 | int ret; | ||
514 | long int value; | ||
515 | |||
516 | ret = kstrtol(buf, 0, &value); | ||
517 | |||
518 | if (ret) { | ||
519 | count = -EINVAL; | ||
520 | goto fail; | ||
521 | } | ||
522 | |||
523 | if (adev->pp_enabled) { | ||
524 | amdgpu_dpm_set_sclk_od(adev, (uint32_t)value); | ||
525 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_READJUST_POWER_STATE, NULL, NULL); | ||
526 | } else if (adev->pm.funcs->set_sclk_od) { | ||
527 | adev->pm.funcs->set_sclk_od(adev, (uint32_t)value); | ||
528 | adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; | ||
529 | amdgpu_pm_compute_clocks(adev); | ||
530 | } | ||
531 | |||
532 | fail: | ||
533 | return count; | ||
534 | } | ||
535 | |||
536 | static ssize_t amdgpu_get_pp_mclk_od(struct device *dev, | ||
537 | struct device_attribute *attr, | ||
538 | char *buf) | ||
539 | { | ||
540 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
541 | struct amdgpu_device *adev = ddev->dev_private; | ||
542 | uint32_t value = 0; | ||
543 | |||
544 | if (adev->pp_enabled) | ||
545 | value = amdgpu_dpm_get_mclk_od(adev); | ||
546 | else if (adev->pm.funcs->get_mclk_od) | ||
547 | value = adev->pm.funcs->get_mclk_od(adev); | ||
548 | |||
549 | return snprintf(buf, PAGE_SIZE, "%d\n", value); | ||
550 | } | ||
551 | |||
552 | static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, | ||
553 | struct device_attribute *attr, | ||
554 | const char *buf, | ||
555 | size_t count) | ||
556 | { | ||
557 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
558 | struct amdgpu_device *adev = ddev->dev_private; | ||
559 | int ret; | ||
560 | long int value; | ||
561 | |||
562 | ret = kstrtol(buf, 0, &value); | ||
563 | |||
564 | if (ret) { | ||
565 | count = -EINVAL; | ||
566 | goto fail; | ||
567 | } | ||
568 | |||
569 | if (adev->pp_enabled) { | ||
570 | amdgpu_dpm_set_mclk_od(adev, (uint32_t)value); | ||
571 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_READJUST_POWER_STATE, NULL, NULL); | ||
572 | } else if (adev->pm.funcs->set_mclk_od) { | ||
573 | adev->pm.funcs->set_mclk_od(adev, (uint32_t)value); | ||
574 | adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; | ||
575 | amdgpu_pm_compute_clocks(adev); | ||
576 | } | ||
577 | |||
468 | fail: | 578 | fail: |
469 | return count; | 579 | return count; |
470 | } | 580 | } |
@@ -490,6 +600,12 @@ static DEVICE_ATTR(pp_dpm_mclk, S_IRUGO | S_IWUSR, | |||
490 | static DEVICE_ATTR(pp_dpm_pcie, S_IRUGO | S_IWUSR, | 600 | static DEVICE_ATTR(pp_dpm_pcie, S_IRUGO | S_IWUSR, |
491 | amdgpu_get_pp_dpm_pcie, | 601 | amdgpu_get_pp_dpm_pcie, |
492 | amdgpu_set_pp_dpm_pcie); | 602 | amdgpu_set_pp_dpm_pcie); |
603 | static DEVICE_ATTR(pp_sclk_od, S_IRUGO | S_IWUSR, | ||
604 | amdgpu_get_pp_sclk_od, | ||
605 | amdgpu_set_pp_sclk_od); | ||
606 | static DEVICE_ATTR(pp_mclk_od, S_IRUGO | S_IWUSR, | ||
607 | amdgpu_get_pp_mclk_od, | ||
608 | amdgpu_set_pp_mclk_od); | ||
493 | 609 | ||
494 | static ssize_t amdgpu_hwmon_show_temp(struct device *dev, | 610 | static ssize_t amdgpu_hwmon_show_temp(struct device *dev, |
495 | struct device_attribute *attr, | 611 | struct device_attribute *attr, |
@@ -1108,22 +1224,34 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) | |||
1108 | DRM_ERROR("failed to create device file pp_table\n"); | 1224 | DRM_ERROR("failed to create device file pp_table\n"); |
1109 | return ret; | 1225 | return ret; |
1110 | } | 1226 | } |
1111 | ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); | ||
1112 | if (ret) { | ||
1113 | DRM_ERROR("failed to create device file pp_dpm_sclk\n"); | ||
1114 | return ret; | ||
1115 | } | ||
1116 | ret = device_create_file(adev->dev, &dev_attr_pp_dpm_mclk); | ||
1117 | if (ret) { | ||
1118 | DRM_ERROR("failed to create device file pp_dpm_mclk\n"); | ||
1119 | return ret; | ||
1120 | } | ||
1121 | ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie); | ||
1122 | if (ret) { | ||
1123 | DRM_ERROR("failed to create device file pp_dpm_pcie\n"); | ||
1124 | return ret; | ||
1125 | } | ||
1126 | } | 1227 | } |
1228 | |||
1229 | ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); | ||
1230 | if (ret) { | ||
1231 | DRM_ERROR("failed to create device file pp_dpm_sclk\n"); | ||
1232 | return ret; | ||
1233 | } | ||
1234 | ret = device_create_file(adev->dev, &dev_attr_pp_dpm_mclk); | ||
1235 | if (ret) { | ||
1236 | DRM_ERROR("failed to create device file pp_dpm_mclk\n"); | ||
1237 | return ret; | ||
1238 | } | ||
1239 | ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie); | ||
1240 | if (ret) { | ||
1241 | DRM_ERROR("failed to create device file pp_dpm_pcie\n"); | ||
1242 | return ret; | ||
1243 | } | ||
1244 | ret = device_create_file(adev->dev, &dev_attr_pp_sclk_od); | ||
1245 | if (ret) { | ||
1246 | DRM_ERROR("failed to create device file pp_sclk_od\n"); | ||
1247 | return ret; | ||
1248 | } | ||
1249 | ret = device_create_file(adev->dev, &dev_attr_pp_mclk_od); | ||
1250 | if (ret) { | ||
1251 | DRM_ERROR("failed to create device file pp_mclk_od\n"); | ||
1252 | return ret; | ||
1253 | } | ||
1254 | |||
1127 | ret = amdgpu_debugfs_pm_init(adev); | 1255 | ret = amdgpu_debugfs_pm_init(adev); |
1128 | if (ret) { | 1256 | if (ret) { |
1129 | DRM_ERROR("Failed to register debugfs file for dpm!\n"); | 1257 | DRM_ERROR("Failed to register debugfs file for dpm!\n"); |
@@ -1146,10 +1274,12 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) | |||
1146 | device_remove_file(adev->dev, &dev_attr_pp_cur_state); | 1274 | device_remove_file(adev->dev, &dev_attr_pp_cur_state); |
1147 | device_remove_file(adev->dev, &dev_attr_pp_force_state); | 1275 | device_remove_file(adev->dev, &dev_attr_pp_force_state); |
1148 | device_remove_file(adev->dev, &dev_attr_pp_table); | 1276 | device_remove_file(adev->dev, &dev_attr_pp_table); |
1149 | device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk); | ||
1150 | device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); | ||
1151 | device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); | ||
1152 | } | 1277 | } |
1278 | device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk); | ||
1279 | device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); | ||
1280 | device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); | ||
1281 | device_remove_file(adev->dev, &dev_attr_pp_sclk_od); | ||
1282 | device_remove_file(adev->dev, &dev_attr_pp_mclk_od); | ||
1153 | } | 1283 | } |
1154 | 1284 | ||
1155 | void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) | 1285 | void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 82256558e0f5..c5738a22b690 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | |||
@@ -52,6 +52,7 @@ 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 | 56 | ||
56 | ret = amd_powerplay_init(pp_init, amd_pp); | 57 | ret = amd_powerplay_init(pp_init, amd_pp); |
57 | kfree(pp_init); | 58 | kfree(pp_init); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 870f9494252c..3b885e3e9b56 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
@@ -28,6 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/debugfs.h> | ||
31 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
32 | #include <drm/amdgpu_drm.h> | 33 | #include <drm/amdgpu_drm.h> |
33 | #include "amdgpu.h" | 34 | #include "amdgpu.h" |
@@ -48,6 +49,7 @@ | |||
48 | */ | 49 | */ |
49 | static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, | 50 | static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, |
50 | struct amdgpu_ring *ring); | 51 | struct amdgpu_ring *ring); |
52 | static void amdgpu_debugfs_ring_fini(struct amdgpu_ring *ring); | ||
51 | 53 | ||
52 | /** | 54 | /** |
53 | * amdgpu_ring_alloc - allocate space on the ring buffer | 55 | * amdgpu_ring_alloc - allocate space on the ring buffer |
@@ -140,78 +142,6 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring) | |||
140 | } | 142 | } |
141 | 143 | ||
142 | /** | 144 | /** |
143 | * amdgpu_ring_backup - Back up the content of a ring | ||
144 | * | ||
145 | * @ring: the ring we want to back up | ||
146 | * | ||
147 | * Saves all unprocessed commits from a ring, returns the number of dwords saved. | ||
148 | */ | ||
149 | unsigned amdgpu_ring_backup(struct amdgpu_ring *ring, | ||
150 | uint32_t **data) | ||
151 | { | ||
152 | unsigned size, ptr, i; | ||
153 | |||
154 | *data = NULL; | ||
155 | |||
156 | if (ring->ring_obj == NULL) | ||
157 | return 0; | ||
158 | |||
159 | /* it doesn't make sense to save anything if all fences are signaled */ | ||
160 | if (!amdgpu_fence_count_emitted(ring)) | ||
161 | return 0; | ||
162 | |||
163 | ptr = le32_to_cpu(*ring->next_rptr_cpu_addr); | ||
164 | |||
165 | size = ring->wptr + (ring->ring_size / 4); | ||
166 | size -= ptr; | ||
167 | size &= ring->ptr_mask; | ||
168 | if (size == 0) | ||
169 | return 0; | ||
170 | |||
171 | /* and then save the content of the ring */ | ||
172 | *data = kmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); | ||
173 | if (!*data) | ||
174 | return 0; | ||
175 | for (i = 0; i < size; ++i) { | ||
176 | (*data)[i] = ring->ring[ptr++]; | ||
177 | ptr &= ring->ptr_mask; | ||
178 | } | ||
179 | |||
180 | return size; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * amdgpu_ring_restore - append saved commands to the ring again | ||
185 | * | ||
186 | * @ring: ring to append commands to | ||
187 | * @size: number of dwords we want to write | ||
188 | * @data: saved commands | ||
189 | * | ||
190 | * Allocates space on the ring and restore the previously saved commands. | ||
191 | */ | ||
192 | int amdgpu_ring_restore(struct amdgpu_ring *ring, | ||
193 | unsigned size, uint32_t *data) | ||
194 | { | ||
195 | int i, r; | ||
196 | |||
197 | if (!size || !data) | ||
198 | return 0; | ||
199 | |||
200 | /* restore the saved ring content */ | ||
201 | r = amdgpu_ring_alloc(ring, size); | ||
202 | if (r) | ||
203 | return r; | ||
204 | |||
205 | for (i = 0; i < size; ++i) { | ||
206 | amdgpu_ring_write(ring, data[i]); | ||
207 | } | ||
208 | |||
209 | amdgpu_ring_commit(ring); | ||
210 | kfree(data); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * amdgpu_ring_init - init driver ring struct. | 145 | * amdgpu_ring_init - init driver ring struct. |
216 | * | 146 | * |
217 | * @adev: amdgpu_device pointer | 147 | * @adev: amdgpu_device pointer |
@@ -260,14 +190,6 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | |||
260 | return r; | 190 | return r; |
261 | } | 191 | } |
262 | 192 | ||
263 | r = amdgpu_wb_get(adev, &ring->next_rptr_offs); | ||
264 | if (r) { | ||
265 | dev_err(adev->dev, "(%d) ring next_rptr wb alloc failed\n", r); | ||
266 | return r; | ||
267 | } | ||
268 | ring->next_rptr_gpu_addr = adev->wb.gpu_addr + ring->next_rptr_offs * 4; | ||
269 | ring->next_rptr_cpu_addr = &adev->wb.wb[ring->next_rptr_offs]; | ||
270 | |||
271 | r = amdgpu_wb_get(adev, &ring->cond_exe_offs); | 193 | r = amdgpu_wb_get(adev, &ring->cond_exe_offs); |
272 | if (r) { | 194 | if (r) { |
273 | dev_err(adev->dev, "(%d) ring cond_exec_polling wb alloc failed\n", r); | 195 | dev_err(adev->dev, "(%d) ring cond_exec_polling wb alloc failed\n", r); |
@@ -310,6 +232,9 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | |||
310 | } | 232 | } |
311 | r = amdgpu_bo_kmap(ring->ring_obj, | 233 | r = amdgpu_bo_kmap(ring->ring_obj, |
312 | (void **)&ring->ring); | 234 | (void **)&ring->ring); |
235 | |||
236 | memset((void *)ring->ring, 0, ring->ring_size); | ||
237 | |||
313 | amdgpu_bo_unreserve(ring->ring_obj); | 238 | amdgpu_bo_unreserve(ring->ring_obj); |
314 | if (r) { | 239 | if (r) { |
315 | dev_err(adev->dev, "(%d) ring map failed\n", r); | 240 | dev_err(adev->dev, "(%d) ring map failed\n", r); |
@@ -347,7 +272,6 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) | |||
347 | amdgpu_wb_free(ring->adev, ring->fence_offs); | 272 | amdgpu_wb_free(ring->adev, ring->fence_offs); |
348 | amdgpu_wb_free(ring->adev, ring->rptr_offs); | 273 | amdgpu_wb_free(ring->adev, ring->rptr_offs); |
349 | amdgpu_wb_free(ring->adev, ring->wptr_offs); | 274 | amdgpu_wb_free(ring->adev, ring->wptr_offs); |
350 | amdgpu_wb_free(ring->adev, ring->next_rptr_offs); | ||
351 | 275 | ||
352 | if (ring_obj) { | 276 | if (ring_obj) { |
353 | r = amdgpu_bo_reserve(ring_obj, false); | 277 | r = amdgpu_bo_reserve(ring_obj, false); |
@@ -358,6 +282,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) | |||
358 | } | 282 | } |
359 | amdgpu_bo_unref(&ring_obj); | 283 | amdgpu_bo_unref(&ring_obj); |
360 | } | 284 | } |
285 | amdgpu_debugfs_ring_fini(ring); | ||
361 | } | 286 | } |
362 | 287 | ||
363 | /* | 288 | /* |
@@ -365,57 +290,62 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) | |||
365 | */ | 290 | */ |
366 | #if defined(CONFIG_DEBUG_FS) | 291 | #if defined(CONFIG_DEBUG_FS) |
367 | 292 | ||
368 | static int amdgpu_debugfs_ring_info(struct seq_file *m, void *data) | 293 | /* Layout of file is 12 bytes consisting of |
294 | * - rptr | ||
295 | * - wptr | ||
296 | * - driver's copy of wptr | ||
297 | * | ||
298 | * followed by n-words of ring data | ||
299 | */ | ||
300 | static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf, | ||
301 | size_t size, loff_t *pos) | ||
369 | { | 302 | { |
370 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 303 | struct amdgpu_ring *ring = (struct amdgpu_ring*)f->f_inode->i_private; |
371 | struct drm_device *dev = node->minor->dev; | 304 | int r, i; |
372 | struct amdgpu_device *adev = dev->dev_private; | 305 | uint32_t value, result, early[3]; |
373 | int roffset = (unsigned long)node->info_ent->data; | 306 | |
374 | struct amdgpu_ring *ring = (void *)(((uint8_t*)adev) + roffset); | 307 | if (*pos & 3 || size & 3) |
375 | uint32_t rptr, wptr, rptr_next; | 308 | return -EINVAL; |
376 | unsigned i; | 309 | |
377 | 310 | result = 0; | |
378 | wptr = amdgpu_ring_get_wptr(ring); | 311 | |
379 | seq_printf(m, "wptr: 0x%08x [%5d]\n", wptr, wptr); | 312 | if (*pos < 12) { |
380 | 313 | early[0] = amdgpu_ring_get_rptr(ring); | |
381 | rptr = amdgpu_ring_get_rptr(ring); | 314 | early[1] = amdgpu_ring_get_wptr(ring); |
382 | rptr_next = le32_to_cpu(*ring->next_rptr_cpu_addr); | 315 | early[2] = ring->wptr; |
383 | 316 | for (i = *pos / 4; i < 3 && size; i++) { | |
384 | seq_printf(m, "rptr: 0x%08x [%5d]\n", rptr, rptr); | 317 | r = put_user(early[i], (uint32_t *)buf); |
385 | 318 | if (r) | |
386 | seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", | 319 | return r; |
387 | ring->wptr, ring->wptr); | 320 | buf += 4; |
388 | 321 | result += 4; | |
389 | if (!ring->ready) | 322 | size -= 4; |
390 | return 0; | 323 | *pos += 4; |
391 | 324 | } | |
392 | /* print 8 dw before current rptr as often it's the last executed | ||
393 | * packet that is the root issue | ||
394 | */ | ||
395 | i = (rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; | ||
396 | while (i != rptr) { | ||
397 | seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); | ||
398 | if (i == rptr) | ||
399 | seq_puts(m, " *"); | ||
400 | if (i == rptr_next) | ||
401 | seq_puts(m, " #"); | ||
402 | seq_puts(m, "\n"); | ||
403 | i = (i + 1) & ring->ptr_mask; | ||
404 | } | 325 | } |
405 | while (i != wptr) { | 326 | |
406 | seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); | 327 | while (size) { |
407 | if (i == rptr) | 328 | if (*pos >= (ring->ring_size + 12)) |
408 | seq_puts(m, " *"); | 329 | return result; |
409 | if (i == rptr_next) | 330 | |
410 | seq_puts(m, " #"); | 331 | value = ring->ring[(*pos - 12)/4]; |
411 | seq_puts(m, "\n"); | 332 | r = put_user(value, (uint32_t*)buf); |
412 | i = (i + 1) & ring->ptr_mask; | 333 | if (r) |
334 | return r; | ||
335 | buf += 4; | ||
336 | result += 4; | ||
337 | size -= 4; | ||
338 | *pos += 4; | ||
413 | } | 339 | } |
414 | return 0; | 340 | |
341 | return result; | ||
415 | } | 342 | } |
416 | 343 | ||
417 | static struct drm_info_list amdgpu_debugfs_ring_info_list[AMDGPU_MAX_RINGS]; | 344 | static const struct file_operations amdgpu_debugfs_ring_fops = { |
418 | static char amdgpu_debugfs_ring_names[AMDGPU_MAX_RINGS][32]; | 345 | .owner = THIS_MODULE, |
346 | .read = amdgpu_debugfs_ring_read, | ||
347 | .llseek = default_llseek | ||
348 | }; | ||
419 | 349 | ||
420 | #endif | 350 | #endif |
421 | 351 | ||
@@ -423,28 +353,27 @@ static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, | |||
423 | struct amdgpu_ring *ring) | 353 | struct amdgpu_ring *ring) |
424 | { | 354 | { |
425 | #if defined(CONFIG_DEBUG_FS) | 355 | #if defined(CONFIG_DEBUG_FS) |
426 | unsigned offset = (uint8_t*)ring - (uint8_t*)adev; | 356 | struct drm_minor *minor = adev->ddev->primary; |
427 | unsigned i; | 357 | struct dentry *ent, *root = minor->debugfs_root; |
428 | struct drm_info_list *info; | 358 | char name[32]; |
429 | char *name; | ||
430 | |||
431 | for (i = 0; i < ARRAY_SIZE(amdgpu_debugfs_ring_info_list); ++i) { | ||
432 | info = &amdgpu_debugfs_ring_info_list[i]; | ||
433 | if (!info->data) | ||
434 | break; | ||
435 | } | ||
436 | 359 | ||
437 | if (i == ARRAY_SIZE(amdgpu_debugfs_ring_info_list)) | ||
438 | return -ENOSPC; | ||
439 | |||
440 | name = &amdgpu_debugfs_ring_names[i][0]; | ||
441 | sprintf(name, "amdgpu_ring_%s", ring->name); | 360 | sprintf(name, "amdgpu_ring_%s", ring->name); |
442 | info->name = name; | ||
443 | info->show = amdgpu_debugfs_ring_info; | ||
444 | info->driver_features = 0; | ||
445 | info->data = (void*)(uintptr_t)offset; | ||
446 | 361 | ||
447 | return amdgpu_debugfs_add_files(adev, info, 1); | 362 | ent = debugfs_create_file(name, |
363 | S_IFREG | S_IRUGO, root, | ||
364 | ring, &amdgpu_debugfs_ring_fops); | ||
365 | if (IS_ERR(ent)) | ||
366 | return PTR_ERR(ent); | ||
367 | |||
368 | i_size_write(ent->d_inode, ring->ring_size + 12); | ||
369 | ring->ent = ent; | ||
448 | #endif | 370 | #endif |
449 | return 0; | 371 | return 0; |
450 | } | 372 | } |
373 | |||
374 | static void amdgpu_debugfs_ring_fini(struct amdgpu_ring *ring) | ||
375 | { | ||
376 | #if defined(CONFIG_DEBUG_FS) | ||
377 | debugfs_remove(ring->ent); | ||
378 | #endif | ||
379 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index 34a92808bbd4..5c8d3022fb87 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | |||
@@ -223,13 +223,16 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, | |||
223 | } | 223 | } |
224 | 224 | ||
225 | /** | 225 | /** |
226 | * amdgpu_sync_is_idle - test if all fences are signaled | 226 | * amdgpu_sync_peek_fence - get the next fence not signaled yet |
227 | * | 227 | * |
228 | * @sync: the sync object | 228 | * @sync: the sync object |
229 | * @ring: optional ring to use for test | ||
229 | * | 230 | * |
230 | * Returns true if all fences in the sync object are signaled. | 231 | * Returns the next fence not signaled yet without removing it from the sync |
232 | * object. | ||
231 | */ | 233 | */ |
232 | bool amdgpu_sync_is_idle(struct amdgpu_sync *sync) | 234 | struct fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync, |
235 | struct amdgpu_ring *ring) | ||
233 | { | 236 | { |
234 | struct amdgpu_sync_entry *e; | 237 | struct amdgpu_sync_entry *e; |
235 | struct hlist_node *tmp; | 238 | struct hlist_node *tmp; |
@@ -237,6 +240,19 @@ bool amdgpu_sync_is_idle(struct amdgpu_sync *sync) | |||
237 | 240 | ||
238 | hash_for_each_safe(sync->fences, i, tmp, e, node) { | 241 | hash_for_each_safe(sync->fences, i, tmp, e, node) { |
239 | struct fence *f = e->fence; | 242 | struct fence *f = e->fence; |
243 | struct amd_sched_fence *s_fence = to_amd_sched_fence(f); | ||
244 | |||
245 | if (ring && s_fence) { | ||
246 | /* For fences from the same ring it is sufficient | ||
247 | * when they are scheduled. | ||
248 | */ | ||
249 | if (s_fence->sched == &ring->sched) { | ||
250 | if (fence_is_signaled(&s_fence->scheduled)) | ||
251 | continue; | ||
252 | |||
253 | return &s_fence->scheduled; | ||
254 | } | ||
255 | } | ||
240 | 256 | ||
241 | if (fence_is_signaled(f)) { | 257 | if (fence_is_signaled(f)) { |
242 | hash_del(&e->node); | 258 | hash_del(&e->node); |
@@ -245,58 +261,19 @@ bool amdgpu_sync_is_idle(struct amdgpu_sync *sync) | |||
245 | continue; | 261 | continue; |
246 | } | 262 | } |
247 | 263 | ||
248 | return false; | 264 | return f; |
249 | } | 265 | } |
250 | 266 | ||
251 | return true; | 267 | return NULL; |
252 | } | 268 | } |
253 | 269 | ||
254 | /** | 270 | /** |
255 | * amdgpu_sync_cycle_fences - move fences from one sync object into another | 271 | * amdgpu_sync_get_fence - get the next fence from the sync object |
256 | * | 272 | * |
257 | * @dst: the destination sync object | 273 | * @sync: sync object to use |
258 | * @src: the source sync object | ||
259 | * @fence: fence to add to source | ||
260 | * | 274 | * |
261 | * Remove all fences from source and put them into destination and add | 275 | * Get and removes the next fence from the sync object not signaled yet. |
262 | * fence as new one into source. | ||
263 | */ | 276 | */ |
264 | int amdgpu_sync_cycle_fences(struct amdgpu_sync *dst, struct amdgpu_sync *src, | ||
265 | struct fence *fence) | ||
266 | { | ||
267 | struct amdgpu_sync_entry *e, *newone; | ||
268 | struct hlist_node *tmp; | ||
269 | int i; | ||
270 | |||
271 | /* Allocate the new entry before moving the old ones */ | ||
272 | newone = kmem_cache_alloc(amdgpu_sync_slab, GFP_KERNEL); | ||
273 | if (!newone) | ||
274 | return -ENOMEM; | ||
275 | |||
276 | hash_for_each_safe(src->fences, i, tmp, e, node) { | ||
277 | struct fence *f = e->fence; | ||
278 | |||
279 | hash_del(&e->node); | ||
280 | if (fence_is_signaled(f)) { | ||
281 | fence_put(f); | ||
282 | kmem_cache_free(amdgpu_sync_slab, e); | ||
283 | continue; | ||
284 | } | ||
285 | |||
286 | if (amdgpu_sync_add_later(dst, f)) { | ||
287 | kmem_cache_free(amdgpu_sync_slab, e); | ||
288 | continue; | ||
289 | } | ||
290 | |||
291 | hash_add(dst->fences, &e->node, f->context); | ||
292 | } | ||
293 | |||
294 | hash_add(src->fences, &newone->node, fence->context); | ||
295 | newone->fence = fence_get(fence); | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync) | 277 | struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync) |
301 | { | 278 | { |
302 | struct amdgpu_sync_entry *e; | 279 | struct amdgpu_sync_entry *e; |
@@ -319,25 +296,6 @@ struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync) | |||
319 | return NULL; | 296 | return NULL; |
320 | } | 297 | } |
321 | 298 | ||
322 | int amdgpu_sync_wait(struct amdgpu_sync *sync) | ||
323 | { | ||
324 | struct amdgpu_sync_entry *e; | ||
325 | struct hlist_node *tmp; | ||
326 | int i, r; | ||
327 | |||
328 | hash_for_each_safe(sync->fences, i, tmp, e, node) { | ||
329 | r = fence_wait(e->fence, false); | ||
330 | if (r) | ||
331 | return r; | ||
332 | |||
333 | hash_del(&e->node); | ||
334 | fence_put(e->fence); | ||
335 | kmem_cache_free(amdgpu_sync_slab, e); | ||
336 | } | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | /** | 299 | /** |
342 | * amdgpu_sync_free - free the sync object | 300 | * amdgpu_sync_free - free the sync object |
343 | * | 301 | * |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index 26a5f4acf584..499803f3ce3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | |||
@@ -11,19 +11,68 @@ | |||
11 | #define TRACE_SYSTEM amdgpu | 11 | #define TRACE_SYSTEM amdgpu |
12 | #define TRACE_INCLUDE_FILE amdgpu_trace | 12 | #define TRACE_INCLUDE_FILE amdgpu_trace |
13 | 13 | ||
14 | TRACE_EVENT(amdgpu_mm_rreg, | ||
15 | TP_PROTO(unsigned did, uint32_t reg, uint32_t value), | ||
16 | TP_ARGS(did, reg, value), | ||
17 | TP_STRUCT__entry( | ||
18 | __field(unsigned, did) | ||
19 | __field(uint32_t, reg) | ||
20 | __field(uint32_t, value) | ||
21 | ), | ||
22 | TP_fast_assign( | ||
23 | __entry->did = did; | ||
24 | __entry->reg = reg; | ||
25 | __entry->value = value; | ||
26 | ), | ||
27 | TP_printk("0x%04lx, 0x%04lx, 0x%08lx", | ||
28 | (unsigned long)__entry->did, | ||
29 | (unsigned long)__entry->reg, | ||
30 | (unsigned long)__entry->value) | ||
31 | ); | ||
32 | |||
33 | TRACE_EVENT(amdgpu_mm_wreg, | ||
34 | TP_PROTO(unsigned did, uint32_t reg, uint32_t value), | ||
35 | TP_ARGS(did, reg, value), | ||
36 | TP_STRUCT__entry( | ||
37 | __field(unsigned, did) | ||
38 | __field(uint32_t, reg) | ||
39 | __field(uint32_t, value) | ||
40 | ), | ||
41 | TP_fast_assign( | ||
42 | __entry->did = did; | ||
43 | __entry->reg = reg; | ||
44 | __entry->value = value; | ||
45 | ), | ||
46 | TP_printk("0x%04lx, 0x%04lx, 0x%08lx", | ||
47 | (unsigned long)__entry->did, | ||
48 | (unsigned long)__entry->reg, | ||
49 | (unsigned long)__entry->value) | ||
50 | ); | ||
51 | |||
14 | TRACE_EVENT(amdgpu_bo_create, | 52 | TRACE_EVENT(amdgpu_bo_create, |
15 | TP_PROTO(struct amdgpu_bo *bo), | 53 | TP_PROTO(struct amdgpu_bo *bo), |
16 | TP_ARGS(bo), | 54 | TP_ARGS(bo), |
17 | TP_STRUCT__entry( | 55 | TP_STRUCT__entry( |
18 | __field(struct amdgpu_bo *, bo) | 56 | __field(struct amdgpu_bo *, bo) |
19 | __field(u32, pages) | 57 | __field(u32, pages) |
58 | __field(u32, type) | ||
59 | __field(u32, prefer) | ||
60 | __field(u32, allow) | ||
61 | __field(u32, visible) | ||
20 | ), | 62 | ), |
21 | 63 | ||
22 | TP_fast_assign( | 64 | TP_fast_assign( |
23 | __entry->bo = bo; | 65 | __entry->bo = bo; |
24 | __entry->pages = bo->tbo.num_pages; | 66 | __entry->pages = bo->tbo.num_pages; |
67 | __entry->type = bo->tbo.mem.mem_type; | ||
68 | __entry->prefer = bo->prefered_domains; | ||
69 | __entry->allow = bo->allowed_domains; | ||
70 | __entry->visible = bo->flags; | ||
25 | ), | 71 | ), |
26 | TP_printk("bo=%p, pages=%u", __entry->bo, __entry->pages) | 72 | |
73 | TP_printk("bo=%p,pages=%u,type=%d,prefered=%d,allowed=%d,visible=%d", | ||
74 | __entry->bo, __entry->pages, __entry->type, | ||
75 | __entry->prefer, __entry->allow, __entry->visible) | ||
27 | ); | 76 | ); |
28 | 77 | ||
29 | TRACE_EVENT(amdgpu_cs, | 78 | TRACE_EVENT(amdgpu_cs, |
@@ -64,7 +113,7 @@ TRACE_EVENT(amdgpu_cs_ioctl, | |||
64 | __entry->adev = job->adev; | 113 | __entry->adev = job->adev; |
65 | __entry->sched_job = &job->base; | 114 | __entry->sched_job = &job->base; |
66 | __entry->ib = job->ibs; | 115 | __entry->ib = job->ibs; |
67 | __entry->fence = &job->base.s_fence->base; | 116 | __entry->fence = &job->base.s_fence->finished; |
68 | __entry->ring_name = job->ring->name; | 117 | __entry->ring_name = job->ring->name; |
69 | __entry->num_ibs = job->num_ibs; | 118 | __entry->num_ibs = job->num_ibs; |
70 | ), | 119 | ), |
@@ -89,7 +138,7 @@ TRACE_EVENT(amdgpu_sched_run_job, | |||
89 | __entry->adev = job->adev; | 138 | __entry->adev = job->adev; |
90 | __entry->sched_job = &job->base; | 139 | __entry->sched_job = &job->base; |
91 | __entry->ib = job->ibs; | 140 | __entry->ib = job->ibs; |
92 | __entry->fence = &job->base.s_fence->base; | 141 | __entry->fence = &job->base.s_fence->finished; |
93 | __entry->ring_name = job->ring->name; | 142 | __entry->ring_name = job->ring->name; |
94 | __entry->num_ibs = job->num_ibs; | 143 | __entry->num_ibs = job->num_ibs; |
95 | ), | 144 | ), |
@@ -244,13 +293,55 @@ TRACE_EVENT(amdgpu_bo_list_set, | |||
244 | TP_STRUCT__entry( | 293 | TP_STRUCT__entry( |
245 | __field(struct amdgpu_bo_list *, list) | 294 | __field(struct amdgpu_bo_list *, list) |
246 | __field(struct amdgpu_bo *, bo) | 295 | __field(struct amdgpu_bo *, bo) |
296 | __field(u64, bo_size) | ||
247 | ), | 297 | ), |
248 | 298 | ||
249 | TP_fast_assign( | 299 | TP_fast_assign( |
250 | __entry->list = list; | 300 | __entry->list = list; |
251 | __entry->bo = bo; | 301 | __entry->bo = bo; |
302 | __entry->bo_size = amdgpu_bo_size(bo); | ||
252 | ), | 303 | ), |
253 | TP_printk("list=%p, bo=%p", __entry->list, __entry->bo) | 304 | TP_printk("list=%p, bo=%p, bo_size = %Ld", |
305 | __entry->list, | ||
306 | __entry->bo, | ||
307 | __entry->bo_size) | ||
308 | ); | ||
309 | |||
310 | TRACE_EVENT(amdgpu_cs_bo_status, | ||
311 | TP_PROTO(uint64_t total_bo, uint64_t total_size), | ||
312 | TP_ARGS(total_bo, total_size), | ||
313 | TP_STRUCT__entry( | ||
314 | __field(u64, total_bo) | ||
315 | __field(u64, total_size) | ||
316 | ), | ||
317 | |||
318 | TP_fast_assign( | ||
319 | __entry->total_bo = total_bo; | ||
320 | __entry->total_size = total_size; | ||
321 | ), | ||
322 | TP_printk("total bo size = %Ld, total bo count = %Ld", | ||
323 | __entry->total_bo, __entry->total_size) | ||
324 | ); | ||
325 | |||
326 | TRACE_EVENT(amdgpu_ttm_bo_move, | ||
327 | TP_PROTO(struct amdgpu_bo* bo, uint32_t new_placement, uint32_t old_placement), | ||
328 | TP_ARGS(bo, new_placement, old_placement), | ||
329 | TP_STRUCT__entry( | ||
330 | __field(struct amdgpu_bo *, bo) | ||
331 | __field(u64, bo_size) | ||
332 | __field(u32, new_placement) | ||
333 | __field(u32, old_placement) | ||
334 | ), | ||
335 | |||
336 | TP_fast_assign( | ||
337 | __entry->bo = bo; | ||
338 | __entry->bo_size = amdgpu_bo_size(bo); | ||
339 | __entry->new_placement = new_placement; | ||
340 | __entry->old_placement = old_placement; | ||
341 | ), | ||
342 | TP_printk("bo=%p from:%d to %d with size = %Ld", | ||
343 | __entry->bo, __entry->old_placement, | ||
344 | __entry->new_placement, __entry->bo_size) | ||
254 | ); | 345 | ); |
255 | 346 | ||
256 | #endif | 347 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 3b9053af4762..b7742e62972a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -286,9 +286,10 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, | |||
286 | r = amdgpu_copy_buffer(ring, old_start, new_start, | 286 | r = amdgpu_copy_buffer(ring, old_start, new_start, |
287 | new_mem->num_pages * PAGE_SIZE, /* bytes */ | 287 | new_mem->num_pages * PAGE_SIZE, /* bytes */ |
288 | bo->resv, &fence); | 288 | bo->resv, &fence); |
289 | /* FIXME: handle copy error */ | 289 | if (r) |
290 | r = ttm_bo_move_accel_cleanup(bo, fence, | 290 | return r; |
291 | evict, no_wait_gpu, new_mem); | 291 | |
292 | r = ttm_bo_pipeline_move(bo, fence, evict, new_mem); | ||
292 | fence_put(fence); | 293 | fence_put(fence); |
293 | return r; | 294 | return r; |
294 | } | 295 | } |
@@ -396,6 +397,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, | |||
396 | return -EINVAL; | 397 | return -EINVAL; |
397 | 398 | ||
398 | adev = amdgpu_get_adev(bo->bdev); | 399 | adev = amdgpu_get_adev(bo->bdev); |
400 | |||
401 | /* remember the eviction */ | ||
402 | if (evict) | ||
403 | atomic64_inc(&adev->num_evictions); | ||
404 | |||
399 | if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { | 405 | if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { |
400 | amdgpu_move_null(bo, new_mem); | 406 | amdgpu_move_null(bo, new_mem); |
401 | return 0; | 407 | return 0; |
@@ -429,7 +435,8 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, | |||
429 | 435 | ||
430 | if (r) { | 436 | if (r) { |
431 | memcpy: | 437 | memcpy: |
432 | r = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); | 438 | r = ttm_bo_move_memcpy(bo, evict, interruptible, |
439 | no_wait_gpu, new_mem); | ||
433 | if (r) { | 440 | if (r) { |
434 | return r; | 441 | return r; |
435 | } | 442 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 9f36ed30ba11..2f8496d48c94 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * Alex Deucher | 25 | * Alex Deucher |
26 | * Jerome Glisse | 26 | * Jerome Glisse |
27 | */ | 27 | */ |
28 | #include <linux/fence-array.h> | ||
28 | #include <drm/drmP.h> | 29 | #include <drm/drmP.h> |
29 | #include <drm/amdgpu_drm.h> | 30 | #include <drm/amdgpu_drm.h> |
30 | #include "amdgpu.h" | 31 | #include "amdgpu.h" |
@@ -114,16 +115,26 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, | |||
114 | /** | 115 | /** |
115 | * amdgpu_vm_get_bos - add the vm BOs to a duplicates list | 116 | * amdgpu_vm_get_bos - add the vm BOs to a duplicates list |
116 | * | 117 | * |
118 | * @adev: amdgpu device pointer | ||
117 | * @vm: vm providing the BOs | 119 | * @vm: vm providing the BOs |
118 | * @duplicates: head of duplicates list | 120 | * @duplicates: head of duplicates list |
119 | * | 121 | * |
120 | * Add the page directory to the BO duplicates list | 122 | * Add the page directory to the BO duplicates list |
121 | * for command submission. | 123 | * for command submission. |
122 | */ | 124 | */ |
123 | void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates) | 125 | void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
126 | struct list_head *duplicates) | ||
124 | { | 127 | { |
128 | uint64_t num_evictions; | ||
125 | unsigned i; | 129 | unsigned i; |
126 | 130 | ||
131 | /* We only need to validate the page tables | ||
132 | * if they aren't already valid. | ||
133 | */ | ||
134 | num_evictions = atomic64_read(&adev->num_evictions); | ||
135 | if (num_evictions == vm->last_eviction_counter) | ||
136 | return; | ||
137 | |||
127 | /* add the vm page table to the list */ | 138 | /* add the vm page table to the list */ |
128 | for (i = 0; i <= vm->max_pde_used; ++i) { | 139 | for (i = 0; i <= vm->max_pde_used; ++i) { |
129 | struct amdgpu_bo_list_entry *entry = &vm->page_tables[i].entry; | 140 | struct amdgpu_bo_list_entry *entry = &vm->page_tables[i].entry; |
@@ -162,6 +173,13 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, | |||
162 | spin_unlock(&glob->lru_lock); | 173 | spin_unlock(&glob->lru_lock); |
163 | } | 174 | } |
164 | 175 | ||
176 | static bool amdgpu_vm_is_gpu_reset(struct amdgpu_device *adev, | ||
177 | struct amdgpu_vm_id *id) | ||
178 | { | ||
179 | return id->current_gpu_reset_count != | ||
180 | atomic_read(&adev->gpu_reset_counter) ? true : false; | ||
181 | } | ||
182 | |||
165 | /** | 183 | /** |
166 | * amdgpu_vm_grab_id - allocate the next free VMID | 184 | * amdgpu_vm_grab_id - allocate the next free VMID |
167 | * | 185 | * |
@@ -174,20 +192,69 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, | |||
174 | */ | 192 | */ |
175 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | 193 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, |
176 | struct amdgpu_sync *sync, struct fence *fence, | 194 | struct amdgpu_sync *sync, struct fence *fence, |
177 | unsigned *vm_id, uint64_t *vm_pd_addr) | 195 | struct amdgpu_job *job) |
178 | { | 196 | { |
179 | uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); | ||
180 | struct amdgpu_device *adev = ring->adev; | 197 | struct amdgpu_device *adev = ring->adev; |
181 | struct fence *updates = sync->last_vm_update; | 198 | struct fence *updates = sync->last_vm_update; |
182 | struct amdgpu_vm_id *id; | 199 | struct amdgpu_vm_id *id, *idle; |
183 | unsigned i = ring->idx; | 200 | struct fence **fences; |
184 | int r; | 201 | unsigned i; |
202 | int r = 0; | ||
203 | |||
204 | fences = kmalloc_array(sizeof(void *), adev->vm_manager.num_ids, | ||
205 | GFP_KERNEL); | ||
206 | if (!fences) | ||
207 | return -ENOMEM; | ||
185 | 208 | ||
186 | mutex_lock(&adev->vm_manager.lock); | 209 | mutex_lock(&adev->vm_manager.lock); |
187 | 210 | ||
211 | /* Check if we have an idle VMID */ | ||
212 | i = 0; | ||
213 | list_for_each_entry(idle, &adev->vm_manager.ids_lru, list) { | ||
214 | fences[i] = amdgpu_sync_peek_fence(&idle->active, ring); | ||
215 | if (!fences[i]) | ||
216 | break; | ||
217 | ++i; | ||
218 | } | ||
219 | |||
220 | /* If we can't find a idle VMID to use, wait till one becomes available */ | ||
221 | if (&idle->list == &adev->vm_manager.ids_lru) { | ||
222 | u64 fence_context = adev->vm_manager.fence_context + ring->idx; | ||
223 | unsigned seqno = ++adev->vm_manager.seqno[ring->idx]; | ||
224 | struct fence_array *array; | ||
225 | unsigned j; | ||
226 | |||
227 | for (j = 0; j < i; ++j) | ||
228 | fence_get(fences[j]); | ||
229 | |||
230 | array = fence_array_create(i, fences, fence_context, | ||
231 | seqno, true); | ||
232 | if (!array) { | ||
233 | for (j = 0; j < i; ++j) | ||
234 | fence_put(fences[j]); | ||
235 | kfree(fences); | ||
236 | r = -ENOMEM; | ||
237 | goto error; | ||
238 | } | ||
239 | |||
240 | |||
241 | r = amdgpu_sync_fence(ring->adev, sync, &array->base); | ||
242 | fence_put(&array->base); | ||
243 | if (r) | ||
244 | goto error; | ||
245 | |||
246 | mutex_unlock(&adev->vm_manager.lock); | ||
247 | return 0; | ||
248 | |||
249 | } | ||
250 | kfree(fences); | ||
251 | |||
252 | job->vm_needs_flush = true; | ||
188 | /* Check if we can use a VMID already assigned to this VM */ | 253 | /* Check if we can use a VMID already assigned to this VM */ |
254 | i = ring->idx; | ||
189 | do { | 255 | do { |
190 | struct fence *flushed; | 256 | struct fence *flushed; |
257 | bool same_ring = ring->idx == i; | ||
191 | 258 | ||
192 | id = vm->ids[i++]; | 259 | id = vm->ids[i++]; |
193 | if (i == AMDGPU_MAX_RINGS) | 260 | if (i == AMDGPU_MAX_RINGS) |
@@ -196,67 +263,49 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
196 | /* Check all the prerequisites to using this VMID */ | 263 | /* Check all the prerequisites to using this VMID */ |
197 | if (!id) | 264 | if (!id) |
198 | continue; | 265 | continue; |
266 | if (amdgpu_vm_is_gpu_reset(adev, id)) | ||
267 | continue; | ||
199 | 268 | ||
200 | if (atomic64_read(&id->owner) != vm->client_id) | 269 | if (atomic64_read(&id->owner) != vm->client_id) |
201 | continue; | 270 | continue; |
202 | 271 | ||
203 | if (pd_addr != id->pd_gpu_addr) | 272 | if (job->vm_pd_addr != id->pd_gpu_addr) |
204 | continue; | 273 | continue; |
205 | 274 | ||
206 | if (id->last_user != ring && | 275 | if (!same_ring && |
207 | (!id->last_flush || !fence_is_signaled(id->last_flush))) | 276 | (!id->last_flush || !fence_is_signaled(id->last_flush))) |
208 | continue; | 277 | continue; |
209 | 278 | ||
210 | flushed = id->flushed_updates; | 279 | flushed = id->flushed_updates; |
211 | if (updates && (!flushed || fence_is_later(updates, flushed))) | 280 | if (updates && |
281 | (!flushed || fence_is_later(updates, flushed))) | ||
212 | continue; | 282 | continue; |
213 | 283 | ||
214 | /* Good we can use this VMID */ | 284 | /* Good we can use this VMID. Remember this submission as |
215 | if (id->last_user == ring) { | 285 | * user of the VMID. |
216 | r = amdgpu_sync_fence(ring->adev, sync, | 286 | */ |
217 | id->first); | ||
218 | if (r) | ||
219 | goto error; | ||
220 | } | ||
221 | |||
222 | /* And remember this submission as user of the VMID */ | ||
223 | r = amdgpu_sync_fence(ring->adev, &id->active, fence); | 287 | r = amdgpu_sync_fence(ring->adev, &id->active, fence); |
224 | if (r) | 288 | if (r) |
225 | goto error; | 289 | goto error; |
226 | 290 | ||
291 | id->current_gpu_reset_count = atomic_read(&adev->gpu_reset_counter); | ||
227 | list_move_tail(&id->list, &adev->vm_manager.ids_lru); | 292 | list_move_tail(&id->list, &adev->vm_manager.ids_lru); |
228 | vm->ids[ring->idx] = id; | 293 | vm->ids[ring->idx] = id; |
229 | 294 | ||
230 | *vm_id = id - adev->vm_manager.ids; | 295 | job->vm_id = id - adev->vm_manager.ids; |
231 | *vm_pd_addr = AMDGPU_VM_NO_FLUSH; | 296 | job->vm_needs_flush = false; |
232 | trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, *vm_pd_addr); | 297 | trace_amdgpu_vm_grab_id(vm, ring->idx, job->vm_id, job->vm_pd_addr); |
233 | 298 | ||
234 | mutex_unlock(&adev->vm_manager.lock); | 299 | mutex_unlock(&adev->vm_manager.lock); |
235 | return 0; | 300 | return 0; |
236 | 301 | ||
237 | } while (i != ring->idx); | 302 | } while (i != ring->idx); |
238 | 303 | ||
239 | id = list_first_entry(&adev->vm_manager.ids_lru, | 304 | /* Still no ID to use? Then use the idle one found earlier */ |
240 | struct amdgpu_vm_id, | 305 | id = idle; |
241 | list); | ||
242 | 306 | ||
243 | if (!amdgpu_sync_is_idle(&id->active)) { | 307 | /* Remember this submission as user of the VMID */ |
244 | struct list_head *head = &adev->vm_manager.ids_lru; | 308 | r = amdgpu_sync_fence(ring->adev, &id->active, fence); |
245 | struct amdgpu_vm_id *tmp; | ||
246 | |||
247 | list_for_each_entry_safe(id, tmp, &adev->vm_manager.ids_lru, | ||
248 | list) { | ||
249 | if (amdgpu_sync_is_idle(&id->active)) { | ||
250 | list_move(&id->list, head); | ||
251 | head = &id->list; | ||
252 | } | ||
253 | } | ||
254 | id = list_first_entry(&adev->vm_manager.ids_lru, | ||
255 | struct amdgpu_vm_id, | ||
256 | list); | ||
257 | } | ||
258 | |||
259 | r = amdgpu_sync_cycle_fences(sync, &id->active, fence); | ||
260 | if (r) | 309 | if (r) |
261 | goto error; | 310 | goto error; |
262 | 311 | ||
@@ -269,22 +318,46 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
269 | fence_put(id->flushed_updates); | 318 | fence_put(id->flushed_updates); |
270 | id->flushed_updates = fence_get(updates); | 319 | id->flushed_updates = fence_get(updates); |
271 | 320 | ||
272 | id->pd_gpu_addr = pd_addr; | 321 | id->pd_gpu_addr = job->vm_pd_addr; |
273 | 322 | id->current_gpu_reset_count = atomic_read(&adev->gpu_reset_counter); | |
274 | list_move_tail(&id->list, &adev->vm_manager.ids_lru); | 323 | list_move_tail(&id->list, &adev->vm_manager.ids_lru); |
275 | id->last_user = ring; | ||
276 | atomic64_set(&id->owner, vm->client_id); | 324 | atomic64_set(&id->owner, vm->client_id); |
277 | vm->ids[ring->idx] = id; | 325 | vm->ids[ring->idx] = id; |
278 | 326 | ||
279 | *vm_id = id - adev->vm_manager.ids; | 327 | job->vm_id = id - adev->vm_manager.ids; |
280 | *vm_pd_addr = pd_addr; | 328 | trace_amdgpu_vm_grab_id(vm, ring->idx, job->vm_id, job->vm_pd_addr); |
281 | trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, *vm_pd_addr); | ||
282 | 329 | ||
283 | error: | 330 | error: |
284 | mutex_unlock(&adev->vm_manager.lock); | 331 | mutex_unlock(&adev->vm_manager.lock); |
285 | return r; | 332 | return r; |
286 | } | 333 | } |
287 | 334 | ||
335 | static bool amdgpu_vm_ring_has_compute_vm_bug(struct amdgpu_ring *ring) | ||
336 | { | ||
337 | struct amdgpu_device *adev = ring->adev; | ||
338 | const struct amdgpu_ip_block_version *ip_block; | ||
339 | |||
340 | if (ring->type != AMDGPU_RING_TYPE_COMPUTE) | ||
341 | /* only compute rings */ | ||
342 | return false; | ||
343 | |||
344 | ip_block = amdgpu_get_ip_block(adev, AMD_IP_BLOCK_TYPE_GFX); | ||
345 | if (!ip_block) | ||
346 | return false; | ||
347 | |||
348 | if (ip_block->major <= 7) { | ||
349 | /* gfx7 has no workaround */ | ||
350 | return true; | ||
351 | } else if (ip_block->major == 8) { | ||
352 | if (adev->gfx.mec_fw_version >= 673) | ||
353 | /* gfx8 is fixed in MEC firmware 673 */ | ||
354 | return false; | ||
355 | else | ||
356 | return true; | ||
357 | } | ||
358 | return false; | ||
359 | } | ||
360 | |||
288 | /** | 361 | /** |
289 | * amdgpu_vm_flush - hardware flush the vm | 362 | * amdgpu_vm_flush - hardware flush the vm |
290 | * | 363 | * |
@@ -294,59 +367,52 @@ error: | |||
294 | * | 367 | * |
295 | * Emit a VM flush when it is necessary. | 368 | * Emit a VM flush when it is necessary. |
296 | */ | 369 | */ |
297 | int amdgpu_vm_flush(struct amdgpu_ring *ring, | 370 | int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job) |
298 | unsigned vm_id, uint64_t pd_addr, | ||
299 | uint32_t gds_base, uint32_t gds_size, | ||
300 | uint32_t gws_base, uint32_t gws_size, | ||
301 | uint32_t oa_base, uint32_t oa_size) | ||
302 | { | 371 | { |
303 | struct amdgpu_device *adev = ring->adev; | 372 | struct amdgpu_device *adev = ring->adev; |
304 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; | 373 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[job->vm_id]; |
305 | bool gds_switch_needed = ring->funcs->emit_gds_switch && ( | 374 | bool gds_switch_needed = ring->funcs->emit_gds_switch && ( |
306 | id->gds_base != gds_base || | 375 | id->gds_base != job->gds_base || |
307 | id->gds_size != gds_size || | 376 | id->gds_size != job->gds_size || |
308 | id->gws_base != gws_base || | 377 | id->gws_base != job->gws_base || |
309 | id->gws_size != gws_size || | 378 | id->gws_size != job->gws_size || |
310 | id->oa_base != oa_base || | 379 | id->oa_base != job->oa_base || |
311 | id->oa_size != oa_size); | 380 | id->oa_size != job->oa_size); |
312 | int r; | 381 | int r; |
313 | 382 | ||
314 | if (ring->funcs->emit_pipeline_sync && ( | 383 | if (ring->funcs->emit_pipeline_sync && ( |
315 | pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || | 384 | job->vm_needs_flush || gds_switch_needed || |
316 | ring->type == AMDGPU_RING_TYPE_COMPUTE)) | 385 | amdgpu_vm_ring_has_compute_vm_bug(ring))) |
317 | amdgpu_ring_emit_pipeline_sync(ring); | 386 | amdgpu_ring_emit_pipeline_sync(ring); |
318 | 387 | ||
319 | if (ring->funcs->emit_vm_flush && | 388 | if (ring->funcs->emit_vm_flush && (job->vm_needs_flush || |
320 | pd_addr != AMDGPU_VM_NO_FLUSH) { | 389 | amdgpu_vm_is_gpu_reset(adev, id))) { |
321 | struct fence *fence; | 390 | struct fence *fence; |
322 | 391 | ||
323 | trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id); | 392 | trace_amdgpu_vm_flush(job->vm_pd_addr, ring->idx, job->vm_id); |
324 | amdgpu_ring_emit_vm_flush(ring, vm_id, pd_addr); | 393 | amdgpu_ring_emit_vm_flush(ring, job->vm_id, job->vm_pd_addr); |
394 | |||
395 | r = amdgpu_fence_emit(ring, &fence); | ||
396 | if (r) | ||
397 | return r; | ||
325 | 398 | ||
326 | mutex_lock(&adev->vm_manager.lock); | 399 | mutex_lock(&adev->vm_manager.lock); |
327 | if ((id->pd_gpu_addr == pd_addr) && (id->last_user == ring)) { | 400 | fence_put(id->last_flush); |
328 | r = amdgpu_fence_emit(ring, &fence); | 401 | id->last_flush = fence; |
329 | if (r) { | ||
330 | mutex_unlock(&adev->vm_manager.lock); | ||
331 | return r; | ||
332 | } | ||
333 | fence_put(id->last_flush); | ||
334 | id->last_flush = fence; | ||
335 | } | ||
336 | mutex_unlock(&adev->vm_manager.lock); | 402 | mutex_unlock(&adev->vm_manager.lock); |
337 | } | 403 | } |
338 | 404 | ||
339 | if (gds_switch_needed) { | 405 | if (gds_switch_needed) { |
340 | id->gds_base = gds_base; | 406 | id->gds_base = job->gds_base; |
341 | id->gds_size = gds_size; | 407 | id->gds_size = job->gds_size; |
342 | id->gws_base = gws_base; | 408 | id->gws_base = job->gws_base; |
343 | id->gws_size = gws_size; | 409 | id->gws_size = job->gws_size; |
344 | id->oa_base = oa_base; | 410 | id->oa_base = job->oa_base; |
345 | id->oa_size = oa_size; | 411 | id->oa_size = job->oa_size; |
346 | amdgpu_ring_emit_gds_switch(ring, vm_id, | 412 | amdgpu_ring_emit_gds_switch(ring, job->vm_id, |
347 | gds_base, gds_size, | 413 | job->gds_base, job->gds_size, |
348 | gws_base, gws_size, | 414 | job->gws_base, job->gws_size, |
349 | oa_base, oa_size); | 415 | job->oa_base, job->oa_size); |
350 | } | 416 | } |
351 | 417 | ||
352 | return 0; | 418 | return 0; |
@@ -723,7 +789,7 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, | |||
723 | * @vm: requested vm | 789 | * @vm: requested vm |
724 | * @start: start of GPU address range | 790 | * @start: start of GPU address range |
725 | * @end: end of GPU address range | 791 | * @end: end of GPU address range |
726 | * @dst: destination address to map to | 792 | * @dst: destination address to map to, the next dst inside the function |
727 | * @flags: mapping flags | 793 | * @flags: mapping flags |
728 | * | 794 | * |
729 | * Update the page tables in the range @start - @end. | 795 | * Update the page tables in the range @start - @end. |
@@ -737,49 +803,75 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, | |||
737 | { | 803 | { |
738 | const uint64_t mask = AMDGPU_VM_PTE_COUNT - 1; | 804 | const uint64_t mask = AMDGPU_VM_PTE_COUNT - 1; |
739 | 805 | ||
740 | uint64_t last_pe_start = ~0, last_pe_end = ~0, last_dst = ~0; | 806 | uint64_t cur_pe_start, cur_pe_end, cur_dst; |
741 | uint64_t addr; | 807 | uint64_t addr; /* next GPU address to be updated */ |
808 | uint64_t pt_idx; | ||
809 | struct amdgpu_bo *pt; | ||
810 | unsigned nptes; /* next number of ptes to be updated */ | ||
811 | uint64_t next_pe_start; | ||
812 | |||
813 | /* initialize the variables */ | ||
814 | addr = start; | ||
815 | pt_idx = addr >> amdgpu_vm_block_size; | ||
816 | pt = vm->page_tables[pt_idx].entry.robj; | ||
817 | |||
818 | if ((addr & ~mask) == (end & ~mask)) | ||
819 | nptes = end - addr; | ||
820 | else | ||
821 | nptes = AMDGPU_VM_PTE_COUNT - (addr & mask); | ||
822 | |||
823 | cur_pe_start = amdgpu_bo_gpu_offset(pt); | ||
824 | cur_pe_start += (addr & mask) * 8; | ||
825 | cur_pe_end = cur_pe_start + 8 * nptes; | ||
826 | cur_dst = dst; | ||
827 | |||
828 | /* for next ptb*/ | ||
829 | addr += nptes; | ||
830 | dst += nptes * AMDGPU_GPU_PAGE_SIZE; | ||
742 | 831 | ||
743 | /* walk over the address space and update the page tables */ | 832 | /* walk over the address space and update the page tables */ |
744 | for (addr = start; addr < end; ) { | 833 | while (addr < end) { |
745 | uint64_t pt_idx = addr >> amdgpu_vm_block_size; | 834 | pt_idx = addr >> amdgpu_vm_block_size; |
746 | struct amdgpu_bo *pt = vm->page_tables[pt_idx].entry.robj; | 835 | pt = vm->page_tables[pt_idx].entry.robj; |
747 | unsigned nptes; | ||
748 | uint64_t pe_start; | ||
749 | 836 | ||
750 | if ((addr & ~mask) == (end & ~mask)) | 837 | if ((addr & ~mask) == (end & ~mask)) |
751 | nptes = end - addr; | 838 | nptes = end - addr; |
752 | else | 839 | else |
753 | nptes = AMDGPU_VM_PTE_COUNT - (addr & mask); | 840 | nptes = AMDGPU_VM_PTE_COUNT - (addr & mask); |
754 | 841 | ||
755 | pe_start = amdgpu_bo_gpu_offset(pt); | 842 | next_pe_start = amdgpu_bo_gpu_offset(pt); |
756 | pe_start += (addr & mask) * 8; | 843 | next_pe_start += (addr & mask) * 8; |
757 | |||
758 | if (last_pe_end != pe_start) { | ||
759 | 844 | ||
845 | if (cur_pe_end == next_pe_start) { | ||
846 | /* The next ptb is consecutive to current ptb. | ||
847 | * Don't call amdgpu_vm_frag_ptes now. | ||
848 | * Will update two ptbs together in future. | ||
849 | */ | ||
850 | cur_pe_end += 8 * nptes; | ||
851 | } else { | ||
760 | amdgpu_vm_frag_ptes(adev, vm_update_params, | 852 | amdgpu_vm_frag_ptes(adev, vm_update_params, |
761 | last_pe_start, last_pe_end, | 853 | cur_pe_start, cur_pe_end, |
762 | last_dst, flags); | 854 | cur_dst, flags); |
763 | 855 | ||
764 | last_pe_start = pe_start; | 856 | cur_pe_start = next_pe_start; |
765 | last_pe_end = pe_start + 8 * nptes; | 857 | cur_pe_end = next_pe_start + 8 * nptes; |
766 | last_dst = dst; | 858 | cur_dst = dst; |
767 | } else { | ||
768 | last_pe_end += 8 * nptes; | ||
769 | } | 859 | } |
770 | 860 | ||
861 | /* for next ptb*/ | ||
771 | addr += nptes; | 862 | addr += nptes; |
772 | dst += nptes * AMDGPU_GPU_PAGE_SIZE; | 863 | dst += nptes * AMDGPU_GPU_PAGE_SIZE; |
773 | } | 864 | } |
774 | 865 | ||
775 | amdgpu_vm_frag_ptes(adev, vm_update_params, last_pe_start, | 866 | amdgpu_vm_frag_ptes(adev, vm_update_params, cur_pe_start, |
776 | last_pe_end, last_dst, flags); | 867 | cur_pe_end, cur_dst, flags); |
777 | } | 868 | } |
778 | 869 | ||
779 | /** | 870 | /** |
780 | * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table | 871 | * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table |
781 | * | 872 | * |
782 | * @adev: amdgpu_device pointer | 873 | * @adev: amdgpu_device pointer |
874 | * @exclusive: fence we need to sync to | ||
783 | * @src: address where to copy page table entries from | 875 | * @src: address where to copy page table entries from |
784 | * @pages_addr: DMA addresses to use for mapping | 876 | * @pages_addr: DMA addresses to use for mapping |
785 | * @vm: requested vm | 877 | * @vm: requested vm |
@@ -793,6 +885,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, | |||
793 | * Returns 0 for success, -EINVAL for failure. | 885 | * Returns 0 for success, -EINVAL for failure. |
794 | */ | 886 | */ |
795 | static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | 887 | static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, |
888 | struct fence *exclusive, | ||
796 | uint64_t src, | 889 | uint64_t src, |
797 | dma_addr_t *pages_addr, | 890 | dma_addr_t *pages_addr, |
798 | struct amdgpu_vm *vm, | 891 | struct amdgpu_vm *vm, |
@@ -853,6 +946,10 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
853 | 946 | ||
854 | vm_update_params.ib = &job->ibs[0]; | 947 | vm_update_params.ib = &job->ibs[0]; |
855 | 948 | ||
949 | r = amdgpu_sync_fence(adev, &job->sync, exclusive); | ||
950 | if (r) | ||
951 | goto error_free; | ||
952 | |||
856 | r = amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv, | 953 | r = amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv, |
857 | owner); | 954 | owner); |
858 | if (r) | 955 | if (r) |
@@ -889,6 +986,7 @@ error_free: | |||
889 | * amdgpu_vm_bo_split_mapping - split a mapping into smaller chunks | 986 | * amdgpu_vm_bo_split_mapping - split a mapping into smaller chunks |
890 | * | 987 | * |
891 | * @adev: amdgpu_device pointer | 988 | * @adev: amdgpu_device pointer |
989 | * @exclusive: fence we need to sync to | ||
892 | * @gtt_flags: flags as they are used for GTT | 990 | * @gtt_flags: flags as they are used for GTT |
893 | * @pages_addr: DMA addresses to use for mapping | 991 | * @pages_addr: DMA addresses to use for mapping |
894 | * @vm: requested vm | 992 | * @vm: requested vm |
@@ -902,6 +1000,7 @@ error_free: | |||
902 | * Returns 0 for success, -EINVAL for failure. | 1000 | * Returns 0 for success, -EINVAL for failure. |
903 | */ | 1001 | */ |
904 | static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | 1002 | static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, |
1003 | struct fence *exclusive, | ||
905 | uint32_t gtt_flags, | 1004 | uint32_t gtt_flags, |
906 | dma_addr_t *pages_addr, | 1005 | dma_addr_t *pages_addr, |
907 | struct amdgpu_vm *vm, | 1006 | struct amdgpu_vm *vm, |
@@ -932,7 +1031,8 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |||
932 | addr += mapping->offset; | 1031 | addr += mapping->offset; |
933 | 1032 | ||
934 | if (!pages_addr || src) | 1033 | if (!pages_addr || src) |
935 | return amdgpu_vm_bo_update_mapping(adev, src, pages_addr, vm, | 1034 | return amdgpu_vm_bo_update_mapping(adev, exclusive, |
1035 | src, pages_addr, vm, | ||
936 | start, mapping->it.last, | 1036 | start, mapping->it.last, |
937 | flags, addr, fence); | 1037 | flags, addr, fence); |
938 | 1038 | ||
@@ -940,7 +1040,8 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |||
940 | uint64_t last; | 1040 | uint64_t last; |
941 | 1041 | ||
942 | last = min((uint64_t)mapping->it.last, start + max_size - 1); | 1042 | last = min((uint64_t)mapping->it.last, start + max_size - 1); |
943 | r = amdgpu_vm_bo_update_mapping(adev, src, pages_addr, vm, | 1043 | r = amdgpu_vm_bo_update_mapping(adev, exclusive, |
1044 | src, pages_addr, vm, | ||
944 | start, last, flags, addr, | 1045 | start, last, flags, addr, |
945 | fence); | 1046 | fence); |
946 | if (r) | 1047 | if (r) |
@@ -973,6 +1074,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, | |||
973 | struct amdgpu_bo_va_mapping *mapping; | 1074 | struct amdgpu_bo_va_mapping *mapping; |
974 | dma_addr_t *pages_addr = NULL; | 1075 | dma_addr_t *pages_addr = NULL; |
975 | uint32_t gtt_flags, flags; | 1076 | uint32_t gtt_flags, flags; |
1077 | struct fence *exclusive; | ||
976 | uint64_t addr; | 1078 | uint64_t addr; |
977 | int r; | 1079 | int r; |
978 | 1080 | ||
@@ -994,8 +1096,11 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, | |||
994 | default: | 1096 | default: |
995 | break; | 1097 | break; |
996 | } | 1098 | } |
1099 | |||
1100 | exclusive = reservation_object_get_excl(bo_va->bo->tbo.resv); | ||
997 | } else { | 1101 | } else { |
998 | addr = 0; | 1102 | addr = 0; |
1103 | exclusive = NULL; | ||
999 | } | 1104 | } |
1000 | 1105 | ||
1001 | flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem); | 1106 | flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem); |
@@ -1007,7 +1112,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, | |||
1007 | spin_unlock(&vm->status_lock); | 1112 | spin_unlock(&vm->status_lock); |
1008 | 1113 | ||
1009 | list_for_each_entry(mapping, &bo_va->invalids, list) { | 1114 | list_for_each_entry(mapping, &bo_va->invalids, list) { |
1010 | r = amdgpu_vm_bo_split_mapping(adev, gtt_flags, pages_addr, vm, | 1115 | r = amdgpu_vm_bo_split_mapping(adev, exclusive, |
1116 | gtt_flags, pages_addr, vm, | ||
1011 | mapping, flags, addr, | 1117 | mapping, flags, addr, |
1012 | &bo_va->last_pt_update); | 1118 | &bo_va->last_pt_update); |
1013 | if (r) | 1119 | if (r) |
@@ -1054,7 +1160,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | |||
1054 | struct amdgpu_bo_va_mapping, list); | 1160 | struct amdgpu_bo_va_mapping, list); |
1055 | list_del(&mapping->list); | 1161 | list_del(&mapping->list); |
1056 | 1162 | ||
1057 | r = amdgpu_vm_bo_split_mapping(adev, 0, NULL, vm, mapping, | 1163 | r = amdgpu_vm_bo_split_mapping(adev, NULL, 0, NULL, vm, mapping, |
1058 | 0, 0, NULL); | 1164 | 0, 0, NULL); |
1059 | kfree(mapping); | 1165 | kfree(mapping); |
1060 | if (r) | 1166 | if (r) |
@@ -1445,6 +1551,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1445 | amdgpu_bo_unreserve(vm->page_directory); | 1551 | amdgpu_bo_unreserve(vm->page_directory); |
1446 | if (r) | 1552 | if (r) |
1447 | goto error_free_page_directory; | 1553 | goto error_free_page_directory; |
1554 | vm->last_eviction_counter = atomic64_read(&adev->num_evictions); | ||
1448 | 1555 | ||
1449 | return 0; | 1556 | return 0; |
1450 | 1557 | ||
@@ -1516,6 +1623,10 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev) | |||
1516 | &adev->vm_manager.ids_lru); | 1623 | &adev->vm_manager.ids_lru); |
1517 | } | 1624 | } |
1518 | 1625 | ||
1626 | adev->vm_manager.fence_context = fence_context_alloc(AMDGPU_MAX_RINGS); | ||
1627 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) | ||
1628 | adev->vm_manager.seqno[i] = 0; | ||
1629 | |||
1519 | atomic_set(&adev->vm_manager.vm_pte_next_ring, 0); | 1630 | atomic_set(&adev->vm_manager.vm_pte_next_ring, 0); |
1520 | atomic64_set(&adev->vm_manager.client_counter, 0); | 1631 | atomic64_set(&adev->vm_manager.client_counter, 0); |
1521 | } | 1632 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 5ec1f1e9c983..5c33ed862695 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
@@ -50,7 +50,9 @@ | |||
50 | #include "gmc/gmc_7_1_sh_mask.h" | 50 | #include "gmc/gmc_7_1_sh_mask.h" |
51 | 51 | ||
52 | MODULE_FIRMWARE("radeon/bonaire_smc.bin"); | 52 | MODULE_FIRMWARE("radeon/bonaire_smc.bin"); |
53 | MODULE_FIRMWARE("radeon/bonaire_k_smc.bin"); | ||
53 | MODULE_FIRMWARE("radeon/hawaii_smc.bin"); | 54 | MODULE_FIRMWARE("radeon/hawaii_smc.bin"); |
55 | MODULE_FIRMWARE("radeon/hawaii_k_smc.bin"); | ||
54 | 56 | ||
55 | #define MC_CG_ARB_FREQ_F0 0x0a | 57 | #define MC_CG_ARB_FREQ_F0 0x0a |
56 | #define MC_CG_ARB_FREQ_F1 0x0b | 58 | #define MC_CG_ARB_FREQ_F1 0x0b |
@@ -736,19 +738,19 @@ static int ci_enable_didt(struct amdgpu_device *adev, bool enable) | |||
736 | 738 | ||
737 | if (pi->caps_sq_ramping || pi->caps_db_ramping || | 739 | if (pi->caps_sq_ramping || pi->caps_db_ramping || |
738 | pi->caps_td_ramping || pi->caps_tcp_ramping) { | 740 | pi->caps_td_ramping || pi->caps_tcp_ramping) { |
739 | gfx_v7_0_enter_rlc_safe_mode(adev); | 741 | adev->gfx.rlc.funcs->enter_safe_mode(adev); |
740 | 742 | ||
741 | if (enable) { | 743 | if (enable) { |
742 | ret = ci_program_pt_config_registers(adev, didt_config_ci); | 744 | ret = ci_program_pt_config_registers(adev, didt_config_ci); |
743 | if (ret) { | 745 | if (ret) { |
744 | gfx_v7_0_exit_rlc_safe_mode(adev); | 746 | adev->gfx.rlc.funcs->exit_safe_mode(adev); |
745 | return ret; | 747 | return ret; |
746 | } | 748 | } |
747 | } | 749 | } |
748 | 750 | ||
749 | ci_do_enable_didt(adev, enable); | 751 | ci_do_enable_didt(adev, enable); |
750 | 752 | ||
751 | gfx_v7_0_exit_rlc_safe_mode(adev); | 753 | adev->gfx.rlc.funcs->exit_safe_mode(adev); |
752 | } | 754 | } |
753 | 755 | ||
754 | return 0; | 756 | return 0; |
@@ -3636,6 +3638,10 @@ static int ci_setup_default_dpm_tables(struct amdgpu_device *adev) | |||
3636 | 3638 | ||
3637 | ci_setup_default_pcie_tables(adev); | 3639 | ci_setup_default_pcie_tables(adev); |
3638 | 3640 | ||
3641 | /* save a copy of the default DPM table */ | ||
3642 | memcpy(&(pi->golden_dpm_table), &(pi->dpm_table), | ||
3643 | sizeof(struct ci_dpm_table)); | ||
3644 | |||
3639 | return 0; | 3645 | return 0; |
3640 | } | 3646 | } |
3641 | 3647 | ||
@@ -5754,10 +5760,18 @@ static int ci_dpm_init_microcode(struct amdgpu_device *adev) | |||
5754 | 5760 | ||
5755 | switch (adev->asic_type) { | 5761 | switch (adev->asic_type) { |
5756 | case CHIP_BONAIRE: | 5762 | case CHIP_BONAIRE: |
5757 | chip_name = "bonaire"; | 5763 | if ((adev->pdev->revision == 0x80) || |
5764 | (adev->pdev->revision == 0x81) || | ||
5765 | (adev->pdev->device == 0x665f)) | ||
5766 | chip_name = "bonaire_k"; | ||
5767 | else | ||
5768 | chip_name = "bonaire"; | ||
5758 | break; | 5769 | break; |
5759 | case CHIP_HAWAII: | 5770 | case CHIP_HAWAII: |
5760 | chip_name = "hawaii"; | 5771 | if (adev->pdev->revision == 0x80) |
5772 | chip_name = "hawaii_k"; | ||
5773 | else | ||
5774 | chip_name = "hawaii"; | ||
5761 | break; | 5775 | break; |
5762 | case CHIP_KAVERI: | 5776 | case CHIP_KAVERI: |
5763 | case CHIP_KABINI: | 5777 | case CHIP_KABINI: |
@@ -6404,6 +6418,186 @@ static int ci_dpm_set_powergating_state(void *handle, | |||
6404 | return 0; | 6418 | return 0; |
6405 | } | 6419 | } |
6406 | 6420 | ||
6421 | static int ci_dpm_print_clock_levels(struct amdgpu_device *adev, | ||
6422 | enum pp_clock_type type, char *buf) | ||
6423 | { | ||
6424 | struct ci_power_info *pi = ci_get_pi(adev); | ||
6425 | struct ci_single_dpm_table *sclk_table = &pi->dpm_table.sclk_table; | ||
6426 | struct ci_single_dpm_table *mclk_table = &pi->dpm_table.mclk_table; | ||
6427 | struct ci_single_dpm_table *pcie_table = &pi->dpm_table.pcie_speed_table; | ||
6428 | |||
6429 | int i, now, size = 0; | ||
6430 | uint32_t clock, pcie_speed; | ||
6431 | |||
6432 | switch (type) { | ||
6433 | case PP_SCLK: | ||
6434 | amdgpu_ci_send_msg_to_smc(adev, PPSMC_MSG_API_GetSclkFrequency); | ||
6435 | clock = RREG32(mmSMC_MSG_ARG_0); | ||
6436 | |||
6437 | for (i = 0; i < sclk_table->count; i++) { | ||
6438 | if (clock > sclk_table->dpm_levels[i].value) | ||
6439 | continue; | ||
6440 | break; | ||
6441 | } | ||
6442 | now = i; | ||
6443 | |||
6444 | for (i = 0; i < sclk_table->count; i++) | ||
6445 | size += sprintf(buf + size, "%d: %uMhz %s\n", | ||
6446 | i, sclk_table->dpm_levels[i].value / 100, | ||
6447 | (i == now) ? "*" : ""); | ||
6448 | break; | ||
6449 | case PP_MCLK: | ||
6450 | amdgpu_ci_send_msg_to_smc(adev, PPSMC_MSG_API_GetMclkFrequency); | ||
6451 | clock = RREG32(mmSMC_MSG_ARG_0); | ||
6452 | |||
6453 | for (i = 0; i < mclk_table->count; i++) { | ||
6454 | if (clock > mclk_table->dpm_levels[i].value) | ||
6455 | continue; | ||
6456 | break; | ||
6457 | } | ||
6458 | now = i; | ||
6459 | |||
6460 | for (i = 0; i < mclk_table->count; i++) | ||
6461 | size += sprintf(buf + size, "%d: %uMhz %s\n", | ||
6462 | i, mclk_table->dpm_levels[i].value / 100, | ||
6463 | (i == now) ? "*" : ""); | ||
6464 | break; | ||
6465 | case PP_PCIE: | ||
6466 | pcie_speed = ci_get_current_pcie_speed(adev); | ||
6467 | for (i = 0; i < pcie_table->count; i++) { | ||
6468 | if (pcie_speed != pcie_table->dpm_levels[i].value) | ||
6469 | continue; | ||
6470 | break; | ||
6471 | } | ||
6472 | now = i; | ||
6473 | |||
6474 | for (i = 0; i < pcie_table->count; i++) | ||
6475 | size += sprintf(buf + size, "%d: %s %s\n", i, | ||
6476 | (pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x1" : | ||
6477 | (pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" : | ||
6478 | (pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "", | ||
6479 | (i == now) ? "*" : ""); | ||
6480 | break; | ||
6481 | default: | ||
6482 | break; | ||
6483 | } | ||
6484 | |||
6485 | return size; | ||
6486 | } | ||
6487 | |||
6488 | static int ci_dpm_force_clock_level(struct amdgpu_device *adev, | ||
6489 | enum pp_clock_type type, uint32_t mask) | ||
6490 | { | ||
6491 | struct ci_power_info *pi = ci_get_pi(adev); | ||
6492 | |||
6493 | if (adev->pm.dpm.forced_level | ||
6494 | != AMDGPU_DPM_FORCED_LEVEL_MANUAL) | ||
6495 | return -EINVAL; | ||
6496 | |||
6497 | switch (type) { | ||
6498 | case PP_SCLK: | ||
6499 | if (!pi->sclk_dpm_key_disabled) | ||
6500 | amdgpu_ci_send_msg_to_smc_with_parameter(adev, | ||
6501 | PPSMC_MSG_SCLKDPM_SetEnabledMask, | ||
6502 | pi->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); | ||
6503 | break; | ||
6504 | |||
6505 | case PP_MCLK: | ||
6506 | if (!pi->mclk_dpm_key_disabled) | ||
6507 | amdgpu_ci_send_msg_to_smc_with_parameter(adev, | ||
6508 | PPSMC_MSG_MCLKDPM_SetEnabledMask, | ||
6509 | pi->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); | ||
6510 | break; | ||
6511 | |||
6512 | case PP_PCIE: | ||
6513 | { | ||
6514 | uint32_t tmp = mask & pi->dpm_level_enable_mask.pcie_dpm_enable_mask; | ||
6515 | uint32_t level = 0; | ||
6516 | |||
6517 | while (tmp >>= 1) | ||
6518 | level++; | ||
6519 | |||
6520 | if (!pi->pcie_dpm_key_disabled) | ||
6521 | amdgpu_ci_send_msg_to_smc_with_parameter(adev, | ||
6522 | PPSMC_MSG_PCIeDPM_ForceLevel, | ||
6523 | level); | ||
6524 | break; | ||
6525 | } | ||
6526 | default: | ||
6527 | break; | ||
6528 | } | ||
6529 | |||
6530 | return 0; | ||
6531 | } | ||
6532 | |||
6533 | static int ci_dpm_get_sclk_od(struct amdgpu_device *adev) | ||
6534 | { | ||
6535 | struct ci_power_info *pi = ci_get_pi(adev); | ||
6536 | struct ci_single_dpm_table *sclk_table = &(pi->dpm_table.sclk_table); | ||
6537 | struct ci_single_dpm_table *golden_sclk_table = | ||
6538 | &(pi->golden_dpm_table.sclk_table); | ||
6539 | int value; | ||
6540 | |||
6541 | value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | ||
6542 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * | ||
6543 | 100 / | ||
6544 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
6545 | |||
6546 | return value; | ||
6547 | } | ||
6548 | |||
6549 | static int ci_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value) | ||
6550 | { | ||
6551 | struct ci_power_info *pi = ci_get_pi(adev); | ||
6552 | struct ci_ps *ps = ci_get_ps(adev->pm.dpm.requested_ps); | ||
6553 | struct ci_single_dpm_table *golden_sclk_table = | ||
6554 | &(pi->golden_dpm_table.sclk_table); | ||
6555 | |||
6556 | if (value > 20) | ||
6557 | value = 20; | ||
6558 | |||
6559 | ps->performance_levels[ps->performance_level_count - 1].sclk = | ||
6560 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value * | ||
6561 | value / 100 + | ||
6562 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
6563 | |||
6564 | return 0; | ||
6565 | } | ||
6566 | |||
6567 | static int ci_dpm_get_mclk_od(struct amdgpu_device *adev) | ||
6568 | { | ||
6569 | struct ci_power_info *pi = ci_get_pi(adev); | ||
6570 | struct ci_single_dpm_table *mclk_table = &(pi->dpm_table.mclk_table); | ||
6571 | struct ci_single_dpm_table *golden_mclk_table = | ||
6572 | &(pi->golden_dpm_table.mclk_table); | ||
6573 | int value; | ||
6574 | |||
6575 | value = (mclk_table->dpm_levels[mclk_table->count - 1].value - | ||
6576 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * | ||
6577 | 100 / | ||
6578 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
6579 | |||
6580 | return value; | ||
6581 | } | ||
6582 | |||
6583 | static int ci_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value) | ||
6584 | { | ||
6585 | struct ci_power_info *pi = ci_get_pi(adev); | ||
6586 | struct ci_ps *ps = ci_get_ps(adev->pm.dpm.requested_ps); | ||
6587 | struct ci_single_dpm_table *golden_mclk_table = | ||
6588 | &(pi->golden_dpm_table.mclk_table); | ||
6589 | |||
6590 | if (value > 20) | ||
6591 | value = 20; | ||
6592 | |||
6593 | ps->performance_levels[ps->performance_level_count - 1].mclk = | ||
6594 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value * | ||
6595 | value / 100 + | ||
6596 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
6597 | |||
6598 | return 0; | ||
6599 | } | ||
6600 | |||
6407 | const struct amd_ip_funcs ci_dpm_ip_funcs = { | 6601 | const struct amd_ip_funcs ci_dpm_ip_funcs = { |
6408 | .name = "ci_dpm", | 6602 | .name = "ci_dpm", |
6409 | .early_init = ci_dpm_early_init, | 6603 | .early_init = ci_dpm_early_init, |
@@ -6438,6 +6632,12 @@ static const struct amdgpu_dpm_funcs ci_dpm_funcs = { | |||
6438 | .get_fan_control_mode = &ci_dpm_get_fan_control_mode, | 6632 | .get_fan_control_mode = &ci_dpm_get_fan_control_mode, |
6439 | .set_fan_speed_percent = &ci_dpm_set_fan_speed_percent, | 6633 | .set_fan_speed_percent = &ci_dpm_set_fan_speed_percent, |
6440 | .get_fan_speed_percent = &ci_dpm_get_fan_speed_percent, | 6634 | .get_fan_speed_percent = &ci_dpm_get_fan_speed_percent, |
6635 | .print_clock_levels = ci_dpm_print_clock_levels, | ||
6636 | .force_clock_level = ci_dpm_force_clock_level, | ||
6637 | .get_sclk_od = ci_dpm_get_sclk_od, | ||
6638 | .set_sclk_od = ci_dpm_set_sclk_od, | ||
6639 | .get_mclk_od = ci_dpm_get_mclk_od, | ||
6640 | .set_mclk_od = ci_dpm_set_mclk_od, | ||
6441 | }; | 6641 | }; |
6442 | 6642 | ||
6443 | static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) | 6643 | static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) |
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.h b/drivers/gpu/drm/amd/amdgpu/ci_dpm.h index faccc30c93bf..91be2996ae7c 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.h | |||
@@ -193,6 +193,7 @@ struct ci_pt_defaults { | |||
193 | 193 | ||
194 | struct ci_power_info { | 194 | struct ci_power_info { |
195 | struct ci_dpm_table dpm_table; | 195 | struct ci_dpm_table dpm_table; |
196 | struct ci_dpm_table golden_dpm_table; | ||
196 | u32 voltage_control; | 197 | u32 voltage_control; |
197 | u32 mvdd_control; | 198 | u32 mvdd_control; |
198 | u32 vddci_control; | 199 | u32 vddci_control; |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 910431808542..a7de4d18ac94 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c | |||
@@ -1035,12 +1035,12 @@ static uint32_t cik_read_indexed_register(struct amdgpu_device *adev, | |||
1035 | 1035 | ||
1036 | mutex_lock(&adev->grbm_idx_mutex); | 1036 | mutex_lock(&adev->grbm_idx_mutex); |
1037 | if (se_num != 0xffffffff || sh_num != 0xffffffff) | 1037 | if (se_num != 0xffffffff || sh_num != 0xffffffff) |
1038 | gfx_v7_0_select_se_sh(adev, se_num, sh_num); | 1038 | amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff); |
1039 | 1039 | ||
1040 | val = RREG32(reg_offset); | 1040 | val = RREG32(reg_offset); |
1041 | 1041 | ||
1042 | if (se_num != 0xffffffff || sh_num != 0xffffffff) | 1042 | if (se_num != 0xffffffff || sh_num != 0xffffffff) |
1043 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 1043 | amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
1044 | mutex_unlock(&adev->grbm_idx_mutex); | 1044 | mutex_unlock(&adev->grbm_idx_mutex); |
1045 | return val; | 1045 | return val; |
1046 | } | 1046 | } |
@@ -1158,10 +1158,11 @@ static void kv_restore_regs_for_reset(struct amdgpu_device *adev, | |||
1158 | WREG32(mmGMCON_RENG_EXECUTE, save->gmcon_reng_execute); | 1158 | WREG32(mmGMCON_RENG_EXECUTE, save->gmcon_reng_execute); |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | static void cik_gpu_pci_config_reset(struct amdgpu_device *adev) | 1161 | static int cik_gpu_pci_config_reset(struct amdgpu_device *adev) |
1162 | { | 1162 | { |
1163 | struct kv_reset_save_regs kv_save = { 0 }; | 1163 | struct kv_reset_save_regs kv_save = { 0 }; |
1164 | u32 i; | 1164 | u32 i; |
1165 | int r = -EINVAL; | ||
1165 | 1166 | ||
1166 | dev_info(adev->dev, "GPU pci config reset\n"); | 1167 | dev_info(adev->dev, "GPU pci config reset\n"); |
1167 | 1168 | ||
@@ -1177,14 +1178,20 @@ static void cik_gpu_pci_config_reset(struct amdgpu_device *adev) | |||
1177 | 1178 | ||
1178 | /* wait for asic to come out of reset */ | 1179 | /* wait for asic to come out of reset */ |
1179 | for (i = 0; i < adev->usec_timeout; i++) { | 1180 | for (i = 0; i < adev->usec_timeout; i++) { |
1180 | if (RREG32(mmCONFIG_MEMSIZE) != 0xffffffff) | 1181 | if (RREG32(mmCONFIG_MEMSIZE) != 0xffffffff) { |
1182 | /* enable BM */ | ||
1183 | pci_set_master(adev->pdev); | ||
1184 | r = 0; | ||
1181 | break; | 1185 | break; |
1186 | } | ||
1182 | udelay(1); | 1187 | udelay(1); |
1183 | } | 1188 | } |
1184 | 1189 | ||
1185 | /* does asic init need to be run first??? */ | 1190 | /* does asic init need to be run first??? */ |
1186 | if (adev->flags & AMD_IS_APU) | 1191 | if (adev->flags & AMD_IS_APU) |
1187 | kv_restore_regs_for_reset(adev, &kv_save); | 1192 | kv_restore_regs_for_reset(adev, &kv_save); |
1193 | |||
1194 | return r; | ||
1188 | } | 1195 | } |
1189 | 1196 | ||
1190 | static void cik_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hung) | 1197 | static void cik_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hung) |
@@ -1210,13 +1217,14 @@ static void cik_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hu | |||
1210 | */ | 1217 | */ |
1211 | static int cik_asic_reset(struct amdgpu_device *adev) | 1218 | static int cik_asic_reset(struct amdgpu_device *adev) |
1212 | { | 1219 | { |
1220 | int r; | ||
1213 | cik_set_bios_scratch_engine_hung(adev, true); | 1221 | cik_set_bios_scratch_engine_hung(adev, true); |
1214 | 1222 | ||
1215 | cik_gpu_pci_config_reset(adev); | 1223 | r = cik_gpu_pci_config_reset(adev); |
1216 | 1224 | ||
1217 | cik_set_bios_scratch_engine_hung(adev, false); | 1225 | cik_set_bios_scratch_engine_hung(adev, false); |
1218 | 1226 | ||
1219 | return 0; | 1227 | return r; |
1220 | } | 1228 | } |
1221 | 1229 | ||
1222 | static int cik_set_uvd_clock(struct amdgpu_device *adev, u32 clock, | 1230 | static int cik_set_uvd_clock(struct amdgpu_device *adev, u32 clock, |
@@ -2014,9 +2022,6 @@ static const struct amdgpu_asic_funcs cik_asic_funcs = | |||
2014 | .set_uvd_clocks = &cik_set_uvd_clocks, | 2022 | .set_uvd_clocks = &cik_set_uvd_clocks, |
2015 | .set_vce_clocks = &cik_set_vce_clocks, | 2023 | .set_vce_clocks = &cik_set_vce_clocks, |
2016 | .get_virtual_caps = &cik_get_virtual_caps, | 2024 | .get_virtual_caps = &cik_get_virtual_caps, |
2017 | /* these should be moved to their own ip modules */ | ||
2018 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, | ||
2019 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, | ||
2020 | }; | 2025 | }; |
2021 | 2026 | ||
2022 | static int cik_common_early_init(void *handle) | 2027 | static int cik_common_early_init(void *handle) |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 9dc4e24e31e7..46aca16a40aa 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
@@ -224,17 +224,6 @@ static void cik_sdma_ring_emit_ib(struct amdgpu_ring *ring, | |||
224 | unsigned vm_id, bool ctx_switch) | 224 | unsigned vm_id, bool ctx_switch) |
225 | { | 225 | { |
226 | u32 extra_bits = vm_id & 0xf; | 226 | u32 extra_bits = vm_id & 0xf; |
227 | u32 next_rptr = ring->wptr + 5; | ||
228 | |||
229 | while ((next_rptr & 7) != 4) | ||
230 | next_rptr++; | ||
231 | |||
232 | next_rptr += 4; | ||
233 | amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); | ||
234 | amdgpu_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
235 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); | ||
236 | amdgpu_ring_write(ring, 1); /* number of DWs to follow */ | ||
237 | amdgpu_ring_write(ring, next_rptr); | ||
238 | 227 | ||
239 | /* IB packet must end on a 8 DW boundary */ | 228 | /* IB packet must end on a 8 DW boundary */ |
240 | cik_sdma_ring_insert_nop(ring, (12 - (ring->wptr & 7)) % 8); | 229 | cik_sdma_ring_insert_nop(ring, (12 - (ring->wptr & 7)) % 8); |
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index 933e425a8154..8ba07e79d4cb 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c | |||
@@ -2219,6 +2219,7 @@ static void cz_dpm_powergate_vce(struct amdgpu_device *adev, bool gate) | |||
2219 | } | 2219 | } |
2220 | } | 2220 | } |
2221 | } else { /*pi->caps_vce_pg*/ | 2221 | } else { /*pi->caps_vce_pg*/ |
2222 | pi->vce_power_gated = gate; | ||
2222 | cz_update_vce_dpm(adev); | 2223 | cz_update_vce_dpm(adev); |
2223 | cz_enable_vce_dpm(adev, !gate); | 2224 | cz_enable_vce_dpm(adev, !gate); |
2224 | } | 2225 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index c90408bc0fde..d4bf133908b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | |||
@@ -307,11 +307,10 @@ static void dce_v11_0_page_flip(struct amdgpu_device *adev, | |||
307 | struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id]; | 307 | struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id]; |
308 | u32 tmp; | 308 | u32 tmp; |
309 | 309 | ||
310 | /* flip at hsync for async, default is vsync */ | 310 | /* flip immediate for async, default is vsync */ |
311 | /* use UPDATE_IMMEDIATE_EN instead for async? */ | ||
312 | tmp = RREG32(mmGRPH_FLIP_CONTROL + amdgpu_crtc->crtc_offset); | 311 | tmp = RREG32(mmGRPH_FLIP_CONTROL + amdgpu_crtc->crtc_offset); |
313 | tmp = REG_SET_FIELD(tmp, GRPH_FLIP_CONTROL, | 312 | tmp = REG_SET_FIELD(tmp, GRPH_FLIP_CONTROL, |
314 | GRPH_SURFACE_UPDATE_H_RETRACE_EN, async ? 1 : 0); | 313 | GRPH_SURFACE_UPDATE_IMMEDIATE_EN, async ? 1 : 0); |
315 | WREG32(mmGRPH_FLIP_CONTROL + amdgpu_crtc->crtc_offset, tmp); | 314 | WREG32(mmGRPH_FLIP_CONTROL + amdgpu_crtc->crtc_offset, tmp); |
316 | /* update the scanout addresses */ | 315 | /* update the scanout addresses */ |
317 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, | 316 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 300ff4aab0fd..4fdfab1e9200 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | |||
@@ -526,36 +526,16 @@ static void dce_v8_0_stop_mc_access(struct amdgpu_device *adev, | |||
526 | crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]), | 526 | crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]), |
527 | CRTC_CONTROL, CRTC_MASTER_EN); | 527 | CRTC_CONTROL, CRTC_MASTER_EN); |
528 | if (crtc_enabled) { | 528 | if (crtc_enabled) { |
529 | #if 0 | 529 | #if 1 |
530 | u32 frame_count; | ||
531 | int j; | ||
532 | |||
533 | save->crtc_enabled[i] = true; | 530 | save->crtc_enabled[i] = true; |
534 | tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]); | 531 | tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]); |
535 | if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) { | 532 | if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) { |
536 | amdgpu_display_vblank_wait(adev, i); | 533 | /*it is correct only for RGB ; black is 0*/ |
537 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); | 534 | WREG32(mmCRTC_BLANK_DATA_COLOR + crtc_offsets[i], 0); |
538 | tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1); | 535 | tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1); |
539 | WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp); | 536 | WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp); |
540 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
541 | } | ||
542 | /* wait for the next frame */ | ||
543 | frame_count = amdgpu_display_vblank_get_counter(adev, i); | ||
544 | for (j = 0; j < adev->usec_timeout; j++) { | ||
545 | if (amdgpu_display_vblank_get_counter(adev, i) != frame_count) | ||
546 | break; | ||
547 | udelay(1); | ||
548 | } | ||
549 | tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]); | ||
550 | if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK) == 0) { | ||
551 | tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 1); | ||
552 | WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp); | ||
553 | } | ||
554 | tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]); | ||
555 | if (REG_GET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK) == 0) { | ||
556 | tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK, 1); | ||
557 | WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp); | ||
558 | } | 537 | } |
538 | mdelay(20); | ||
559 | #else | 539 | #else |
560 | /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ | 540 | /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ |
561 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); | 541 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); |
@@ -575,55 +555,22 @@ static void dce_v8_0_stop_mc_access(struct amdgpu_device *adev, | |||
575 | static void dce_v8_0_resume_mc_access(struct amdgpu_device *adev, | 555 | static void dce_v8_0_resume_mc_access(struct amdgpu_device *adev, |
576 | struct amdgpu_mode_mc_save *save) | 556 | struct amdgpu_mode_mc_save *save) |
577 | { | 557 | { |
578 | u32 tmp, frame_count; | 558 | u32 tmp; |
579 | int i, j; | 559 | int i; |
580 | 560 | ||
581 | /* update crtc base addresses */ | 561 | /* update crtc base addresses */ |
582 | for (i = 0; i < adev->mode_info.num_crtc; i++) { | 562 | for (i = 0; i < adev->mode_info.num_crtc; i++) { |
583 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], | 563 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], |
584 | upper_32_bits(adev->mc.vram_start)); | 564 | upper_32_bits(adev->mc.vram_start)); |
585 | WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], | ||
586 | upper_32_bits(adev->mc.vram_start)); | ||
587 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], | 565 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], |
588 | (u32)adev->mc.vram_start); | 566 | (u32)adev->mc.vram_start); |
589 | WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], | ||
590 | (u32)adev->mc.vram_start); | ||
591 | 567 | ||
592 | if (save->crtc_enabled[i]) { | 568 | if (save->crtc_enabled[i]) { |
593 | tmp = RREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i]); | ||
594 | if (REG_GET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE) != 3) { | ||
595 | tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE, 3); | ||
596 | WREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i], tmp); | ||
597 | } | ||
598 | tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]); | ||
599 | if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK)) { | ||
600 | tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 0); | ||
601 | WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp); | ||
602 | } | ||
603 | tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]); | ||
604 | if (REG_GET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK)) { | ||
605 | tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK, 0); | ||
606 | WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp); | ||
607 | } | ||
608 | for (j = 0; j < adev->usec_timeout; j++) { | ||
609 | tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]); | ||
610 | if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING) == 0) | ||
611 | break; | ||
612 | udelay(1); | ||
613 | } | ||
614 | tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]); | 569 | tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]); |
615 | tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0); | 570 | tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0); |
616 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); | ||
617 | WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp); | 571 | WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp); |
618 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
619 | /* wait for the next frame */ | ||
620 | frame_count = amdgpu_display_vblank_get_counter(adev, i); | ||
621 | for (j = 0; j < adev->usec_timeout; j++) { | ||
622 | if (amdgpu_display_vblank_get_counter(adev, i) != frame_count) | ||
623 | break; | ||
624 | udelay(1); | ||
625 | } | ||
626 | } | 572 | } |
573 | mdelay(20); | ||
627 | } | 574 | } |
628 | 575 | ||
629 | WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start)); | 576 | WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index fc8ff4d3ccf8..f6bd9465dbdc 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
@@ -1583,9 +1583,15 @@ static void gfx_v7_0_tiling_mode_table_init(struct amdgpu_device *adev) | |||
1583 | * registers are instanced per SE or SH. 0xffffffff means | 1583 | * registers are instanced per SE or SH. 0xffffffff means |
1584 | * broadcast to all SEs or SHs (CIK). | 1584 | * broadcast to all SEs or SHs (CIK). |
1585 | */ | 1585 | */ |
1586 | void gfx_v7_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num) | 1586 | static void gfx_v7_0_select_se_sh(struct amdgpu_device *adev, |
1587 | u32 se_num, u32 sh_num, u32 instance) | ||
1587 | { | 1588 | { |
1588 | u32 data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK; | 1589 | u32 data; |
1590 | |||
1591 | if (instance == 0xffffffff) | ||
1592 | data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1); | ||
1593 | else | ||
1594 | data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_INDEX, instance); | ||
1589 | 1595 | ||
1590 | if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) | 1596 | if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) |
1591 | data |= GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | | 1597 | data |= GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | |
@@ -1659,13 +1665,13 @@ static void gfx_v7_0_setup_rb(struct amdgpu_device *adev) | |||
1659 | mutex_lock(&adev->grbm_idx_mutex); | 1665 | mutex_lock(&adev->grbm_idx_mutex); |
1660 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { | 1666 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { |
1661 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { | 1667 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { |
1662 | gfx_v7_0_select_se_sh(adev, i, j); | 1668 | gfx_v7_0_select_se_sh(adev, i, j, 0xffffffff); |
1663 | data = gfx_v7_0_get_rb_active_bitmap(adev); | 1669 | data = gfx_v7_0_get_rb_active_bitmap(adev); |
1664 | active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) * | 1670 | active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) * |
1665 | rb_bitmap_width_per_sh); | 1671 | rb_bitmap_width_per_sh); |
1666 | } | 1672 | } |
1667 | } | 1673 | } |
1668 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 1674 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
1669 | mutex_unlock(&adev->grbm_idx_mutex); | 1675 | mutex_unlock(&adev->grbm_idx_mutex); |
1670 | 1676 | ||
1671 | adev->gfx.config.backend_enable_mask = active_rbs; | 1677 | adev->gfx.config.backend_enable_mask = active_rbs; |
@@ -1746,7 +1752,7 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev) | |||
1746 | * making sure that the following register writes will be broadcasted | 1752 | * making sure that the following register writes will be broadcasted |
1747 | * to all the shaders | 1753 | * to all the shaders |
1748 | */ | 1754 | */ |
1749 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 1755 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
1750 | 1756 | ||
1751 | /* XXX SH_MEM regs */ | 1757 | /* XXX SH_MEM regs */ |
1752 | /* where to put LDS, scratch, GPUVM in FSA64 space */ | 1758 | /* where to put LDS, scratch, GPUVM in FSA64 space */ |
@@ -2050,17 +2056,6 @@ static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | |||
2050 | unsigned vm_id, bool ctx_switch) | 2056 | unsigned vm_id, bool ctx_switch) |
2051 | { | 2057 | { |
2052 | u32 header, control = 0; | 2058 | u32 header, control = 0; |
2053 | u32 next_rptr = ring->wptr + 5; | ||
2054 | |||
2055 | if (ctx_switch) | ||
2056 | next_rptr += 2; | ||
2057 | |||
2058 | next_rptr += 4; | ||
2059 | amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | ||
2060 | amdgpu_ring_write(ring, WRITE_DATA_DST_SEL(5) | WR_CONFIRM); | ||
2061 | amdgpu_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
2062 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); | ||
2063 | amdgpu_ring_write(ring, next_rptr); | ||
2064 | 2059 | ||
2065 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ | 2060 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ |
2066 | if (ctx_switch) { | 2061 | if (ctx_switch) { |
@@ -2089,22 +2084,9 @@ static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring, | |||
2089 | struct amdgpu_ib *ib, | 2084 | struct amdgpu_ib *ib, |
2090 | unsigned vm_id, bool ctx_switch) | 2085 | unsigned vm_id, bool ctx_switch) |
2091 | { | 2086 | { |
2092 | u32 header, control = 0; | 2087 | u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vm_id << 24); |
2093 | u32 next_rptr = ring->wptr + 5; | ||
2094 | 2088 | ||
2095 | control |= INDIRECT_BUFFER_VALID; | 2089 | amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
2096 | next_rptr += 4; | ||
2097 | amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | ||
2098 | amdgpu_ring_write(ring, WRITE_DATA_DST_SEL(5) | WR_CONFIRM); | ||
2099 | amdgpu_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
2100 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); | ||
2101 | amdgpu_ring_write(ring, next_rptr); | ||
2102 | |||
2103 | header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); | ||
2104 | |||
2105 | control |= ib->length_dw | (vm_id << 24); | ||
2106 | |||
2107 | amdgpu_ring_write(ring, header); | ||
2108 | amdgpu_ring_write(ring, | 2090 | amdgpu_ring_write(ring, |
2109 | #ifdef __BIG_ENDIAN | 2091 | #ifdef __BIG_ENDIAN |
2110 | (2 << 0) | | 2092 | (2 << 0) | |
@@ -3221,7 +3203,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev) | |||
3221 | } | 3203 | } |
3222 | } | 3204 | } |
3223 | adev->gfx.rlc.cs_data = ci_cs_data; | 3205 | adev->gfx.rlc.cs_data = ci_cs_data; |
3224 | adev->gfx.rlc.cp_table_size = CP_ME_TABLE_SIZE * 5 * 4; | 3206 | adev->gfx.rlc.cp_table_size = ALIGN(CP_ME_TABLE_SIZE * 5 * 4, 2048); /* CP JT */ |
3207 | adev->gfx.rlc.cp_table_size += 64 * 1024; /* GDS */ | ||
3225 | 3208 | ||
3226 | src_ptr = adev->gfx.rlc.reg_list; | 3209 | src_ptr = adev->gfx.rlc.reg_list; |
3227 | dws = adev->gfx.rlc.reg_list_size; | 3210 | dws = adev->gfx.rlc.reg_list_size; |
@@ -3379,7 +3362,7 @@ static void gfx_v7_0_wait_for_rlc_serdes(struct amdgpu_device *adev) | |||
3379 | mutex_lock(&adev->grbm_idx_mutex); | 3362 | mutex_lock(&adev->grbm_idx_mutex); |
3380 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { | 3363 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { |
3381 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { | 3364 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { |
3382 | gfx_v7_0_select_se_sh(adev, i, j); | 3365 | gfx_v7_0_select_se_sh(adev, i, j, 0xffffffff); |
3383 | for (k = 0; k < adev->usec_timeout; k++) { | 3366 | for (k = 0; k < adev->usec_timeout; k++) { |
3384 | if (RREG32(mmRLC_SERDES_CU_MASTER_BUSY) == 0) | 3367 | if (RREG32(mmRLC_SERDES_CU_MASTER_BUSY) == 0) |
3385 | break; | 3368 | break; |
@@ -3387,7 +3370,7 @@ static void gfx_v7_0_wait_for_rlc_serdes(struct amdgpu_device *adev) | |||
3387 | } | 3370 | } |
3388 | } | 3371 | } |
3389 | } | 3372 | } |
3390 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 3373 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
3391 | mutex_unlock(&adev->grbm_idx_mutex); | 3374 | mutex_unlock(&adev->grbm_idx_mutex); |
3392 | 3375 | ||
3393 | mask = RLC_SERDES_NONCU_MASTER_BUSY__SE_MASTER_BUSY_MASK | | 3376 | mask = RLC_SERDES_NONCU_MASTER_BUSY__SE_MASTER_BUSY_MASK | |
@@ -3434,7 +3417,7 @@ static u32 gfx_v7_0_halt_rlc(struct amdgpu_device *adev) | |||
3434 | return orig; | 3417 | return orig; |
3435 | } | 3418 | } |
3436 | 3419 | ||
3437 | void gfx_v7_0_enter_rlc_safe_mode(struct amdgpu_device *adev) | 3420 | static void gfx_v7_0_enter_rlc_safe_mode(struct amdgpu_device *adev) |
3438 | { | 3421 | { |
3439 | u32 tmp, i, mask; | 3422 | u32 tmp, i, mask; |
3440 | 3423 | ||
@@ -3456,7 +3439,7 @@ void gfx_v7_0_enter_rlc_safe_mode(struct amdgpu_device *adev) | |||
3456 | } | 3439 | } |
3457 | } | 3440 | } |
3458 | 3441 | ||
3459 | void gfx_v7_0_exit_rlc_safe_mode(struct amdgpu_device *adev) | 3442 | static void gfx_v7_0_exit_rlc_safe_mode(struct amdgpu_device *adev) |
3460 | { | 3443 | { |
3461 | u32 tmp; | 3444 | u32 tmp; |
3462 | 3445 | ||
@@ -3471,7 +3454,7 @@ void gfx_v7_0_exit_rlc_safe_mode(struct amdgpu_device *adev) | |||
3471 | * | 3454 | * |
3472 | * Halt the RLC ME (MicroEngine) (CIK). | 3455 | * Halt the RLC ME (MicroEngine) (CIK). |
3473 | */ | 3456 | */ |
3474 | void gfx_v7_0_rlc_stop(struct amdgpu_device *adev) | 3457 | static void gfx_v7_0_rlc_stop(struct amdgpu_device *adev) |
3475 | { | 3458 | { |
3476 | WREG32(mmRLC_CNTL, 0); | 3459 | WREG32(mmRLC_CNTL, 0); |
3477 | 3460 | ||
@@ -3547,7 +3530,7 @@ static int gfx_v7_0_rlc_resume(struct amdgpu_device *adev) | |||
3547 | WREG32(mmRLC_LB_CNTR_MAX, 0x00008000); | 3530 | WREG32(mmRLC_LB_CNTR_MAX, 0x00008000); |
3548 | 3531 | ||
3549 | mutex_lock(&adev->grbm_idx_mutex); | 3532 | mutex_lock(&adev->grbm_idx_mutex); |
3550 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 3533 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
3551 | WREG32(mmRLC_LB_INIT_CU_MASK, 0xffffffff); | 3534 | WREG32(mmRLC_LB_INIT_CU_MASK, 0xffffffff); |
3552 | WREG32(mmRLC_LB_PARAMS, 0x00600408); | 3535 | WREG32(mmRLC_LB_PARAMS, 0x00600408); |
3553 | WREG32(mmRLC_LB_CNTL, 0x80000004); | 3536 | WREG32(mmRLC_LB_CNTL, 0x80000004); |
@@ -3587,7 +3570,7 @@ static void gfx_v7_0_enable_cgcg(struct amdgpu_device *adev, bool enable) | |||
3587 | tmp = gfx_v7_0_halt_rlc(adev); | 3570 | tmp = gfx_v7_0_halt_rlc(adev); |
3588 | 3571 | ||
3589 | mutex_lock(&adev->grbm_idx_mutex); | 3572 | mutex_lock(&adev->grbm_idx_mutex); |
3590 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 3573 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
3591 | WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); | 3574 | WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); |
3592 | WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); | 3575 | WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); |
3593 | tmp2 = RLC_SERDES_WR_CTRL__BPM_ADDR_MASK | | 3576 | tmp2 = RLC_SERDES_WR_CTRL__BPM_ADDR_MASK | |
@@ -3638,7 +3621,7 @@ static void gfx_v7_0_enable_mgcg(struct amdgpu_device *adev, bool enable) | |||
3638 | tmp = gfx_v7_0_halt_rlc(adev); | 3621 | tmp = gfx_v7_0_halt_rlc(adev); |
3639 | 3622 | ||
3640 | mutex_lock(&adev->grbm_idx_mutex); | 3623 | mutex_lock(&adev->grbm_idx_mutex); |
3641 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 3624 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
3642 | WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); | 3625 | WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); |
3643 | WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); | 3626 | WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); |
3644 | data = RLC_SERDES_WR_CTRL__BPM_ADDR_MASK | | 3627 | data = RLC_SERDES_WR_CTRL__BPM_ADDR_MASK | |
@@ -3689,7 +3672,7 @@ static void gfx_v7_0_enable_mgcg(struct amdgpu_device *adev, bool enable) | |||
3689 | tmp = gfx_v7_0_halt_rlc(adev); | 3672 | tmp = gfx_v7_0_halt_rlc(adev); |
3690 | 3673 | ||
3691 | mutex_lock(&adev->grbm_idx_mutex); | 3674 | mutex_lock(&adev->grbm_idx_mutex); |
3692 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 3675 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
3693 | WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); | 3676 | WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); |
3694 | WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); | 3677 | WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); |
3695 | data = RLC_SERDES_WR_CTRL__BPM_ADDR_MASK | RLC_SERDES_WR_CTRL__MGCG_OVERRIDE_1_MASK; | 3678 | data = RLC_SERDES_WR_CTRL__BPM_ADDR_MASK | RLC_SERDES_WR_CTRL__MGCG_OVERRIDE_1_MASK; |
@@ -3867,6 +3850,20 @@ static void gfx_v7_0_enable_gfx_cgpg(struct amdgpu_device *adev, | |||
3867 | } | 3850 | } |
3868 | } | 3851 | } |
3869 | 3852 | ||
3853 | static void gfx_v7_0_set_user_cu_inactive_bitmap(struct amdgpu_device *adev, | ||
3854 | u32 bitmap) | ||
3855 | { | ||
3856 | u32 data; | ||
3857 | |||
3858 | if (!bitmap) | ||
3859 | return; | ||
3860 | |||
3861 | data = bitmap << GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT; | ||
3862 | data &= GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK; | ||
3863 | |||
3864 | WREG32(mmGC_USER_SHADER_ARRAY_CONFIG, data); | ||
3865 | } | ||
3866 | |||
3870 | static u32 gfx_v7_0_get_cu_active_bitmap(struct amdgpu_device *adev) | 3867 | static u32 gfx_v7_0_get_cu_active_bitmap(struct amdgpu_device *adev) |
3871 | { | 3868 | { |
3872 | u32 data, mask; | 3869 | u32 data, mask; |
@@ -4123,7 +4120,7 @@ static void gfx_v7_0_fini_pg(struct amdgpu_device *adev) | |||
4123 | * Fetches a GPU clock counter snapshot (SI). | 4120 | * Fetches a GPU clock counter snapshot (SI). |
4124 | * Returns the 64 bit clock counter snapshot. | 4121 | * Returns the 64 bit clock counter snapshot. |
4125 | */ | 4122 | */ |
4126 | uint64_t gfx_v7_0_get_gpu_clock_counter(struct amdgpu_device *adev) | 4123 | static uint64_t gfx_v7_0_get_gpu_clock_counter(struct amdgpu_device *adev) |
4127 | { | 4124 | { |
4128 | uint64_t clock; | 4125 | uint64_t clock; |
4129 | 4126 | ||
@@ -4183,12 +4180,24 @@ static void gfx_v7_0_ring_emit_gds_switch(struct amdgpu_ring *ring, | |||
4183 | amdgpu_ring_write(ring, (1 << (oa_size + oa_base)) - (1 << oa_base)); | 4180 | amdgpu_ring_write(ring, (1 << (oa_size + oa_base)) - (1 << oa_base)); |
4184 | } | 4181 | } |
4185 | 4182 | ||
4183 | static const struct amdgpu_gfx_funcs gfx_v7_0_gfx_funcs = { | ||
4184 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, | ||
4185 | .select_se_sh = &gfx_v7_0_select_se_sh, | ||
4186 | }; | ||
4187 | |||
4188 | static const struct amdgpu_rlc_funcs gfx_v7_0_rlc_funcs = { | ||
4189 | .enter_safe_mode = gfx_v7_0_enter_rlc_safe_mode, | ||
4190 | .exit_safe_mode = gfx_v7_0_exit_rlc_safe_mode | ||
4191 | }; | ||
4192 | |||
4186 | static int gfx_v7_0_early_init(void *handle) | 4193 | static int gfx_v7_0_early_init(void *handle) |
4187 | { | 4194 | { |
4188 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 4195 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
4189 | 4196 | ||
4190 | adev->gfx.num_gfx_rings = GFX7_NUM_GFX_RINGS; | 4197 | adev->gfx.num_gfx_rings = GFX7_NUM_GFX_RINGS; |
4191 | adev->gfx.num_compute_rings = GFX7_NUM_COMPUTE_RINGS; | 4198 | adev->gfx.num_compute_rings = GFX7_NUM_COMPUTE_RINGS; |
4199 | adev->gfx.funcs = &gfx_v7_0_gfx_funcs; | ||
4200 | adev->gfx.rlc.funcs = &gfx_v7_0_rlc_funcs; | ||
4192 | gfx_v7_0_set_ring_funcs(adev); | 4201 | gfx_v7_0_set_ring_funcs(adev); |
4193 | gfx_v7_0_set_irq_funcs(adev); | 4202 | gfx_v7_0_set_irq_funcs(adev); |
4194 | gfx_v7_0_set_gds_init(adev); | 4203 | gfx_v7_0_set_gds_init(adev); |
@@ -5032,16 +5041,22 @@ static void gfx_v7_0_get_cu_info(struct amdgpu_device *adev) | |||
5032 | int i, j, k, counter, active_cu_number = 0; | 5041 | int i, j, k, counter, active_cu_number = 0; |
5033 | u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; | 5042 | u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; |
5034 | struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info; | 5043 | struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info; |
5044 | unsigned disable_masks[4 * 2]; | ||
5035 | 5045 | ||
5036 | memset(cu_info, 0, sizeof(*cu_info)); | 5046 | memset(cu_info, 0, sizeof(*cu_info)); |
5037 | 5047 | ||
5048 | amdgpu_gfx_parse_disable_cu(disable_masks, 4, 2); | ||
5049 | |||
5038 | mutex_lock(&adev->grbm_idx_mutex); | 5050 | mutex_lock(&adev->grbm_idx_mutex); |
5039 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { | 5051 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { |
5040 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { | 5052 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { |
5041 | mask = 1; | 5053 | mask = 1; |
5042 | ao_bitmap = 0; | 5054 | ao_bitmap = 0; |
5043 | counter = 0; | 5055 | counter = 0; |
5044 | gfx_v7_0_select_se_sh(adev, i, j); | 5056 | gfx_v7_0_select_se_sh(adev, i, j, 0xffffffff); |
5057 | if (i < 4 && j < 2) | ||
5058 | gfx_v7_0_set_user_cu_inactive_bitmap( | ||
5059 | adev, disable_masks[i * 2 + j]); | ||
5045 | bitmap = gfx_v7_0_get_cu_active_bitmap(adev); | 5060 | bitmap = gfx_v7_0_get_cu_active_bitmap(adev); |
5046 | cu_info->bitmap[i][j] = bitmap; | 5061 | cu_info->bitmap[i][j] = bitmap; |
5047 | 5062 | ||
@@ -5057,7 +5072,7 @@ static void gfx_v7_0_get_cu_info(struct amdgpu_device *adev) | |||
5057 | ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); | 5072 | ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); |
5058 | } | 5073 | } |
5059 | } | 5074 | } |
5060 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 5075 | gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
5061 | mutex_unlock(&adev->grbm_idx_mutex); | 5076 | mutex_unlock(&adev->grbm_idx_mutex); |
5062 | 5077 | ||
5063 | cu_info->number = active_cu_number; | 5078 | cu_info->number = active_cu_number; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.h b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.h index e747aa935c88..94e3ea147c26 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.h +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.h | |||
@@ -26,11 +26,4 @@ | |||
26 | 26 | ||
27 | extern const struct amd_ip_funcs gfx_v7_0_ip_funcs; | 27 | extern const struct amd_ip_funcs gfx_v7_0_ip_funcs; |
28 | 28 | ||
29 | /* XXX these shouldn't be exported */ | ||
30 | void gfx_v7_0_enter_rlc_safe_mode(struct amdgpu_device *adev); | ||
31 | void gfx_v7_0_exit_rlc_safe_mode(struct amdgpu_device *adev); | ||
32 | void gfx_v7_0_rlc_stop(struct amdgpu_device *adev); | ||
33 | uint64_t gfx_v7_0_get_gpu_clock_counter(struct amdgpu_device *adev); | ||
34 | void gfx_v7_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num); | ||
35 | |||
36 | #endif | 29 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 1a5cbaff1e34..c30b6ac25d89 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
@@ -1150,6 +1150,71 @@ static void gfx_v8_0_get_csb_buffer(struct amdgpu_device *adev, | |||
1150 | buffer[count++] = cpu_to_le32(0); | 1150 | buffer[count++] = cpu_to_le32(0); |
1151 | } | 1151 | } |
1152 | 1152 | ||
1153 | static void cz_init_cp_jump_table(struct amdgpu_device *adev) | ||
1154 | { | ||
1155 | const __le32 *fw_data; | ||
1156 | volatile u32 *dst_ptr; | ||
1157 | int me, i, max_me = 4; | ||
1158 | u32 bo_offset = 0; | ||
1159 | u32 table_offset, table_size; | ||
1160 | |||
1161 | if (adev->asic_type == CHIP_CARRIZO) | ||
1162 | max_me = 5; | ||
1163 | |||
1164 | /* write the cp table buffer */ | ||
1165 | dst_ptr = adev->gfx.rlc.cp_table_ptr; | ||
1166 | for (me = 0; me < max_me; me++) { | ||
1167 | if (me == 0) { | ||
1168 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1169 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data; | ||
1170 | fw_data = (const __le32 *) | ||
1171 | (adev->gfx.ce_fw->data + | ||
1172 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1173 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1174 | table_size = le32_to_cpu(hdr->jt_size); | ||
1175 | } else if (me == 1) { | ||
1176 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1177 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data; | ||
1178 | fw_data = (const __le32 *) | ||
1179 | (adev->gfx.pfp_fw->data + | ||
1180 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1181 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1182 | table_size = le32_to_cpu(hdr->jt_size); | ||
1183 | } else if (me == 2) { | ||
1184 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1185 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data; | ||
1186 | fw_data = (const __le32 *) | ||
1187 | (adev->gfx.me_fw->data + | ||
1188 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1189 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1190 | table_size = le32_to_cpu(hdr->jt_size); | ||
1191 | } else if (me == 3) { | ||
1192 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1193 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; | ||
1194 | fw_data = (const __le32 *) | ||
1195 | (adev->gfx.mec_fw->data + | ||
1196 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1197 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1198 | table_size = le32_to_cpu(hdr->jt_size); | ||
1199 | } else if (me == 4) { | ||
1200 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1201 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; | ||
1202 | fw_data = (const __le32 *) | ||
1203 | (adev->gfx.mec2_fw->data + | ||
1204 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1205 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1206 | table_size = le32_to_cpu(hdr->jt_size); | ||
1207 | } | ||
1208 | |||
1209 | for (i = 0; i < table_size; i ++) { | ||
1210 | dst_ptr[bo_offset + i] = | ||
1211 | cpu_to_le32(le32_to_cpu(fw_data[table_offset + i])); | ||
1212 | } | ||
1213 | |||
1214 | bo_offset += table_size; | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1153 | static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev) | 1218 | static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev) |
1154 | { | 1219 | { |
1155 | int r; | 1220 | int r; |
@@ -1165,6 +1230,18 @@ static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev) | |||
1165 | amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj); | 1230 | amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj); |
1166 | adev->gfx.rlc.clear_state_obj = NULL; | 1231 | adev->gfx.rlc.clear_state_obj = NULL; |
1167 | } | 1232 | } |
1233 | |||
1234 | /* jump table block */ | ||
1235 | if (adev->gfx.rlc.cp_table_obj) { | ||
1236 | r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, false); | ||
1237 | if (unlikely(r != 0)) | ||
1238 | dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r); | ||
1239 | amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj); | ||
1240 | amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); | ||
1241 | |||
1242 | amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj); | ||
1243 | adev->gfx.rlc.cp_table_obj = NULL; | ||
1244 | } | ||
1168 | } | 1245 | } |
1169 | 1246 | ||
1170 | static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) | 1247 | static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) |
@@ -1221,6 +1298,46 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) | |||
1221 | amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); | 1298 | amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); |
1222 | } | 1299 | } |
1223 | 1300 | ||
1301 | if ((adev->asic_type == CHIP_CARRIZO) || | ||
1302 | (adev->asic_type == CHIP_STONEY)) { | ||
1303 | adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */ | ||
1304 | if (adev->gfx.rlc.cp_table_obj == NULL) { | ||
1305 | r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true, | ||
1306 | AMDGPU_GEM_DOMAIN_VRAM, | ||
1307 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, | ||
1308 | NULL, NULL, | ||
1309 | &adev->gfx.rlc.cp_table_obj); | ||
1310 | if (r) { | ||
1311 | dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r); | ||
1312 | return r; | ||
1313 | } | ||
1314 | } | ||
1315 | |||
1316 | r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, false); | ||
1317 | if (unlikely(r != 0)) { | ||
1318 | dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r); | ||
1319 | return r; | ||
1320 | } | ||
1321 | r = amdgpu_bo_pin(adev->gfx.rlc.cp_table_obj, AMDGPU_GEM_DOMAIN_VRAM, | ||
1322 | &adev->gfx.rlc.cp_table_gpu_addr); | ||
1323 | if (r) { | ||
1324 | amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); | ||
1325 | dev_warn(adev->dev, "(%d) pin RLC cp_table bo failed\n", r); | ||
1326 | return r; | ||
1327 | } | ||
1328 | r = amdgpu_bo_kmap(adev->gfx.rlc.cp_table_obj, (void **)&adev->gfx.rlc.cp_table_ptr); | ||
1329 | if (r) { | ||
1330 | dev_warn(adev->dev, "(%d) map RLC cp table bo failed\n", r); | ||
1331 | return r; | ||
1332 | } | ||
1333 | |||
1334 | cz_init_cp_jump_table(adev); | ||
1335 | |||
1336 | amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj); | ||
1337 | amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); | ||
1338 | |||
1339 | } | ||
1340 | |||
1224 | return 0; | 1341 | return 0; |
1225 | } | 1342 | } |
1226 | 1343 | ||
@@ -3329,9 +3446,15 @@ static void gfx_v8_0_tiling_mode_table_init(struct amdgpu_device *adev) | |||
3329 | } | 3446 | } |
3330 | } | 3447 | } |
3331 | 3448 | ||
3332 | void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num) | 3449 | static void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, |
3450 | u32 se_num, u32 sh_num, u32 instance) | ||
3333 | { | 3451 | { |
3334 | u32 data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1); | 3452 | u32 data; |
3453 | |||
3454 | if (instance == 0xffffffff) | ||
3455 | data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1); | ||
3456 | else | ||
3457 | data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_INDEX, instance); | ||
3335 | 3458 | ||
3336 | if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) { | 3459 | if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) { |
3337 | data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1); | 3460 | data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1); |
@@ -3381,13 +3504,13 @@ static void gfx_v8_0_setup_rb(struct amdgpu_device *adev) | |||
3381 | mutex_lock(&adev->grbm_idx_mutex); | 3504 | mutex_lock(&adev->grbm_idx_mutex); |
3382 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { | 3505 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { |
3383 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { | 3506 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { |
3384 | gfx_v8_0_select_se_sh(adev, i, j); | 3507 | gfx_v8_0_select_se_sh(adev, i, j, 0xffffffff); |
3385 | data = gfx_v8_0_get_rb_active_bitmap(adev); | 3508 | data = gfx_v8_0_get_rb_active_bitmap(adev); |
3386 | active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) * | 3509 | active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) * |
3387 | rb_bitmap_width_per_sh); | 3510 | rb_bitmap_width_per_sh); |
3388 | } | 3511 | } |
3389 | } | 3512 | } |
3390 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 3513 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
3391 | mutex_unlock(&adev->grbm_idx_mutex); | 3514 | mutex_unlock(&adev->grbm_idx_mutex); |
3392 | 3515 | ||
3393 | adev->gfx.config.backend_enable_mask = active_rbs; | 3516 | adev->gfx.config.backend_enable_mask = active_rbs; |
@@ -3491,7 +3614,7 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev) | |||
3491 | * making sure that the following register writes will be broadcasted | 3614 | * making sure that the following register writes will be broadcasted |
3492 | * to all the shaders | 3615 | * to all the shaders |
3493 | */ | 3616 | */ |
3494 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 3617 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
3495 | 3618 | ||
3496 | WREG32(mmPA_SC_FIFO_SIZE, | 3619 | WREG32(mmPA_SC_FIFO_SIZE, |
3497 | (adev->gfx.config.sc_prim_fifo_size_frontend << | 3620 | (adev->gfx.config.sc_prim_fifo_size_frontend << |
@@ -3514,7 +3637,7 @@ static void gfx_v8_0_wait_for_rlc_serdes(struct amdgpu_device *adev) | |||
3514 | mutex_lock(&adev->grbm_idx_mutex); | 3637 | mutex_lock(&adev->grbm_idx_mutex); |
3515 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { | 3638 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { |
3516 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { | 3639 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { |
3517 | gfx_v8_0_select_se_sh(adev, i, j); | 3640 | gfx_v8_0_select_se_sh(adev, i, j, 0xffffffff); |
3518 | for (k = 0; k < adev->usec_timeout; k++) { | 3641 | for (k = 0; k < adev->usec_timeout; k++) { |
3519 | if (RREG32(mmRLC_SERDES_CU_MASTER_BUSY) == 0) | 3642 | if (RREG32(mmRLC_SERDES_CU_MASTER_BUSY) == 0) |
3520 | break; | 3643 | break; |
@@ -3522,7 +3645,7 @@ static void gfx_v8_0_wait_for_rlc_serdes(struct amdgpu_device *adev) | |||
3522 | } | 3645 | } |
3523 | } | 3646 | } |
3524 | } | 3647 | } |
3525 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 3648 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
3526 | mutex_unlock(&adev->grbm_idx_mutex); | 3649 | mutex_unlock(&adev->grbm_idx_mutex); |
3527 | 3650 | ||
3528 | mask = RLC_SERDES_NONCU_MASTER_BUSY__SE_MASTER_BUSY_MASK | | 3651 | mask = RLC_SERDES_NONCU_MASTER_BUSY__SE_MASTER_BUSY_MASK | |
@@ -3683,13 +3806,13 @@ static void gfx_v8_0_enable_save_restore_machine(struct amdgpu_device *adev) | |||
3683 | WREG32(mmRLC_SRM_CNTL, data); | 3806 | WREG32(mmRLC_SRM_CNTL, data); |
3684 | } | 3807 | } |
3685 | 3808 | ||
3686 | static void polaris11_init_power_gating(struct amdgpu_device *adev) | 3809 | static void gfx_v8_0_init_power_gating(struct amdgpu_device *adev) |
3687 | { | 3810 | { |
3688 | uint32_t data; | 3811 | uint32_t data; |
3689 | 3812 | ||
3690 | if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | | 3813 | if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | |
3691 | AMD_PG_SUPPORT_GFX_SMG | | 3814 | AMD_PG_SUPPORT_GFX_SMG | |
3692 | AMD_PG_SUPPORT_GFX_DMG)) { | 3815 | AMD_PG_SUPPORT_GFX_DMG)) { |
3693 | data = RREG32(mmCP_RB_WPTR_POLL_CNTL); | 3816 | data = RREG32(mmCP_RB_WPTR_POLL_CNTL); |
3694 | data &= ~CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT_MASK; | 3817 | data &= ~CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT_MASK; |
3695 | data |= (0x60 << CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT__SHIFT); | 3818 | data |= (0x60 << CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT__SHIFT); |
@@ -3714,6 +3837,53 @@ static void polaris11_init_power_gating(struct amdgpu_device *adev) | |||
3714 | } | 3837 | } |
3715 | } | 3838 | } |
3716 | 3839 | ||
3840 | static void cz_enable_sck_slow_down_on_power_up(struct amdgpu_device *adev, | ||
3841 | bool enable) | ||
3842 | { | ||
3843 | u32 data, orig; | ||
3844 | |||
3845 | orig = data = RREG32(mmRLC_PG_CNTL); | ||
3846 | |||
3847 | if (enable) | ||
3848 | data |= RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK; | ||
3849 | else | ||
3850 | data &= ~RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK; | ||
3851 | |||
3852 | if (orig != data) | ||
3853 | WREG32(mmRLC_PG_CNTL, data); | ||
3854 | } | ||
3855 | |||
3856 | static void cz_enable_sck_slow_down_on_power_down(struct amdgpu_device *adev, | ||
3857 | bool enable) | ||
3858 | { | ||
3859 | u32 data, orig; | ||
3860 | |||
3861 | orig = data = RREG32(mmRLC_PG_CNTL); | ||
3862 | |||
3863 | if (enable) | ||
3864 | data |= RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK; | ||
3865 | else | ||
3866 | data &= ~RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK; | ||
3867 | |||
3868 | if (orig != data) | ||
3869 | WREG32(mmRLC_PG_CNTL, data); | ||
3870 | } | ||
3871 | |||
3872 | static void cz_enable_cp_power_gating(struct amdgpu_device *adev, bool enable) | ||
3873 | { | ||
3874 | u32 data, orig; | ||
3875 | |||
3876 | orig = data = RREG32(mmRLC_PG_CNTL); | ||
3877 | |||
3878 | if (enable) | ||
3879 | data &= ~RLC_PG_CNTL__CP_PG_DISABLE_MASK; | ||
3880 | else | ||
3881 | data |= RLC_PG_CNTL__CP_PG_DISABLE_MASK; | ||
3882 | |||
3883 | if (orig != data) | ||
3884 | WREG32(mmRLC_PG_CNTL, data); | ||
3885 | } | ||
3886 | |||
3717 | static void gfx_v8_0_init_pg(struct amdgpu_device *adev) | 3887 | static void gfx_v8_0_init_pg(struct amdgpu_device *adev) |
3718 | { | 3888 | { |
3719 | if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | | 3889 | if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | |
@@ -3726,8 +3896,25 @@ static void gfx_v8_0_init_pg(struct amdgpu_device *adev) | |||
3726 | gfx_v8_0_init_save_restore_list(adev); | 3896 | gfx_v8_0_init_save_restore_list(adev); |
3727 | gfx_v8_0_enable_save_restore_machine(adev); | 3897 | gfx_v8_0_enable_save_restore_machine(adev); |
3728 | 3898 | ||
3729 | if (adev->asic_type == CHIP_POLARIS11) | 3899 | if ((adev->asic_type == CHIP_CARRIZO) || |
3730 | polaris11_init_power_gating(adev); | 3900 | (adev->asic_type == CHIP_STONEY)) { |
3901 | WREG32(mmRLC_JUMP_TABLE_RESTORE, adev->gfx.rlc.cp_table_gpu_addr >> 8); | ||
3902 | gfx_v8_0_init_power_gating(adev); | ||
3903 | WREG32(mmRLC_PG_ALWAYS_ON_CU_MASK, adev->gfx.cu_info.ao_cu_mask); | ||
3904 | if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) { | ||
3905 | cz_enable_sck_slow_down_on_power_up(adev, true); | ||
3906 | cz_enable_sck_slow_down_on_power_down(adev, true); | ||
3907 | } else { | ||
3908 | cz_enable_sck_slow_down_on_power_up(adev, false); | ||
3909 | cz_enable_sck_slow_down_on_power_down(adev, false); | ||
3910 | } | ||
3911 | if (adev->pg_flags & AMD_PG_SUPPORT_CP) | ||
3912 | cz_enable_cp_power_gating(adev, true); | ||
3913 | else | ||
3914 | cz_enable_cp_power_gating(adev, false); | ||
3915 | } else if (adev->asic_type == CHIP_POLARIS11) { | ||
3916 | gfx_v8_0_init_power_gating(adev); | ||
3917 | } | ||
3731 | } | 3918 | } |
3732 | } | 3919 | } |
3733 | 3920 | ||
@@ -4966,7 +5153,7 @@ static int gfx_v8_0_soft_reset(void *handle) | |||
4966 | * Fetches a GPU clock counter snapshot. | 5153 | * Fetches a GPU clock counter snapshot. |
4967 | * Returns the 64 bit clock counter snapshot. | 5154 | * Returns the 64 bit clock counter snapshot. |
4968 | */ | 5155 | */ |
4969 | uint64_t gfx_v8_0_get_gpu_clock_counter(struct amdgpu_device *adev) | 5156 | static uint64_t gfx_v8_0_get_gpu_clock_counter(struct amdgpu_device *adev) |
4970 | { | 5157 | { |
4971 | uint64_t clock; | 5158 | uint64_t clock; |
4972 | 5159 | ||
@@ -5026,12 +5213,18 @@ static void gfx_v8_0_ring_emit_gds_switch(struct amdgpu_ring *ring, | |||
5026 | amdgpu_ring_write(ring, (1 << (oa_size + oa_base)) - (1 << oa_base)); | 5213 | amdgpu_ring_write(ring, (1 << (oa_size + oa_base)) - (1 << oa_base)); |
5027 | } | 5214 | } |
5028 | 5215 | ||
5216 | static const struct amdgpu_gfx_funcs gfx_v8_0_gfx_funcs = { | ||
5217 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, | ||
5218 | .select_se_sh = &gfx_v8_0_select_se_sh, | ||
5219 | }; | ||
5220 | |||
5029 | static int gfx_v8_0_early_init(void *handle) | 5221 | static int gfx_v8_0_early_init(void *handle) |
5030 | { | 5222 | { |
5031 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 5223 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
5032 | 5224 | ||
5033 | adev->gfx.num_gfx_rings = GFX8_NUM_GFX_RINGS; | 5225 | adev->gfx.num_gfx_rings = GFX8_NUM_GFX_RINGS; |
5034 | adev->gfx.num_compute_rings = GFX8_NUM_COMPUTE_RINGS; | 5226 | adev->gfx.num_compute_rings = GFX8_NUM_COMPUTE_RINGS; |
5227 | adev->gfx.funcs = &gfx_v8_0_gfx_funcs; | ||
5035 | gfx_v8_0_set_ring_funcs(adev); | 5228 | gfx_v8_0_set_ring_funcs(adev); |
5036 | gfx_v8_0_set_irq_funcs(adev); | 5229 | gfx_v8_0_set_irq_funcs(adev); |
5037 | gfx_v8_0_set_gds_init(adev); | 5230 | gfx_v8_0_set_gds_init(adev); |
@@ -5064,51 +5257,43 @@ static int gfx_v8_0_late_init(void *handle) | |||
5064 | return 0; | 5257 | return 0; |
5065 | } | 5258 | } |
5066 | 5259 | ||
5067 | static void polaris11_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev, | 5260 | static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev, |
5068 | bool enable) | 5261 | bool enable) |
5069 | { | 5262 | { |
5070 | uint32_t data, temp; | 5263 | uint32_t data, temp; |
5071 | 5264 | ||
5072 | /* Send msg to SMU via Powerplay */ | 5265 | if (adev->asic_type == CHIP_POLARIS11) |
5073 | amdgpu_set_powergating_state(adev, | 5266 | /* Send msg to SMU via Powerplay */ |
5074 | AMD_IP_BLOCK_TYPE_SMC, | 5267 | amdgpu_set_powergating_state(adev, |
5075 | enable ? AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE); | 5268 | AMD_IP_BLOCK_TYPE_SMC, |
5269 | enable ? | ||
5270 | AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE); | ||
5076 | 5271 | ||
5077 | if (enable) { | 5272 | temp = data = RREG32(mmRLC_PG_CNTL); |
5078 | /* Enable static MGPG */ | 5273 | /* Enable static MGPG */ |
5079 | temp = data = RREG32(mmRLC_PG_CNTL); | 5274 | if (enable) |
5080 | data |= RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; | 5275 | data |= RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; |
5081 | 5276 | else | |
5082 | if (temp != data) | ||
5083 | WREG32(mmRLC_PG_CNTL, data); | ||
5084 | } else { | ||
5085 | temp = data = RREG32(mmRLC_PG_CNTL); | ||
5086 | data &= ~RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; | 5277 | data &= ~RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; |
5087 | 5278 | ||
5088 | if (temp != data) | 5279 | if (temp != data) |
5089 | WREG32(mmRLC_PG_CNTL, data); | 5280 | WREG32(mmRLC_PG_CNTL, data); |
5090 | } | ||
5091 | } | 5281 | } |
5092 | 5282 | ||
5093 | static void polaris11_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *adev, | 5283 | static void gfx_v8_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *adev, |
5094 | bool enable) | 5284 | bool enable) |
5095 | { | 5285 | { |
5096 | uint32_t data, temp; | 5286 | uint32_t data, temp; |
5097 | 5287 | ||
5098 | if (enable) { | 5288 | temp = data = RREG32(mmRLC_PG_CNTL); |
5099 | /* Enable dynamic MGPG */ | 5289 | /* Enable dynamic MGPG */ |
5100 | temp = data = RREG32(mmRLC_PG_CNTL); | 5290 | if (enable) |
5101 | data |= RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; | 5291 | data |= RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; |
5102 | 5292 | else | |
5103 | if (temp != data) | ||
5104 | WREG32(mmRLC_PG_CNTL, data); | ||
5105 | } else { | ||
5106 | temp = data = RREG32(mmRLC_PG_CNTL); | ||
5107 | data &= ~RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; | 5293 | data &= ~RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; |
5108 | 5294 | ||
5109 | if (temp != data) | 5295 | if (temp != data) |
5110 | WREG32(mmRLC_PG_CNTL, data); | 5296 | WREG32(mmRLC_PG_CNTL, data); |
5111 | } | ||
5112 | } | 5297 | } |
5113 | 5298 | ||
5114 | static void polaris11_enable_gfx_quick_mg_power_gating(struct amdgpu_device *adev, | 5299 | static void polaris11_enable_gfx_quick_mg_power_gating(struct amdgpu_device *adev, |
@@ -5116,19 +5301,63 @@ static void polaris11_enable_gfx_quick_mg_power_gating(struct amdgpu_device *ade | |||
5116 | { | 5301 | { |
5117 | uint32_t data, temp; | 5302 | uint32_t data, temp; |
5118 | 5303 | ||
5119 | if (enable) { | 5304 | temp = data = RREG32(mmRLC_PG_CNTL); |
5120 | /* Enable quick PG */ | 5305 | /* Enable quick PG */ |
5121 | temp = data = RREG32(mmRLC_PG_CNTL); | 5306 | if (enable) |
5122 | data |= 0x100000; | 5307 | data |= RLC_PG_CNTL__QUICK_PG_ENABLE_MASK; |
5308 | else | ||
5309 | data &= ~RLC_PG_CNTL__QUICK_PG_ENABLE_MASK; | ||
5123 | 5310 | ||
5124 | if (temp != data) | 5311 | if (temp != data) |
5125 | WREG32(mmRLC_PG_CNTL, data); | 5312 | WREG32(mmRLC_PG_CNTL, data); |
5126 | } else { | 5313 | } |
5127 | temp = data = RREG32(mmRLC_PG_CNTL); | ||
5128 | data &= ~0x100000; | ||
5129 | 5314 | ||
5130 | if (temp != data) | 5315 | static void cz_enable_gfx_cg_power_gating(struct amdgpu_device *adev, |
5131 | WREG32(mmRLC_PG_CNTL, data); | 5316 | bool enable) |
5317 | { | ||
5318 | u32 data, orig; | ||
5319 | |||
5320 | orig = data = RREG32(mmRLC_PG_CNTL); | ||
5321 | |||
5322 | if (enable) | ||
5323 | data |= RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK; | ||
5324 | else | ||
5325 | data &= ~RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK; | ||
5326 | |||
5327 | if (orig != data) | ||
5328 | WREG32(mmRLC_PG_CNTL, data); | ||
5329 | } | ||
5330 | |||
5331 | static void cz_enable_gfx_pipeline_power_gating(struct amdgpu_device *adev, | ||
5332 | bool enable) | ||
5333 | { | ||
5334 | u32 data, orig; | ||
5335 | |||
5336 | orig = data = RREG32(mmRLC_PG_CNTL); | ||
5337 | |||
5338 | if (enable) | ||
5339 | data |= RLC_PG_CNTL__GFX_PIPELINE_PG_ENABLE_MASK; | ||
5340 | else | ||
5341 | data &= ~RLC_PG_CNTL__GFX_PIPELINE_PG_ENABLE_MASK; | ||
5342 | |||
5343 | if (orig != data) | ||
5344 | WREG32(mmRLC_PG_CNTL, data); | ||
5345 | |||
5346 | /* Read any GFX register to wake up GFX. */ | ||
5347 | if (!enable) | ||
5348 | data = RREG32(mmDB_RENDER_CONTROL); | ||
5349 | } | ||
5350 | |||
5351 | static void cz_update_gfx_cg_power_gating(struct amdgpu_device *adev, | ||
5352 | bool enable) | ||
5353 | { | ||
5354 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) { | ||
5355 | cz_enable_gfx_cg_power_gating(adev, true); | ||
5356 | if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE) | ||
5357 | cz_enable_gfx_pipeline_power_gating(adev, true); | ||
5358 | } else { | ||
5359 | cz_enable_gfx_cg_power_gating(adev, false); | ||
5360 | cz_enable_gfx_pipeline_power_gating(adev, false); | ||
5132 | } | 5361 | } |
5133 | } | 5362 | } |
5134 | 5363 | ||
@@ -5136,21 +5365,42 @@ static int gfx_v8_0_set_powergating_state(void *handle, | |||
5136 | enum amd_powergating_state state) | 5365 | enum amd_powergating_state state) |
5137 | { | 5366 | { |
5138 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 5367 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
5368 | bool enable = (state == AMD_PG_STATE_GATE) ? true : false; | ||
5139 | 5369 | ||
5140 | if (!(adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) | 5370 | if (!(adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) |
5141 | return 0; | 5371 | return 0; |
5142 | 5372 | ||
5143 | switch (adev->asic_type) { | 5373 | switch (adev->asic_type) { |
5374 | case CHIP_CARRIZO: | ||
5375 | case CHIP_STONEY: | ||
5376 | if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) | ||
5377 | cz_update_gfx_cg_power_gating(adev, enable); | ||
5378 | |||
5379 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable) | ||
5380 | gfx_v8_0_enable_gfx_static_mg_power_gating(adev, true); | ||
5381 | else | ||
5382 | gfx_v8_0_enable_gfx_static_mg_power_gating(adev, false); | ||
5383 | |||
5384 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_DMG) && enable) | ||
5385 | gfx_v8_0_enable_gfx_dynamic_mg_power_gating(adev, true); | ||
5386 | else | ||
5387 | gfx_v8_0_enable_gfx_dynamic_mg_power_gating(adev, false); | ||
5388 | break; | ||
5144 | case CHIP_POLARIS11: | 5389 | case CHIP_POLARIS11: |
5145 | if (adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) | 5390 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable) |
5146 | polaris11_enable_gfx_static_mg_power_gating(adev, | 5391 | gfx_v8_0_enable_gfx_static_mg_power_gating(adev, true); |
5147 | state == AMD_PG_STATE_GATE ? true : false); | 5392 | else |
5148 | else if (adev->pg_flags & AMD_PG_SUPPORT_GFX_DMG) | 5393 | gfx_v8_0_enable_gfx_static_mg_power_gating(adev, false); |
5149 | polaris11_enable_gfx_dynamic_mg_power_gating(adev, | 5394 | |
5150 | state == AMD_PG_STATE_GATE ? true : false); | 5395 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_DMG) && enable) |
5396 | gfx_v8_0_enable_gfx_dynamic_mg_power_gating(adev, true); | ||
5151 | else | 5397 | else |
5152 | polaris11_enable_gfx_quick_mg_power_gating(adev, | 5398 | gfx_v8_0_enable_gfx_dynamic_mg_power_gating(adev, false); |
5153 | state == AMD_PG_STATE_GATE ? true : false); | 5399 | |
5400 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_QUICK_MG) && enable) | ||
5401 | polaris11_enable_gfx_quick_mg_power_gating(adev, true); | ||
5402 | else | ||
5403 | polaris11_enable_gfx_quick_mg_power_gating(adev, false); | ||
5154 | break; | 5404 | break; |
5155 | default: | 5405 | default: |
5156 | break; | 5406 | break; |
@@ -5164,7 +5414,7 @@ static void gfx_v8_0_send_serdes_cmd(struct amdgpu_device *adev, | |||
5164 | { | 5414 | { |
5165 | uint32_t data; | 5415 | uint32_t data; |
5166 | 5416 | ||
5167 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 5417 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
5168 | 5418 | ||
5169 | WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); | 5419 | WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); |
5170 | WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); | 5420 | WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); |
@@ -5552,6 +5802,8 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev | |||
5552 | WREG32(mmRLC_CGCG_CGLS_CTRL, data); | 5802 | WREG32(mmRLC_CGCG_CGLS_CTRL, data); |
5553 | } | 5803 | } |
5554 | 5804 | ||
5805 | gfx_v8_0_wait_for_rlc_serdes(adev); | ||
5806 | |||
5555 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 5807 | adev->gfx.rlc.funcs->exit_safe_mode(adev); |
5556 | } | 5808 | } |
5557 | static int gfx_v8_0_update_gfx_clock_gating(struct amdgpu_device *adev, | 5809 | static int gfx_v8_0_update_gfx_clock_gating(struct amdgpu_device *adev, |
@@ -5677,17 +5929,6 @@ static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | |||
5677 | unsigned vm_id, bool ctx_switch) | 5929 | unsigned vm_id, bool ctx_switch) |
5678 | { | 5930 | { |
5679 | u32 header, control = 0; | 5931 | u32 header, control = 0; |
5680 | u32 next_rptr = ring->wptr + 5; | ||
5681 | |||
5682 | if (ctx_switch) | ||
5683 | next_rptr += 2; | ||
5684 | |||
5685 | next_rptr += 4; | ||
5686 | amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | ||
5687 | amdgpu_ring_write(ring, WRITE_DATA_DST_SEL(5) | WR_CONFIRM); | ||
5688 | amdgpu_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
5689 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); | ||
5690 | amdgpu_ring_write(ring, next_rptr); | ||
5691 | 5932 | ||
5692 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ | 5933 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ |
5693 | if (ctx_switch) { | 5934 | if (ctx_switch) { |
@@ -5716,23 +5957,9 @@ static void gfx_v8_0_ring_emit_ib_compute(struct amdgpu_ring *ring, | |||
5716 | struct amdgpu_ib *ib, | 5957 | struct amdgpu_ib *ib, |
5717 | unsigned vm_id, bool ctx_switch) | 5958 | unsigned vm_id, bool ctx_switch) |
5718 | { | 5959 | { |
5719 | u32 header, control = 0; | 5960 | u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vm_id << 24); |
5720 | u32 next_rptr = ring->wptr + 5; | ||
5721 | |||
5722 | control |= INDIRECT_BUFFER_VALID; | ||
5723 | 5961 | ||
5724 | next_rptr += 4; | 5962 | amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
5725 | amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | ||
5726 | amdgpu_ring_write(ring, WRITE_DATA_DST_SEL(5) | WR_CONFIRM); | ||
5727 | amdgpu_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
5728 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); | ||
5729 | amdgpu_ring_write(ring, next_rptr); | ||
5730 | |||
5731 | header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); | ||
5732 | |||
5733 | control |= ib->length_dw | (vm_id << 24); | ||
5734 | |||
5735 | amdgpu_ring_write(ring, header); | ||
5736 | amdgpu_ring_write(ring, | 5963 | amdgpu_ring_write(ring, |
5737 | #ifdef __BIG_ENDIAN | 5964 | #ifdef __BIG_ENDIAN |
5738 | (2 << 0) | | 5965 | (2 << 0) | |
@@ -6185,9 +6412,9 @@ static void gfx_v8_0_set_rlc_funcs(struct amdgpu_device *adev) | |||
6185 | { | 6412 | { |
6186 | switch (adev->asic_type) { | 6413 | switch (adev->asic_type) { |
6187 | case CHIP_TOPAZ: | 6414 | case CHIP_TOPAZ: |
6188 | case CHIP_STONEY: | ||
6189 | adev->gfx.rlc.funcs = &iceland_rlc_funcs; | 6415 | adev->gfx.rlc.funcs = &iceland_rlc_funcs; |
6190 | break; | 6416 | break; |
6417 | case CHIP_STONEY: | ||
6191 | case CHIP_CARRIZO: | 6418 | case CHIP_CARRIZO: |
6192 | adev->gfx.rlc.funcs = &cz_rlc_funcs; | 6419 | adev->gfx.rlc.funcs = &cz_rlc_funcs; |
6193 | break; | 6420 | break; |
@@ -6225,6 +6452,20 @@ static void gfx_v8_0_set_gds_init(struct amdgpu_device *adev) | |||
6225 | } | 6452 | } |
6226 | } | 6453 | } |
6227 | 6454 | ||
6455 | static void gfx_v8_0_set_user_cu_inactive_bitmap(struct amdgpu_device *adev, | ||
6456 | u32 bitmap) | ||
6457 | { | ||
6458 | u32 data; | ||
6459 | |||
6460 | if (!bitmap) | ||
6461 | return; | ||
6462 | |||
6463 | data = bitmap << GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT; | ||
6464 | data &= GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK; | ||
6465 | |||
6466 | WREG32(mmGC_USER_SHADER_ARRAY_CONFIG, data); | ||
6467 | } | ||
6468 | |||
6228 | static u32 gfx_v8_0_get_cu_active_bitmap(struct amdgpu_device *adev) | 6469 | static u32 gfx_v8_0_get_cu_active_bitmap(struct amdgpu_device *adev) |
6229 | { | 6470 | { |
6230 | u32 data, mask; | 6471 | u32 data, mask; |
@@ -6245,16 +6486,22 @@ static void gfx_v8_0_get_cu_info(struct amdgpu_device *adev) | |||
6245 | int i, j, k, counter, active_cu_number = 0; | 6486 | int i, j, k, counter, active_cu_number = 0; |
6246 | u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; | 6487 | u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; |
6247 | struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info; | 6488 | struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info; |
6489 | unsigned disable_masks[4 * 2]; | ||
6248 | 6490 | ||
6249 | memset(cu_info, 0, sizeof(*cu_info)); | 6491 | memset(cu_info, 0, sizeof(*cu_info)); |
6250 | 6492 | ||
6493 | amdgpu_gfx_parse_disable_cu(disable_masks, 4, 2); | ||
6494 | |||
6251 | mutex_lock(&adev->grbm_idx_mutex); | 6495 | mutex_lock(&adev->grbm_idx_mutex); |
6252 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { | 6496 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { |
6253 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { | 6497 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { |
6254 | mask = 1; | 6498 | mask = 1; |
6255 | ao_bitmap = 0; | 6499 | ao_bitmap = 0; |
6256 | counter = 0; | 6500 | counter = 0; |
6257 | gfx_v8_0_select_se_sh(adev, i, j); | 6501 | gfx_v8_0_select_se_sh(adev, i, j, 0xffffffff); |
6502 | if (i < 4 && j < 2) | ||
6503 | gfx_v8_0_set_user_cu_inactive_bitmap( | ||
6504 | adev, disable_masks[i * 2 + j]); | ||
6258 | bitmap = gfx_v8_0_get_cu_active_bitmap(adev); | 6505 | bitmap = gfx_v8_0_get_cu_active_bitmap(adev); |
6259 | cu_info->bitmap[i][j] = bitmap; | 6506 | cu_info->bitmap[i][j] = bitmap; |
6260 | 6507 | ||
@@ -6270,7 +6517,7 @@ static void gfx_v8_0_get_cu_info(struct amdgpu_device *adev) | |||
6270 | ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); | 6517 | ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); |
6271 | } | 6518 | } |
6272 | } | 6519 | } |
6273 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 6520 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
6274 | mutex_unlock(&adev->grbm_idx_mutex); | 6521 | mutex_unlock(&adev->grbm_idx_mutex); |
6275 | 6522 | ||
6276 | cu_info->number = active_cu_number; | 6523 | cu_info->number = active_cu_number; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h index 16a49f53a2fa..bc82c794312c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.h | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | extern const struct amd_ip_funcs gfx_v8_0_ip_funcs; | 27 | extern const struct amd_ip_funcs gfx_v8_0_ip_funcs; |
28 | 28 | ||
29 | uint64_t gfx_v8_0_get_gpu_clock_counter(struct amdgpu_device *adev); | ||
30 | void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num); | 29 | void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num); |
31 | 30 | ||
32 | #endif | 31 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 1feb6439cb0b..d24a82bd0c7a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | |||
@@ -39,6 +39,7 @@ | |||
39 | 39 | ||
40 | static void gmc_v7_0_set_gart_funcs(struct amdgpu_device *adev); | 40 | static void gmc_v7_0_set_gart_funcs(struct amdgpu_device *adev); |
41 | static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev); | 41 | static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev); |
42 | static int gmc_v7_0_wait_for_idle(void *handle); | ||
42 | 43 | ||
43 | MODULE_FIRMWARE("radeon/bonaire_mc.bin"); | 44 | MODULE_FIRMWARE("radeon/bonaire_mc.bin"); |
44 | MODULE_FIRMWARE("radeon/hawaii_mc.bin"); | 45 | MODULE_FIRMWARE("radeon/hawaii_mc.bin"); |
@@ -73,39 +74,15 @@ static void gmc_v7_0_init_golden_registers(struct amdgpu_device *adev) | |||
73 | } | 74 | } |
74 | } | 75 | } |
75 | 76 | ||
76 | /** | 77 | static void gmc_v7_0_mc_stop(struct amdgpu_device *adev, |
77 | * gmc7_mc_wait_for_idle - wait for MC idle callback. | 78 | struct amdgpu_mode_mc_save *save) |
78 | * | ||
79 | * @adev: amdgpu_device pointer | ||
80 | * | ||
81 | * Wait for the MC (memory controller) to be idle. | ||
82 | * (evergreen+). | ||
83 | * Returns 0 if the MC is idle, -1 if not. | ||
84 | */ | ||
85 | int gmc_v7_0_mc_wait_for_idle(struct amdgpu_device *adev) | ||
86 | { | ||
87 | unsigned i; | ||
88 | u32 tmp; | ||
89 | |||
90 | for (i = 0; i < adev->usec_timeout; i++) { | ||
91 | /* read MC_STATUS */ | ||
92 | tmp = RREG32(mmSRBM_STATUS) & 0x1F00; | ||
93 | if (!tmp) | ||
94 | return 0; | ||
95 | udelay(1); | ||
96 | } | ||
97 | return -1; | ||
98 | } | ||
99 | |||
100 | void gmc_v7_0_mc_stop(struct amdgpu_device *adev, | ||
101 | struct amdgpu_mode_mc_save *save) | ||
102 | { | 79 | { |
103 | u32 blackout; | 80 | u32 blackout; |
104 | 81 | ||
105 | if (adev->mode_info.num_crtc) | 82 | if (adev->mode_info.num_crtc) |
106 | amdgpu_display_stop_mc_access(adev, save); | 83 | amdgpu_display_stop_mc_access(adev, save); |
107 | 84 | ||
108 | amdgpu_asic_wait_for_mc_idle(adev); | 85 | gmc_v7_0_wait_for_idle((void *)adev); |
109 | 86 | ||
110 | blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL); | 87 | blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL); |
111 | if (REG_GET_FIELD(blackout, MC_SHARED_BLACKOUT_CNTL, BLACKOUT_MODE) != 1) { | 88 | if (REG_GET_FIELD(blackout, MC_SHARED_BLACKOUT_CNTL, BLACKOUT_MODE) != 1) { |
@@ -120,8 +97,8 @@ void gmc_v7_0_mc_stop(struct amdgpu_device *adev, | |||
120 | udelay(100); | 97 | udelay(100); |
121 | } | 98 | } |
122 | 99 | ||
123 | void gmc_v7_0_mc_resume(struct amdgpu_device *adev, | 100 | static void gmc_v7_0_mc_resume(struct amdgpu_device *adev, |
124 | struct amdgpu_mode_mc_save *save) | 101 | struct amdgpu_mode_mc_save *save) |
125 | { | 102 | { |
126 | u32 tmp; | 103 | u32 tmp; |
127 | 104 | ||
@@ -311,7 +288,7 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev) | |||
311 | amdgpu_display_set_vga_render_state(adev, false); | 288 | amdgpu_display_set_vga_render_state(adev, false); |
312 | 289 | ||
313 | gmc_v7_0_mc_stop(adev, &save); | 290 | gmc_v7_0_mc_stop(adev, &save); |
314 | if (amdgpu_asic_wait_for_mc_idle(adev)) { | 291 | if (gmc_v7_0_wait_for_idle((void *)adev)) { |
315 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); | 292 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); |
316 | } | 293 | } |
317 | /* Update configuration */ | 294 | /* Update configuration */ |
@@ -331,7 +308,7 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev) | |||
331 | WREG32(mmMC_VM_AGP_BASE, 0); | 308 | WREG32(mmMC_VM_AGP_BASE, 0); |
332 | WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF); | 309 | WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF); |
333 | WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF); | 310 | WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF); |
334 | if (amdgpu_asic_wait_for_mc_idle(adev)) { | 311 | if (gmc_v7_0_wait_for_idle((void *)adev)) { |
335 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); | 312 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); |
336 | } | 313 | } |
337 | gmc_v7_0_mc_resume(adev, &save); | 314 | gmc_v7_0_mc_resume(adev, &save); |
@@ -1137,7 +1114,7 @@ static int gmc_v7_0_soft_reset(void *handle) | |||
1137 | 1114 | ||
1138 | if (srbm_soft_reset) { | 1115 | if (srbm_soft_reset) { |
1139 | gmc_v7_0_mc_stop(adev, &save); | 1116 | gmc_v7_0_mc_stop(adev, &save); |
1140 | if (gmc_v7_0_wait_for_idle(adev)) { | 1117 | if (gmc_v7_0_wait_for_idle((void *)adev)) { |
1141 | dev_warn(adev->dev, "Wait for GMC idle timed out !\n"); | 1118 | dev_warn(adev->dev, "Wait for GMC idle timed out !\n"); |
1142 | } | 1119 | } |
1143 | 1120 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.h b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.h index 36fcbbc46ada..0b386b5d2f7a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.h +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.h | |||
@@ -26,11 +26,4 @@ | |||
26 | 26 | ||
27 | extern const struct amd_ip_funcs gmc_v7_0_ip_funcs; | 27 | extern const struct amd_ip_funcs gmc_v7_0_ip_funcs; |
28 | 28 | ||
29 | /* XXX these shouldn't be exported */ | ||
30 | void gmc_v7_0_mc_stop(struct amdgpu_device *adev, | ||
31 | struct amdgpu_mode_mc_save *save); | ||
32 | void gmc_v7_0_mc_resume(struct amdgpu_device *adev, | ||
33 | struct amdgpu_mode_mc_save *save); | ||
34 | int gmc_v7_0_mc_wait_for_idle(struct amdgpu_device *adev); | ||
35 | |||
36 | #endif | 29 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 9945d5bbf1fe..717359d3ba8c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | static void gmc_v8_0_set_gart_funcs(struct amdgpu_device *adev); | 42 | static void gmc_v8_0_set_gart_funcs(struct amdgpu_device *adev); |
43 | static void gmc_v8_0_set_irq_funcs(struct amdgpu_device *adev); | 43 | static void gmc_v8_0_set_irq_funcs(struct amdgpu_device *adev); |
44 | static int gmc_v8_0_wait_for_idle(void *handle); | ||
44 | 45 | ||
45 | MODULE_FIRMWARE("amdgpu/tonga_mc.bin"); | 46 | MODULE_FIRMWARE("amdgpu/tonga_mc.bin"); |
46 | MODULE_FIRMWARE("amdgpu/polaris11_mc.bin"); | 47 | MODULE_FIRMWARE("amdgpu/polaris11_mc.bin"); |
@@ -147,44 +148,15 @@ static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev) | |||
147 | } | 148 | } |
148 | } | 149 | } |
149 | 150 | ||
150 | /** | 151 | static void gmc_v8_0_mc_stop(struct amdgpu_device *adev, |
151 | * gmc8_mc_wait_for_idle - wait for MC idle callback. | 152 | struct amdgpu_mode_mc_save *save) |
152 | * | ||
153 | * @adev: amdgpu_device pointer | ||
154 | * | ||
155 | * Wait for the MC (memory controller) to be idle. | ||
156 | * (evergreen+). | ||
157 | * Returns 0 if the MC is idle, -1 if not. | ||
158 | */ | ||
159 | int gmc_v8_0_mc_wait_for_idle(struct amdgpu_device *adev) | ||
160 | { | ||
161 | unsigned i; | ||
162 | u32 tmp; | ||
163 | |||
164 | for (i = 0; i < adev->usec_timeout; i++) { | ||
165 | /* read MC_STATUS */ | ||
166 | tmp = RREG32(mmSRBM_STATUS) & (SRBM_STATUS__VMC_BUSY_MASK | | ||
167 | SRBM_STATUS__MCB_BUSY_MASK | | ||
168 | SRBM_STATUS__MCB_NON_DISPLAY_BUSY_MASK | | ||
169 | SRBM_STATUS__MCC_BUSY_MASK | | ||
170 | SRBM_STATUS__MCD_BUSY_MASK | | ||
171 | SRBM_STATUS__VMC1_BUSY_MASK); | ||
172 | if (!tmp) | ||
173 | return 0; | ||
174 | udelay(1); | ||
175 | } | ||
176 | return -1; | ||
177 | } | ||
178 | |||
179 | void gmc_v8_0_mc_stop(struct amdgpu_device *adev, | ||
180 | struct amdgpu_mode_mc_save *save) | ||
181 | { | 153 | { |
182 | u32 blackout; | 154 | u32 blackout; |
183 | 155 | ||
184 | if (adev->mode_info.num_crtc) | 156 | if (adev->mode_info.num_crtc) |
185 | amdgpu_display_stop_mc_access(adev, save); | 157 | amdgpu_display_stop_mc_access(adev, save); |
186 | 158 | ||
187 | amdgpu_asic_wait_for_mc_idle(adev); | 159 | gmc_v8_0_wait_for_idle(adev); |
188 | 160 | ||
189 | blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL); | 161 | blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL); |
190 | if (REG_GET_FIELD(blackout, MC_SHARED_BLACKOUT_CNTL, BLACKOUT_MODE) != 1) { | 162 | if (REG_GET_FIELD(blackout, MC_SHARED_BLACKOUT_CNTL, BLACKOUT_MODE) != 1) { |
@@ -199,8 +171,8 @@ void gmc_v8_0_mc_stop(struct amdgpu_device *adev, | |||
199 | udelay(100); | 171 | udelay(100); |
200 | } | 172 | } |
201 | 173 | ||
202 | void gmc_v8_0_mc_resume(struct amdgpu_device *adev, | 174 | static void gmc_v8_0_mc_resume(struct amdgpu_device *adev, |
203 | struct amdgpu_mode_mc_save *save) | 175 | struct amdgpu_mode_mc_save *save) |
204 | { | 176 | { |
205 | u32 tmp; | 177 | u32 tmp; |
206 | 178 | ||
@@ -393,7 +365,7 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev) | |||
393 | amdgpu_display_set_vga_render_state(adev, false); | 365 | amdgpu_display_set_vga_render_state(adev, false); |
394 | 366 | ||
395 | gmc_v8_0_mc_stop(adev, &save); | 367 | gmc_v8_0_mc_stop(adev, &save); |
396 | if (amdgpu_asic_wait_for_mc_idle(adev)) { | 368 | if (gmc_v8_0_wait_for_idle((void *)adev)) { |
397 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); | 369 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); |
398 | } | 370 | } |
399 | /* Update configuration */ | 371 | /* Update configuration */ |
@@ -413,7 +385,7 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev) | |||
413 | WREG32(mmMC_VM_AGP_BASE, 0); | 385 | WREG32(mmMC_VM_AGP_BASE, 0); |
414 | WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF); | 386 | WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF); |
415 | WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF); | 387 | WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF); |
416 | if (amdgpu_asic_wait_for_mc_idle(adev)) { | 388 | if (gmc_v8_0_wait_for_idle((void *)adev)) { |
417 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); | 389 | dev_warn(adev->dev, "Wait for MC idle timedout !\n"); |
418 | } | 390 | } |
419 | gmc_v8_0_mc_resume(adev, &save); | 391 | gmc_v8_0_mc_resume(adev, &save); |
@@ -1140,7 +1112,7 @@ static int gmc_v8_0_soft_reset(void *handle) | |||
1140 | 1112 | ||
1141 | if (srbm_soft_reset) { | 1113 | if (srbm_soft_reset) { |
1142 | gmc_v8_0_mc_stop(adev, &save); | 1114 | gmc_v8_0_mc_stop(adev, &save); |
1143 | if (gmc_v8_0_wait_for_idle(adev)) { | 1115 | if (gmc_v8_0_wait_for_idle((void *)adev)) { |
1144 | dev_warn(adev->dev, "Wait for GMC idle timed out !\n"); | 1116 | dev_warn(adev->dev, "Wait for GMC idle timed out !\n"); |
1145 | } | 1117 | } |
1146 | 1118 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.h b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.h index 973436086b38..fc5001a8119d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.h +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.h | |||
@@ -26,11 +26,4 @@ | |||
26 | 26 | ||
27 | extern const struct amd_ip_funcs gmc_v8_0_ip_funcs; | 27 | extern const struct amd_ip_funcs gmc_v8_0_ip_funcs; |
28 | 28 | ||
29 | /* XXX these shouldn't be exported */ | ||
30 | void gmc_v8_0_mc_stop(struct amdgpu_device *adev, | ||
31 | struct amdgpu_mode_mc_save *save); | ||
32 | void gmc_v8_0_mc_resume(struct amdgpu_device *adev, | ||
33 | struct amdgpu_mode_mc_save *save); | ||
34 | int gmc_v8_0_mc_wait_for_idle(struct amdgpu_device *adev); | ||
35 | |||
36 | #endif | 29 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index a789a863d677..5a0e245771ce 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c | |||
@@ -507,19 +507,19 @@ static int kv_enable_didt(struct amdgpu_device *adev, bool enable) | |||
507 | pi->caps_db_ramping || | 507 | pi->caps_db_ramping || |
508 | pi->caps_td_ramping || | 508 | pi->caps_td_ramping || |
509 | pi->caps_tcp_ramping) { | 509 | pi->caps_tcp_ramping) { |
510 | gfx_v7_0_enter_rlc_safe_mode(adev); | 510 | adev->gfx.rlc.funcs->enter_safe_mode(adev); |
511 | 511 | ||
512 | if (enable) { | 512 | if (enable) { |
513 | ret = kv_program_pt_config_registers(adev, didt_config_kv); | 513 | ret = kv_program_pt_config_registers(adev, didt_config_kv); |
514 | if (ret) { | 514 | if (ret) { |
515 | gfx_v7_0_exit_rlc_safe_mode(adev); | 515 | adev->gfx.rlc.funcs->exit_safe_mode(adev); |
516 | return ret; | 516 | return ret; |
517 | } | 517 | } |
518 | } | 518 | } |
519 | 519 | ||
520 | kv_do_enable_didt(adev, enable); | 520 | kv_do_enable_didt(adev, enable); |
521 | 521 | ||
522 | gfx_v7_0_exit_rlc_safe_mode(adev); | 522 | adev->gfx.rlc.funcs->exit_safe_mode(adev); |
523 | } | 523 | } |
524 | 524 | ||
525 | return 0; | 525 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index b556bd0a8797..ac3730a6e49f 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
@@ -255,19 +255,6 @@ static void sdma_v2_4_ring_emit_ib(struct amdgpu_ring *ring, | |||
255 | unsigned vm_id, bool ctx_switch) | 255 | unsigned vm_id, bool ctx_switch) |
256 | { | 256 | { |
257 | u32 vmid = vm_id & 0xf; | 257 | u32 vmid = vm_id & 0xf; |
258 | u32 next_rptr = ring->wptr + 5; | ||
259 | |||
260 | while ((next_rptr & 7) != 2) | ||
261 | next_rptr++; | ||
262 | |||
263 | next_rptr += 6; | ||
264 | |||
265 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | | ||
266 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR)); | ||
267 | amdgpu_ring_write(ring, lower_32_bits(ring->next_rptr_gpu_addr) & 0xfffffffc); | ||
268 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr)); | ||
269 | amdgpu_ring_write(ring, SDMA_PKT_WRITE_UNTILED_DW_3_COUNT(1)); | ||
270 | amdgpu_ring_write(ring, next_rptr); | ||
271 | 258 | ||
272 | /* IB packet must end on a 8 DW boundary */ | 259 | /* IB packet must end on a 8 DW boundary */ |
273 | sdma_v2_4_ring_insert_nop(ring, (10 - (ring->wptr & 7)) % 8); | 260 | sdma_v2_4_ring_insert_nop(ring, (10 - (ring->wptr & 7)) % 8); |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 532ea88da66a..f00db6f4c04c 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
@@ -415,18 +415,6 @@ static void sdma_v3_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
415 | unsigned vm_id, bool ctx_switch) | 415 | unsigned vm_id, bool ctx_switch) |
416 | { | 416 | { |
417 | u32 vmid = vm_id & 0xf; | 417 | u32 vmid = vm_id & 0xf; |
418 | u32 next_rptr = ring->wptr + 5; | ||
419 | |||
420 | while ((next_rptr & 7) != 2) | ||
421 | next_rptr++; | ||
422 | next_rptr += 6; | ||
423 | |||
424 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | | ||
425 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR)); | ||
426 | amdgpu_ring_write(ring, lower_32_bits(ring->next_rptr_gpu_addr) & 0xfffffffc); | ||
427 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr)); | ||
428 | amdgpu_ring_write(ring, SDMA_PKT_WRITE_UNTILED_DW_3_COUNT(1)); | ||
429 | amdgpu_ring_write(ring, next_rptr); | ||
430 | 418 | ||
431 | /* IB packet must end on a 8 DW boundary */ | 419 | /* IB packet must end on a 8 DW boundary */ |
432 | sdma_v3_0_ring_insert_nop(ring, (10 - (ring->wptr & 7)) % 8); | 420 | sdma_v3_0_ring_insert_nop(ring, (10 - (ring->wptr & 7)) % 8); |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index f07551476a70..416c8567d3ed 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include "oss/oss_2_0_d.h" | 34 | #include "oss/oss_2_0_d.h" |
35 | #include "oss/oss_2_0_sh_mask.h" | 35 | #include "oss/oss_2_0_sh_mask.h" |
36 | 36 | ||
37 | #include "bif/bif_4_1_d.h" | ||
38 | |||
37 | static void uvd_v4_2_mc_resume(struct amdgpu_device *adev); | 39 | static void uvd_v4_2_mc_resume(struct amdgpu_device *adev); |
38 | static void uvd_v4_2_init_cg(struct amdgpu_device *adev); | 40 | static void uvd_v4_2_init_cg(struct amdgpu_device *adev); |
39 | static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev); | 41 | static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev); |
@@ -439,6 +441,32 @@ static void uvd_v4_2_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq | |||
439 | } | 441 | } |
440 | 442 | ||
441 | /** | 443 | /** |
444 | * uvd_v4_2_ring_emit_hdp_flush - emit an hdp flush | ||
445 | * | ||
446 | * @ring: amdgpu_ring pointer | ||
447 | * | ||
448 | * Emits an hdp flush. | ||
449 | */ | ||
450 | static void uvd_v4_2_ring_emit_hdp_flush(struct amdgpu_ring *ring) | ||
451 | { | ||
452 | amdgpu_ring_write(ring, PACKET0(mmHDP_MEM_COHERENCY_FLUSH_CNTL, 0)); | ||
453 | amdgpu_ring_write(ring, 0); | ||
454 | } | ||
455 | |||
456 | /** | ||
457 | * uvd_v4_2_ring_hdp_invalidate - emit an hdp invalidate | ||
458 | * | ||
459 | * @ring: amdgpu_ring pointer | ||
460 | * | ||
461 | * Emits an hdp invalidate. | ||
462 | */ | ||
463 | static void uvd_v4_2_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) | ||
464 | { | ||
465 | amdgpu_ring_write(ring, PACKET0(mmHDP_DEBUG0, 0)); | ||
466 | amdgpu_ring_write(ring, 1); | ||
467 | } | ||
468 | |||
469 | /** | ||
442 | * uvd_v4_2_ring_test_ring - register write test | 470 | * uvd_v4_2_ring_test_ring - register write test |
443 | * | 471 | * |
444 | * @ring: amdgpu_ring pointer | 472 | * @ring: amdgpu_ring pointer |
@@ -763,6 +791,8 @@ static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = { | |||
763 | .parse_cs = amdgpu_uvd_ring_parse_cs, | 791 | .parse_cs = amdgpu_uvd_ring_parse_cs, |
764 | .emit_ib = uvd_v4_2_ring_emit_ib, | 792 | .emit_ib = uvd_v4_2_ring_emit_ib, |
765 | .emit_fence = uvd_v4_2_ring_emit_fence, | 793 | .emit_fence = uvd_v4_2_ring_emit_fence, |
794 | .emit_hdp_flush = uvd_v4_2_ring_emit_hdp_flush, | ||
795 | .emit_hdp_invalidate = uvd_v4_2_ring_emit_hdp_invalidate, | ||
766 | .test_ring = uvd_v4_2_ring_test_ring, | 796 | .test_ring = uvd_v4_2_ring_test_ring, |
767 | .test_ib = uvd_v4_2_ring_test_ib, | 797 | .test_ib = uvd_v4_2_ring_test_ib, |
768 | .insert_nop = amdgpu_ring_insert_nop, | 798 | .insert_nop = amdgpu_ring_insert_nop, |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index e0a76a883d46..dd636c4c4b08 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "uvd/uvd_5_0_sh_mask.h" | 31 | #include "uvd/uvd_5_0_sh_mask.h" |
32 | #include "oss/oss_2_0_d.h" | 32 | #include "oss/oss_2_0_d.h" |
33 | #include "oss/oss_2_0_sh_mask.h" | 33 | #include "oss/oss_2_0_sh_mask.h" |
34 | #include "bif/bif_5_0_d.h" | ||
34 | #include "vi.h" | 35 | #include "vi.h" |
35 | 36 | ||
36 | static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev); | 37 | static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev); |
@@ -489,6 +490,32 @@ static void uvd_v5_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq | |||
489 | } | 490 | } |
490 | 491 | ||
491 | /** | 492 | /** |
493 | * uvd_v5_0_ring_emit_hdp_flush - emit an hdp flush | ||
494 | * | ||
495 | * @ring: amdgpu_ring pointer | ||
496 | * | ||
497 | * Emits an hdp flush. | ||
498 | */ | ||
499 | static void uvd_v5_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) | ||
500 | { | ||
501 | amdgpu_ring_write(ring, PACKET0(mmHDP_MEM_COHERENCY_FLUSH_CNTL, 0)); | ||
502 | amdgpu_ring_write(ring, 0); | ||
503 | } | ||
504 | |||
505 | /** | ||
506 | * uvd_v5_0_ring_hdp_invalidate - emit an hdp invalidate | ||
507 | * | ||
508 | * @ring: amdgpu_ring pointer | ||
509 | * | ||
510 | * Emits an hdp invalidate. | ||
511 | */ | ||
512 | static void uvd_v5_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) | ||
513 | { | ||
514 | amdgpu_ring_write(ring, PACKET0(mmHDP_DEBUG0, 0)); | ||
515 | amdgpu_ring_write(ring, 1); | ||
516 | } | ||
517 | |||
518 | /** | ||
492 | * uvd_v5_0_ring_test_ring - register write test | 519 | * uvd_v5_0_ring_test_ring - register write test |
493 | * | 520 | * |
494 | * @ring: amdgpu_ring pointer | 521 | * @ring: amdgpu_ring pointer |
@@ -815,6 +842,8 @@ static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = { | |||
815 | .parse_cs = amdgpu_uvd_ring_parse_cs, | 842 | .parse_cs = amdgpu_uvd_ring_parse_cs, |
816 | .emit_ib = uvd_v5_0_ring_emit_ib, | 843 | .emit_ib = uvd_v5_0_ring_emit_ib, |
817 | .emit_fence = uvd_v5_0_ring_emit_fence, | 844 | .emit_fence = uvd_v5_0_ring_emit_fence, |
845 | .emit_hdp_flush = uvd_v5_0_ring_emit_hdp_flush, | ||
846 | .emit_hdp_invalidate = uvd_v5_0_ring_emit_hdp_invalidate, | ||
818 | .test_ring = uvd_v5_0_ring_test_ring, | 847 | .test_ring = uvd_v5_0_ring_test_ring, |
819 | .test_ib = uvd_v5_0_ring_test_ib, | 848 | .test_ib = uvd_v5_0_ring_test_ib, |
820 | .insert_nop = amdgpu_ring_insert_nop, | 849 | .insert_nop = amdgpu_ring_insert_nop, |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index c9929d665c01..07e9a987fbee 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "oss/oss_2_0_sh_mask.h" | 33 | #include "oss/oss_2_0_sh_mask.h" |
34 | #include "smu/smu_7_1_3_d.h" | 34 | #include "smu/smu_7_1_3_d.h" |
35 | #include "smu/smu_7_1_3_sh_mask.h" | 35 | #include "smu/smu_7_1_3_sh_mask.h" |
36 | #include "bif/bif_5_1_d.h" | ||
36 | #include "vi.h" | 37 | #include "vi.h" |
37 | 38 | ||
38 | static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev); | 39 | static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev); |
@@ -385,8 +386,8 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) | |||
385 | uint32_t mp_swap_cntl; | 386 | uint32_t mp_swap_cntl; |
386 | int i, j, r; | 387 | int i, j, r; |
387 | 388 | ||
388 | /*disable DPG */ | 389 | /* disable DPG */ |
389 | WREG32_P(mmUVD_POWER_STATUS, 0, ~(1 << 2)); | 390 | WREG32_P(mmUVD_POWER_STATUS, 0, ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); |
390 | 391 | ||
391 | /* disable byte swapping */ | 392 | /* disable byte swapping */ |
392 | lmi_swap_cntl = 0; | 393 | lmi_swap_cntl = 0; |
@@ -405,17 +406,21 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) | |||
405 | } | 406 | } |
406 | 407 | ||
407 | /* disable interupt */ | 408 | /* disable interupt */ |
408 | WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1)); | 409 | WREG32_P(mmUVD_MASTINT_EN, 0, ~UVD_MASTINT_EN__VCPU_EN_MASK); |
409 | 410 | ||
410 | /* stall UMC and register bus before resetting VCPU */ | 411 | /* stall UMC and register bus before resetting VCPU */ |
411 | WREG32_P(mmUVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); | 412 | WREG32_P(mmUVD_LMI_CTRL2, UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); |
412 | mdelay(1); | 413 | mdelay(1); |
413 | 414 | ||
414 | /* put LMI, VCPU, RBC etc... into reset */ | 415 | /* put LMI, VCPU, RBC etc... into reset */ |
415 | WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | 416 | WREG32(mmUVD_SOFT_RESET, |
416 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | 417 | UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | |
417 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | 418 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | |
418 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | 419 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | |
420 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
421 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
422 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
423 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
419 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); | 424 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); |
420 | mdelay(5); | 425 | mdelay(5); |
421 | 426 | ||
@@ -424,8 +429,13 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) | |||
424 | mdelay(5); | 429 | mdelay(5); |
425 | 430 | ||
426 | /* initialize UVD memory controller */ | 431 | /* initialize UVD memory controller */ |
427 | WREG32(mmUVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) | | 432 | WREG32(mmUVD_LMI_CTRL, |
428 | (1 << 21) | (1 << 9) | (1 << 20)); | 433 | (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | |
434 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | ||
435 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | ||
436 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | ||
437 | UVD_LMI_CTRL__REQ_MODE_MASK | | ||
438 | UVD_LMI_CTRL__DISABLE_ON_FWV_FAIL_MASK); | ||
429 | 439 | ||
430 | #ifdef __BIG_ENDIAN | 440 | #ifdef __BIG_ENDIAN |
431 | /* swap (8 in 32) RB and IB */ | 441 | /* swap (8 in 32) RB and IB */ |
@@ -447,10 +457,10 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) | |||
447 | mdelay(5); | 457 | mdelay(5); |
448 | 458 | ||
449 | /* enable VCPU clock */ | 459 | /* enable VCPU clock */ |
450 | WREG32(mmUVD_VCPU_CNTL, 1 << 9); | 460 | WREG32(mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK); |
451 | 461 | ||
452 | /* enable UMC */ | 462 | /* enable UMC */ |
453 | WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8)); | 463 | WREG32_P(mmUVD_LMI_CTRL2, 0, ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); |
454 | 464 | ||
455 | /* boot up the VCPU */ | 465 | /* boot up the VCPU */ |
456 | WREG32(mmUVD_SOFT_RESET, 0); | 466 | WREG32(mmUVD_SOFT_RESET, 0); |
@@ -484,10 +494,12 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) | |||
484 | return r; | 494 | return r; |
485 | } | 495 | } |
486 | /* enable master interrupt */ | 496 | /* enable master interrupt */ |
487 | WREG32_P(mmUVD_MASTINT_EN, 3 << 1, ~(3 << 1)); | 497 | WREG32_P(mmUVD_MASTINT_EN, |
498 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | ||
499 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); | ||
488 | 500 | ||
489 | /* clear the bit 4 of UVD_STATUS */ | 501 | /* clear the bit 4 of UVD_STATUS */ |
490 | WREG32_P(mmUVD_STATUS, 0, ~(2 << 1)); | 502 | WREG32_P(mmUVD_STATUS, 0, ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); |
491 | 503 | ||
492 | rb_bufsz = order_base_2(ring->ring_size); | 504 | rb_bufsz = order_base_2(ring->ring_size); |
493 | tmp = 0; | 505 | tmp = 0; |
@@ -581,6 +593,32 @@ static void uvd_v6_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq | |||
581 | } | 593 | } |
582 | 594 | ||
583 | /** | 595 | /** |
596 | * uvd_v6_0_ring_emit_hdp_flush - emit an hdp flush | ||
597 | * | ||
598 | * @ring: amdgpu_ring pointer | ||
599 | * | ||
600 | * Emits an hdp flush. | ||
601 | */ | ||
602 | static void uvd_v6_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) | ||
603 | { | ||
604 | amdgpu_ring_write(ring, PACKET0(mmHDP_MEM_COHERENCY_FLUSH_CNTL, 0)); | ||
605 | amdgpu_ring_write(ring, 0); | ||
606 | } | ||
607 | |||
608 | /** | ||
609 | * uvd_v6_0_ring_hdp_invalidate - emit an hdp invalidate | ||
610 | * | ||
611 | * @ring: amdgpu_ring pointer | ||
612 | * | ||
613 | * Emits an hdp invalidate. | ||
614 | */ | ||
615 | static void uvd_v6_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) | ||
616 | { | ||
617 | amdgpu_ring_write(ring, PACKET0(mmHDP_DEBUG0, 0)); | ||
618 | amdgpu_ring_write(ring, 1); | ||
619 | } | ||
620 | |||
621 | /** | ||
584 | * uvd_v6_0_ring_test_ring - register write test | 622 | * uvd_v6_0_ring_test_ring - register write test |
585 | * | 623 | * |
586 | * @ring: amdgpu_ring pointer | 624 | * @ring: amdgpu_ring pointer |
@@ -847,7 +885,8 @@ static int uvd_v6_0_set_clockgating_state(void *handle, | |||
847 | bool enable = (state == AMD_CG_STATE_GATE) ? true : false; | 885 | bool enable = (state == AMD_CG_STATE_GATE) ? true : false; |
848 | static int curstate = -1; | 886 | static int curstate = -1; |
849 | 887 | ||
850 | if (adev->asic_type == CHIP_FIJI) | 888 | if (adev->asic_type == CHIP_FIJI || |
889 | adev->asic_type == CHIP_POLARIS10) | ||
851 | uvd_v6_set_bypass_mode(adev, enable); | 890 | uvd_v6_set_bypass_mode(adev, enable); |
852 | 891 | ||
853 | if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG)) | 892 | if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG)) |
@@ -919,6 +958,8 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_funcs = { | |||
919 | .parse_cs = amdgpu_uvd_ring_parse_cs, | 958 | .parse_cs = amdgpu_uvd_ring_parse_cs, |
920 | .emit_ib = uvd_v6_0_ring_emit_ib, | 959 | .emit_ib = uvd_v6_0_ring_emit_ib, |
921 | .emit_fence = uvd_v6_0_ring_emit_fence, | 960 | .emit_fence = uvd_v6_0_ring_emit_fence, |
961 | .emit_hdp_flush = uvd_v6_0_ring_emit_hdp_flush, | ||
962 | .emit_hdp_invalidate = uvd_v6_0_ring_emit_hdp_invalidate, | ||
922 | .test_ring = uvd_v6_0_ring_test_ring, | 963 | .test_ring = uvd_v6_0_ring_test_ring, |
923 | .test_ib = uvd_v6_0_ring_test_ib, | 964 | .test_ib = uvd_v6_0_ring_test_ib, |
924 | .insert_nop = amdgpu_ring_insert_nop, | 965 | .insert_nop = amdgpu_ring_insert_nop, |
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index a65c96029476..cda7def9dc2c 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
@@ -203,6 +203,29 @@ static void vi_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | |||
203 | spin_unlock_irqrestore(&adev->didt_idx_lock, flags); | 203 | spin_unlock_irqrestore(&adev->didt_idx_lock, flags); |
204 | } | 204 | } |
205 | 205 | ||
206 | static u32 vi_gc_cac_rreg(struct amdgpu_device *adev, u32 reg) | ||
207 | { | ||
208 | unsigned long flags; | ||
209 | u32 r; | ||
210 | |||
211 | spin_lock_irqsave(&adev->gc_cac_idx_lock, flags); | ||
212 | WREG32(mmGC_CAC_IND_INDEX, (reg)); | ||
213 | r = RREG32(mmGC_CAC_IND_DATA); | ||
214 | spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags); | ||
215 | return r; | ||
216 | } | ||
217 | |||
218 | static void vi_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | ||
219 | { | ||
220 | unsigned long flags; | ||
221 | |||
222 | spin_lock_irqsave(&adev->gc_cac_idx_lock, flags); | ||
223 | WREG32(mmGC_CAC_IND_INDEX, (reg)); | ||
224 | WREG32(mmGC_CAC_IND_DATA, (v)); | ||
225 | spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags); | ||
226 | } | ||
227 | |||
228 | |||
206 | static const u32 tonga_mgcg_cgcg_init[] = | 229 | static const u32 tonga_mgcg_cgcg_init[] = |
207 | { | 230 | { |
208 | mmCGTT_DRM_CLK_CTRL0, 0xffffffff, 0x00600100, | 231 | mmCGTT_DRM_CLK_CTRL0, 0xffffffff, 0x00600100, |
@@ -533,12 +556,12 @@ static uint32_t vi_read_indexed_register(struct amdgpu_device *adev, u32 se_num, | |||
533 | 556 | ||
534 | mutex_lock(&adev->grbm_idx_mutex); | 557 | mutex_lock(&adev->grbm_idx_mutex); |
535 | if (se_num != 0xffffffff || sh_num != 0xffffffff) | 558 | if (se_num != 0xffffffff || sh_num != 0xffffffff) |
536 | gfx_v8_0_select_se_sh(adev, se_num, sh_num); | 559 | amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff); |
537 | 560 | ||
538 | val = RREG32(reg_offset); | 561 | val = RREG32(reg_offset); |
539 | 562 | ||
540 | if (se_num != 0xffffffff || sh_num != 0xffffffff) | 563 | if (se_num != 0xffffffff || sh_num != 0xffffffff) |
541 | gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); | 564 | amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
542 | mutex_unlock(&adev->grbm_idx_mutex); | 565 | mutex_unlock(&adev->grbm_idx_mutex); |
543 | return val; | 566 | return val; |
544 | } | 567 | } |
@@ -597,7 +620,7 @@ static int vi_read_register(struct amdgpu_device *adev, u32 se_num, | |||
597 | return -EINVAL; | 620 | return -EINVAL; |
598 | } | 621 | } |
599 | 622 | ||
600 | static void vi_gpu_pci_config_reset(struct amdgpu_device *adev) | 623 | static int vi_gpu_pci_config_reset(struct amdgpu_device *adev) |
601 | { | 624 | { |
602 | u32 i; | 625 | u32 i; |
603 | 626 | ||
@@ -612,11 +635,14 @@ static void vi_gpu_pci_config_reset(struct amdgpu_device *adev) | |||
612 | 635 | ||
613 | /* wait for asic to come out of reset */ | 636 | /* wait for asic to come out of reset */ |
614 | for (i = 0; i < adev->usec_timeout; i++) { | 637 | for (i = 0; i < adev->usec_timeout; i++) { |
615 | if (RREG32(mmCONFIG_MEMSIZE) != 0xffffffff) | 638 | if (RREG32(mmCONFIG_MEMSIZE) != 0xffffffff) { |
616 | break; | 639 | /* enable BM */ |
640 | pci_set_master(adev->pdev); | ||
641 | return 0; | ||
642 | } | ||
617 | udelay(1); | 643 | udelay(1); |
618 | } | 644 | } |
619 | 645 | return -EINVAL; | |
620 | } | 646 | } |
621 | 647 | ||
622 | static void vi_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hung) | 648 | static void vi_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hung) |
@@ -642,13 +668,15 @@ static void vi_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hun | |||
642 | */ | 668 | */ |
643 | static int vi_asic_reset(struct amdgpu_device *adev) | 669 | static int vi_asic_reset(struct amdgpu_device *adev) |
644 | { | 670 | { |
671 | int r; | ||
672 | |||
645 | vi_set_bios_scratch_engine_hung(adev, true); | 673 | vi_set_bios_scratch_engine_hung(adev, true); |
646 | 674 | ||
647 | vi_gpu_pci_config_reset(adev); | 675 | r = vi_gpu_pci_config_reset(adev); |
648 | 676 | ||
649 | vi_set_bios_scratch_engine_hung(adev, false); | 677 | vi_set_bios_scratch_engine_hung(adev, false); |
650 | 678 | ||
651 | return 0; | 679 | return r; |
652 | } | 680 | } |
653 | 681 | ||
654 | static int vi_set_uvd_clock(struct amdgpu_device *adev, u32 clock, | 682 | static int vi_set_uvd_clock(struct amdgpu_device *adev, u32 clock, |
@@ -1133,9 +1161,6 @@ static const struct amdgpu_asic_funcs vi_asic_funcs = | |||
1133 | .set_uvd_clocks = &vi_set_uvd_clocks, | 1161 | .set_uvd_clocks = &vi_set_uvd_clocks, |
1134 | .set_vce_clocks = &vi_set_vce_clocks, | 1162 | .set_vce_clocks = &vi_set_vce_clocks, |
1135 | .get_virtual_caps = &vi_get_virtual_caps, | 1163 | .get_virtual_caps = &vi_get_virtual_caps, |
1136 | /* these should be moved to their own ip modules */ | ||
1137 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, | ||
1138 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, | ||
1139 | }; | 1164 | }; |
1140 | 1165 | ||
1141 | static int vi_common_early_init(void *handle) | 1166 | static int vi_common_early_init(void *handle) |
@@ -1156,6 +1181,8 @@ static int vi_common_early_init(void *handle) | |||
1156 | adev->uvd_ctx_wreg = &vi_uvd_ctx_wreg; | 1181 | adev->uvd_ctx_wreg = &vi_uvd_ctx_wreg; |
1157 | adev->didt_rreg = &vi_didt_rreg; | 1182 | adev->didt_rreg = &vi_didt_rreg; |
1158 | adev->didt_wreg = &vi_didt_wreg; | 1183 | adev->didt_wreg = &vi_didt_wreg; |
1184 | adev->gc_cac_rreg = &vi_gc_cac_rreg; | ||
1185 | adev->gc_cac_wreg = &vi_gc_cac_wreg; | ||
1159 | 1186 | ||
1160 | adev->asic_funcs = &vi_asic_funcs; | 1187 | adev->asic_funcs = &vi_asic_funcs; |
1161 | 1188 | ||
@@ -1222,19 +1249,39 @@ static int vi_common_early_init(void *handle) | |||
1222 | AMD_CG_SUPPORT_HDP_LS | | 1249 | AMD_CG_SUPPORT_HDP_LS | |
1223 | AMD_CG_SUPPORT_SDMA_MGCG | | 1250 | AMD_CG_SUPPORT_SDMA_MGCG | |
1224 | AMD_CG_SUPPORT_SDMA_LS; | 1251 | AMD_CG_SUPPORT_SDMA_LS; |
1252 | /* rev0 hardware doesn't support PG */ | ||
1225 | adev->pg_flags = 0; | 1253 | adev->pg_flags = 0; |
1254 | if (adev->rev_id != 0x00) | ||
1255 | adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | | ||
1256 | AMD_PG_SUPPORT_GFX_SMG | | ||
1257 | AMD_PG_SUPPORT_GFX_DMG | | ||
1258 | AMD_PG_SUPPORT_CP | | ||
1259 | AMD_PG_SUPPORT_RLC_SMU_HS | | ||
1260 | AMD_PG_SUPPORT_GFX_PIPELINE; | ||
1226 | adev->external_rev_id = adev->rev_id + 0x1; | 1261 | adev->external_rev_id = adev->rev_id + 0x1; |
1227 | break; | 1262 | break; |
1228 | case CHIP_STONEY: | 1263 | case CHIP_STONEY: |
1229 | adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG | | 1264 | adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG | |
1230 | AMD_CG_SUPPORT_GFX_MGCG | | 1265 | AMD_CG_SUPPORT_GFX_MGCG | |
1231 | AMD_CG_SUPPORT_GFX_MGLS | | 1266 | AMD_CG_SUPPORT_GFX_MGLS | |
1267 | AMD_CG_SUPPORT_GFX_RLC_LS | | ||
1268 | AMD_CG_SUPPORT_GFX_CP_LS | | ||
1269 | AMD_CG_SUPPORT_GFX_CGTS | | ||
1270 | AMD_CG_SUPPORT_GFX_MGLS | | ||
1271 | AMD_CG_SUPPORT_GFX_CGTS_LS | | ||
1272 | AMD_CG_SUPPORT_GFX_CGCG | | ||
1273 | AMD_CG_SUPPORT_GFX_CGLS | | ||
1232 | AMD_CG_SUPPORT_BIF_LS | | 1274 | AMD_CG_SUPPORT_BIF_LS | |
1233 | AMD_CG_SUPPORT_HDP_MGCG | | 1275 | AMD_CG_SUPPORT_HDP_MGCG | |
1234 | AMD_CG_SUPPORT_HDP_LS | | 1276 | AMD_CG_SUPPORT_HDP_LS | |
1235 | AMD_CG_SUPPORT_SDMA_MGCG | | 1277 | AMD_CG_SUPPORT_SDMA_MGCG | |
1236 | AMD_CG_SUPPORT_SDMA_LS; | 1278 | AMD_CG_SUPPORT_SDMA_LS; |
1237 | adev->pg_flags = 0; | 1279 | adev->pg_flags = AMD_PG_SUPPORT_GFX_PG | |
1280 | AMD_PG_SUPPORT_GFX_SMG | | ||
1281 | AMD_PG_SUPPORT_GFX_DMG | | ||
1282 | AMD_PG_SUPPORT_GFX_PIPELINE | | ||
1283 | AMD_PG_SUPPORT_CP | | ||
1284 | AMD_PG_SUPPORT_RLC_SMU_HS; | ||
1238 | adev->external_rev_id = adev->rev_id + 0x1; | 1285 | adev->external_rev_id = adev->rev_id + 0x1; |
1239 | break; | 1286 | break; |
1240 | default: | 1287 | default: |
diff --git a/drivers/gpu/drm/amd/include/amd_pcie.h b/drivers/gpu/drm/amd/include/amd_pcie.h index 7c2a916c1e63..5eb895fd98bf 100644 --- a/drivers/gpu/drm/amd/include/amd_pcie.h +++ b/drivers/gpu/drm/amd/include/amd_pcie.h | |||
@@ -37,6 +37,13 @@ | |||
37 | #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_MASK 0x0000FFFF | 37 | #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_MASK 0x0000FFFF |
38 | #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_SHIFT 0 | 38 | #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_SHIFT 0 |
39 | 39 | ||
40 | /* gen: chipset 1/2, asic 1/2/3 */ | ||
41 | #define AMDGPU_DEFAULT_PCIE_GEN_MASK (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 \ | ||
42 | | CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 \ | ||
43 | | CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 \ | ||
44 | | CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 \ | ||
45 | | CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3) | ||
46 | |||
40 | /* Following flags shows PCIe lane width switch supported in driver which are decided by chipset and ASIC */ | 47 | /* Following flags shows PCIe lane width switch supported in driver which are decided by chipset and ASIC */ |
41 | #define CAIL_PCIE_LINK_WIDTH_SUPPORT_X1 0x00010000 | 48 | #define CAIL_PCIE_LINK_WIDTH_SUPPORT_X1 0x00010000 |
42 | #define CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 0x00020000 | 49 | #define CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 0x00020000 |
@@ -47,4 +54,11 @@ | |||
47 | #define CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 0x00400000 | 54 | #define CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 0x00400000 |
48 | #define CAIL_PCIE_LINK_WIDTH_SUPPORT_SHIFT 16 | 55 | #define CAIL_PCIE_LINK_WIDTH_SUPPORT_SHIFT 16 |
49 | 56 | ||
57 | /* 1/2/4/8/16 lanes */ | ||
58 | #define AMDGPU_DEFAULT_PCIE_MLW_MASK (CAIL_PCIE_LINK_WIDTH_SUPPORT_X1 \ | ||
59 | | CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 \ | ||
60 | | CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 \ | ||
61 | | CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 \ | ||
62 | | CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) | ||
63 | |||
50 | #endif | 64 | #endif |
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index afce1edbe250..a74a0d2ff1ca 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h | |||
@@ -26,15 +26,6 @@ | |||
26 | #define AMD_MAX_USEC_TIMEOUT 100000 /* 100 ms */ | 26 | #define AMD_MAX_USEC_TIMEOUT 100000 /* 100 ms */ |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * Supported GPU families (aligned with amdgpu_drm.h) | ||
30 | */ | ||
31 | #define AMD_FAMILY_UNKNOWN 0 | ||
32 | #define AMD_FAMILY_CI 120 /* Bonaire, Hawaii */ | ||
33 | #define AMD_FAMILY_KV 125 /* Kaveri, Kabini, Mullins */ | ||
34 | #define AMD_FAMILY_VI 130 /* Iceland, Tonga */ | ||
35 | #define AMD_FAMILY_CZ 135 /* Carrizo */ | ||
36 | |||
37 | /* | ||
38 | * Supported ASIC types | 29 | * Supported ASIC types |
39 | */ | 30 | */ |
40 | enum amd_asic_type { | 31 | enum amd_asic_type { |
@@ -120,6 +111,8 @@ enum amd_powergating_state { | |||
120 | #define AMD_PG_SUPPORT_SDMA (1 << 8) | 111 | #define AMD_PG_SUPPORT_SDMA (1 << 8) |
121 | #define AMD_PG_SUPPORT_ACP (1 << 9) | 112 | #define AMD_PG_SUPPORT_ACP (1 << 9) |
122 | #define AMD_PG_SUPPORT_SAMU (1 << 10) | 113 | #define AMD_PG_SUPPORT_SAMU (1 << 10) |
114 | #define AMD_PG_SUPPORT_GFX_QUICK_MG (1 << 11) | ||
115 | #define AMD_PG_SUPPORT_GFX_PIPELINE (1 << 12) | ||
123 | 116 | ||
124 | enum amd_pm_state_type { | 117 | enum amd_pm_state_type { |
125 | /* not used for dpm */ | 118 | /* not used for dpm */ |
diff --git a/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_d.h b/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_d.h index ebaf67bb1589..90ff7c8a6011 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_d.h +++ b/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_d.h | |||
@@ -2823,4 +2823,7 @@ | |||
2823 | #define mmDC_EDC_CSINVOC_CNT 0x3192 | 2823 | #define mmDC_EDC_CSINVOC_CNT 0x3192 |
2824 | #define mmDC_EDC_RESTORE_CNT 0x3193 | 2824 | #define mmDC_EDC_RESTORE_CNT 0x3193 |
2825 | 2825 | ||
2826 | #define mmGC_CAC_IND_INDEX 0x129a | ||
2827 | #define mmGC_CAC_IND_DATA 0x129b | ||
2828 | |||
2826 | #endif /* GFX_8_0_D_H */ | 2829 | #endif /* GFX_8_0_D_H */ |
diff --git a/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_sh_mask.h index 7d722458d9f5..4070ca3a68eb 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_8_0_sh_mask.h | |||
@@ -8730,8 +8730,6 @@ | |||
8730 | #define RLC_GPM_STAT__DYN_CU_POWERING_DOWN__SHIFT 0x10 | 8730 | #define RLC_GPM_STAT__DYN_CU_POWERING_DOWN__SHIFT 0x10 |
8731 | #define RLC_GPM_STAT__ABORTED_PD_SEQUENCE_MASK 0x20000 | 8731 | #define RLC_GPM_STAT__ABORTED_PD_SEQUENCE_MASK 0x20000 |
8732 | #define RLC_GPM_STAT__ABORTED_PD_SEQUENCE__SHIFT 0x11 | 8732 | #define RLC_GPM_STAT__ABORTED_PD_SEQUENCE__SHIFT 0x11 |
8733 | #define RLC_GPM_STAT__RESERVED_MASK 0xfc0000 | ||
8734 | #define RLC_GPM_STAT__RESERVED__SHIFT 0x12 | ||
8735 | #define RLC_GPM_STAT__PG_ERROR_STATUS_MASK 0xff000000 | 8733 | #define RLC_GPM_STAT__PG_ERROR_STATUS_MASK 0xff000000 |
8736 | #define RLC_GPM_STAT__PG_ERROR_STATUS__SHIFT 0x18 | 8734 | #define RLC_GPM_STAT__PG_ERROR_STATUS__SHIFT 0x18 |
8737 | #define RLC_GPU_CLOCK_32_RES_SEL__RES_SEL_MASK 0x3f | 8735 | #define RLC_GPU_CLOCK_32_RES_SEL__RES_SEL_MASK 0x3f |
@@ -8764,8 +8762,10 @@ | |||
8764 | #define RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE__SHIFT 0x12 | 8762 | #define RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE__SHIFT 0x12 |
8765 | #define RLC_PG_CNTL__SMU_HANDSHAKE_ENABLE_MASK 0x80000 | 8763 | #define RLC_PG_CNTL__SMU_HANDSHAKE_ENABLE_MASK 0x80000 |
8766 | #define RLC_PG_CNTL__SMU_HANDSHAKE_ENABLE__SHIFT 0x13 | 8764 | #define RLC_PG_CNTL__SMU_HANDSHAKE_ENABLE__SHIFT 0x13 |
8767 | #define RLC_PG_CNTL__RESERVED1_MASK 0xf00000 | 8765 | #define RLC_PG_CNTL__QUICK_PG_ENABLE_MASK 0x100000 |
8768 | #define RLC_PG_CNTL__RESERVED1__SHIFT 0x14 | 8766 | #define RLC_PG_CNTL__QUICK_PG_ENABLE__SHIFT 0x14 |
8767 | #define RLC_PG_CNTL__RESERVED1_MASK 0xe00000 | ||
8768 | #define RLC_PG_CNTL__RESERVED1__SHIFT 0x15 | ||
8769 | #define RLC_GPM_THREAD_PRIORITY__THREAD0_PRIORITY_MASK 0xff | 8769 | #define RLC_GPM_THREAD_PRIORITY__THREAD0_PRIORITY_MASK 0xff |
8770 | #define RLC_GPM_THREAD_PRIORITY__THREAD0_PRIORITY__SHIFT 0x0 | 8770 | #define RLC_GPM_THREAD_PRIORITY__THREAD0_PRIORITY__SHIFT 0x0 |
8771 | #define RLC_GPM_THREAD_PRIORITY__THREAD1_PRIORITY_MASK 0xff00 | 8771 | #define RLC_GPM_THREAD_PRIORITY__THREAD1_PRIORITY_MASK 0xff00 |
@@ -9102,8 +9102,6 @@ | |||
9102 | #define RLC_GPM_LOG_CONT__CONT__SHIFT 0x0 | 9102 | #define RLC_GPM_LOG_CONT__CONT__SHIFT 0x0 |
9103 | #define RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG_MASK 0xff | 9103 | #define RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG_MASK 0xff |
9104 | #define RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG__SHIFT 0x0 | 9104 | #define RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG__SHIFT 0x0 |
9105 | #define RLC_PG_DELAY_3__RESERVED_MASK 0xffffff00 | ||
9106 | #define RLC_PG_DELAY_3__RESERVED__SHIFT 0x8 | ||
9107 | #define RLC_GPM_INT_DISABLE_TH0__DISABLE_MASK 0xffffffff | 9105 | #define RLC_GPM_INT_DISABLE_TH0__DISABLE_MASK 0xffffffff |
9108 | #define RLC_GPM_INT_DISABLE_TH0__DISABLE__SHIFT 0x0 | 9106 | #define RLC_GPM_INT_DISABLE_TH0__DISABLE__SHIFT 0x0 |
9109 | #define RLC_GPM_INT_DISABLE_TH1__DISABLE_MASK 0xffffffff | 9107 | #define RLC_GPM_INT_DISABLE_TH1__DISABLE_MASK 0xffffffff |
@@ -9124,14 +9122,8 @@ | |||
9124 | #define RLC_SRM_DEBUG_SELECT__RESERVED__SHIFT 0x8 | 9122 | #define RLC_SRM_DEBUG_SELECT__RESERVED__SHIFT 0x8 |
9125 | #define RLC_SRM_DEBUG__DATA_MASK 0xffffffff | 9123 | #define RLC_SRM_DEBUG__DATA_MASK 0xffffffff |
9126 | #define RLC_SRM_DEBUG__DATA__SHIFT 0x0 | 9124 | #define RLC_SRM_DEBUG__DATA__SHIFT 0x0 |
9127 | #define RLC_SRM_ARAM_ADDR__ADDR_MASK 0x3ff | ||
9128 | #define RLC_SRM_ARAM_ADDR__ADDR__SHIFT 0x0 | ||
9129 | #define RLC_SRM_ARAM_ADDR__RESERVED_MASK 0xfffffc00 | ||
9130 | #define RLC_SRM_ARAM_ADDR__RESERVED__SHIFT 0xa | ||
9131 | #define RLC_SRM_ARAM_DATA__DATA_MASK 0xffffffff | 9125 | #define RLC_SRM_ARAM_DATA__DATA_MASK 0xffffffff |
9132 | #define RLC_SRM_ARAM_DATA__DATA__SHIFT 0x0 | 9126 | #define RLC_SRM_ARAM_DATA__DATA__SHIFT 0x0 |
9133 | #define RLC_SRM_DRAM_ADDR__ADDR_MASK 0x3ff | ||
9134 | #define RLC_SRM_DRAM_ADDR__ADDR__SHIFT 0x0 | ||
9135 | #define RLC_SRM_DRAM_ADDR__RESERVED_MASK 0xfffffc00 | 9127 | #define RLC_SRM_DRAM_ADDR__RESERVED_MASK 0xfffffc00 |
9136 | #define RLC_SRM_DRAM_ADDR__RESERVED__SHIFT 0xa | 9128 | #define RLC_SRM_DRAM_ADDR__RESERVED__SHIFT 0xa |
9137 | #define RLC_SRM_DRAM_DATA__DATA_MASK 0xffffffff | 9129 | #define RLC_SRM_DRAM_DATA__DATA_MASK 0xffffffff |
@@ -17946,8 +17938,6 @@ | |||
17946 | #define VGT_TESS_DISTRIBUTION__ACCUM_TRI__SHIFT 0x8 | 17938 | #define VGT_TESS_DISTRIBUTION__ACCUM_TRI__SHIFT 0x8 |
17947 | #define VGT_TESS_DISTRIBUTION__ACCUM_QUAD_MASK 0xff0000 | 17939 | #define VGT_TESS_DISTRIBUTION__ACCUM_QUAD_MASK 0xff0000 |
17948 | #define VGT_TESS_DISTRIBUTION__ACCUM_QUAD__SHIFT 0x10 | 17940 | #define VGT_TESS_DISTRIBUTION__ACCUM_QUAD__SHIFT 0x10 |
17949 | #define VGT_TESS_DISTRIBUTION__DONUT_SPLIT_MASK 0xff000000 | ||
17950 | #define VGT_TESS_DISTRIBUTION__DONUT_SPLIT__SHIFT 0x18 | ||
17951 | #define VGT_TF_RING_SIZE__SIZE_MASK 0xffff | 17941 | #define VGT_TF_RING_SIZE__SIZE_MASK 0xffff |
17952 | #define VGT_TF_RING_SIZE__SIZE__SHIFT 0x0 | 17942 | #define VGT_TF_RING_SIZE__SIZE__SHIFT 0x0 |
17953 | #define VGT_SYS_CONFIG__DUAL_CORE_EN_MASK 0x1 | 17943 | #define VGT_SYS_CONFIG__DUAL_CORE_EN_MASK 0x1 |
@@ -20502,8 +20492,6 @@ | |||
20502 | #define DIDT_SQ_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 | 20492 | #define DIDT_SQ_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 |
20503 | #define DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 | 20493 | #define DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 |
20504 | #define DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 | 20494 | #define DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 |
20505 | #define DIDT_SQ_CTRL0__UNUSED_0_MASK 0xffffffc0 | ||
20506 | #define DIDT_SQ_CTRL0__UNUSED_0__SHIFT 0x6 | ||
20507 | #define DIDT_SQ_CTRL1__MIN_POWER_MASK 0xffff | 20495 | #define DIDT_SQ_CTRL1__MIN_POWER_MASK 0xffff |
20508 | #define DIDT_SQ_CTRL1__MIN_POWER__SHIFT 0x0 | 20496 | #define DIDT_SQ_CTRL1__MIN_POWER__SHIFT 0x0 |
20509 | #define DIDT_SQ_CTRL1__MAX_POWER_MASK 0xffff0000 | 20497 | #define DIDT_SQ_CTRL1__MAX_POWER_MASK 0xffff0000 |
@@ -20558,8 +20546,6 @@ | |||
20558 | #define DIDT_DB_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 | 20546 | #define DIDT_DB_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 |
20559 | #define DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 | 20547 | #define DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 |
20560 | #define DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 | 20548 | #define DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 |
20561 | #define DIDT_DB_CTRL0__UNUSED_0_MASK 0xffffffc0 | ||
20562 | #define DIDT_DB_CTRL0__UNUSED_0__SHIFT 0x6 | ||
20563 | #define DIDT_DB_CTRL1__MIN_POWER_MASK 0xffff | 20549 | #define DIDT_DB_CTRL1__MIN_POWER_MASK 0xffff |
20564 | #define DIDT_DB_CTRL1__MIN_POWER__SHIFT 0x0 | 20550 | #define DIDT_DB_CTRL1__MIN_POWER__SHIFT 0x0 |
20565 | #define DIDT_DB_CTRL1__MAX_POWER_MASK 0xffff0000 | 20551 | #define DIDT_DB_CTRL1__MAX_POWER_MASK 0xffff0000 |
@@ -20614,8 +20600,6 @@ | |||
20614 | #define DIDT_TD_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 | 20600 | #define DIDT_TD_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 |
20615 | #define DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 | 20601 | #define DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 |
20616 | #define DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 | 20602 | #define DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 |
20617 | #define DIDT_TD_CTRL0__UNUSED_0_MASK 0xffffffc0 | ||
20618 | #define DIDT_TD_CTRL0__UNUSED_0__SHIFT 0x6 | ||
20619 | #define DIDT_TD_CTRL1__MIN_POWER_MASK 0xffff | 20603 | #define DIDT_TD_CTRL1__MIN_POWER_MASK 0xffff |
20620 | #define DIDT_TD_CTRL1__MIN_POWER__SHIFT 0x0 | 20604 | #define DIDT_TD_CTRL1__MIN_POWER__SHIFT 0x0 |
20621 | #define DIDT_TD_CTRL1__MAX_POWER_MASK 0xffff0000 | 20605 | #define DIDT_TD_CTRL1__MAX_POWER_MASK 0xffff0000 |
@@ -20670,8 +20654,6 @@ | |||
20670 | #define DIDT_TCP_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 | 20654 | #define DIDT_TCP_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 |
20671 | #define DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 | 20655 | #define DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 |
20672 | #define DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 | 20656 | #define DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 |
20673 | #define DIDT_TCP_CTRL0__UNUSED_0_MASK 0xffffffc0 | ||
20674 | #define DIDT_TCP_CTRL0__UNUSED_0__SHIFT 0x6 | ||
20675 | #define DIDT_TCP_CTRL1__MIN_POWER_MASK 0xffff | 20657 | #define DIDT_TCP_CTRL1__MIN_POWER_MASK 0xffff |
20676 | #define DIDT_TCP_CTRL1__MIN_POWER__SHIFT 0x0 | 20658 | #define DIDT_TCP_CTRL1__MIN_POWER__SHIFT 0x0 |
20677 | #define DIDT_TCP_CTRL1__MAX_POWER_MASK 0xffff0000 | 20659 | #define DIDT_TCP_CTRL1__MAX_POWER_MASK 0xffff0000 |
@@ -20726,8 +20708,6 @@ | |||
20726 | #define DIDT_DBR_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 | 20708 | #define DIDT_DBR_CTRL0__DIDT_CTRL_RST__SHIFT 0x4 |
20727 | #define DIDT_DBR_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 | 20709 | #define DIDT_DBR_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20 |
20728 | #define DIDT_DBR_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 | 20710 | #define DIDT_DBR_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5 |
20729 | #define DIDT_DBR_CTRL0__UNUSED_0_MASK 0xffffffc0 | ||
20730 | #define DIDT_DBR_CTRL0__UNUSED_0__SHIFT 0x6 | ||
20731 | #define DIDT_DBR_CTRL1__MIN_POWER_MASK 0xffff | 20711 | #define DIDT_DBR_CTRL1__MIN_POWER_MASK 0xffff |
20732 | #define DIDT_DBR_CTRL1__MIN_POWER__SHIFT 0x0 | 20712 | #define DIDT_DBR_CTRL1__MIN_POWER__SHIFT 0x0 |
20733 | #define DIDT_DBR_CTRL1__MAX_POWER_MASK 0xffff0000 | 20713 | #define DIDT_DBR_CTRL1__MAX_POWER_MASK 0xffff0000 |
@@ -20773,4 +20753,84 @@ | |||
20773 | #define DIDT_DBR_WEIGHT8_11__WEIGHT11_MASK 0xff000000 | 20753 | #define DIDT_DBR_WEIGHT8_11__WEIGHT11_MASK 0xff000000 |
20774 | #define DIDT_DBR_WEIGHT8_11__WEIGHT11__SHIFT 0x18 | 20754 | #define DIDT_DBR_WEIGHT8_11__WEIGHT11__SHIFT 0x18 |
20775 | 20755 | ||
20756 | #define DIDT_SQ_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK 0x00000001 | ||
20757 | #define DIDT_SQ_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT 0x00000000 | ||
20758 | |||
20759 | #define DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK 0x0000007e | ||
20760 | #define DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK 0x00001f80L | ||
20761 | #define DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT 0x00000001 | ||
20762 | #define DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT 0x00000007 | ||
20763 | |||
20764 | #define DIDT_SQ_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK 0x1fffe000L | ||
20765 | #define DIDT_SQ_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT 0x0000000d | ||
20766 | |||
20767 | #define DIDT_SQ_STALL_CTRL__UNUSED_0_MASK 0xe0000000L | ||
20768 | #define DIDT_SQ_STALL_CTRL__UNUSED_0__SHIFT 0x0000001d | ||
20769 | |||
20770 | #define DIDT_SQ_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK 0x00000001L | ||
20771 | #define DIDT_SQ_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT 0x00000000 | ||
20772 | |||
20773 | #define DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK 0x00007ffeL | ||
20774 | #define DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT 0x00000001 | ||
20775 | #define DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK 0x1fff8000L | ||
20776 | #define DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT 0x0000000f | ||
20777 | |||
20778 | #define DIDT_TD_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK 0x00000001L | ||
20779 | #define DIDT_TD_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT 0x00000000 | ||
20780 | |||
20781 | #define DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK 0x0000007eL | ||
20782 | #define DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK 0x00001f80L | ||
20783 | #define DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT 0x00000001 | ||
20784 | #define DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT 0x00000007 | ||
20785 | |||
20786 | #define DIDT_TD_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK 0x1fffe000L | ||
20787 | #define DIDT_TD_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT 0x0000000d | ||
20788 | |||
20789 | #define DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI_MASK 0x00000fc0L | ||
20790 | #define DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO_MASK 0x0003f000L | ||
20791 | #define DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT 0x00000006 | ||
20792 | #define DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT 0x0000000c | ||
20793 | |||
20794 | #define DIDT_TD_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK 0x00000001L | ||
20795 | #define DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK 0x00007ffeL | ||
20796 | #define DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK 0x1fff8000L | ||
20797 | |||
20798 | #define DIDT_TD_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT 0x00000000 | ||
20799 | #define DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT 0x00000001 | ||
20800 | #define DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT 0x0000000f | ||
20801 | |||
20802 | #define DIDT_TD_STALL_CTRL__UNUSED_0_MASK 0xe0000000L | ||
20803 | #define DIDT_TD_STALL_CTRL__UNUSED_0__SHIFT 0x0000001d | ||
20804 | |||
20805 | #define DIDT_TD_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI_MASK 0x00000fc0L | ||
20806 | #define DIDT_TD_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO_MASK 0x0003f000L | ||
20807 | #define DIDT_TD_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT 0x00000006 | ||
20808 | #define DIDT_TD_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT 0x0000000c | ||
20809 | |||
20810 | #define DIDT_TCP_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK 0x00000001L | ||
20811 | #define DIDT_TCP_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT 0x00000000 | ||
20812 | |||
20813 | #define DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK 0x0000007eL | ||
20814 | #define DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK 0x00001f80L | ||
20815 | #define DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT 0x00000001 | ||
20816 | #define DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT 0x00000007 | ||
20817 | |||
20818 | #define DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK 0x1fffe000L | ||
20819 | #define DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT 0x0000000d | ||
20820 | |||
20821 | #define DIDT_TCP_STALL_CTRL__UNUSED_0_MASK 0xe0000000L | ||
20822 | #define DIDT_TCP_STALL_CTRL__UNUSED_0__SHIFT 0x0000001d | ||
20823 | |||
20824 | #define DIDT_TCP_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK 0x00000001L | ||
20825 | #define DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK 0x00007ffeL | ||
20826 | #define DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK 0x1fff8000L | ||
20827 | #define DIDT_TCP_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT 0x00000000 | ||
20828 | #define DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT 0x00000001 | ||
20829 | #define DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT 0x0000000f | ||
20830 | |||
20831 | #define DIDT_TCP_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI_MASK 0x00000fc0L | ||
20832 | #define DIDT_TCP_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO_MASK 0x0003f000L | ||
20833 | #define DIDT_TCP_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT 0x00000006 | ||
20834 | #define DIDT_TCP_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT 0x0000000c | ||
20835 | |||
20776 | #endif /* GFX_8_0_SH_MASK_H */ | 20836 | #endif /* GFX_8_0_SH_MASK_H */ |
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h index 7464daf89ca1..0c8c85d2a2a5 100644 --- a/drivers/gpu/drm/amd/include/cgs_common.h +++ b/drivers/gpu/drm/amd/include/cgs_common.h | |||
@@ -49,6 +49,7 @@ enum cgs_ind_reg { | |||
49 | CGS_IND_REG__SMC, | 49 | CGS_IND_REG__SMC, |
50 | CGS_IND_REG__UVD_CTX, | 50 | CGS_IND_REG__UVD_CTX, |
51 | CGS_IND_REG__DIDT, | 51 | CGS_IND_REG__DIDT, |
52 | CGS_IND_REG_GC_CAC, | ||
52 | CGS_IND_REG__AUDIO_ENDPT | 53 | CGS_IND_REG__AUDIO_ENDPT |
53 | }; | 54 | }; |
54 | 55 | ||
@@ -115,6 +116,7 @@ enum cgs_system_info_id { | |||
115 | CGS_SYSTEM_INFO_CG_FLAGS, | 116 | CGS_SYSTEM_INFO_CG_FLAGS, |
116 | CGS_SYSTEM_INFO_PG_FLAGS, | 117 | CGS_SYSTEM_INFO_PG_FLAGS, |
117 | CGS_SYSTEM_INFO_GFX_CU_INFO, | 118 | CGS_SYSTEM_INFO_GFX_CU_INFO, |
119 | CGS_SYSTEM_INFO_GFX_SE_INFO, | ||
118 | CGS_SYSTEM_INFO_ID_MAXIMUM, | 120 | CGS_SYSTEM_INFO_ID_MAXIMUM, |
119 | }; | 121 | }; |
120 | 122 | ||
@@ -189,7 +191,6 @@ typedef unsigned long cgs_handle_t; | |||
189 | 191 | ||
190 | struct cgs_acpi_method_argument { | 192 | struct cgs_acpi_method_argument { |
191 | uint32_t type; | 193 | uint32_t type; |
192 | uint32_t method_length; | ||
193 | uint32_t data_length; | 194 | uint32_t data_length; |
194 | union{ | 195 | union{ |
195 | uint32_t value; | 196 | uint32_t value; |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index e629f8a9fe93..f9e03ad0baa2 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
@@ -536,6 +536,10 @@ int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id, void *input, | |||
536 | case AMD_PP_EVENT_COMPLETE_INIT: | 536 | case AMD_PP_EVENT_COMPLETE_INIT: |
537 | ret = pem_handle_event(pp_handle->eventmgr, event_id, &data); | 537 | ret = pem_handle_event(pp_handle->eventmgr, event_id, &data); |
538 | break; | 538 | break; |
539 | case AMD_PP_EVENT_READJUST_POWER_STATE: | ||
540 | pp_handle->hwmgr->current_ps = pp_handle->hwmgr->boot_ps; | ||
541 | ret = pem_handle_event(pp_handle->eventmgr, event_id, &data); | ||
542 | break; | ||
539 | default: | 543 | default: |
540 | break; | 544 | break; |
541 | } | 545 | } |
@@ -740,12 +744,12 @@ static int pp_dpm_get_pp_table(void *handle, char **table) | |||
740 | 744 | ||
741 | PP_CHECK_HW(hwmgr); | 745 | PP_CHECK_HW(hwmgr); |
742 | 746 | ||
743 | if (hwmgr->hwmgr_func->get_pp_table == NULL) { | 747 | if (!hwmgr->soft_pp_table) |
744 | printk(KERN_INFO "%s was not implemented.\n", __func__); | 748 | return -EINVAL; |
745 | return 0; | 749 | |
746 | } | 750 | *table = (char *)hwmgr->soft_pp_table; |
747 | 751 | ||
748 | return hwmgr->hwmgr_func->get_pp_table(hwmgr, table); | 752 | return hwmgr->soft_pp_table_size; |
749 | } | 753 | } |
750 | 754 | ||
751 | static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) | 755 | static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) |
@@ -759,12 +763,23 @@ static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) | |||
759 | 763 | ||
760 | PP_CHECK_HW(hwmgr); | 764 | PP_CHECK_HW(hwmgr); |
761 | 765 | ||
762 | if (hwmgr->hwmgr_func->set_pp_table == NULL) { | 766 | if (!hwmgr->hardcode_pp_table) { |
763 | printk(KERN_INFO "%s was not implemented.\n", __func__); | 767 | hwmgr->hardcode_pp_table = |
764 | return 0; | 768 | kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL); |
769 | |||
770 | if (!hwmgr->hardcode_pp_table) | ||
771 | return -ENOMEM; | ||
772 | |||
773 | /* to avoid powerplay crash when hardcode pptable is empty */ | ||
774 | memcpy(hwmgr->hardcode_pp_table, hwmgr->soft_pp_table, | ||
775 | hwmgr->soft_pp_table_size); | ||
765 | } | 776 | } |
766 | 777 | ||
767 | return hwmgr->hwmgr_func->set_pp_table(hwmgr, buf, size); | 778 | memcpy(hwmgr->hardcode_pp_table, buf, size); |
779 | |||
780 | hwmgr->soft_pp_table = hwmgr->hardcode_pp_table; | ||
781 | |||
782 | return amd_powerplay_reset(handle); | ||
768 | } | 783 | } |
769 | 784 | ||
770 | static int pp_dpm_force_clock_level(void *handle, | 785 | static int pp_dpm_force_clock_level(void *handle, |
@@ -806,6 +821,82 @@ static int pp_dpm_print_clock_levels(void *handle, | |||
806 | return hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf); | 821 | return hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf); |
807 | } | 822 | } |
808 | 823 | ||
824 | static int pp_dpm_get_sclk_od(void *handle) | ||
825 | { | ||
826 | struct pp_hwmgr *hwmgr; | ||
827 | |||
828 | if (!handle) | ||
829 | return -EINVAL; | ||
830 | |||
831 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
832 | |||
833 | PP_CHECK_HW(hwmgr); | ||
834 | |||
835 | if (hwmgr->hwmgr_func->get_sclk_od == NULL) { | ||
836 | printk(KERN_INFO "%s was not implemented.\n", __func__); | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | return hwmgr->hwmgr_func->get_sclk_od(hwmgr); | ||
841 | } | ||
842 | |||
843 | static int pp_dpm_set_sclk_od(void *handle, uint32_t value) | ||
844 | { | ||
845 | struct pp_hwmgr *hwmgr; | ||
846 | |||
847 | if (!handle) | ||
848 | return -EINVAL; | ||
849 | |||
850 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
851 | |||
852 | PP_CHECK_HW(hwmgr); | ||
853 | |||
854 | if (hwmgr->hwmgr_func->set_sclk_od == NULL) { | ||
855 | printk(KERN_INFO "%s was not implemented.\n", __func__); | ||
856 | return 0; | ||
857 | } | ||
858 | |||
859 | return hwmgr->hwmgr_func->set_sclk_od(hwmgr, value); | ||
860 | } | ||
861 | |||
862 | static int pp_dpm_get_mclk_od(void *handle) | ||
863 | { | ||
864 | struct pp_hwmgr *hwmgr; | ||
865 | |||
866 | if (!handle) | ||
867 | return -EINVAL; | ||
868 | |||
869 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
870 | |||
871 | PP_CHECK_HW(hwmgr); | ||
872 | |||
873 | if (hwmgr->hwmgr_func->get_mclk_od == NULL) { | ||
874 | printk(KERN_INFO "%s was not implemented.\n", __func__); | ||
875 | return 0; | ||
876 | } | ||
877 | |||
878 | return hwmgr->hwmgr_func->get_mclk_od(hwmgr); | ||
879 | } | ||
880 | |||
881 | static int pp_dpm_set_mclk_od(void *handle, uint32_t value) | ||
882 | { | ||
883 | struct pp_hwmgr *hwmgr; | ||
884 | |||
885 | if (!handle) | ||
886 | return -EINVAL; | ||
887 | |||
888 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
889 | |||
890 | PP_CHECK_HW(hwmgr); | ||
891 | |||
892 | if (hwmgr->hwmgr_func->set_mclk_od == NULL) { | ||
893 | printk(KERN_INFO "%s was not implemented.\n", __func__); | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value); | ||
898 | } | ||
899 | |||
809 | const struct amd_powerplay_funcs pp_dpm_funcs = { | 900 | const struct amd_powerplay_funcs pp_dpm_funcs = { |
810 | .get_temperature = pp_dpm_get_temperature, | 901 | .get_temperature = pp_dpm_get_temperature, |
811 | .load_firmware = pp_dpm_load_fw, | 902 | .load_firmware = pp_dpm_load_fw, |
@@ -828,6 +919,10 @@ const struct amd_powerplay_funcs pp_dpm_funcs = { | |||
828 | .set_pp_table = pp_dpm_set_pp_table, | 919 | .set_pp_table = pp_dpm_set_pp_table, |
829 | .force_clock_level = pp_dpm_force_clock_level, | 920 | .force_clock_level = pp_dpm_force_clock_level, |
830 | .print_clock_levels = pp_dpm_print_clock_levels, | 921 | .print_clock_levels = pp_dpm_print_clock_levels, |
922 | .get_sclk_od = pp_dpm_get_sclk_od, | ||
923 | .set_sclk_od = pp_dpm_set_sclk_od, | ||
924 | .get_mclk_od = pp_dpm_get_mclk_od, | ||
925 | .set_mclk_od = pp_dpm_set_mclk_od, | ||
831 | }; | 926 | }; |
832 | 927 | ||
833 | static int amd_pp_instance_init(struct amd_pp_init *pp_init, | 928 | static int amd_pp_instance_init(struct amd_pp_init *pp_init, |
@@ -909,6 +1004,44 @@ int amd_powerplay_fini(void *handle) | |||
909 | return 0; | 1004 | return 0; |
910 | } | 1005 | } |
911 | 1006 | ||
1007 | int amd_powerplay_reset(void *handle) | ||
1008 | { | ||
1009 | struct pp_instance *instance = (struct pp_instance *)handle; | ||
1010 | struct pp_eventmgr *eventmgr; | ||
1011 | struct pem_event_data event_data = { {0} }; | ||
1012 | int ret; | ||
1013 | |||
1014 | if (instance == NULL) | ||
1015 | return -EINVAL; | ||
1016 | |||
1017 | eventmgr = instance->eventmgr; | ||
1018 | if (!eventmgr || !eventmgr->pp_eventmgr_fini) | ||
1019 | return -EINVAL; | ||
1020 | |||
1021 | eventmgr->pp_eventmgr_fini(eventmgr); | ||
1022 | |||
1023 | ret = pp_sw_fini(handle); | ||
1024 | if (ret) | ||
1025 | return ret; | ||
1026 | |||
1027 | kfree(instance->hwmgr->ps); | ||
1028 | |||
1029 | ret = pp_sw_init(handle); | ||
1030 | if (ret) | ||
1031 | return ret; | ||
1032 | |||
1033 | hw_init_power_state_table(instance->hwmgr); | ||
1034 | |||
1035 | if (eventmgr == NULL || eventmgr->pp_eventmgr_init == NULL) | ||
1036 | return -EINVAL; | ||
1037 | |||
1038 | ret = eventmgr->pp_eventmgr_init(eventmgr); | ||
1039 | if (ret) | ||
1040 | return ret; | ||
1041 | |||
1042 | return pem_handle_event(eventmgr, AMD_PP_EVENT_COMPLETE_INIT, &event_data); | ||
1043 | } | ||
1044 | |||
912 | /* export this function to DAL */ | 1045 | /* export this function to DAL */ |
913 | 1046 | ||
914 | int amd_powerplay_display_configuration_change(void *handle, | 1047 | int amd_powerplay_display_configuration_change(void *handle, |
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c index 5cd123472db4..b6f45fd01fa6 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c | |||
@@ -132,8 +132,7 @@ int pem_task_enable_dynamic_state_management(struct pp_eventmgr *eventmgr, struc | |||
132 | 132 | ||
133 | int pem_task_disable_dynamic_state_management(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | 133 | int pem_task_disable_dynamic_state_management(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) |
134 | { | 134 | { |
135 | /* TODO */ | 135 | return phm_disable_dynamic_state_management(eventmgr->hwmgr); |
136 | return 0; | ||
137 | } | 136 | } |
138 | 137 | ||
139 | int pem_task_enable_clock_power_gatings_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | 138 | int pem_task_enable_clock_power_gatings_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c index 436fc16dabb6..2da548f6337e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c | |||
@@ -206,7 +206,7 @@ int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate) | |||
206 | AMD_IP_BLOCK_TYPE_VCE, | 206 | AMD_IP_BLOCK_TYPE_VCE, |
207 | AMD_PG_STATE_GATE); | 207 | AMD_PG_STATE_GATE); |
208 | cz_enable_disable_vce_dpm(hwmgr, false); | 208 | cz_enable_disable_vce_dpm(hwmgr, false); |
209 | /* TODO: to figure out why vce can't be poweroff*/ | 209 | cz_dpm_powerdown_vce(hwmgr); |
210 | cz_hwmgr->vce_power_gated = true; | 210 | cz_hwmgr->vce_power_gated = true; |
211 | } else { | 211 | } else { |
212 | cz_dpm_powerup_vce(hwmgr); | 212 | cz_dpm_powerup_vce(hwmgr); |
@@ -225,6 +225,7 @@ int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate) | |||
225 | } | 225 | } |
226 | } | 226 | } |
227 | } else { | 227 | } else { |
228 | cz_hwmgr->vce_power_gated = bgate; | ||
228 | cz_dpm_update_vce_dpm(hwmgr); | 229 | cz_dpm_update_vce_dpm(hwmgr); |
229 | cz_enable_disable_vce_dpm(hwmgr, !bgate); | 230 | cz_enable_disable_vce_dpm(hwmgr, !bgate); |
230 | return 0; | 231 | return 0; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index 1f14c477d15d..9bf622e123b6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | |||
@@ -1180,6 +1180,13 @@ static int cz_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, | |||
1180 | static int cz_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | 1180 | static int cz_hwmgr_backend_init(struct pp_hwmgr *hwmgr) |
1181 | { | 1181 | { |
1182 | int result = 0; | 1182 | int result = 0; |
1183 | struct cz_hwmgr *data; | ||
1184 | |||
1185 | data = kzalloc(sizeof(struct cz_hwmgr), GFP_KERNEL); | ||
1186 | if (data == NULL) | ||
1187 | return -ENOMEM; | ||
1188 | |||
1189 | hwmgr->backend = data; | ||
1183 | 1190 | ||
1184 | result = cz_initialize_dpm_defaults(hwmgr); | 1191 | result = cz_initialize_dpm_defaults(hwmgr); |
1185 | if (result != 0) { | 1192 | if (result != 0) { |
@@ -1909,15 +1916,7 @@ static const struct pp_hwmgr_func cz_hwmgr_funcs = { | |||
1909 | 1916 | ||
1910 | int cz_hwmgr_init(struct pp_hwmgr *hwmgr) | 1917 | int cz_hwmgr_init(struct pp_hwmgr *hwmgr) |
1911 | { | 1918 | { |
1912 | struct cz_hwmgr *cz_hwmgr; | ||
1913 | int ret = 0; | ||
1914 | |||
1915 | cz_hwmgr = kzalloc(sizeof(struct cz_hwmgr), GFP_KERNEL); | ||
1916 | if (cz_hwmgr == NULL) | ||
1917 | return -ENOMEM; | ||
1918 | |||
1919 | hwmgr->backend = cz_hwmgr; | ||
1920 | hwmgr->hwmgr_func = &cz_hwmgr_funcs; | 1919 | hwmgr->hwmgr_func = &cz_hwmgr_funcs; |
1921 | hwmgr->pptable_func = &pptable_funcs; | 1920 | hwmgr->pptable_func = &pptable_funcs; |
1922 | return ret; | 1921 | return 0; |
1923 | } | 1922 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 92912ab20944..744aa886a2be 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | |||
@@ -581,25 +581,24 @@ static int fiji_patch_boot_state(struct pp_hwmgr *hwmgr, | |||
581 | 581 | ||
582 | static int fiji_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) | 582 | static int fiji_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) |
583 | { | 583 | { |
584 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
585 | |||
586 | if (data->soft_pp_table) { | ||
587 | kfree(data->soft_pp_table); | ||
588 | data->soft_pp_table = NULL; | ||
589 | } | ||
590 | |||
591 | return phm_hwmgr_backend_fini(hwmgr); | 584 | return phm_hwmgr_backend_fini(hwmgr); |
592 | } | 585 | } |
593 | 586 | ||
594 | static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | 587 | static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr) |
595 | { | 588 | { |
596 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | 589 | struct fiji_hwmgr *data; |
597 | uint32_t i; | 590 | uint32_t i; |
598 | struct phm_ppt_v1_information *table_info = | 591 | struct phm_ppt_v1_information *table_info = |
599 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | 592 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
600 | bool stay_in_boot; | 593 | bool stay_in_boot; |
601 | int result; | 594 | int result; |
602 | 595 | ||
596 | data = kzalloc(sizeof(struct fiji_hwmgr), GFP_KERNEL); | ||
597 | if (data == NULL) | ||
598 | return -ENOMEM; | ||
599 | |||
600 | hwmgr->backend = data; | ||
601 | |||
603 | data->dll_default_on = false; | 602 | data->dll_default_on = false; |
604 | data->sram_end = SMC_RAM_END; | 603 | data->sram_end = SMC_RAM_END; |
605 | 604 | ||
@@ -734,7 +733,7 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
734 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO; | 733 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO; |
735 | result = cgs_query_system_info(hwmgr->device, &sys_info); | 734 | result = cgs_query_system_info(hwmgr->device, &sys_info); |
736 | if (result) | 735 | if (result) |
737 | data->pcie_gen_cap = 0x30007; | 736 | data->pcie_gen_cap = AMDGPU_DEFAULT_PCIE_GEN_MASK; |
738 | else | 737 | else |
739 | data->pcie_gen_cap = (uint32_t)sys_info.value; | 738 | data->pcie_gen_cap = (uint32_t)sys_info.value; |
740 | if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) | 739 | if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) |
@@ -743,7 +742,7 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
743 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW; | 742 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW; |
744 | result = cgs_query_system_info(hwmgr->device, &sys_info); | 743 | result = cgs_query_system_info(hwmgr->device, &sys_info); |
745 | if (result) | 744 | if (result) |
746 | data->pcie_lane_cap = 0x2f0000; | 745 | data->pcie_lane_cap = AMDGPU_DEFAULT_PCIE_MLW_MASK; |
747 | else | 746 | else |
748 | data->pcie_lane_cap = (uint32_t)sys_info.value; | 747 | data->pcie_lane_cap = (uint32_t)sys_info.value; |
749 | } else { | 748 | } else { |
@@ -1236,6 +1235,34 @@ static int fiji_program_voting_clients(struct pp_hwmgr *hwmgr) | |||
1236 | return 0; | 1235 | return 0; |
1237 | } | 1236 | } |
1238 | 1237 | ||
1238 | static int fiji_clear_voting_clients(struct pp_hwmgr *hwmgr) | ||
1239 | { | ||
1240 | /* Reset voting clients before disabling DPM */ | ||
1241 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
1242 | SCLK_PWRMGT_CNTL, RESET_SCLK_CNT, 1); | ||
1243 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
1244 | SCLK_PWRMGT_CNTL, RESET_BUSY_CNT, 1); | ||
1245 | |||
1246 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
1247 | ixCG_FREQ_TRAN_VOTING_0, 0); | ||
1248 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
1249 | ixCG_FREQ_TRAN_VOTING_1, 0); | ||
1250 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
1251 | ixCG_FREQ_TRAN_VOTING_2, 0); | ||
1252 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
1253 | ixCG_FREQ_TRAN_VOTING_3, 0); | ||
1254 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
1255 | ixCG_FREQ_TRAN_VOTING_4, 0); | ||
1256 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
1257 | ixCG_FREQ_TRAN_VOTING_5, 0); | ||
1258 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
1259 | ixCG_FREQ_TRAN_VOTING_6, 0); | ||
1260 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
1261 | ixCG_FREQ_TRAN_VOTING_7, 0); | ||
1262 | |||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1239 | /** | 1266 | /** |
1240 | * Get the location of various tables inside the FW image. | 1267 | * Get the location of various tables inside the FW image. |
1241 | * | 1268 | * |
@@ -1363,6 +1390,17 @@ static int fiji_copy_and_switch_arb_sets(struct pp_hwmgr *hwmgr, | |||
1363 | } | 1390 | } |
1364 | 1391 | ||
1365 | /** | 1392 | /** |
1393 | * Call SMC to reset S0/S1 to S1 and Reset SMIO to initial value | ||
1394 | * | ||
1395 | * @param hwmgr the address of the powerplay hardware manager. | ||
1396 | * @return if success then 0; | ||
1397 | */ | ||
1398 | static int fiji_reset_to_default(struct pp_hwmgr *hwmgr) | ||
1399 | { | ||
1400 | return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_ResetToDefaults); | ||
1401 | } | ||
1402 | |||
1403 | /** | ||
1366 | * Initial switch from ARB F0->F1 | 1404 | * Initial switch from ARB F0->F1 |
1367 | * | 1405 | * |
1368 | * @param hwmgr the address of the powerplay hardware manager. | 1406 | * @param hwmgr the address of the powerplay hardware manager. |
@@ -1375,6 +1413,21 @@ static int fiji_initial_switch_from_arbf0_to_f1(struct pp_hwmgr *hwmgr) | |||
1375 | MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1); | 1413 | MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1); |
1376 | } | 1414 | } |
1377 | 1415 | ||
1416 | static int fiji_force_switch_to_arbf0(struct pp_hwmgr *hwmgr) | ||
1417 | { | ||
1418 | uint32_t tmp; | ||
1419 | |||
1420 | tmp = (cgs_read_ind_register(hwmgr->device, | ||
1421 | CGS_IND_REG__SMC, ixSMC_SCRATCH9) & | ||
1422 | 0x0000ff00) >> 8; | ||
1423 | |||
1424 | if (tmp == MC_CG_ARB_FREQ_F0) | ||
1425 | return 0; | ||
1426 | |||
1427 | return fiji_copy_and_switch_arb_sets(hwmgr, | ||
1428 | tmp, MC_CG_ARB_FREQ_F0); | ||
1429 | } | ||
1430 | |||
1378 | static int fiji_reset_single_dpm_table(struct pp_hwmgr *hwmgr, | 1431 | static int fiji_reset_single_dpm_table(struct pp_hwmgr *hwmgr, |
1379 | struct fiji_single_dpm_table *dpm_table, uint32_t count) | 1432 | struct fiji_single_dpm_table *dpm_table, uint32_t count) |
1380 | { | 1433 | { |
@@ -3177,6 +3230,17 @@ static int fiji_enable_ulv(struct pp_hwmgr *hwmgr) | |||
3177 | return 0; | 3230 | return 0; |
3178 | } | 3231 | } |
3179 | 3232 | ||
3233 | static int fiji_disable_ulv(struct pp_hwmgr *hwmgr) | ||
3234 | { | ||
3235 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
3236 | struct fiji_ulv_parm *ulv = &(data->ulv); | ||
3237 | |||
3238 | if (ulv->ulv_supported) | ||
3239 | return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_DisableULV); | ||
3240 | |||
3241 | return 0; | ||
3242 | } | ||
3243 | |||
3180 | static int fiji_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) | 3244 | static int fiji_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) |
3181 | { | 3245 | { |
3182 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | 3246 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
@@ -3197,6 +3261,21 @@ static int fiji_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) | |||
3197 | return 0; | 3261 | return 0; |
3198 | } | 3262 | } |
3199 | 3263 | ||
3264 | static int fiji_disable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) | ||
3265 | { | ||
3266 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
3267 | PHM_PlatformCaps_SclkDeepSleep)) { | ||
3268 | if (smum_send_msg_to_smc(hwmgr->smumgr, | ||
3269 | PPSMC_MSG_MASTER_DeepSleep_OFF)) { | ||
3270 | PP_ASSERT_WITH_CODE(false, | ||
3271 | "Attempt to disable Master Deep Sleep switch failed!", | ||
3272 | return -1); | ||
3273 | } | ||
3274 | } | ||
3275 | |||
3276 | return 0; | ||
3277 | } | ||
3278 | |||
3200 | static int fiji_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) | 3279 | static int fiji_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) |
3201 | { | 3280 | { |
3202 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | 3281 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); |
@@ -3357,6 +3436,70 @@ static int fiji_start_dpm(struct pp_hwmgr *hwmgr) | |||
3357 | return 0; | 3436 | return 0; |
3358 | } | 3437 | } |
3359 | 3438 | ||
3439 | static int fiji_disable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) | ||
3440 | { | ||
3441 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
3442 | |||
3443 | /* disable SCLK dpm */ | ||
3444 | if (!data->sclk_dpm_key_disabled) | ||
3445 | PP_ASSERT_WITH_CODE( | ||
3446 | (smum_send_msg_to_smc(hwmgr->smumgr, | ||
3447 | PPSMC_MSG_DPM_Disable) == 0), | ||
3448 | "Failed to disable SCLK DPM!", | ||
3449 | return -1); | ||
3450 | |||
3451 | /* disable MCLK dpm */ | ||
3452 | if (!data->mclk_dpm_key_disabled) { | ||
3453 | PP_ASSERT_WITH_CODE( | ||
3454 | (smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | ||
3455 | PPSMC_MSG_MCLKDPM_SetEnabledMask, 1) == 0), | ||
3456 | "Failed to force MCLK DPM0!", | ||
3457 | return -1); | ||
3458 | |||
3459 | PP_ASSERT_WITH_CODE( | ||
3460 | (smum_send_msg_to_smc(hwmgr->smumgr, | ||
3461 | PPSMC_MSG_MCLKDPM_Disable) == 0), | ||
3462 | "Failed to disable MCLK DPM!", | ||
3463 | return -1); | ||
3464 | } | ||
3465 | |||
3466 | return 0; | ||
3467 | } | ||
3468 | |||
3469 | static int fiji_stop_dpm(struct pp_hwmgr *hwmgr) | ||
3470 | { | ||
3471 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
3472 | |||
3473 | /* disable general power management */ | ||
3474 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, | ||
3475 | GLOBAL_PWRMGT_EN, 0); | ||
3476 | /* disable sclk deep sleep */ | ||
3477 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL, | ||
3478 | DYNAMIC_PM_EN, 0); | ||
3479 | |||
3480 | /* disable PCIE dpm */ | ||
3481 | if (!data->pcie_dpm_key_disabled) { | ||
3482 | PP_ASSERT_WITH_CODE( | ||
3483 | (smum_send_msg_to_smc(hwmgr->smumgr, | ||
3484 | PPSMC_MSG_PCIeDPM_Disable) == 0), | ||
3485 | "Failed to disable pcie DPM during DPM Stop Function!", | ||
3486 | return -1); | ||
3487 | } | ||
3488 | |||
3489 | if (fiji_disable_sclk_mclk_dpm(hwmgr)) { | ||
3490 | printk(KERN_ERR "Failed to disable Sclk DPM and Mclk DPM!"); | ||
3491 | return -1; | ||
3492 | } | ||
3493 | |||
3494 | PP_ASSERT_WITH_CODE( | ||
3495 | (smum_send_msg_to_smc(hwmgr->smumgr, | ||
3496 | PPSMC_MSG_Voltage_Cntl_Disable) == 0), | ||
3497 | "Failed to disable voltage DPM during DPM Stop Function!", | ||
3498 | return -1); | ||
3499 | |||
3500 | return 0; | ||
3501 | } | ||
3502 | |||
3360 | static void fiji_set_dpm_event_sources(struct pp_hwmgr *hwmgr, | 3503 | static void fiji_set_dpm_event_sources(struct pp_hwmgr *hwmgr, |
3361 | uint32_t sources) | 3504 | uint32_t sources) |
3362 | { | 3505 | { |
@@ -3415,6 +3558,23 @@ static int fiji_enable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) | |||
3415 | return fiji_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); | 3558 | return fiji_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); |
3416 | } | 3559 | } |
3417 | 3560 | ||
3561 | static int fiji_disable_auto_throttle_source(struct pp_hwmgr *hwmgr, | ||
3562 | PHM_AutoThrottleSource source) | ||
3563 | { | ||
3564 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
3565 | |||
3566 | if (data->active_auto_throttle_sources & (1 << source)) { | ||
3567 | data->active_auto_throttle_sources &= ~(1 << source); | ||
3568 | fiji_set_dpm_event_sources(hwmgr, data->active_auto_throttle_sources); | ||
3569 | } | ||
3570 | return 0; | ||
3571 | } | ||
3572 | |||
3573 | static int fiji_disable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) | ||
3574 | { | ||
3575 | return fiji_disable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); | ||
3576 | } | ||
3577 | |||
3418 | static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | 3578 | static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr) |
3419 | { | 3579 | { |
3420 | int tmp_result, result = 0; | 3580 | int tmp_result, result = 0; |
@@ -3529,6 +3689,64 @@ static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | |||
3529 | return result; | 3689 | return result; |
3530 | } | 3690 | } |
3531 | 3691 | ||
3692 | static int fiji_disable_dpm_tasks(struct pp_hwmgr *hwmgr) | ||
3693 | { | ||
3694 | int tmp_result, result = 0; | ||
3695 | |||
3696 | tmp_result = (fiji_is_dpm_running(hwmgr)) ? 0 : -1; | ||
3697 | PP_ASSERT_WITH_CODE(tmp_result == 0, | ||
3698 | "DPM is not running right now, no need to disable DPM!", | ||
3699 | return 0); | ||
3700 | |||
3701 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
3702 | PHM_PlatformCaps_ThermalController)) | ||
3703 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
3704 | GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, 1); | ||
3705 | |||
3706 | tmp_result = fiji_disable_power_containment(hwmgr); | ||
3707 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3708 | "Failed to disable power containment!", result = tmp_result); | ||
3709 | |||
3710 | tmp_result = fiji_disable_smc_cac(hwmgr); | ||
3711 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3712 | "Failed to disable SMC CAC!", result = tmp_result); | ||
3713 | |||
3714 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
3715 | CG_SPLL_SPREAD_SPECTRUM, SSEN, 0); | ||
3716 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
3717 | GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, 0); | ||
3718 | |||
3719 | tmp_result = fiji_disable_thermal_auto_throttle(hwmgr); | ||
3720 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3721 | "Failed to disable thermal auto throttle!", result = tmp_result); | ||
3722 | |||
3723 | tmp_result = fiji_stop_dpm(hwmgr); | ||
3724 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3725 | "Failed to stop DPM!", result = tmp_result); | ||
3726 | |||
3727 | tmp_result = fiji_disable_deep_sleep_master_switch(hwmgr); | ||
3728 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3729 | "Failed to disable deep sleep master switch!", result = tmp_result); | ||
3730 | |||
3731 | tmp_result = fiji_disable_ulv(hwmgr); | ||
3732 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3733 | "Failed to disable ULV!", result = tmp_result); | ||
3734 | |||
3735 | tmp_result = fiji_clear_voting_clients(hwmgr); | ||
3736 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3737 | "Failed to clear voting clients!", result = tmp_result); | ||
3738 | |||
3739 | tmp_result = fiji_reset_to_default(hwmgr); | ||
3740 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3741 | "Failed to reset to default!", result = tmp_result); | ||
3742 | |||
3743 | tmp_result = fiji_force_switch_to_arbf0(hwmgr); | ||
3744 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
3745 | "Failed to force to switch arbf0!", result = tmp_result); | ||
3746 | |||
3747 | return result; | ||
3748 | } | ||
3749 | |||
3532 | static int fiji_force_dpm_highest(struct pp_hwmgr *hwmgr) | 3750 | static int fiji_force_dpm_highest(struct pp_hwmgr *hwmgr) |
3533 | { | 3751 | { |
3534 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | 3752 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); |
@@ -5071,42 +5289,6 @@ static int fiji_get_fan_control_mode(struct pp_hwmgr *hwmgr) | |||
5071 | CG_FDO_CTRL2, FDO_PWM_MODE); | 5289 | CG_FDO_CTRL2, FDO_PWM_MODE); |
5072 | } | 5290 | } |
5073 | 5291 | ||
5074 | static int fiji_get_pp_table(struct pp_hwmgr *hwmgr, char **table) | ||
5075 | { | ||
5076 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
5077 | |||
5078 | if (!data->soft_pp_table) { | ||
5079 | data->soft_pp_table = kmemdup(hwmgr->soft_pp_table, | ||
5080 | hwmgr->soft_pp_table_size, | ||
5081 | GFP_KERNEL); | ||
5082 | if (!data->soft_pp_table) | ||
5083 | return -ENOMEM; | ||
5084 | } | ||
5085 | |||
5086 | *table = (char *)&data->soft_pp_table; | ||
5087 | |||
5088 | return hwmgr->soft_pp_table_size; | ||
5089 | } | ||
5090 | |||
5091 | static int fiji_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size) | ||
5092 | { | ||
5093 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
5094 | |||
5095 | if (!data->soft_pp_table) { | ||
5096 | data->soft_pp_table = kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL); | ||
5097 | if (!data->soft_pp_table) | ||
5098 | return -ENOMEM; | ||
5099 | } | ||
5100 | |||
5101 | memcpy(data->soft_pp_table, buf, size); | ||
5102 | |||
5103 | hwmgr->soft_pp_table = data->soft_pp_table; | ||
5104 | |||
5105 | /* TODO: re-init powerplay to implement modified pptable */ | ||
5106 | |||
5107 | return 0; | ||
5108 | } | ||
5109 | |||
5110 | static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, | 5292 | static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, |
5111 | enum pp_clock_type type, uint32_t mask) | 5293 | enum pp_clock_type type, uint32_t mask) |
5112 | { | 5294 | { |
@@ -5276,12 +5458,96 @@ bool fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *h | |||
5276 | return is_update_required; | 5458 | return is_update_required; |
5277 | } | 5459 | } |
5278 | 5460 | ||
5461 | static int fiji_get_sclk_od(struct pp_hwmgr *hwmgr) | ||
5462 | { | ||
5463 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
5464 | struct fiji_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); | ||
5465 | struct fiji_single_dpm_table *golden_sclk_table = | ||
5466 | &(data->golden_dpm_table.sclk_table); | ||
5467 | int value; | ||
5468 | |||
5469 | value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | ||
5470 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * | ||
5471 | 100 / | ||
5472 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
5473 | |||
5474 | return value; | ||
5475 | } | ||
5476 | |||
5477 | static int fiji_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) | ||
5478 | { | ||
5479 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
5480 | struct fiji_single_dpm_table *golden_sclk_table = | ||
5481 | &(data->golden_dpm_table.sclk_table); | ||
5482 | struct pp_power_state *ps; | ||
5483 | struct fiji_power_state *fiji_ps; | ||
5484 | |||
5485 | if (value > 20) | ||
5486 | value = 20; | ||
5487 | |||
5488 | ps = hwmgr->request_ps; | ||
5489 | |||
5490 | if (ps == NULL) | ||
5491 | return -EINVAL; | ||
5492 | |||
5493 | fiji_ps = cast_phw_fiji_power_state(&ps->hardware); | ||
5494 | |||
5495 | fiji_ps->performance_levels[fiji_ps->performance_level_count - 1].engine_clock = | ||
5496 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value * | ||
5497 | value / 100 + | ||
5498 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
5499 | |||
5500 | return 0; | ||
5501 | } | ||
5502 | |||
5503 | static int fiji_get_mclk_od(struct pp_hwmgr *hwmgr) | ||
5504 | { | ||
5505 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
5506 | struct fiji_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); | ||
5507 | struct fiji_single_dpm_table *golden_mclk_table = | ||
5508 | &(data->golden_dpm_table.mclk_table); | ||
5509 | int value; | ||
5510 | |||
5511 | value = (mclk_table->dpm_levels[mclk_table->count - 1].value - | ||
5512 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * | ||
5513 | 100 / | ||
5514 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
5515 | |||
5516 | return value; | ||
5517 | } | ||
5518 | |||
5519 | static int fiji_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) | ||
5520 | { | ||
5521 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
5522 | struct fiji_single_dpm_table *golden_mclk_table = | ||
5523 | &(data->golden_dpm_table.mclk_table); | ||
5524 | struct pp_power_state *ps; | ||
5525 | struct fiji_power_state *fiji_ps; | ||
5526 | |||
5527 | if (value > 20) | ||
5528 | value = 20; | ||
5529 | |||
5530 | ps = hwmgr->request_ps; | ||
5531 | |||
5532 | if (ps == NULL) | ||
5533 | return -EINVAL; | ||
5534 | |||
5535 | fiji_ps = cast_phw_fiji_power_state(&ps->hardware); | ||
5536 | |||
5537 | fiji_ps->performance_levels[fiji_ps->performance_level_count - 1].memory_clock = | ||
5538 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value * | ||
5539 | value / 100 + | ||
5540 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
5541 | |||
5542 | return 0; | ||
5543 | } | ||
5279 | 5544 | ||
5280 | static const struct pp_hwmgr_func fiji_hwmgr_funcs = { | 5545 | static const struct pp_hwmgr_func fiji_hwmgr_funcs = { |
5281 | .backend_init = &fiji_hwmgr_backend_init, | 5546 | .backend_init = &fiji_hwmgr_backend_init, |
5282 | .backend_fini = &fiji_hwmgr_backend_fini, | 5547 | .backend_fini = &fiji_hwmgr_backend_fini, |
5283 | .asic_setup = &fiji_setup_asic_task, | 5548 | .asic_setup = &fiji_setup_asic_task, |
5284 | .dynamic_state_management_enable = &fiji_enable_dpm_tasks, | 5549 | .dynamic_state_management_enable = &fiji_enable_dpm_tasks, |
5550 | .dynamic_state_management_disable = &fiji_disable_dpm_tasks, | ||
5285 | .force_dpm_level = &fiji_dpm_force_dpm_level, | 5551 | .force_dpm_level = &fiji_dpm_force_dpm_level, |
5286 | .get_num_of_pp_table_entries = &tonga_get_number_of_powerplay_table_entries, | 5552 | .get_num_of_pp_table_entries = &tonga_get_number_of_powerplay_table_entries, |
5287 | .get_power_state_size = &fiji_get_power_state_size, | 5553 | .get_power_state_size = &fiji_get_power_state_size, |
@@ -5314,24 +5580,18 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = { | |||
5314 | .get_fan_control_mode = fiji_get_fan_control_mode, | 5580 | .get_fan_control_mode = fiji_get_fan_control_mode, |
5315 | .check_states_equal = fiji_check_states_equal, | 5581 | .check_states_equal = fiji_check_states_equal, |
5316 | .check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration, | 5582 | .check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration, |
5317 | .get_pp_table = fiji_get_pp_table, | ||
5318 | .set_pp_table = fiji_set_pp_table, | ||
5319 | .force_clock_level = fiji_force_clock_level, | 5583 | .force_clock_level = fiji_force_clock_level, |
5320 | .print_clock_levels = fiji_print_clock_levels, | 5584 | .print_clock_levels = fiji_print_clock_levels, |
5585 | .get_sclk_od = fiji_get_sclk_od, | ||
5586 | .set_sclk_od = fiji_set_sclk_od, | ||
5587 | .get_mclk_od = fiji_get_mclk_od, | ||
5588 | .set_mclk_od = fiji_set_mclk_od, | ||
5321 | }; | 5589 | }; |
5322 | 5590 | ||
5323 | int fiji_hwmgr_init(struct pp_hwmgr *hwmgr) | 5591 | int fiji_hwmgr_init(struct pp_hwmgr *hwmgr) |
5324 | { | 5592 | { |
5325 | struct fiji_hwmgr *data; | ||
5326 | int ret = 0; | ||
5327 | |||
5328 | data = kzalloc(sizeof(struct fiji_hwmgr), GFP_KERNEL); | ||
5329 | if (data == NULL) | ||
5330 | return -ENOMEM; | ||
5331 | |||
5332 | hwmgr->backend = data; | ||
5333 | hwmgr->hwmgr_func = &fiji_hwmgr_funcs; | 5593 | hwmgr->hwmgr_func = &fiji_hwmgr_funcs; |
5334 | hwmgr->pptable_func = &tonga_pptable_funcs; | 5594 | hwmgr->pptable_func = &tonga_pptable_funcs; |
5335 | pp_fiji_thermal_initialize(hwmgr); | 5595 | pp_fiji_thermal_initialize(hwmgr); |
5336 | return ret; | 5596 | return 0; |
5337 | } | 5597 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h index 170edf5a772d..bf67c2a92c68 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h | |||
@@ -302,9 +302,6 @@ struct fiji_hwmgr { | |||
302 | bool pg_acp_init; | 302 | bool pg_acp_init; |
303 | bool frtc_enabled; | 303 | bool frtc_enabled; |
304 | bool frtc_status_changed; | 304 | bool frtc_status_changed; |
305 | |||
306 | /* soft pptable for re-uploading into smu */ | ||
307 | void *soft_pp_table; | ||
308 | }; | 305 | }; |
309 | 306 | ||
310 | /* To convert to Q8.8 format for firmware */ | 307 | /* To convert to Q8.8 format for firmware */ |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c index db23a4068baf..44658451a8d2 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c | |||
@@ -73,17 +73,18 @@ void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) | |||
73 | 73 | ||
74 | if (!tmp) { | 74 | if (!tmp) { |
75 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 75 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
76 | PHM_PlatformCaps_PowerContainment); | ||
77 | |||
78 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | ||
79 | PHM_PlatformCaps_CAC); | 76 | PHM_PlatformCaps_CAC); |
80 | 77 | ||
81 | fiji_hwmgr->fast_watermark_threshold = 100; | 78 | fiji_hwmgr->fast_watermark_threshold = 100; |
82 | 79 | ||
83 | tmp = 1; | 80 | if (hwmgr->powercontainment_enabled) { |
84 | fiji_hwmgr->enable_dte_feature = tmp ? false : true; | 81 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
85 | fiji_hwmgr->enable_tdc_limit_feature = tmp ? true : false; | 82 | PHM_PlatformCaps_PowerContainment); |
86 | fiji_hwmgr->enable_pkg_pwr_tracking_feature = tmp ? true : false; | 83 | tmp = 1; |
84 | fiji_hwmgr->enable_dte_feature = tmp ? false : true; | ||
85 | fiji_hwmgr->enable_tdc_limit_feature = tmp ? true : false; | ||
86 | fiji_hwmgr->enable_pkg_pwr_tracking_feature = tmp ? true : false; | ||
87 | } | ||
87 | } | 88 | } |
88 | } | 89 | } |
89 | 90 | ||
@@ -459,6 +460,23 @@ int fiji_enable_smc_cac(struct pp_hwmgr *hwmgr) | |||
459 | return result; | 460 | return result; |
460 | } | 461 | } |
461 | 462 | ||
463 | int fiji_disable_smc_cac(struct pp_hwmgr *hwmgr) | ||
464 | { | ||
465 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
466 | int result = 0; | ||
467 | |||
468 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
469 | PHM_PlatformCaps_CAC) && data->cac_enabled) { | ||
470 | int smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
471 | (uint16_t)(PPSMC_MSG_DisableCac)); | ||
472 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
473 | "Failed to disable CAC in SMC.", result = -1); | ||
474 | |||
475 | data->cac_enabled = false; | ||
476 | } | ||
477 | return result; | ||
478 | } | ||
479 | |||
462 | int fiji_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n) | 480 | int fiji_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n) |
463 | { | 481 | { |
464 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | 482 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); |
@@ -528,6 +546,48 @@ int fiji_enable_power_containment(struct pp_hwmgr *hwmgr) | |||
528 | return result; | 546 | return result; |
529 | } | 547 | } |
530 | 548 | ||
549 | int fiji_disable_power_containment(struct pp_hwmgr *hwmgr) | ||
550 | { | ||
551 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
552 | int result = 0; | ||
553 | |||
554 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
555 | PHM_PlatformCaps_PowerContainment) && | ||
556 | data->power_containment_features) { | ||
557 | int smc_result; | ||
558 | |||
559 | if (data->power_containment_features & | ||
560 | POWERCONTAINMENT_FEATURE_TDCLimit) { | ||
561 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
562 | (uint16_t)(PPSMC_MSG_TDCLimitDisable)); | ||
563 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
564 | "Failed to disable TDCLimit in SMC.", | ||
565 | result = smc_result); | ||
566 | } | ||
567 | |||
568 | if (data->power_containment_features & | ||
569 | POWERCONTAINMENT_FEATURE_DTE) { | ||
570 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
571 | (uint16_t)(PPSMC_MSG_DisableDTE)); | ||
572 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
573 | "Failed to disable DTE in SMC.", | ||
574 | result = smc_result); | ||
575 | } | ||
576 | |||
577 | if (data->power_containment_features & | ||
578 | POWERCONTAINMENT_FEATURE_PkgPwrLimit) { | ||
579 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
580 | (uint16_t)(PPSMC_MSG_PkgPwrLimitDisable)); | ||
581 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
582 | "Failed to disable PkgPwrTracking in SMC.", | ||
583 | result = smc_result); | ||
584 | } | ||
585 | data->power_containment_features = 0; | ||
586 | } | ||
587 | |||
588 | return result; | ||
589 | } | ||
590 | |||
531 | int fiji_power_control_set_level(struct pp_hwmgr *hwmgr) | 591 | int fiji_power_control_set_level(struct pp_hwmgr *hwmgr) |
532 | { | 592 | { |
533 | struct phm_ppt_v1_information *table_info = | 593 | struct phm_ppt_v1_information *table_info = |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.h index 55e58200f33a..fec772421733 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.h | |||
@@ -36,6 +36,19 @@ enum fiji_pt_config_reg_type { | |||
36 | #define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002 | 36 | #define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002 |
37 | #define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004 | 37 | #define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004 |
38 | 38 | ||
39 | #define DIDT_SQ_CTRL0__UNUSED_0_MASK 0xffffffc0 | ||
40 | #define DIDT_SQ_CTRL0__UNUSED_0__SHIFT 0x6 | ||
41 | #define DIDT_TD_CTRL0__UNUSED_0_MASK 0xffffffc0 | ||
42 | #define DIDT_TD_CTRL0__UNUSED_0__SHIFT 0x6 | ||
43 | #define DIDT_TCP_CTRL0__UNUSED_0_MASK 0xffffffc0 | ||
44 | #define DIDT_TCP_CTRL0__UNUSED_0__SHIFT 0x6 | ||
45 | #define DIDT_SQ_TUNING_CTRL__UNUSED_0_MASK 0xe0000000 | ||
46 | #define DIDT_SQ_TUNING_CTRL__UNUSED_0__SHIFT 0x0000001d | ||
47 | #define DIDT_TD_TUNING_CTRL__UNUSED_0_MASK 0xe0000000 | ||
48 | #define DIDT_TD_TUNING_CTRL__UNUSED_0__SHIFT 0x0000001d | ||
49 | #define DIDT_TCP_TUNING_CTRL__UNUSED_0_MASK 0xe0000000 | ||
50 | #define DIDT_TCP_TUNING_CTRL__UNUSED_0__SHIFT 0x0000001d | ||
51 | |||
39 | struct fiji_pt_config_reg { | 52 | struct fiji_pt_config_reg { |
40 | uint32_t offset; | 53 | uint32_t offset; |
41 | uint32_t mask; | 54 | uint32_t mask; |
@@ -58,7 +71,9 @@ void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr); | |||
58 | int fiji_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr); | 71 | int fiji_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr); |
59 | int fiji_populate_pm_fuses(struct pp_hwmgr *hwmgr); | 72 | int fiji_populate_pm_fuses(struct pp_hwmgr *hwmgr); |
60 | int fiji_enable_smc_cac(struct pp_hwmgr *hwmgr); | 73 | int fiji_enable_smc_cac(struct pp_hwmgr *hwmgr); |
74 | int fiji_disable_smc_cac(struct pp_hwmgr *hwmgr); | ||
61 | int fiji_enable_power_containment(struct pp_hwmgr *hwmgr); | 75 | int fiji_enable_power_containment(struct pp_hwmgr *hwmgr); |
76 | int fiji_disable_power_containment(struct pp_hwmgr *hwmgr); | ||
62 | int fiji_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n); | 77 | int fiji_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n); |
63 | int fiji_power_control_set_level(struct pp_hwmgr *hwmgr); | 78 | int fiji_power_control_set_level(struct pp_hwmgr *hwmgr); |
64 | 79 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index efb77eda7508..789f98ad2615 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c | |||
@@ -154,6 +154,30 @@ int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) | |||
154 | return ret; | 154 | return ret; |
155 | } | 155 | } |
156 | 156 | ||
157 | int phm_disable_dynamic_state_management(struct pp_hwmgr *hwmgr) | ||
158 | { | ||
159 | int ret = -1; | ||
160 | bool enabled; | ||
161 | |||
162 | PHM_FUNC_CHECK(hwmgr); | ||
163 | |||
164 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
165 | PHM_PlatformCaps_TablelessHardwareInterface)) { | ||
166 | if (hwmgr->hwmgr_func->dynamic_state_management_disable) | ||
167 | ret = hwmgr->hwmgr_func->dynamic_state_management_disable(hwmgr); | ||
168 | } else { | ||
169 | ret = phm_dispatch_table(hwmgr, | ||
170 | &(hwmgr->disable_dynamic_state_management), | ||
171 | NULL, NULL); | ||
172 | } | ||
173 | |||
174 | enabled = ret == 0 ? false : true; | ||
175 | |||
176 | cgs_notify_dpm_enabled(hwmgr->device, enabled); | ||
177 | |||
178 | return ret; | ||
179 | } | ||
180 | |||
157 | int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level) | 181 | int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level) |
158 | { | 182 | { |
159 | PHM_FUNC_CHECK(hwmgr); | 183 | PHM_FUNC_CHECK(hwmgr); |
@@ -314,7 +338,7 @@ int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr, | |||
314 | if (hwmgr->hwmgr_func->store_cc6_data == NULL) | 338 | if (hwmgr->hwmgr_func->store_cc6_data == NULL) |
315 | return -EINVAL; | 339 | return -EINVAL; |
316 | 340 | ||
317 | /* to do pass other display configuration in furture */ | 341 | /* TODO: pass other display configuration in the future */ |
318 | 342 | ||
319 | if (hwmgr->hwmgr_func->store_cc6_data) | 343 | if (hwmgr->hwmgr_func->store_cc6_data) |
320 | hwmgr->hwmgr_func->store_cc6_data(hwmgr, | 344 | hwmgr->hwmgr_func->store_cc6_data(hwmgr, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 20f20e075588..03b6128ebc20 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <drm/amdgpu_drm.h> | ||
27 | #include "cgs_common.h" | 28 | #include "cgs_common.h" |
28 | #include "power_state.h" | 29 | #include "power_state.h" |
29 | #include "hwmgr.h" | 30 | #include "hwmgr.h" |
@@ -58,12 +59,13 @@ int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | |||
58 | hwmgr->hw_revision = pp_init->rev_id; | 59 | hwmgr->hw_revision = pp_init->rev_id; |
59 | hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; | 60 | hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; |
60 | hwmgr->power_source = PP_PowerSource_AC; | 61 | hwmgr->power_source = PP_PowerSource_AC; |
62 | hwmgr->powercontainment_enabled = pp_init->powercontainment_enabled; | ||
61 | 63 | ||
62 | switch (hwmgr->chip_family) { | 64 | switch (hwmgr->chip_family) { |
63 | case AMD_FAMILY_CZ: | 65 | case AMDGPU_FAMILY_CZ: |
64 | cz_hwmgr_init(hwmgr); | 66 | cz_hwmgr_init(hwmgr); |
65 | break; | 67 | break; |
66 | case AMD_FAMILY_VI: | 68 | case AMDGPU_FAMILY_VI: |
67 | switch (hwmgr->chip_id) { | 69 | switch (hwmgr->chip_id) { |
68 | case CHIP_TONGA: | 70 | case CHIP_TONGA: |
69 | tonga_hwmgr_init(hwmgr); | 71 | tonga_hwmgr_init(hwmgr); |
@@ -94,6 +96,8 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr) | |||
94 | return -EINVAL; | 96 | return -EINVAL; |
95 | 97 | ||
96 | /* do hwmgr finish*/ | 98 | /* do hwmgr finish*/ |
99 | kfree(hwmgr->hardcode_pp_table); | ||
100 | |||
97 | kfree(hwmgr->backend); | 101 | kfree(hwmgr->backend); |
98 | 102 | ||
99 | kfree(hwmgr->start_thermal_controller.function_list); | 103 | kfree(hwmgr->start_thermal_controller.function_list); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c index 8f142a74ad08..aeec25c66aa8 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_clockpowergating.c | |||
@@ -106,11 +106,17 @@ int polaris10_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate) | |||
106 | data->uvd_power_gated = bgate; | 106 | data->uvd_power_gated = bgate; |
107 | 107 | ||
108 | if (bgate) { | 108 | if (bgate) { |
109 | cgs_set_clockgating_state(hwmgr->device, | ||
110 | AMD_IP_BLOCK_TYPE_UVD, | ||
111 | AMD_CG_STATE_GATE); | ||
109 | polaris10_update_uvd_dpm(hwmgr, true); | 112 | polaris10_update_uvd_dpm(hwmgr, true); |
110 | polaris10_phm_powerdown_uvd(hwmgr); | 113 | polaris10_phm_powerdown_uvd(hwmgr); |
111 | } else { | 114 | } else { |
112 | polaris10_phm_powerup_uvd(hwmgr); | 115 | polaris10_phm_powerup_uvd(hwmgr); |
113 | polaris10_update_uvd_dpm(hwmgr, false); | 116 | polaris10_update_uvd_dpm(hwmgr, false); |
117 | cgs_set_clockgating_state(hwmgr->device, | ||
118 | AMD_IP_BLOCK_TYPE_UVD, | ||
119 | AMD_PG_STATE_UNGATE); | ||
114 | } | 120 | } |
115 | 121 | ||
116 | return 0; | 122 | return 0; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c index 64ee78f7d41e..9d764c4d253e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c | |||
@@ -389,6 +389,34 @@ static int polaris10_program_voting_clients(struct pp_hwmgr *hwmgr) | |||
389 | return 0; | 389 | return 0; |
390 | } | 390 | } |
391 | 391 | ||
392 | static int polaris10_clear_voting_clients(struct pp_hwmgr *hwmgr) | ||
393 | { | ||
394 | /* Reset voting clients before disabling DPM */ | ||
395 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
396 | SCLK_PWRMGT_CNTL, RESET_SCLK_CNT, 1); | ||
397 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
398 | SCLK_PWRMGT_CNTL, RESET_BUSY_CNT, 1); | ||
399 | |||
400 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
401 | ixCG_FREQ_TRAN_VOTING_0, 0); | ||
402 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
403 | ixCG_FREQ_TRAN_VOTING_1, 0); | ||
404 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
405 | ixCG_FREQ_TRAN_VOTING_2, 0); | ||
406 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
407 | ixCG_FREQ_TRAN_VOTING_3, 0); | ||
408 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
409 | ixCG_FREQ_TRAN_VOTING_4, 0); | ||
410 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
411 | ixCG_FREQ_TRAN_VOTING_5, 0); | ||
412 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
413 | ixCG_FREQ_TRAN_VOTING_6, 0); | ||
414 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
415 | ixCG_FREQ_TRAN_VOTING_7, 0); | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
392 | /** | 420 | /** |
393 | * Get the location of various tables inside the FW image. | 421 | * Get the location of various tables inside the FW image. |
394 | * | 422 | * |
@@ -515,6 +543,11 @@ static int polaris10_copy_and_switch_arb_sets(struct pp_hwmgr *hwmgr, | |||
515 | return 0; | 543 | return 0; |
516 | } | 544 | } |
517 | 545 | ||
546 | static int polaris10_reset_to_default(struct pp_hwmgr *hwmgr) | ||
547 | { | ||
548 | return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_ResetToDefaults); | ||
549 | } | ||
550 | |||
518 | /** | 551 | /** |
519 | * Initial switch from ARB F0->F1 | 552 | * Initial switch from ARB F0->F1 |
520 | * | 553 | * |
@@ -528,6 +561,21 @@ static int polaris10_initial_switch_from_arbf0_to_f1(struct pp_hwmgr *hwmgr) | |||
528 | MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1); | 561 | MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1); |
529 | } | 562 | } |
530 | 563 | ||
564 | static int polaris10_force_switch_to_arbf0(struct pp_hwmgr *hwmgr) | ||
565 | { | ||
566 | uint32_t tmp; | ||
567 | |||
568 | tmp = (cgs_read_ind_register(hwmgr->device, | ||
569 | CGS_IND_REG__SMC, ixSMC_SCRATCH9) & | ||
570 | 0x0000ff00) >> 8; | ||
571 | |||
572 | if (tmp == MC_CG_ARB_FREQ_F0) | ||
573 | return 0; | ||
574 | |||
575 | return polaris10_copy_and_switch_arb_sets(hwmgr, | ||
576 | tmp, MC_CG_ARB_FREQ_F0); | ||
577 | } | ||
578 | |||
531 | static int polaris10_setup_default_pcie_table(struct pp_hwmgr *hwmgr) | 579 | static int polaris10_setup_default_pcie_table(struct pp_hwmgr *hwmgr) |
532 | { | 580 | { |
533 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 581 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
@@ -1356,9 +1404,9 @@ static int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr) | |||
1356 | return result; | 1404 | return result; |
1357 | } | 1405 | } |
1358 | 1406 | ||
1359 | /* in order to prevent MC activity from stutter mode to push DPM up. | 1407 | /* In order to prevent MC activity from stutter mode to push DPM up, |
1360 | * the UVD change complements this by putting the MCLK in | 1408 | * the UVD change complements this by putting the MCLK in |
1361 | * a higher state by default such that we are not effected by | 1409 | * a higher state by default such that we are not affected by |
1362 | * up threshold or and MCLK DPM latency. | 1410 | * up threshold or and MCLK DPM latency. |
1363 | */ | 1411 | */ |
1364 | levels[0].ActivityLevel = 0x1f; | 1412 | levels[0].ActivityLevel = 0x1f; |
@@ -1865,9 +1913,8 @@ static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr, | |||
1865 | if (POLARIS10_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) { | 1913 | if (POLARIS10_VOLTAGE_CONTROL_BY_SVID2 == data->mvdd_control) { |
1866 | config = VR_SVI2_PLANE_2; | 1914 | config = VR_SVI2_PLANE_2; |
1867 | table->VRConfig |= (config << VRCONF_MVDD_SHIFT); | 1915 | table->VRConfig |= (config << VRCONF_MVDD_SHIFT); |
1868 | } else if (POLARIS10_VOLTAGE_CONTROL_BY_GPIO == data->mvdd_control) { | 1916 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, data->soft_regs_start + |
1869 | config = VR_SMIO_PATTERN_2; | 1917 | offsetof(SMU74_SoftRegisters, AllowMvddSwitch), 0x1); |
1870 | table->VRConfig |= (config << VRCONF_MVDD_SHIFT); | ||
1871 | } else { | 1918 | } else { |
1872 | config = VR_STATIC_VOLTAGE; | 1919 | config = VR_STATIC_VOLTAGE; |
1873 | table->VRConfig |= (config << VRCONF_MVDD_SHIFT); | 1920 | table->VRConfig |= (config << VRCONF_MVDD_SHIFT); |
@@ -2237,6 +2284,17 @@ static int polaris10_enable_ulv(struct pp_hwmgr *hwmgr) | |||
2237 | return 0; | 2284 | return 0; |
2238 | } | 2285 | } |
2239 | 2286 | ||
2287 | static int polaris10_disable_ulv(struct pp_hwmgr *hwmgr) | ||
2288 | { | ||
2289 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
2290 | struct polaris10_ulv_parm *ulv = &(data->ulv); | ||
2291 | |||
2292 | if (ulv->ulv_supported) | ||
2293 | return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_DisableULV); | ||
2294 | |||
2295 | return 0; | ||
2296 | } | ||
2297 | |||
2240 | static int polaris10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) | 2298 | static int polaris10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) |
2241 | { | 2299 | { |
2242 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | 2300 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
@@ -2257,6 +2315,21 @@ static int polaris10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) | |||
2257 | return 0; | 2315 | return 0; |
2258 | } | 2316 | } |
2259 | 2317 | ||
2318 | static int polaris10_disable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) | ||
2319 | { | ||
2320 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
2321 | PHM_PlatformCaps_SclkDeepSleep)) { | ||
2322 | if (smum_send_msg_to_smc(hwmgr->smumgr, | ||
2323 | PPSMC_MSG_MASTER_DeepSleep_OFF)) { | ||
2324 | PP_ASSERT_WITH_CODE(false, | ||
2325 | "Attempt to disable Master Deep Sleep switch failed!", | ||
2326 | return -1); | ||
2327 | } | ||
2328 | } | ||
2329 | |||
2330 | return 0; | ||
2331 | } | ||
2332 | |||
2260 | static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) | 2333 | static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) |
2261 | { | 2334 | { |
2262 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 2335 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
@@ -2354,6 +2427,58 @@ static int polaris10_start_dpm(struct pp_hwmgr *hwmgr) | |||
2354 | return 0; | 2427 | return 0; |
2355 | } | 2428 | } |
2356 | 2429 | ||
2430 | static int polaris10_disable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) | ||
2431 | { | ||
2432 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
2433 | |||
2434 | /* disable SCLK dpm */ | ||
2435 | if (!data->sclk_dpm_key_disabled) | ||
2436 | PP_ASSERT_WITH_CODE( | ||
2437 | (smum_send_msg_to_smc(hwmgr->smumgr, | ||
2438 | PPSMC_MSG_DPM_Disable) == 0), | ||
2439 | "Failed to disable SCLK DPM!", | ||
2440 | return -1); | ||
2441 | |||
2442 | /* disable MCLK dpm */ | ||
2443 | if (!data->mclk_dpm_key_disabled) { | ||
2444 | PP_ASSERT_WITH_CODE( | ||
2445 | (smum_send_msg_to_smc(hwmgr->smumgr, | ||
2446 | PPSMC_MSG_MCLKDPM_Disable) == 0), | ||
2447 | "Failed to disable MCLK DPM!", | ||
2448 | return -1); | ||
2449 | } | ||
2450 | |||
2451 | return 0; | ||
2452 | } | ||
2453 | |||
2454 | static int polaris10_stop_dpm(struct pp_hwmgr *hwmgr) | ||
2455 | { | ||
2456 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
2457 | |||
2458 | /* disable general power management */ | ||
2459 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT, | ||
2460 | GLOBAL_PWRMGT_EN, 0); | ||
2461 | /* disable sclk deep sleep */ | ||
2462 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL, | ||
2463 | DYNAMIC_PM_EN, 0); | ||
2464 | |||
2465 | /* disable PCIE dpm */ | ||
2466 | if (!data->pcie_dpm_key_disabled) { | ||
2467 | PP_ASSERT_WITH_CODE( | ||
2468 | (smum_send_msg_to_smc(hwmgr->smumgr, | ||
2469 | PPSMC_MSG_PCIeDPM_Disable) == 0), | ||
2470 | "Failed to disable pcie DPM during DPM Stop Function!", | ||
2471 | return -1); | ||
2472 | } | ||
2473 | |||
2474 | if (polaris10_disable_sclk_mclk_dpm(hwmgr)) { | ||
2475 | printk(KERN_ERR "Failed to disable Sclk DPM and Mclk DPM!"); | ||
2476 | return -1; | ||
2477 | } | ||
2478 | |||
2479 | return 0; | ||
2480 | } | ||
2481 | |||
2357 | static void polaris10_set_dpm_event_sources(struct pp_hwmgr *hwmgr, uint32_t sources) | 2482 | static void polaris10_set_dpm_event_sources(struct pp_hwmgr *hwmgr, uint32_t sources) |
2358 | { | 2483 | { |
2359 | bool protection; | 2484 | bool protection; |
@@ -2411,6 +2536,23 @@ static int polaris10_enable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) | |||
2411 | return polaris10_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); | 2536 | return polaris10_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); |
2412 | } | 2537 | } |
2413 | 2538 | ||
2539 | static int polaris10_disable_auto_throttle_source(struct pp_hwmgr *hwmgr, | ||
2540 | PHM_AutoThrottleSource source) | ||
2541 | { | ||
2542 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
2543 | |||
2544 | if (data->active_auto_throttle_sources & (1 << source)) { | ||
2545 | data->active_auto_throttle_sources &= ~(1 << source); | ||
2546 | polaris10_set_dpm_event_sources(hwmgr, data->active_auto_throttle_sources); | ||
2547 | } | ||
2548 | return 0; | ||
2549 | } | ||
2550 | |||
2551 | static int polaris10_disable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) | ||
2552 | { | ||
2553 | return polaris10_disable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); | ||
2554 | } | ||
2555 | |||
2414 | int polaris10_pcie_performance_request(struct pp_hwmgr *hwmgr) | 2556 | int polaris10_pcie_performance_request(struct pp_hwmgr *hwmgr) |
2415 | { | 2557 | { |
2416 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 2558 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
@@ -2532,8 +2674,60 @@ int polaris10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | |||
2532 | 2674 | ||
2533 | int polaris10_disable_dpm_tasks(struct pp_hwmgr *hwmgr) | 2675 | int polaris10_disable_dpm_tasks(struct pp_hwmgr *hwmgr) |
2534 | { | 2676 | { |
2677 | int tmp_result, result = 0; | ||
2535 | 2678 | ||
2536 | return 0; | 2679 | tmp_result = (polaris10_is_dpm_running(hwmgr)) ? 0 : -1; |
2680 | PP_ASSERT_WITH_CODE(tmp_result == 0, | ||
2681 | "DPM is not running right now, no need to disable DPM!", | ||
2682 | return 0); | ||
2683 | |||
2684 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
2685 | PHM_PlatformCaps_ThermalController)) | ||
2686 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
2687 | GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, 1); | ||
2688 | |||
2689 | tmp_result = polaris10_disable_power_containment(hwmgr); | ||
2690 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2691 | "Failed to disable power containment!", result = tmp_result); | ||
2692 | |||
2693 | tmp_result = polaris10_disable_smc_cac(hwmgr); | ||
2694 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2695 | "Failed to disable SMC CAC!", result = tmp_result); | ||
2696 | |||
2697 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
2698 | CG_SPLL_SPREAD_SPECTRUM, SSEN, 0); | ||
2699 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | ||
2700 | GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, 0); | ||
2701 | |||
2702 | tmp_result = polaris10_disable_thermal_auto_throttle(hwmgr); | ||
2703 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2704 | "Failed to disable thermal auto throttle!", result = tmp_result); | ||
2705 | |||
2706 | tmp_result = polaris10_stop_dpm(hwmgr); | ||
2707 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2708 | "Failed to stop DPM!", result = tmp_result); | ||
2709 | |||
2710 | tmp_result = polaris10_disable_deep_sleep_master_switch(hwmgr); | ||
2711 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2712 | "Failed to disable deep sleep master switch!", result = tmp_result); | ||
2713 | |||
2714 | tmp_result = polaris10_disable_ulv(hwmgr); | ||
2715 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2716 | "Failed to disable ULV!", result = tmp_result); | ||
2717 | |||
2718 | tmp_result = polaris10_clear_voting_clients(hwmgr); | ||
2719 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2720 | "Failed to clear voting clients!", result = tmp_result); | ||
2721 | |||
2722 | tmp_result = polaris10_reset_to_default(hwmgr); | ||
2723 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2724 | "Failed to reset to default!", result = tmp_result); | ||
2725 | |||
2726 | tmp_result = polaris10_force_switch_to_arbf0(hwmgr); | ||
2727 | PP_ASSERT_WITH_CODE((tmp_result == 0), | ||
2728 | "Failed to force to switch arbf0!", result = tmp_result); | ||
2729 | |||
2730 | return result; | ||
2537 | } | 2731 | } |
2538 | 2732 | ||
2539 | int polaris10_reset_asic_tasks(struct pp_hwmgr *hwmgr) | 2733 | int polaris10_reset_asic_tasks(struct pp_hwmgr *hwmgr) |
@@ -2544,13 +2738,6 @@ int polaris10_reset_asic_tasks(struct pp_hwmgr *hwmgr) | |||
2544 | 2738 | ||
2545 | int polaris10_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) | 2739 | int polaris10_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) |
2546 | { | 2740 | { |
2547 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
2548 | |||
2549 | if (data->soft_pp_table) { | ||
2550 | kfree(data->soft_pp_table); | ||
2551 | data->soft_pp_table = NULL; | ||
2552 | } | ||
2553 | |||
2554 | return phm_hwmgr_backend_fini(hwmgr); | 2741 | return phm_hwmgr_backend_fini(hwmgr); |
2555 | } | 2742 | } |
2556 | 2743 | ||
@@ -2606,8 +2793,13 @@ int polaris10_set_features_platform_caps(struct pp_hwmgr *hwmgr) | |||
2606 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | 2793 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, |
2607 | PHM_PlatformCaps_TCPRamping); | 2794 | PHM_PlatformCaps_TCPRamping); |
2608 | 2795 | ||
2609 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 2796 | if (hwmgr->powercontainment_enabled) |
2610 | PHM_PlatformCaps_PowerContainment); | 2797 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
2798 | PHM_PlatformCaps_PowerContainment); | ||
2799 | else | ||
2800 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
2801 | PHM_PlatformCaps_PowerContainment); | ||
2802 | |||
2611 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 2803 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
2612 | PHM_PlatformCaps_CAC); | 2804 | PHM_PlatformCaps_CAC); |
2613 | 2805 | ||
@@ -2679,12 +2871,12 @@ static int polaris10_get_evv_voltages(struct pp_hwmgr *hwmgr) | |||
2679 | } | 2871 | } |
2680 | } | 2872 | } |
2681 | 2873 | ||
2682 | 2874 | if (atomctrl_get_voltage_evv_on_sclk_ai(hwmgr, | |
2683 | PP_ASSERT_WITH_CODE(0 == atomctrl_get_voltage_evv_on_sclk_ai(hwmgr, | 2875 | VOLTAGE_TYPE_VDDC, |
2684 | VOLTAGE_TYPE_VDDC, sclk, vv_id, &vddc), | 2876 | sclk, vv_id, &vddc) != 0) { |
2685 | "Error retrieving EVV voltage value!", | 2877 | printk(KERN_WARNING "failed to retrieving EVV voltage!\n"); |
2686 | continue); | 2878 | continue; |
2687 | 2879 | } | |
2688 | 2880 | ||
2689 | /* need to make sure vddc is less than 2v or else, it could burn the ASIC. */ | 2881 | /* need to make sure vddc is less than 2v or else, it could burn the ASIC. */ |
2690 | PP_ASSERT_WITH_CODE((vddc < 2000 && vddc != 0), | 2882 | PP_ASSERT_WITH_CODE((vddc < 2000 && vddc != 0), |
@@ -2915,13 +3107,19 @@ static int polaris10_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr) | |||
2915 | 3107 | ||
2916 | int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | 3108 | int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) |
2917 | { | 3109 | { |
2918 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 3110 | struct polaris10_hwmgr *data; |
2919 | struct pp_atomctrl_gpio_pin_assignment gpio_pin_assignment; | 3111 | struct pp_atomctrl_gpio_pin_assignment gpio_pin_assignment; |
2920 | uint32_t temp_reg; | 3112 | uint32_t temp_reg; |
2921 | int result; | 3113 | int result; |
2922 | struct phm_ppt_v1_information *table_info = | 3114 | struct phm_ppt_v1_information *table_info = |
2923 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | 3115 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
2924 | 3116 | ||
3117 | data = kzalloc(sizeof(struct polaris10_hwmgr), GFP_KERNEL); | ||
3118 | if (data == NULL) | ||
3119 | return -ENOMEM; | ||
3120 | |||
3121 | hwmgr->backend = data; | ||
3122 | |||
2925 | data->dll_default_on = false; | 3123 | data->dll_default_on = false; |
2926 | data->sram_end = SMC_RAM_END; | 3124 | data->sram_end = SMC_RAM_END; |
2927 | data->mclk_dpm0_activity_target = 0xa; | 3125 | data->mclk_dpm0_activity_target = 0xa; |
@@ -3094,7 +3292,7 @@ int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
3094 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO; | 3292 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO; |
3095 | result = cgs_query_system_info(hwmgr->device, &sys_info); | 3293 | result = cgs_query_system_info(hwmgr->device, &sys_info); |
3096 | if (result) | 3294 | if (result) |
3097 | data->pcie_gen_cap = 0x30007; | 3295 | data->pcie_gen_cap = AMDGPU_DEFAULT_PCIE_GEN_MASK; |
3098 | else | 3296 | else |
3099 | data->pcie_gen_cap = (uint32_t)sys_info.value; | 3297 | data->pcie_gen_cap = (uint32_t)sys_info.value; |
3100 | if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) | 3298 | if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) |
@@ -3103,7 +3301,7 @@ int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
3103 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW; | 3301 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW; |
3104 | result = cgs_query_system_info(hwmgr->device, &sys_info); | 3302 | result = cgs_query_system_info(hwmgr->device, &sys_info); |
3105 | if (result) | 3303 | if (result) |
3106 | data->pcie_lane_cap = 0x2f0000; | 3304 | data->pcie_lane_cap = AMDGPU_DEFAULT_PCIE_MLW_MASK; |
3107 | else | 3305 | else |
3108 | data->pcie_lane_cap = (uint32_t)sys_info.value; | 3306 | data->pcie_lane_cap = (uint32_t)sys_info.value; |
3109 | 3307 | ||
@@ -4753,42 +4951,6 @@ int polaris10_setup_asic_task(struct pp_hwmgr *hwmgr) | |||
4753 | return result; | 4951 | return result; |
4754 | } | 4952 | } |
4755 | 4953 | ||
4756 | static int polaris10_get_pp_table(struct pp_hwmgr *hwmgr, char **table) | ||
4757 | { | ||
4758 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
4759 | |||
4760 | if (!data->soft_pp_table) { | ||
4761 | data->soft_pp_table = kmemdup(hwmgr->soft_pp_table, | ||
4762 | hwmgr->soft_pp_table_size, | ||
4763 | GFP_KERNEL); | ||
4764 | if (!data->soft_pp_table) | ||
4765 | return -ENOMEM; | ||
4766 | } | ||
4767 | |||
4768 | *table = (char *)&data->soft_pp_table; | ||
4769 | |||
4770 | return hwmgr->soft_pp_table_size; | ||
4771 | } | ||
4772 | |||
4773 | static int polaris10_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size) | ||
4774 | { | ||
4775 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
4776 | |||
4777 | if (!data->soft_pp_table) { | ||
4778 | data->soft_pp_table = kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL); | ||
4779 | if (!data->soft_pp_table) | ||
4780 | return -ENOMEM; | ||
4781 | } | ||
4782 | |||
4783 | memcpy(data->soft_pp_table, buf, size); | ||
4784 | |||
4785 | hwmgr->soft_pp_table = data->soft_pp_table; | ||
4786 | |||
4787 | /* TODO: re-init powerplay to implement modified pptable */ | ||
4788 | |||
4789 | return 0; | ||
4790 | } | ||
4791 | |||
4792 | static int polaris10_force_clock_level(struct pp_hwmgr *hwmgr, | 4954 | static int polaris10_force_clock_level(struct pp_hwmgr *hwmgr, |
4793 | enum pp_clock_type type, uint32_t mask) | 4955 | enum pp_clock_type type, uint32_t mask) |
4794 | { | 4956 | { |
@@ -4931,6 +5093,89 @@ static int polaris10_get_fan_control_mode(struct pp_hwmgr *hwmgr) | |||
4931 | CG_FDO_CTRL2, FDO_PWM_MODE); | 5093 | CG_FDO_CTRL2, FDO_PWM_MODE); |
4932 | } | 5094 | } |
4933 | 5095 | ||
5096 | static int polaris10_get_sclk_od(struct pp_hwmgr *hwmgr) | ||
5097 | { | ||
5098 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
5099 | struct polaris10_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); | ||
5100 | struct polaris10_single_dpm_table *golden_sclk_table = | ||
5101 | &(data->golden_dpm_table.sclk_table); | ||
5102 | int value; | ||
5103 | |||
5104 | value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | ||
5105 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * | ||
5106 | 100 / | ||
5107 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
5108 | |||
5109 | return value; | ||
5110 | } | ||
5111 | |||
5112 | static int polaris10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) | ||
5113 | { | ||
5114 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
5115 | struct polaris10_single_dpm_table *golden_sclk_table = | ||
5116 | &(data->golden_dpm_table.sclk_table); | ||
5117 | struct pp_power_state *ps; | ||
5118 | struct polaris10_power_state *polaris10_ps; | ||
5119 | |||
5120 | if (value > 20) | ||
5121 | value = 20; | ||
5122 | |||
5123 | ps = hwmgr->request_ps; | ||
5124 | |||
5125 | if (ps == NULL) | ||
5126 | return -EINVAL; | ||
5127 | |||
5128 | polaris10_ps = cast_phw_polaris10_power_state(&ps->hardware); | ||
5129 | |||
5130 | polaris10_ps->performance_levels[polaris10_ps->performance_level_count - 1].engine_clock = | ||
5131 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value * | ||
5132 | value / 100 + | ||
5133 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
5134 | |||
5135 | return 0; | ||
5136 | } | ||
5137 | |||
5138 | static int polaris10_get_mclk_od(struct pp_hwmgr *hwmgr) | ||
5139 | { | ||
5140 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
5141 | struct polaris10_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); | ||
5142 | struct polaris10_single_dpm_table *golden_mclk_table = | ||
5143 | &(data->golden_dpm_table.mclk_table); | ||
5144 | int value; | ||
5145 | |||
5146 | value = (mclk_table->dpm_levels[mclk_table->count - 1].value - | ||
5147 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * | ||
5148 | 100 / | ||
5149 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
5150 | |||
5151 | return value; | ||
5152 | } | ||
5153 | |||
5154 | static int polaris10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) | ||
5155 | { | ||
5156 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
5157 | struct polaris10_single_dpm_table *golden_mclk_table = | ||
5158 | &(data->golden_dpm_table.mclk_table); | ||
5159 | struct pp_power_state *ps; | ||
5160 | struct polaris10_power_state *polaris10_ps; | ||
5161 | |||
5162 | if (value > 20) | ||
5163 | value = 20; | ||
5164 | |||
5165 | ps = hwmgr->request_ps; | ||
5166 | |||
5167 | if (ps == NULL) | ||
5168 | return -EINVAL; | ||
5169 | |||
5170 | polaris10_ps = cast_phw_polaris10_power_state(&ps->hardware); | ||
5171 | |||
5172 | polaris10_ps->performance_levels[polaris10_ps->performance_level_count - 1].memory_clock = | ||
5173 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value * | ||
5174 | value / 100 + | ||
5175 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
5176 | |||
5177 | return 0; | ||
5178 | } | ||
4934 | static const struct pp_hwmgr_func polaris10_hwmgr_funcs = { | 5179 | static const struct pp_hwmgr_func polaris10_hwmgr_funcs = { |
4935 | .backend_init = &polaris10_hwmgr_backend_init, | 5180 | .backend_init = &polaris10_hwmgr_backend_init, |
4936 | .backend_fini = &polaris10_hwmgr_backend_fini, | 5181 | .backend_fini = &polaris10_hwmgr_backend_fini, |
@@ -4969,22 +5214,17 @@ static const struct pp_hwmgr_func polaris10_hwmgr_funcs = { | |||
4969 | .check_states_equal = polaris10_check_states_equal, | 5214 | .check_states_equal = polaris10_check_states_equal, |
4970 | .set_fan_control_mode = polaris10_set_fan_control_mode, | 5215 | .set_fan_control_mode = polaris10_set_fan_control_mode, |
4971 | .get_fan_control_mode = polaris10_get_fan_control_mode, | 5216 | .get_fan_control_mode = polaris10_get_fan_control_mode, |
4972 | .get_pp_table = polaris10_get_pp_table, | ||
4973 | .set_pp_table = polaris10_set_pp_table, | ||
4974 | .force_clock_level = polaris10_force_clock_level, | 5217 | .force_clock_level = polaris10_force_clock_level, |
4975 | .print_clock_levels = polaris10_print_clock_levels, | 5218 | .print_clock_levels = polaris10_print_clock_levels, |
4976 | .enable_per_cu_power_gating = polaris10_phm_enable_per_cu_power_gating, | 5219 | .enable_per_cu_power_gating = polaris10_phm_enable_per_cu_power_gating, |
5220 | .get_sclk_od = polaris10_get_sclk_od, | ||
5221 | .set_sclk_od = polaris10_set_sclk_od, | ||
5222 | .get_mclk_od = polaris10_get_mclk_od, | ||
5223 | .set_mclk_od = polaris10_set_mclk_od, | ||
4977 | }; | 5224 | }; |
4978 | 5225 | ||
4979 | int polaris10_hwmgr_init(struct pp_hwmgr *hwmgr) | 5226 | int polaris10_hwmgr_init(struct pp_hwmgr *hwmgr) |
4980 | { | 5227 | { |
4981 | struct polaris10_hwmgr *data; | ||
4982 | |||
4983 | data = kzalloc (sizeof(struct polaris10_hwmgr), GFP_KERNEL); | ||
4984 | if (data == NULL) | ||
4985 | return -ENOMEM; | ||
4986 | |||
4987 | hwmgr->backend = data; | ||
4988 | hwmgr->hwmgr_func = &polaris10_hwmgr_funcs; | 5228 | hwmgr->hwmgr_func = &polaris10_hwmgr_funcs; |
4989 | hwmgr->pptable_func = &tonga_pptable_funcs; | 5229 | hwmgr->pptable_func = &tonga_pptable_funcs; |
4990 | pp_polaris10_thermal_initialize(hwmgr); | 5230 | pp_polaris10_thermal_initialize(hwmgr); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h index d717789441f5..fd38b0d7a3c2 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h | |||
@@ -309,10 +309,6 @@ struct polaris10_hwmgr { | |||
309 | uint32_t up_hyst; | 309 | uint32_t up_hyst; |
310 | uint32_t disable_dpm_mask; | 310 | uint32_t disable_dpm_mask; |
311 | bool apply_optimized_settings; | 311 | bool apply_optimized_settings; |
312 | |||
313 | /* soft pptable for re-uploading into smu */ | ||
314 | void *soft_pp_table; | ||
315 | |||
316 | uint32_t avfs_vdroop_override_setting; | 312 | uint32_t avfs_vdroop_override_setting; |
317 | bool apply_avfs_cks_off_voltage; | 313 | bool apply_avfs_cks_off_voltage; |
318 | }; | 314 | }; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c index ae96f14b827c..5620e268b553 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c | |||
@@ -312,6 +312,23 @@ int polaris10_enable_smc_cac(struct pp_hwmgr *hwmgr) | |||
312 | return result; | 312 | return result; |
313 | } | 313 | } |
314 | 314 | ||
315 | int polaris10_disable_smc_cac(struct pp_hwmgr *hwmgr) | ||
316 | { | ||
317 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
318 | int result = 0; | ||
319 | |||
320 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
321 | PHM_PlatformCaps_CAC) && data->cac_enabled) { | ||
322 | int smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
323 | (uint16_t)(PPSMC_MSG_DisableCac)); | ||
324 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
325 | "Failed to disable CAC in SMC.", result = -1); | ||
326 | |||
327 | data->cac_enabled = false; | ||
328 | } | ||
329 | return result; | ||
330 | } | ||
331 | |||
315 | int polaris10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n) | 332 | int polaris10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n) |
316 | { | 333 | { |
317 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 334 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
@@ -373,6 +390,48 @@ int polaris10_enable_power_containment(struct pp_hwmgr *hwmgr) | |||
373 | return result; | 390 | return result; |
374 | } | 391 | } |
375 | 392 | ||
393 | int polaris10_disable_power_containment(struct pp_hwmgr *hwmgr) | ||
394 | { | ||
395 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
396 | int result = 0; | ||
397 | |||
398 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | ||
399 | PHM_PlatformCaps_PowerContainment) && | ||
400 | data->power_containment_features) { | ||
401 | int smc_result; | ||
402 | |||
403 | if (data->power_containment_features & | ||
404 | POWERCONTAINMENT_FEATURE_TDCLimit) { | ||
405 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
406 | (uint16_t)(PPSMC_MSG_TDCLimitDisable)); | ||
407 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
408 | "Failed to disable TDCLimit in SMC.", | ||
409 | result = smc_result); | ||
410 | } | ||
411 | |||
412 | if (data->power_containment_features & | ||
413 | POWERCONTAINMENT_FEATURE_DTE) { | ||
414 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
415 | (uint16_t)(PPSMC_MSG_DisableDTE)); | ||
416 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
417 | "Failed to disable DTE in SMC.", | ||
418 | result = smc_result); | ||
419 | } | ||
420 | |||
421 | if (data->power_containment_features & | ||
422 | POWERCONTAINMENT_FEATURE_PkgPwrLimit) { | ||
423 | smc_result = smum_send_msg_to_smc(hwmgr->smumgr, | ||
424 | (uint16_t)(PPSMC_MSG_PkgPwrLimitDisable)); | ||
425 | PP_ASSERT_WITH_CODE((smc_result == 0), | ||
426 | "Failed to disable PkgPwrTracking in SMC.", | ||
427 | result = smc_result); | ||
428 | } | ||
429 | data->power_containment_features = 0; | ||
430 | } | ||
431 | |||
432 | return result; | ||
433 | } | ||
434 | |||
376 | int polaris10_power_control_set_level(struct pp_hwmgr *hwmgr) | 435 | int polaris10_power_control_set_level(struct pp_hwmgr *hwmgr) |
377 | { | 436 | { |
378 | struct phm_ppt_v1_information *table_info = | 437 | struct phm_ppt_v1_information *table_info = |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.h index 68bc1cb6d40c..d492d6d28867 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.h | |||
@@ -31,6 +31,19 @@ enum polaris10_pt_config_reg_type { | |||
31 | POLARIS10_CONFIGREG_MAX | 31 | POLARIS10_CONFIGREG_MAX |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #define DIDT_SQ_CTRL0__UNUSED_0_MASK 0xfffc0000 | ||
35 | #define DIDT_SQ_CTRL0__UNUSED_0__SHIFT 0x12 | ||
36 | #define DIDT_TD_CTRL0__UNUSED_0_MASK 0xfffc0000 | ||
37 | #define DIDT_TD_CTRL0__UNUSED_0__SHIFT 0x12 | ||
38 | #define DIDT_TCP_CTRL0__UNUSED_0_MASK 0xfffc0000 | ||
39 | #define DIDT_TCP_CTRL0__UNUSED_0__SHIFT 0x12 | ||
40 | #define DIDT_SQ_TUNING_CTRL__UNUSED_0_MASK 0xc0000000 | ||
41 | #define DIDT_SQ_TUNING_CTRL__UNUSED_0__SHIFT 0x0000001e | ||
42 | #define DIDT_TD_TUNING_CTRL__UNUSED_0_MASK 0xc0000000 | ||
43 | #define DIDT_TD_TUNING_CTRL__UNUSED_0__SHIFT 0x0000001e | ||
44 | #define DIDT_TCP_TUNING_CTRL__UNUSED_0_MASK 0xc0000000 | ||
45 | #define DIDT_TCP_TUNING_CTRL__UNUSED_0__SHIFT 0x0000001e | ||
46 | |||
34 | /* PowerContainment Features */ | 47 | /* PowerContainment Features */ |
35 | #define POWERCONTAINMENT_FEATURE_DTE 0x00000001 | 48 | #define POWERCONTAINMENT_FEATURE_DTE 0x00000001 |
36 | #define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002 | 49 | #define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002 |
@@ -62,7 +75,9 @@ void polaris10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr); | |||
62 | int polaris10_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr); | 75 | int polaris10_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr); |
63 | int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr); | 76 | int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr); |
64 | int polaris10_enable_smc_cac(struct pp_hwmgr *hwmgr); | 77 | int polaris10_enable_smc_cac(struct pp_hwmgr *hwmgr); |
78 | int polaris10_disable_smc_cac(struct pp_hwmgr *hwmgr); | ||
65 | int polaris10_enable_power_containment(struct pp_hwmgr *hwmgr); | 79 | int polaris10_enable_power_containment(struct pp_hwmgr *hwmgr); |
80 | int polaris10_disable_power_containment(struct pp_hwmgr *hwmgr); | ||
66 | int polaris10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n); | 81 | int polaris10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n); |
67 | int polaris10_power_control_set_level(struct pp_hwmgr *hwmgr); | 82 | int polaris10_power_control_set_level(struct pp_hwmgr *hwmgr); |
68 | 83 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c index bf4e18fd3872..5d70e2c47faf 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c | |||
@@ -552,13 +552,13 @@ static bool atomctrl_lookup_gpio_pin( | |||
552 | pin_assignment->ucGpioPinBitShift; | 552 | pin_assignment->ucGpioPinBitShift; |
553 | gpio_pin_assignment->us_gpio_pin_aindex = | 553 | gpio_pin_assignment->us_gpio_pin_aindex = |
554 | le16_to_cpu(pin_assignment->usGpioPin_AIndex); | 554 | le16_to_cpu(pin_assignment->usGpioPin_AIndex); |
555 | return false; | 555 | return true; |
556 | } | 556 | } |
557 | 557 | ||
558 | offset += offsetof(ATOM_GPIO_PIN_ASSIGNMENT, ucGPIO_ID) + 1; | 558 | offset += offsetof(ATOM_GPIO_PIN_ASSIGNMENT, ucGPIO_ID) + 1; |
559 | } | 559 | } |
560 | 560 | ||
561 | return true; | 561 | return false; |
562 | } | 562 | } |
563 | 563 | ||
564 | /** | 564 | /** |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c index 2f1a14fe05b1..35bc8a29b773 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c | |||
@@ -794,15 +794,18 @@ static const ATOM_PPLIB_STATE_V2 *get_state_entry_v2( | |||
794 | static const ATOM_PPLIB_POWERPLAYTABLE *get_powerplay_table( | 794 | static const ATOM_PPLIB_POWERPLAYTABLE *get_powerplay_table( |
795 | struct pp_hwmgr *hwmgr) | 795 | struct pp_hwmgr *hwmgr) |
796 | { | 796 | { |
797 | const void *table_addr = NULL; | 797 | const void *table_addr = hwmgr->soft_pp_table; |
798 | uint8_t frev, crev; | 798 | uint8_t frev, crev; |
799 | uint16_t size; | 799 | uint16_t size; |
800 | 800 | ||
801 | table_addr = cgs_atom_get_data_table(hwmgr->device, | 801 | if (!table_addr) { |
802 | GetIndexIntoMasterTable(DATA, PowerPlayInfo), | 802 | table_addr = cgs_atom_get_data_table(hwmgr->device, |
803 | &size, &frev, &crev); | 803 | GetIndexIntoMasterTable(DATA, PowerPlayInfo), |
804 | &size, &frev, &crev); | ||
804 | 805 | ||
805 | hwmgr->soft_pp_table = table_addr; | 806 | hwmgr->soft_pp_table = table_addr; |
807 | hwmgr->soft_pp_table_size = size; | ||
808 | } | ||
806 | 809 | ||
807 | return (const ATOM_PPLIB_POWERPLAYTABLE *)table_addr; | 810 | return (const ATOM_PPLIB_POWERPLAYTABLE *)table_addr; |
808 | } | 811 | } |
@@ -1499,7 +1502,7 @@ int get_number_of_vce_state_table_entries( | |||
1499 | const ATOM_PPLIB_VCE_State_Table *vce_table = | 1502 | const ATOM_PPLIB_VCE_State_Table *vce_table = |
1500 | get_vce_state_table(hwmgr, table); | 1503 | get_vce_state_table(hwmgr, table); |
1501 | 1504 | ||
1502 | if (vce_table > 0) | 1505 | if (vce_table) |
1503 | return vce_table->numEntries; | 1506 | return vce_table->numEntries; |
1504 | 1507 | ||
1505 | return 0; | 1508 | return 0; |
@@ -1589,11 +1592,6 @@ static int pp_tables_initialize(struct pp_hwmgr *hwmgr) | |||
1589 | 1592 | ||
1590 | static int pp_tables_uninitialize(struct pp_hwmgr *hwmgr) | 1593 | static int pp_tables_uninitialize(struct pp_hwmgr *hwmgr) |
1591 | { | 1594 | { |
1592 | if (NULL != hwmgr->soft_pp_table) { | ||
1593 | kfree(hwmgr->soft_pp_table); | ||
1594 | hwmgr->soft_pp_table = NULL; | ||
1595 | } | ||
1596 | |||
1597 | if (NULL != hwmgr->dyn_state.vddc_dependency_on_sclk) { | 1595 | if (NULL != hwmgr->dyn_state.vddc_dependency_on_sclk) { |
1598 | kfree(hwmgr->dyn_state.vddc_dependency_on_sclk); | 1596 | kfree(hwmgr->dyn_state.vddc_dependency_on_sclk); |
1599 | hwmgr->dyn_state.vddc_dependency_on_sclk = NULL; | 1597 | hwmgr->dyn_state.vddc_dependency_on_sclk = NULL; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 233eb7f36c1d..6c4553cf8023 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | |||
@@ -3026,8 +3026,8 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
3026 | 3026 | ||
3027 | reg_value = 0; | 3027 | reg_value = 0; |
3028 | if ((0 == reg_value) && | 3028 | if ((0 == reg_value) && |
3029 | (0 == atomctrl_get_pp_assign_pin(hwmgr, | 3029 | (atomctrl_get_pp_assign_pin(hwmgr, VDDC_VRHOT_GPIO_PINID, |
3030 | VDDC_VRHOT_GPIO_PINID, &gpio_pin_assignment))) { | 3030 | &gpio_pin_assignment))) { |
3031 | table->VRHotGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; | 3031 | table->VRHotGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; |
3032 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 3032 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
3033 | PHM_PlatformCaps_RegulatorHot); | 3033 | PHM_PlatformCaps_RegulatorHot); |
@@ -3040,8 +3040,8 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
3040 | /* ACDC Switch GPIO */ | 3040 | /* ACDC Switch GPIO */ |
3041 | reg_value = 0; | 3041 | reg_value = 0; |
3042 | if ((0 == reg_value) && | 3042 | if ((0 == reg_value) && |
3043 | (0 == atomctrl_get_pp_assign_pin(hwmgr, | 3043 | (atomctrl_get_pp_assign_pin(hwmgr, PP_AC_DC_SWITCH_GPIO_PINID, |
3044 | PP_AC_DC_SWITCH_GPIO_PINID, &gpio_pin_assignment))) { | 3044 | &gpio_pin_assignment))) { |
3045 | table->AcDcGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; | 3045 | table->AcDcGpio = gpio_pin_assignment.uc_gpio_pin_bit_shift; |
3046 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 3046 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
3047 | PHM_PlatformCaps_AutomaticDCTransition); | 3047 | PHM_PlatformCaps_AutomaticDCTransition); |
@@ -3063,8 +3063,7 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
3063 | } | 3063 | } |
3064 | 3064 | ||
3065 | reg_value = 0; | 3065 | reg_value = 0; |
3066 | if ((0 == reg_value) && | 3066 | if ((0 == reg_value) && (atomctrl_get_pp_assign_pin(hwmgr, |
3067 | (0 == atomctrl_get_pp_assign_pin(hwmgr, | ||
3068 | THERMAL_INT_OUTPUT_GPIO_PINID, &gpio_pin_assignment))) { | 3067 | THERMAL_INT_OUTPUT_GPIO_PINID, &gpio_pin_assignment))) { |
3069 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 3068 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
3070 | PHM_PlatformCaps_ThermalOutGPIO); | 3069 | PHM_PlatformCaps_ThermalOutGPIO); |
@@ -4422,13 +4421,6 @@ int tonga_reset_asic_tasks(struct pp_hwmgr *hwmgr) | |||
4422 | 4421 | ||
4423 | int tonga_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) | 4422 | int tonga_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) |
4424 | { | 4423 | { |
4425 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
4426 | |||
4427 | if (data->soft_pp_table) { | ||
4428 | kfree(data->soft_pp_table); | ||
4429 | data->soft_pp_table = NULL; | ||
4430 | } | ||
4431 | |||
4432 | return phm_hwmgr_backend_fini(hwmgr); | 4424 | return phm_hwmgr_backend_fini(hwmgr); |
4433 | } | 4425 | } |
4434 | 4426 | ||
@@ -4442,7 +4434,7 @@ int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
4442 | { | 4434 | { |
4443 | int result = 0; | 4435 | int result = 0; |
4444 | SMU72_Discrete_DpmTable *table = NULL; | 4436 | SMU72_Discrete_DpmTable *table = NULL; |
4445 | tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | 4437 | tonga_hwmgr *data; |
4446 | pp_atomctrl_gpio_pin_assignment gpio_pin_assignment; | 4438 | pp_atomctrl_gpio_pin_assignment gpio_pin_assignment; |
4447 | struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable); | 4439 | struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable); |
4448 | phw_tonga_ulv_parm *ulv; | 4440 | phw_tonga_ulv_parm *ulv; |
@@ -4451,6 +4443,12 @@ int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
4451 | PP_ASSERT_WITH_CODE((NULL != hwmgr), | 4443 | PP_ASSERT_WITH_CODE((NULL != hwmgr), |
4452 | "Invalid Parameter!", return -1;); | 4444 | "Invalid Parameter!", return -1;); |
4453 | 4445 | ||
4446 | data = kzalloc(sizeof(struct tonga_hwmgr), GFP_KERNEL); | ||
4447 | if (data == NULL) | ||
4448 | return -ENOMEM; | ||
4449 | |||
4450 | hwmgr->backend = data; | ||
4451 | |||
4454 | data->dll_defaule_on = 0; | 4452 | data->dll_defaule_on = 0; |
4455 | data->sram_end = SMC_RAM_END; | 4453 | data->sram_end = SMC_RAM_END; |
4456 | 4454 | ||
@@ -4571,7 +4569,7 @@ int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
4571 | * if ucGPIO_ID=VDDC_PCC_GPIO_PINID in GPIO_LUTable, | 4569 | * if ucGPIO_ID=VDDC_PCC_GPIO_PINID in GPIO_LUTable, |
4572 | * Peak Current Control feature is enabled and we should program PCC HW register | 4570 | * Peak Current Control feature is enabled and we should program PCC HW register |
4573 | */ | 4571 | */ |
4574 | if (0 == atomctrl_get_pp_assign_pin(hwmgr, VDDC_PCC_GPIO_PINID, &gpio_pin_assignment)) { | 4572 | if (atomctrl_get_pp_assign_pin(hwmgr, VDDC_PCC_GPIO_PINID, &gpio_pin_assignment)) { |
4575 | uint32_t temp_reg = cgs_read_ind_register(hwmgr->device, | 4573 | uint32_t temp_reg = cgs_read_ind_register(hwmgr->device, |
4576 | CGS_IND_REG__SMC, ixCNB_PWRMGT_CNTL); | 4574 | CGS_IND_REG__SMC, ixCNB_PWRMGT_CNTL); |
4577 | 4575 | ||
@@ -4639,7 +4637,7 @@ int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
4639 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO; | 4637 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO; |
4640 | result = cgs_query_system_info(hwmgr->device, &sys_info); | 4638 | result = cgs_query_system_info(hwmgr->device, &sys_info); |
4641 | if (result) | 4639 | if (result) |
4642 | data->pcie_gen_cap = 0x30007; | 4640 | data->pcie_gen_cap = AMDGPU_DEFAULT_PCIE_GEN_MASK; |
4643 | else | 4641 | else |
4644 | data->pcie_gen_cap = (uint32_t)sys_info.value; | 4642 | data->pcie_gen_cap = (uint32_t)sys_info.value; |
4645 | if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) | 4643 | if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) |
@@ -4648,7 +4646,7 @@ int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
4648 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW; | 4646 | sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW; |
4649 | result = cgs_query_system_info(hwmgr->device, &sys_info); | 4647 | result = cgs_query_system_info(hwmgr->device, &sys_info); |
4650 | if (result) | 4648 | if (result) |
4651 | data->pcie_lane_cap = 0x2f0000; | 4649 | data->pcie_lane_cap = AMDGPU_DEFAULT_PCIE_MLW_MASK; |
4652 | else | 4650 | else |
4653 | data->pcie_lane_cap = (uint32_t)sys_info.value; | 4651 | data->pcie_lane_cap = (uint32_t)sys_info.value; |
4654 | } else { | 4652 | } else { |
@@ -6031,42 +6029,6 @@ static int tonga_get_fan_control_mode(struct pp_hwmgr *hwmgr) | |||
6031 | CG_FDO_CTRL2, FDO_PWM_MODE); | 6029 | CG_FDO_CTRL2, FDO_PWM_MODE); |
6032 | } | 6030 | } |
6033 | 6031 | ||
6034 | static int tonga_get_pp_table(struct pp_hwmgr *hwmgr, char **table) | ||
6035 | { | ||
6036 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
6037 | |||
6038 | if (!data->soft_pp_table) { | ||
6039 | data->soft_pp_table = kmemdup(hwmgr->soft_pp_table, | ||
6040 | hwmgr->soft_pp_table_size, | ||
6041 | GFP_KERNEL); | ||
6042 | if (!data->soft_pp_table) | ||
6043 | return -ENOMEM; | ||
6044 | } | ||
6045 | |||
6046 | *table = (char *)&data->soft_pp_table; | ||
6047 | |||
6048 | return hwmgr->soft_pp_table_size; | ||
6049 | } | ||
6050 | |||
6051 | static int tonga_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size) | ||
6052 | { | ||
6053 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
6054 | |||
6055 | if (!data->soft_pp_table) { | ||
6056 | data->soft_pp_table = kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL); | ||
6057 | if (!data->soft_pp_table) | ||
6058 | return -ENOMEM; | ||
6059 | } | ||
6060 | |||
6061 | memcpy(data->soft_pp_table, buf, size); | ||
6062 | |||
6063 | hwmgr->soft_pp_table = data->soft_pp_table; | ||
6064 | |||
6065 | /* TODO: re-init powerplay to implement modified pptable */ | ||
6066 | |||
6067 | return 0; | ||
6068 | } | ||
6069 | |||
6070 | static int tonga_force_clock_level(struct pp_hwmgr *hwmgr, | 6032 | static int tonga_force_clock_level(struct pp_hwmgr *hwmgr, |
6071 | enum pp_clock_type type, uint32_t mask) | 6033 | enum pp_clock_type type, uint32_t mask) |
6072 | { | 6034 | { |
@@ -6174,11 +6136,96 @@ static int tonga_print_clock_levels(struct pp_hwmgr *hwmgr, | |||
6174 | return size; | 6136 | return size; |
6175 | } | 6137 | } |
6176 | 6138 | ||
6139 | static int tonga_get_sclk_od(struct pp_hwmgr *hwmgr) | ||
6140 | { | ||
6141 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
6142 | struct tonga_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); | ||
6143 | struct tonga_single_dpm_table *golden_sclk_table = | ||
6144 | &(data->golden_dpm_table.sclk_table); | ||
6145 | int value; | ||
6146 | |||
6147 | value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | ||
6148 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * | ||
6149 | 100 / | ||
6150 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
6151 | |||
6152 | return value; | ||
6153 | } | ||
6154 | |||
6155 | static int tonga_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) | ||
6156 | { | ||
6157 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
6158 | struct tonga_single_dpm_table *golden_sclk_table = | ||
6159 | &(data->golden_dpm_table.sclk_table); | ||
6160 | struct pp_power_state *ps; | ||
6161 | struct tonga_power_state *tonga_ps; | ||
6162 | |||
6163 | if (value > 20) | ||
6164 | value = 20; | ||
6165 | |||
6166 | ps = hwmgr->request_ps; | ||
6167 | |||
6168 | if (ps == NULL) | ||
6169 | return -EINVAL; | ||
6170 | |||
6171 | tonga_ps = cast_phw_tonga_power_state(&ps->hardware); | ||
6172 | |||
6173 | tonga_ps->performance_levels[tonga_ps->performance_level_count - 1].engine_clock = | ||
6174 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value * | ||
6175 | value / 100 + | ||
6176 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
6177 | |||
6178 | return 0; | ||
6179 | } | ||
6180 | |||
6181 | static int tonga_get_mclk_od(struct pp_hwmgr *hwmgr) | ||
6182 | { | ||
6183 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
6184 | struct tonga_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); | ||
6185 | struct tonga_single_dpm_table *golden_mclk_table = | ||
6186 | &(data->golden_dpm_table.mclk_table); | ||
6187 | int value; | ||
6188 | |||
6189 | value = (mclk_table->dpm_levels[mclk_table->count - 1].value - | ||
6190 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * | ||
6191 | 100 / | ||
6192 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
6193 | |||
6194 | return value; | ||
6195 | } | ||
6196 | |||
6197 | static int tonga_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) | ||
6198 | { | ||
6199 | struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); | ||
6200 | struct tonga_single_dpm_table *golden_mclk_table = | ||
6201 | &(data->golden_dpm_table.mclk_table); | ||
6202 | struct pp_power_state *ps; | ||
6203 | struct tonga_power_state *tonga_ps; | ||
6204 | |||
6205 | if (value > 20) | ||
6206 | value = 20; | ||
6207 | |||
6208 | ps = hwmgr->request_ps; | ||
6209 | |||
6210 | if (ps == NULL) | ||
6211 | return -EINVAL; | ||
6212 | |||
6213 | tonga_ps = cast_phw_tonga_power_state(&ps->hardware); | ||
6214 | |||
6215 | tonga_ps->performance_levels[tonga_ps->performance_level_count - 1].memory_clock = | ||
6216 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value * | ||
6217 | value / 100 + | ||
6218 | golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | ||
6219 | |||
6220 | return 0; | ||
6221 | } | ||
6222 | |||
6177 | static const struct pp_hwmgr_func tonga_hwmgr_funcs = { | 6223 | static const struct pp_hwmgr_func tonga_hwmgr_funcs = { |
6178 | .backend_init = &tonga_hwmgr_backend_init, | 6224 | .backend_init = &tonga_hwmgr_backend_init, |
6179 | .backend_fini = &tonga_hwmgr_backend_fini, | 6225 | .backend_fini = &tonga_hwmgr_backend_fini, |
6180 | .asic_setup = &tonga_setup_asic_task, | 6226 | .asic_setup = &tonga_setup_asic_task, |
6181 | .dynamic_state_management_enable = &tonga_enable_dpm_tasks, | 6227 | .dynamic_state_management_enable = &tonga_enable_dpm_tasks, |
6228 | .dynamic_state_management_disable = &tonga_disable_dpm_tasks, | ||
6182 | .apply_state_adjust_rules = tonga_apply_state_adjust_rules, | 6229 | .apply_state_adjust_rules = tonga_apply_state_adjust_rules, |
6183 | .force_dpm_level = &tonga_force_dpm_level, | 6230 | .force_dpm_level = &tonga_force_dpm_level, |
6184 | .power_state_set = tonga_set_power_state_tasks, | 6231 | .power_state_set = tonga_set_power_state_tasks, |
@@ -6212,22 +6259,16 @@ static const struct pp_hwmgr_func tonga_hwmgr_funcs = { | |||
6212 | .check_states_equal = tonga_check_states_equal, | 6259 | .check_states_equal = tonga_check_states_equal, |
6213 | .set_fan_control_mode = tonga_set_fan_control_mode, | 6260 | .set_fan_control_mode = tonga_set_fan_control_mode, |
6214 | .get_fan_control_mode = tonga_get_fan_control_mode, | 6261 | .get_fan_control_mode = tonga_get_fan_control_mode, |
6215 | .get_pp_table = tonga_get_pp_table, | ||
6216 | .set_pp_table = tonga_set_pp_table, | ||
6217 | .force_clock_level = tonga_force_clock_level, | 6262 | .force_clock_level = tonga_force_clock_level, |
6218 | .print_clock_levels = tonga_print_clock_levels, | 6263 | .print_clock_levels = tonga_print_clock_levels, |
6264 | .get_sclk_od = tonga_get_sclk_od, | ||
6265 | .set_sclk_od = tonga_set_sclk_od, | ||
6266 | .get_mclk_od = tonga_get_mclk_od, | ||
6267 | .set_mclk_od = tonga_set_mclk_od, | ||
6219 | }; | 6268 | }; |
6220 | 6269 | ||
6221 | int tonga_hwmgr_init(struct pp_hwmgr *hwmgr) | 6270 | int tonga_hwmgr_init(struct pp_hwmgr *hwmgr) |
6222 | { | 6271 | { |
6223 | tonga_hwmgr *data; | ||
6224 | |||
6225 | data = kzalloc (sizeof(tonga_hwmgr), GFP_KERNEL); | ||
6226 | if (data == NULL) | ||
6227 | return -ENOMEM; | ||
6228 | memset(data, 0x00, sizeof(tonga_hwmgr)); | ||
6229 | |||
6230 | hwmgr->backend = data; | ||
6231 | hwmgr->hwmgr_func = &tonga_hwmgr_funcs; | 6272 | hwmgr->hwmgr_func = &tonga_hwmgr_funcs; |
6232 | hwmgr->pptable_func = &tonga_pptable_funcs; | 6273 | hwmgr->pptable_func = &tonga_pptable_funcs; |
6233 | pp_tonga_thermal_initialize(hwmgr); | 6274 | pp_tonga_thermal_initialize(hwmgr); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h index 573cd39fe78d..3961884bfa9b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h | |||
@@ -352,9 +352,6 @@ struct tonga_hwmgr { | |||
352 | bool samu_power_gated; /* 1: gated, 0:not gated */ | 352 | bool samu_power_gated; /* 1: gated, 0:not gated */ |
353 | bool acp_power_gated; /* 1: gated, 0:not gated */ | 353 | bool acp_power_gated; /* 1: gated, 0:not gated */ |
354 | bool pg_acp_init; | 354 | bool pg_acp_init; |
355 | |||
356 | /* soft pptable for re-uploading into smu */ | ||
357 | void *soft_pp_table; | ||
358 | }; | 355 | }; |
359 | 356 | ||
360 | typedef struct tonga_hwmgr tonga_hwmgr; | 357 | typedef struct tonga_hwmgr tonga_hwmgr; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c index 671fdb4d615a..94d6b472e1fe 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c | |||
@@ -1077,9 +1077,6 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) | |||
1077 | struct phm_ppt_v1_information *pp_table_information = | 1077 | struct phm_ppt_v1_information *pp_table_information = |
1078 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | 1078 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
1079 | 1079 | ||
1080 | if (NULL != hwmgr->soft_pp_table) | ||
1081 | hwmgr->soft_pp_table = NULL; | ||
1082 | |||
1083 | kfree(pp_table_information->vdd_dep_on_sclk); | 1080 | kfree(pp_table_information->vdd_dep_on_sclk); |
1084 | pp_table_information->vdd_dep_on_sclk = NULL; | 1081 | pp_table_information->vdd_dep_on_sclk = NULL; |
1085 | 1082 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index 50b367d44307..b764c8c05ec8 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | |||
@@ -132,6 +132,7 @@ 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 | }; | 136 | }; |
136 | enum amd_pp_display_config_type{ | 137 | enum amd_pp_display_config_type{ |
137 | AMD_PP_DisplayConfigType_None = 0, | 138 | AMD_PP_DisplayConfigType_None = 0, |
@@ -342,6 +343,10 @@ struct amd_powerplay_funcs { | |||
342 | int (*set_pp_table)(void *handle, const char *buf, size_t size); | 343 | int (*set_pp_table)(void *handle, const char *buf, size_t size); |
343 | int (*force_clock_level)(void *handle, enum pp_clock_type type, uint32_t mask); | 344 | int (*force_clock_level)(void *handle, enum pp_clock_type type, uint32_t mask); |
344 | int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); | 345 | int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); |
346 | int (*get_sclk_od)(void *handle); | ||
347 | int (*set_sclk_od)(void *handle, uint32_t value); | ||
348 | int (*get_mclk_od)(void *handle); | ||
349 | int (*set_mclk_od)(void *handle, uint32_t value); | ||
345 | }; | 350 | }; |
346 | 351 | ||
347 | struct amd_powerplay { | 352 | struct amd_powerplay { |
@@ -355,6 +360,8 @@ int amd_powerplay_init(struct amd_pp_init *pp_init, | |||
355 | 360 | ||
356 | int amd_powerplay_fini(void *handle); | 361 | int amd_powerplay_fini(void *handle); |
357 | 362 | ||
363 | int amd_powerplay_reset(void *handle); | ||
364 | |||
358 | int amd_powerplay_display_configuration_change(void *handle, | 365 | int amd_powerplay_display_configuration_change(void *handle, |
359 | const struct amd_pp_display_configuration *input); | 366 | const struct amd_pp_display_configuration *input); |
360 | 367 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h index 56f712c7d07a..962cb5385951 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h | |||
@@ -340,6 +340,7 @@ extern int phm_powergate_vce(struct pp_hwmgr *hwmgr, bool gate); | |||
340 | extern int phm_powerdown_uvd(struct pp_hwmgr *hwmgr); | 340 | extern int phm_powerdown_uvd(struct pp_hwmgr *hwmgr); |
341 | extern int phm_setup_asic(struct pp_hwmgr *hwmgr); | 341 | extern int phm_setup_asic(struct pp_hwmgr *hwmgr); |
342 | extern int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr); | 342 | extern int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr); |
343 | extern int phm_disable_dynamic_state_management(struct pp_hwmgr *hwmgr); | ||
343 | extern void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr); | 344 | extern void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr); |
344 | extern bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr); | 345 | extern bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr); |
345 | extern int phm_block_hw_access(struct pp_hwmgr *hwmgr, bool block); | 346 | extern int phm_block_hw_access(struct pp_hwmgr *hwmgr, bool block); |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 28f571449495..0bbc42a224e5 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | |||
@@ -278,6 +278,8 @@ struct pp_hwmgr_func { | |||
278 | 278 | ||
279 | int (*dynamic_state_management_enable)( | 279 | int (*dynamic_state_management_enable)( |
280 | struct pp_hwmgr *hw_mgr); | 280 | struct pp_hwmgr *hw_mgr); |
281 | int (*dynamic_state_management_disable)( | ||
282 | struct pp_hwmgr *hw_mgr); | ||
281 | 283 | ||
282 | int (*patch_boot_state)(struct pp_hwmgr *hwmgr, | 284 | int (*patch_boot_state)(struct pp_hwmgr *hwmgr, |
283 | struct pp_hw_power_state *hw_ps); | 285 | struct pp_hw_power_state *hw_ps); |
@@ -333,11 +335,13 @@ struct pp_hwmgr_func { | |||
333 | int (*get_clock_by_type)(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks); | 335 | int (*get_clock_by_type)(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks); |
334 | int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); | 336 | int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); |
335 | int (*power_off_asic)(struct pp_hwmgr *hwmgr); | 337 | int (*power_off_asic)(struct pp_hwmgr *hwmgr); |
336 | int (*get_pp_table)(struct pp_hwmgr *hwmgr, char **table); | ||
337 | int (*set_pp_table)(struct pp_hwmgr *hwmgr, const char *buf, size_t size); | ||
338 | int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); | 338 | int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); |
339 | int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); | 339 | int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); |
340 | int (*enable_per_cu_power_gating)(struct pp_hwmgr *hwmgr, bool enable); | 340 | int (*enable_per_cu_power_gating)(struct pp_hwmgr *hwmgr, bool enable); |
341 | int (*get_sclk_od)(struct pp_hwmgr *hwmgr); | ||
342 | int (*set_sclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); | ||
343 | int (*get_mclk_od)(struct pp_hwmgr *hwmgr); | ||
344 | int (*set_mclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); | ||
341 | }; | 345 | }; |
342 | 346 | ||
343 | struct pp_table_func { | 347 | struct pp_table_func { |
@@ -578,6 +582,7 @@ struct pp_hwmgr { | |||
578 | struct pp_smumgr *smumgr; | 582 | struct pp_smumgr *smumgr; |
579 | const void *soft_pp_table; | 583 | const void *soft_pp_table; |
580 | uint32_t soft_pp_table_size; | 584 | uint32_t soft_pp_table_size; |
585 | void *hardcode_pp_table; | ||
581 | bool need_pp_table_upload; | 586 | bool need_pp_table_upload; |
582 | enum amd_dpm_forced_level dpm_level; | 587 | enum amd_dpm_forced_level dpm_level; |
583 | bool block_hw_access; | 588 | bool block_hw_access; |
@@ -607,6 +612,7 @@ struct pp_hwmgr { | |||
607 | uint32_t num_ps; | 612 | uint32_t num_ps; |
608 | struct pp_thermal_controller_info thermal_controller; | 613 | struct pp_thermal_controller_info thermal_controller; |
609 | bool fan_ctrl_is_in_default_mode; | 614 | bool fan_ctrl_is_in_default_mode; |
615 | bool powercontainment_enabled; | ||
610 | uint32_t fan_ctrl_default_mode; | 616 | uint32_t fan_ctrl_default_mode; |
611 | uint32_t tmin; | 617 | uint32_t tmin; |
612 | struct phm_microcode_version_info microcode_version_info; | 618 | struct phm_microcode_version_info microcode_version_info; |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index 0728c1e3d97a..7723473e51a0 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <drm/amdgpu_drm.h> | ||
26 | #include "pp_instance.h" | 27 | #include "pp_instance.h" |
27 | #include "smumgr.h" | 28 | #include "smumgr.h" |
28 | #include "cgs_common.h" | 29 | #include "cgs_common.h" |
@@ -52,10 +53,10 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | |||
52 | handle->smu_mgr = smumgr; | 53 | handle->smu_mgr = smumgr; |
53 | 54 | ||
54 | switch (smumgr->chip_family) { | 55 | switch (smumgr->chip_family) { |
55 | case AMD_FAMILY_CZ: | 56 | case AMDGPU_FAMILY_CZ: |
56 | cz_smum_init(smumgr); | 57 | cz_smum_init(smumgr); |
57 | break; | 58 | break; |
58 | case AMD_FAMILY_VI: | 59 | case AMDGPU_FAMILY_VI: |
59 | switch (smumgr->chip_id) { | 60 | switch (smumgr->chip_id) { |
60 | case CHIP_TONGA: | 61 | case CHIP_TONGA: |
61 | tonga_smum_init(smumgr); | 62 | tonga_smum_init(smumgr); |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h index c89dc777768f..b961a1c6caf3 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h | |||
@@ -26,7 +26,7 @@ TRACE_EVENT(amd_sched_job, | |||
26 | TP_fast_assign( | 26 | TP_fast_assign( |
27 | __entry->entity = sched_job->s_entity; | 27 | __entry->entity = sched_job->s_entity; |
28 | __entry->sched_job = sched_job; | 28 | __entry->sched_job = sched_job; |
29 | __entry->fence = &sched_job->s_fence->base; | 29 | __entry->fence = &sched_job->s_fence->finished; |
30 | __entry->name = sched_job->sched->name; | 30 | __entry->name = sched_job->sched->name; |
31 | __entry->job_count = kfifo_len( | 31 | __entry->job_count = kfifo_len( |
32 | &sched_job->s_entity->job_queue) / sizeof(sched_job); | 32 | &sched_job->s_entity->job_queue) / sizeof(sched_job); |
@@ -46,7 +46,7 @@ TRACE_EVENT(amd_sched_process_job, | |||
46 | ), | 46 | ), |
47 | 47 | ||
48 | TP_fast_assign( | 48 | TP_fast_assign( |
49 | __entry->fence = &fence->base; | 49 | __entry->fence = &fence->finished; |
50 | ), | 50 | ), |
51 | TP_printk("fence=%p signaled", __entry->fence) | 51 | TP_printk("fence=%p signaled", __entry->fence) |
52 | ); | 52 | ); |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index c16248cee779..70ff09d10885 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity); | 33 | static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity); |
34 | static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); | 34 | static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); |
35 | static void amd_sched_process_job(struct fence *f, struct fence_cb *cb); | ||
35 | 36 | ||
36 | struct kmem_cache *sched_fence_slab; | 37 | struct kmem_cache *sched_fence_slab; |
37 | atomic_t sched_fence_slab_ref = ATOMIC_INIT(0); | 38 | atomic_t sched_fence_slab_ref = ATOMIC_INIT(0); |
@@ -140,7 +141,7 @@ int amd_sched_entity_init(struct amd_gpu_scheduler *sched, | |||
140 | return r; | 141 | return r; |
141 | 142 | ||
142 | atomic_set(&entity->fence_seq, 0); | 143 | atomic_set(&entity->fence_seq, 0); |
143 | entity->fence_context = fence_context_alloc(1); | 144 | entity->fence_context = fence_context_alloc(2); |
144 | 145 | ||
145 | return 0; | 146 | return 0; |
146 | } | 147 | } |
@@ -251,17 +252,21 @@ static bool amd_sched_entity_add_dependency_cb(struct amd_sched_entity *entity) | |||
251 | 252 | ||
252 | s_fence = to_amd_sched_fence(fence); | 253 | s_fence = to_amd_sched_fence(fence); |
253 | if (s_fence && s_fence->sched == sched) { | 254 | if (s_fence && s_fence->sched == sched) { |
254 | /* Fence is from the same scheduler */ | ||
255 | if (test_bit(AMD_SCHED_FENCE_SCHEDULED_BIT, &fence->flags)) { | ||
256 | /* Ignore it when it is already scheduled */ | ||
257 | fence_put(entity->dependency); | ||
258 | return false; | ||
259 | } | ||
260 | 255 | ||
261 | /* Wait for fence to be scheduled */ | 256 | /* |
262 | entity->cb.func = amd_sched_entity_clear_dep; | 257 | * Fence is from the same scheduler, only need to wait for |
263 | list_add_tail(&entity->cb.node, &s_fence->scheduled_cb); | 258 | * it to be scheduled |
264 | return true; | 259 | */ |
260 | fence = fence_get(&s_fence->scheduled); | ||
261 | fence_put(entity->dependency); | ||
262 | entity->dependency = fence; | ||
263 | if (!fence_add_callback(fence, &entity->cb, | ||
264 | amd_sched_entity_clear_dep)) | ||
265 | return true; | ||
266 | |||
267 | /* Ignore it when it is already scheduled */ | ||
268 | fence_put(fence); | ||
269 | return false; | ||
265 | } | 270 | } |
266 | 271 | ||
267 | if (!fence_add_callback(entity->dependency, &entity->cb, | 272 | if (!fence_add_callback(entity->dependency, &entity->cb, |
@@ -319,46 +324,108 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job) | |||
319 | return added; | 324 | return added; |
320 | } | 325 | } |
321 | 326 | ||
322 | static void amd_sched_free_job(struct fence *f, struct fence_cb *cb) { | ||
323 | struct amd_sched_job *job = container_of(cb, struct amd_sched_job, cb_free_job); | ||
324 | schedule_work(&job->work_free_job); | ||
325 | } | ||
326 | |||
327 | /* job_finish is called after hw fence signaled, and | 327 | /* job_finish is called after hw fence signaled, and |
328 | * the job had already been deleted from ring_mirror_list | 328 | * the job had already been deleted from ring_mirror_list |
329 | */ | 329 | */ |
330 | void amd_sched_job_finish(struct amd_sched_job *s_job) | 330 | static void amd_sched_job_finish(struct work_struct *work) |
331 | { | 331 | { |
332 | struct amd_sched_job *next; | 332 | struct amd_sched_job *s_job = container_of(work, struct amd_sched_job, |
333 | finish_work); | ||
333 | struct amd_gpu_scheduler *sched = s_job->sched; | 334 | struct amd_gpu_scheduler *sched = s_job->sched; |
334 | 335 | ||
336 | /* remove job from ring_mirror_list */ | ||
337 | spin_lock(&sched->job_list_lock); | ||
338 | list_del_init(&s_job->node); | ||
335 | if (sched->timeout != MAX_SCHEDULE_TIMEOUT) { | 339 | if (sched->timeout != MAX_SCHEDULE_TIMEOUT) { |
336 | if (cancel_delayed_work(&s_job->work_tdr)) | 340 | struct amd_sched_job *next; |
337 | amd_sched_job_put(s_job); | 341 | |
342 | spin_unlock(&sched->job_list_lock); | ||
343 | cancel_delayed_work_sync(&s_job->work_tdr); | ||
344 | spin_lock(&sched->job_list_lock); | ||
338 | 345 | ||
339 | /* queue TDR for next job */ | 346 | /* queue TDR for next job */ |
340 | next = list_first_entry_or_null(&sched->ring_mirror_list, | 347 | next = list_first_entry_or_null(&sched->ring_mirror_list, |
341 | struct amd_sched_job, node); | 348 | struct amd_sched_job, node); |
342 | 349 | ||
343 | if (next) { | 350 | if (next) |
344 | INIT_DELAYED_WORK(&next->work_tdr, s_job->timeout_callback); | ||
345 | amd_sched_job_get(next); | ||
346 | schedule_delayed_work(&next->work_tdr, sched->timeout); | 351 | schedule_delayed_work(&next->work_tdr, sched->timeout); |
347 | } | ||
348 | } | 352 | } |
353 | spin_unlock(&sched->job_list_lock); | ||
354 | sched->ops->free_job(s_job); | ||
349 | } | 355 | } |
350 | 356 | ||
351 | void amd_sched_job_begin(struct amd_sched_job *s_job) | 357 | static void amd_sched_job_finish_cb(struct fence *f, struct fence_cb *cb) |
358 | { | ||
359 | struct amd_sched_job *job = container_of(cb, struct amd_sched_job, | ||
360 | finish_cb); | ||
361 | schedule_work(&job->finish_work); | ||
362 | } | ||
363 | |||
364 | static void amd_sched_job_begin(struct amd_sched_job *s_job) | ||
352 | { | 365 | { |
353 | struct amd_gpu_scheduler *sched = s_job->sched; | 366 | struct amd_gpu_scheduler *sched = s_job->sched; |
354 | 367 | ||
368 | spin_lock(&sched->job_list_lock); | ||
369 | list_add_tail(&s_job->node, &sched->ring_mirror_list); | ||
355 | if (sched->timeout != MAX_SCHEDULE_TIMEOUT && | 370 | if (sched->timeout != MAX_SCHEDULE_TIMEOUT && |
356 | list_first_entry_or_null(&sched->ring_mirror_list, struct amd_sched_job, node) == s_job) | 371 | list_first_entry_or_null(&sched->ring_mirror_list, |
357 | { | 372 | struct amd_sched_job, node) == s_job) |
358 | INIT_DELAYED_WORK(&s_job->work_tdr, s_job->timeout_callback); | 373 | schedule_delayed_work(&s_job->work_tdr, sched->timeout); |
359 | amd_sched_job_get(s_job); | 374 | spin_unlock(&sched->job_list_lock); |
375 | } | ||
376 | |||
377 | static void amd_sched_job_timedout(struct work_struct *work) | ||
378 | { | ||
379 | struct amd_sched_job *job = container_of(work, struct amd_sched_job, | ||
380 | work_tdr.work); | ||
381 | |||
382 | job->sched->ops->timedout_job(job); | ||
383 | } | ||
384 | |||
385 | void amd_sched_hw_job_reset(struct amd_gpu_scheduler *sched) | ||
386 | { | ||
387 | struct amd_sched_job *s_job; | ||
388 | |||
389 | spin_lock(&sched->job_list_lock); | ||
390 | list_for_each_entry_reverse(s_job, &sched->ring_mirror_list, node) { | ||
391 | if (fence_remove_callback(s_job->s_fence->parent, &s_job->s_fence->cb)) { | ||
392 | fence_put(s_job->s_fence->parent); | ||
393 | s_job->s_fence->parent = NULL; | ||
394 | } | ||
395 | } | ||
396 | spin_unlock(&sched->job_list_lock); | ||
397 | } | ||
398 | |||
399 | void amd_sched_job_recovery(struct amd_gpu_scheduler *sched) | ||
400 | { | ||
401 | struct amd_sched_job *s_job; | ||
402 | int r; | ||
403 | |||
404 | spin_lock(&sched->job_list_lock); | ||
405 | s_job = list_first_entry_or_null(&sched->ring_mirror_list, | ||
406 | struct amd_sched_job, node); | ||
407 | if (s_job) | ||
360 | schedule_delayed_work(&s_job->work_tdr, sched->timeout); | 408 | schedule_delayed_work(&s_job->work_tdr, sched->timeout); |
409 | |||
410 | list_for_each_entry(s_job, &sched->ring_mirror_list, node) { | ||
411 | struct amd_sched_fence *s_fence = s_job->s_fence; | ||
412 | struct fence *fence = sched->ops->run_job(s_job); | ||
413 | if (fence) { | ||
414 | s_fence->parent = fence_get(fence); | ||
415 | r = fence_add_callback(fence, &s_fence->cb, | ||
416 | amd_sched_process_job); | ||
417 | if (r == -ENOENT) | ||
418 | amd_sched_process_job(fence, &s_fence->cb); | ||
419 | else if (r) | ||
420 | DRM_ERROR("fence add callback failed (%d)\n", | ||
421 | r); | ||
422 | fence_put(fence); | ||
423 | } else { | ||
424 | DRM_ERROR("Failed to run job!\n"); | ||
425 | amd_sched_process_job(NULL, &s_fence->cb); | ||
426 | } | ||
361 | } | 427 | } |
428 | spin_unlock(&sched->job_list_lock); | ||
362 | } | 429 | } |
363 | 430 | ||
364 | /** | 431 | /** |
@@ -372,36 +439,29 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job) | |||
372 | { | 439 | { |
373 | struct amd_sched_entity *entity = sched_job->s_entity; | 440 | struct amd_sched_entity *entity = sched_job->s_entity; |
374 | 441 | ||
375 | sched_job->use_sched = 1; | ||
376 | fence_add_callback(&sched_job->s_fence->base, | ||
377 | &sched_job->cb_free_job, amd_sched_free_job); | ||
378 | trace_amd_sched_job(sched_job); | 442 | trace_amd_sched_job(sched_job); |
443 | fence_add_callback(&sched_job->s_fence->finished, &sched_job->finish_cb, | ||
444 | amd_sched_job_finish_cb); | ||
379 | wait_event(entity->sched->job_scheduled, | 445 | wait_event(entity->sched->job_scheduled, |
380 | amd_sched_entity_in(sched_job)); | 446 | amd_sched_entity_in(sched_job)); |
381 | } | 447 | } |
382 | 448 | ||
383 | /* init a sched_job with basic field */ | 449 | /* init a sched_job with basic field */ |
384 | int amd_sched_job_init(struct amd_sched_job *job, | 450 | int amd_sched_job_init(struct amd_sched_job *job, |
385 | struct amd_gpu_scheduler *sched, | 451 | struct amd_gpu_scheduler *sched, |
386 | struct amd_sched_entity *entity, | 452 | struct amd_sched_entity *entity, |
387 | void (*timeout_cb)(struct work_struct *work), | 453 | void *owner) |
388 | void (*free_cb)(struct kref *refcount), | ||
389 | void *owner, struct fence **fence) | ||
390 | { | 454 | { |
391 | INIT_LIST_HEAD(&job->node); | ||
392 | kref_init(&job->refcount); | ||
393 | job->sched = sched; | 455 | job->sched = sched; |
394 | job->s_entity = entity; | 456 | job->s_entity = entity; |
395 | job->s_fence = amd_sched_fence_create(entity, owner); | 457 | job->s_fence = amd_sched_fence_create(entity, owner); |
396 | if (!job->s_fence) | 458 | if (!job->s_fence) |
397 | return -ENOMEM; | 459 | return -ENOMEM; |
398 | 460 | ||
399 | job->s_fence->s_job = job; | 461 | INIT_WORK(&job->finish_work, amd_sched_job_finish); |
400 | job->timeout_callback = timeout_cb; | 462 | INIT_LIST_HEAD(&job->node); |
401 | job->free_callback = free_cb; | 463 | INIT_DELAYED_WORK(&job->work_tdr, amd_sched_job_timedout); |
402 | 464 | ||
403 | if (fence) | ||
404 | *fence = &job->s_fence->base; | ||
405 | return 0; | 465 | return 0; |
406 | } | 466 | } |
407 | 467 | ||
@@ -450,23 +510,25 @@ static void amd_sched_process_job(struct fence *f, struct fence_cb *cb) | |||
450 | struct amd_sched_fence *s_fence = | 510 | struct amd_sched_fence *s_fence = |
451 | container_of(cb, struct amd_sched_fence, cb); | 511 | container_of(cb, struct amd_sched_fence, cb); |
452 | struct amd_gpu_scheduler *sched = s_fence->sched; | 512 | struct amd_gpu_scheduler *sched = s_fence->sched; |
453 | unsigned long flags; | ||
454 | 513 | ||
455 | atomic_dec(&sched->hw_rq_count); | 514 | atomic_dec(&sched->hw_rq_count); |
456 | 515 | amd_sched_fence_finished(s_fence); | |
457 | /* remove job from ring_mirror_list */ | ||
458 | spin_lock_irqsave(&sched->job_list_lock, flags); | ||
459 | list_del_init(&s_fence->s_job->node); | ||
460 | sched->ops->finish_job(s_fence->s_job); | ||
461 | spin_unlock_irqrestore(&sched->job_list_lock, flags); | ||
462 | |||
463 | amd_sched_fence_signal(s_fence); | ||
464 | 516 | ||
465 | trace_amd_sched_process_job(s_fence); | 517 | trace_amd_sched_process_job(s_fence); |
466 | fence_put(&s_fence->base); | 518 | fence_put(&s_fence->finished); |
467 | wake_up_interruptible(&sched->wake_up_worker); | 519 | wake_up_interruptible(&sched->wake_up_worker); |
468 | } | 520 | } |
469 | 521 | ||
522 | static bool amd_sched_blocked(struct amd_gpu_scheduler *sched) | ||
523 | { | ||
524 | if (kthread_should_park()) { | ||
525 | kthread_parkme(); | ||
526 | return true; | ||
527 | } | ||
528 | |||
529 | return false; | ||
530 | } | ||
531 | |||
470 | static int amd_sched_main(void *param) | 532 | static int amd_sched_main(void *param) |
471 | { | 533 | { |
472 | struct sched_param sparam = {.sched_priority = 1}; | 534 | struct sched_param sparam = {.sched_priority = 1}; |
@@ -476,14 +538,15 @@ static int amd_sched_main(void *param) | |||
476 | sched_setscheduler(current, SCHED_FIFO, &sparam); | 538 | sched_setscheduler(current, SCHED_FIFO, &sparam); |
477 | 539 | ||
478 | while (!kthread_should_stop()) { | 540 | while (!kthread_should_stop()) { |
479 | struct amd_sched_entity *entity; | 541 | struct amd_sched_entity *entity = NULL; |
480 | struct amd_sched_fence *s_fence; | 542 | struct amd_sched_fence *s_fence; |
481 | struct amd_sched_job *sched_job; | 543 | struct amd_sched_job *sched_job; |
482 | struct fence *fence; | 544 | struct fence *fence; |
483 | 545 | ||
484 | wait_event_interruptible(sched->wake_up_worker, | 546 | wait_event_interruptible(sched->wake_up_worker, |
485 | (entity = amd_sched_select_entity(sched)) || | 547 | (!amd_sched_blocked(sched) && |
486 | kthread_should_stop()); | 548 | (entity = amd_sched_select_entity(sched))) || |
549 | kthread_should_stop()); | ||
487 | 550 | ||
488 | if (!entity) | 551 | if (!entity) |
489 | continue; | 552 | continue; |
@@ -495,16 +558,19 @@ static int amd_sched_main(void *param) | |||
495 | s_fence = sched_job->s_fence; | 558 | s_fence = sched_job->s_fence; |
496 | 559 | ||
497 | atomic_inc(&sched->hw_rq_count); | 560 | atomic_inc(&sched->hw_rq_count); |
498 | amd_sched_job_pre_schedule(sched, sched_job); | 561 | amd_sched_job_begin(sched_job); |
562 | |||
499 | fence = sched->ops->run_job(sched_job); | 563 | fence = sched->ops->run_job(sched_job); |
500 | amd_sched_fence_scheduled(s_fence); | 564 | amd_sched_fence_scheduled(s_fence); |
501 | if (fence) { | 565 | if (fence) { |
566 | s_fence->parent = fence_get(fence); | ||
502 | r = fence_add_callback(fence, &s_fence->cb, | 567 | r = fence_add_callback(fence, &s_fence->cb, |
503 | amd_sched_process_job); | 568 | amd_sched_process_job); |
504 | if (r == -ENOENT) | 569 | if (r == -ENOENT) |
505 | amd_sched_process_job(fence, &s_fence->cb); | 570 | amd_sched_process_job(fence, &s_fence->cb); |
506 | else if (r) | 571 | else if (r) |
507 | DRM_ERROR("fence add callback failed (%d)\n", r); | 572 | DRM_ERROR("fence add callback failed (%d)\n", |
573 | r); | ||
508 | fence_put(fence); | 574 | fence_put(fence); |
509 | } else { | 575 | } else { |
510 | DRM_ERROR("Failed to run job!\n"); | 576 | DRM_ERROR("Failed to run job!\n"); |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index 070095a9433c..7cbbbfb502ef 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/kfifo.h> | 27 | #include <linux/kfifo.h> |
28 | #include <linux/fence.h> | 28 | #include <linux/fence.h> |
29 | 29 | ||
30 | #define AMD_SCHED_FENCE_SCHEDULED_BIT FENCE_FLAG_USER_BITS | ||
31 | |||
32 | struct amd_gpu_scheduler; | 30 | struct amd_gpu_scheduler; |
33 | struct amd_sched_rq; | 31 | struct amd_sched_rq; |
34 | 32 | ||
@@ -68,36 +66,34 @@ struct amd_sched_rq { | |||
68 | }; | 66 | }; |
69 | 67 | ||
70 | struct amd_sched_fence { | 68 | struct amd_sched_fence { |
71 | struct fence base; | 69 | struct fence scheduled; |
70 | struct fence finished; | ||
72 | struct fence_cb cb; | 71 | struct fence_cb cb; |
73 | struct list_head scheduled_cb; | 72 | struct fence *parent; |
74 | struct amd_gpu_scheduler *sched; | 73 | struct amd_gpu_scheduler *sched; |
75 | spinlock_t lock; | 74 | spinlock_t lock; |
76 | void *owner; | 75 | void *owner; |
77 | struct amd_sched_job *s_job; | ||
78 | }; | 76 | }; |
79 | 77 | ||
80 | struct amd_sched_job { | 78 | struct amd_sched_job { |
81 | struct kref refcount; | ||
82 | struct amd_gpu_scheduler *sched; | 79 | struct amd_gpu_scheduler *sched; |
83 | struct amd_sched_entity *s_entity; | 80 | struct amd_sched_entity *s_entity; |
84 | struct amd_sched_fence *s_fence; | 81 | struct amd_sched_fence *s_fence; |
85 | bool use_sched; /* true if the job goes to scheduler */ | 82 | struct fence_cb finish_cb; |
86 | struct fence_cb cb_free_job; | 83 | struct work_struct finish_work; |
87 | struct work_struct work_free_job; | 84 | struct list_head node; |
88 | struct list_head node; | 85 | struct delayed_work work_tdr; |
89 | struct delayed_work work_tdr; | ||
90 | void (*timeout_callback) (struct work_struct *work); | ||
91 | void (*free_callback)(struct kref *refcount); | ||
92 | }; | 86 | }; |
93 | 87 | ||
94 | extern const struct fence_ops amd_sched_fence_ops; | 88 | extern const struct fence_ops amd_sched_fence_ops_scheduled; |
89 | extern const struct fence_ops amd_sched_fence_ops_finished; | ||
95 | static inline struct amd_sched_fence *to_amd_sched_fence(struct fence *f) | 90 | static inline struct amd_sched_fence *to_amd_sched_fence(struct fence *f) |
96 | { | 91 | { |
97 | struct amd_sched_fence *__f = container_of(f, struct amd_sched_fence, base); | 92 | if (f->ops == &amd_sched_fence_ops_scheduled) |
93 | return container_of(f, struct amd_sched_fence, scheduled); | ||
98 | 94 | ||
99 | if (__f->base.ops == &amd_sched_fence_ops) | 95 | if (f->ops == &amd_sched_fence_ops_finished) |
100 | return __f; | 96 | return container_of(f, struct amd_sched_fence, finished); |
101 | 97 | ||
102 | return NULL; | 98 | return NULL; |
103 | } | 99 | } |
@@ -109,8 +105,8 @@ static inline struct amd_sched_fence *to_amd_sched_fence(struct fence *f) | |||
109 | struct amd_sched_backend_ops { | 105 | struct amd_sched_backend_ops { |
110 | struct fence *(*dependency)(struct amd_sched_job *sched_job); | 106 | struct fence *(*dependency)(struct amd_sched_job *sched_job); |
111 | struct fence *(*run_job)(struct amd_sched_job *sched_job); | 107 | struct fence *(*run_job)(struct amd_sched_job *sched_job); |
112 | void (*begin_job)(struct amd_sched_job *sched_job); | 108 | void (*timedout_job)(struct amd_sched_job *sched_job); |
113 | void (*finish_job)(struct amd_sched_job *sched_job); | 109 | void (*free_job)(struct amd_sched_job *sched_job); |
114 | }; | 110 | }; |
115 | 111 | ||
116 | enum amd_sched_priority { | 112 | enum amd_sched_priority { |
@@ -152,25 +148,11 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job); | |||
152 | struct amd_sched_fence *amd_sched_fence_create( | 148 | struct amd_sched_fence *amd_sched_fence_create( |
153 | struct amd_sched_entity *s_entity, void *owner); | 149 | struct amd_sched_entity *s_entity, void *owner); |
154 | void amd_sched_fence_scheduled(struct amd_sched_fence *fence); | 150 | void amd_sched_fence_scheduled(struct amd_sched_fence *fence); |
155 | void amd_sched_fence_signal(struct amd_sched_fence *fence); | 151 | void amd_sched_fence_finished(struct amd_sched_fence *fence); |
156 | int amd_sched_job_init(struct amd_sched_job *job, | 152 | int amd_sched_job_init(struct amd_sched_job *job, |
157 | struct amd_gpu_scheduler *sched, | 153 | struct amd_gpu_scheduler *sched, |
158 | struct amd_sched_entity *entity, | 154 | struct amd_sched_entity *entity, |
159 | void (*timeout_cb)(struct work_struct *work), | 155 | void *owner); |
160 | void (*free_cb)(struct kref* refcount), | 156 | void amd_sched_hw_job_reset(struct amd_gpu_scheduler *sched); |
161 | void *owner, struct fence **fence); | 157 | void amd_sched_job_recovery(struct amd_gpu_scheduler *sched); |
162 | void amd_sched_job_pre_schedule(struct amd_gpu_scheduler *sched , | ||
163 | struct amd_sched_job *s_job); | ||
164 | void amd_sched_job_finish(struct amd_sched_job *s_job); | ||
165 | void amd_sched_job_begin(struct amd_sched_job *s_job); | ||
166 | static inline void amd_sched_job_get(struct amd_sched_job *job) { | ||
167 | if (job) | ||
168 | kref_get(&job->refcount); | ||
169 | } | ||
170 | |||
171 | static inline void amd_sched_job_put(struct amd_sched_job *job) { | ||
172 | if (job) | ||
173 | kref_put(&job->refcount, job->free_callback); | ||
174 | } | ||
175 | |||
176 | #endif | 158 | #endif |
diff --git a/drivers/gpu/drm/amd/scheduler/sched_fence.c b/drivers/gpu/drm/amd/scheduler/sched_fence.c index 2a732c490375..6b63beaf7574 100644 --- a/drivers/gpu/drm/amd/scheduler/sched_fence.c +++ b/drivers/gpu/drm/amd/scheduler/sched_fence.c | |||
@@ -27,7 +27,8 @@ | |||
27 | #include <drm/drmP.h> | 27 | #include <drm/drmP.h> |
28 | #include "gpu_scheduler.h" | 28 | #include "gpu_scheduler.h" |
29 | 29 | ||
30 | struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *s_entity, void *owner) | 30 | struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *entity, |
31 | void *owner) | ||
31 | { | 32 | { |
32 | struct amd_sched_fence *fence = NULL; | 33 | struct amd_sched_fence *fence = NULL; |
33 | unsigned seq; | 34 | unsigned seq; |
@@ -36,46 +37,37 @@ struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *s_entity | |||
36 | if (fence == NULL) | 37 | if (fence == NULL) |
37 | return NULL; | 38 | return NULL; |
38 | 39 | ||
39 | INIT_LIST_HEAD(&fence->scheduled_cb); | ||
40 | fence->owner = owner; | 40 | fence->owner = owner; |
41 | fence->sched = s_entity->sched; | 41 | fence->sched = entity->sched; |
42 | spin_lock_init(&fence->lock); | 42 | spin_lock_init(&fence->lock); |
43 | 43 | ||
44 | seq = atomic_inc_return(&s_entity->fence_seq); | 44 | seq = atomic_inc_return(&entity->fence_seq); |
45 | fence_init(&fence->base, &amd_sched_fence_ops, &fence->lock, | 45 | fence_init(&fence->scheduled, &amd_sched_fence_ops_scheduled, |
46 | s_entity->fence_context, seq); | 46 | &fence->lock, entity->fence_context, seq); |
47 | fence_init(&fence->finished, &amd_sched_fence_ops_finished, | ||
48 | &fence->lock, entity->fence_context + 1, seq); | ||
47 | 49 | ||
48 | return fence; | 50 | return fence; |
49 | } | 51 | } |
50 | 52 | ||
51 | void amd_sched_fence_signal(struct amd_sched_fence *fence) | 53 | void amd_sched_fence_scheduled(struct amd_sched_fence *fence) |
52 | { | 54 | { |
53 | int ret = fence_signal(&fence->base); | 55 | int ret = fence_signal(&fence->scheduled); |
56 | |||
54 | if (!ret) | 57 | if (!ret) |
55 | FENCE_TRACE(&fence->base, "signaled from irq context\n"); | 58 | FENCE_TRACE(&fence->scheduled, "signaled from irq context\n"); |
56 | else | 59 | else |
57 | FENCE_TRACE(&fence->base, "was already signaled\n"); | 60 | FENCE_TRACE(&fence->scheduled, "was already signaled\n"); |
58 | } | ||
59 | |||
60 | void amd_sched_job_pre_schedule(struct amd_gpu_scheduler *sched , | ||
61 | struct amd_sched_job *s_job) | ||
62 | { | ||
63 | unsigned long flags; | ||
64 | spin_lock_irqsave(&sched->job_list_lock, flags); | ||
65 | list_add_tail(&s_job->node, &sched->ring_mirror_list); | ||
66 | sched->ops->begin_job(s_job); | ||
67 | spin_unlock_irqrestore(&sched->job_list_lock, flags); | ||
68 | } | 61 | } |
69 | 62 | ||
70 | void amd_sched_fence_scheduled(struct amd_sched_fence *s_fence) | 63 | void amd_sched_fence_finished(struct amd_sched_fence *fence) |
71 | { | 64 | { |
72 | struct fence_cb *cur, *tmp; | 65 | int ret = fence_signal(&fence->finished); |
73 | 66 | ||
74 | set_bit(AMD_SCHED_FENCE_SCHEDULED_BIT, &s_fence->base.flags); | 67 | if (!ret) |
75 | list_for_each_entry_safe(cur, tmp, &s_fence->scheduled_cb, node) { | 68 | FENCE_TRACE(&fence->finished, "signaled from irq context\n"); |
76 | list_del_init(&cur->node); | 69 | else |
77 | cur->func(&s_fence->base, cur); | 70 | FENCE_TRACE(&fence->finished, "was already signaled\n"); |
78 | } | ||
79 | } | 71 | } |
80 | 72 | ||
81 | static const char *amd_sched_fence_get_driver_name(struct fence *fence) | 73 | static const char *amd_sched_fence_get_driver_name(struct fence *fence) |
@@ -105,6 +97,8 @@ static void amd_sched_fence_free(struct rcu_head *rcu) | |||
105 | { | 97 | { |
106 | struct fence *f = container_of(rcu, struct fence, rcu); | 98 | struct fence *f = container_of(rcu, struct fence, rcu); |
107 | struct amd_sched_fence *fence = to_amd_sched_fence(f); | 99 | struct amd_sched_fence *fence = to_amd_sched_fence(f); |
100 | |||
101 | fence_put(fence->parent); | ||
108 | kmem_cache_free(sched_fence_slab, fence); | 102 | kmem_cache_free(sched_fence_slab, fence); |
109 | } | 103 | } |
110 | 104 | ||
@@ -116,16 +110,41 @@ static void amd_sched_fence_free(struct rcu_head *rcu) | |||
116 | * This function is called when the reference count becomes zero. | 110 | * This function is called when the reference count becomes zero. |
117 | * It just RCU schedules freeing up the fence. | 111 | * It just RCU schedules freeing up the fence. |
118 | */ | 112 | */ |
119 | static void amd_sched_fence_release(struct fence *f) | 113 | static void amd_sched_fence_release_scheduled(struct fence *f) |
120 | { | 114 | { |
121 | call_rcu(&f->rcu, amd_sched_fence_free); | 115 | struct amd_sched_fence *fence = to_amd_sched_fence(f); |
116 | |||
117 | call_rcu(&fence->finished.rcu, amd_sched_fence_free); | ||
122 | } | 118 | } |
123 | 119 | ||
124 | const struct fence_ops amd_sched_fence_ops = { | 120 | /** |
121 | * amd_sched_fence_release_scheduled - drop extra reference | ||
122 | * | ||
123 | * @f: fence | ||
124 | * | ||
125 | * Drop the extra reference from the scheduled fence to the base fence. | ||
126 | */ | ||
127 | static void amd_sched_fence_release_finished(struct fence *f) | ||
128 | { | ||
129 | struct amd_sched_fence *fence = to_amd_sched_fence(f); | ||
130 | |||
131 | fence_put(&fence->scheduled); | ||
132 | } | ||
133 | |||
134 | const struct fence_ops amd_sched_fence_ops_scheduled = { | ||
135 | .get_driver_name = amd_sched_fence_get_driver_name, | ||
136 | .get_timeline_name = amd_sched_fence_get_timeline_name, | ||
137 | .enable_signaling = amd_sched_fence_enable_signaling, | ||
138 | .signaled = NULL, | ||
139 | .wait = fence_default_wait, | ||
140 | .release = amd_sched_fence_release_scheduled, | ||
141 | }; | ||
142 | |||
143 | const struct fence_ops amd_sched_fence_ops_finished = { | ||
125 | .get_driver_name = amd_sched_fence_get_driver_name, | 144 | .get_driver_name = amd_sched_fence_get_driver_name, |
126 | .get_timeline_name = amd_sched_fence_get_timeline_name, | 145 | .get_timeline_name = amd_sched_fence_get_timeline_name, |
127 | .enable_signaling = amd_sched_fence_enable_signaling, | 146 | .enable_signaling = amd_sched_fence_enable_signaling, |
128 | .signaled = NULL, | 147 | .signaled = NULL, |
129 | .wait = fence_default_wait, | 148 | .wait = fence_default_wait, |
130 | .release = amd_sched_fence_release, | 149 | .release = amd_sched_fence_release_finished, |
131 | }; | 150 | }; |
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c index 59f2f93b6f84..b29a41218fc9 100644 --- a/drivers/gpu/drm/ast/ast_ttm.c +++ b/drivers/gpu/drm/ast/ast_ttm.c | |||
@@ -186,17 +186,6 @@ static void ast_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg * | |||
186 | { | 186 | { |
187 | } | 187 | } |
188 | 188 | ||
189 | static int ast_bo_move(struct ttm_buffer_object *bo, | ||
190 | bool evict, bool interruptible, | ||
191 | bool no_wait_gpu, | ||
192 | struct ttm_mem_reg *new_mem) | ||
193 | { | ||
194 | int r; | ||
195 | r = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); | ||
196 | return r; | ||
197 | } | ||
198 | |||
199 | |||
200 | static void ast_ttm_backend_destroy(struct ttm_tt *tt) | 189 | static void ast_ttm_backend_destroy(struct ttm_tt *tt) |
201 | { | 190 | { |
202 | ttm_tt_fini(tt); | 191 | ttm_tt_fini(tt); |
@@ -241,7 +230,7 @@ struct ttm_bo_driver ast_bo_driver = { | |||
241 | .ttm_tt_unpopulate = ast_ttm_tt_unpopulate, | 230 | .ttm_tt_unpopulate = ast_ttm_tt_unpopulate, |
242 | .init_mem_type = ast_bo_init_mem_type, | 231 | .init_mem_type = ast_bo_init_mem_type, |
243 | .evict_flags = ast_bo_evict_flags, | 232 | .evict_flags = ast_bo_evict_flags, |
244 | .move = ast_bo_move, | 233 | .move = NULL, |
245 | .verify_access = ast_bo_verify_access, | 234 | .verify_access = ast_bo_verify_access, |
246 | .io_mem_reserve = &ast_ttm_io_mem_reserve, | 235 | .io_mem_reserve = &ast_ttm_io_mem_reserve, |
247 | .io_mem_free = &ast_ttm_io_mem_free, | 236 | .io_mem_free = &ast_ttm_io_mem_free, |
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c index 6cf912c45e48..b109fdcaa679 100644 --- a/drivers/gpu/drm/bochs/bochs_mm.c +++ b/drivers/gpu/drm/bochs/bochs_mm.c | |||
@@ -165,15 +165,6 @@ static void bochs_ttm_io_mem_free(struct ttm_bo_device *bdev, | |||
165 | { | 165 | { |
166 | } | 166 | } |
167 | 167 | ||
168 | static int bochs_bo_move(struct ttm_buffer_object *bo, | ||
169 | bool evict, bool interruptible, | ||
170 | bool no_wait_gpu, | ||
171 | struct ttm_mem_reg *new_mem) | ||
172 | { | ||
173 | return ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); | ||
174 | } | ||
175 | |||
176 | |||
177 | static void bochs_ttm_backend_destroy(struct ttm_tt *tt) | 168 | static void bochs_ttm_backend_destroy(struct ttm_tt *tt) |
178 | { | 169 | { |
179 | ttm_tt_fini(tt); | 170 | ttm_tt_fini(tt); |
@@ -208,7 +199,7 @@ struct ttm_bo_driver bochs_bo_driver = { | |||
208 | .ttm_tt_unpopulate = ttm_pool_unpopulate, | 199 | .ttm_tt_unpopulate = ttm_pool_unpopulate, |
209 | .init_mem_type = bochs_bo_init_mem_type, | 200 | .init_mem_type = bochs_bo_init_mem_type, |
210 | .evict_flags = bochs_bo_evict_flags, | 201 | .evict_flags = bochs_bo_evict_flags, |
211 | .move = bochs_bo_move, | 202 | .move = NULL, |
212 | .verify_access = bochs_bo_verify_access, | 203 | .verify_access = bochs_bo_verify_access, |
213 | .io_mem_reserve = &bochs_ttm_io_mem_reserve, | 204 | .io_mem_reserve = &bochs_ttm_io_mem_reserve, |
214 | .io_mem_free = &bochs_ttm_io_mem_free, | 205 | .io_mem_free = &bochs_ttm_io_mem_free, |
diff --git a/drivers/gpu/drm/cirrus/cirrus_ttm.c b/drivers/gpu/drm/cirrus/cirrus_ttm.c index 6768b7b1af32..1cc9ee607128 100644 --- a/drivers/gpu/drm/cirrus/cirrus_ttm.c +++ b/drivers/gpu/drm/cirrus/cirrus_ttm.c | |||
@@ -186,17 +186,6 @@ static void cirrus_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_re | |||
186 | { | 186 | { |
187 | } | 187 | } |
188 | 188 | ||
189 | static int cirrus_bo_move(struct ttm_buffer_object *bo, | ||
190 | bool evict, bool interruptible, | ||
191 | bool no_wait_gpu, | ||
192 | struct ttm_mem_reg *new_mem) | ||
193 | { | ||
194 | int r; | ||
195 | r = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); | ||
196 | return r; | ||
197 | } | ||
198 | |||
199 | |||
200 | static void cirrus_ttm_backend_destroy(struct ttm_tt *tt) | 189 | static void cirrus_ttm_backend_destroy(struct ttm_tt *tt) |
201 | { | 190 | { |
202 | ttm_tt_fini(tt); | 191 | ttm_tt_fini(tt); |
@@ -241,7 +230,7 @@ struct ttm_bo_driver cirrus_bo_driver = { | |||
241 | .ttm_tt_unpopulate = cirrus_ttm_tt_unpopulate, | 230 | .ttm_tt_unpopulate = cirrus_ttm_tt_unpopulate, |
242 | .init_mem_type = cirrus_bo_init_mem_type, | 231 | .init_mem_type = cirrus_bo_init_mem_type, |
243 | .evict_flags = cirrus_bo_evict_flags, | 232 | .evict_flags = cirrus_bo_evict_flags, |
244 | .move = cirrus_bo_move, | 233 | .move = NULL, |
245 | .verify_access = cirrus_bo_verify_access, | 234 | .verify_access = cirrus_bo_verify_access, |
246 | .io_mem_reserve = &cirrus_ttm_io_mem_reserve, | 235 | .io_mem_reserve = &cirrus_ttm_io_mem_reserve, |
247 | .io_mem_free = &cirrus_ttm_io_mem_free, | 236 | .io_mem_free = &cirrus_ttm_io_mem_free, |
diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c index 9d5083d0f1ee..68268e55d595 100644 --- a/drivers/gpu/drm/mgag200/mgag200_ttm.c +++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c | |||
@@ -186,17 +186,6 @@ static void mgag200_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_r | |||
186 | { | 186 | { |
187 | } | 187 | } |
188 | 188 | ||
189 | static int mgag200_bo_move(struct ttm_buffer_object *bo, | ||
190 | bool evict, bool interruptible, | ||
191 | bool no_wait_gpu, | ||
192 | struct ttm_mem_reg *new_mem) | ||
193 | { | ||
194 | int r; | ||
195 | r = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); | ||
196 | return r; | ||
197 | } | ||
198 | |||
199 | |||
200 | static void mgag200_ttm_backend_destroy(struct ttm_tt *tt) | 189 | static void mgag200_ttm_backend_destroy(struct ttm_tt *tt) |
201 | { | 190 | { |
202 | ttm_tt_fini(tt); | 191 | ttm_tt_fini(tt); |
@@ -241,7 +230,7 @@ struct ttm_bo_driver mgag200_bo_driver = { | |||
241 | .ttm_tt_unpopulate = mgag200_ttm_tt_unpopulate, | 230 | .ttm_tt_unpopulate = mgag200_ttm_tt_unpopulate, |
242 | .init_mem_type = mgag200_bo_init_mem_type, | 231 | .init_mem_type = mgag200_bo_init_mem_type, |
243 | .evict_flags = mgag200_bo_evict_flags, | 232 | .evict_flags = mgag200_bo_evict_flags, |
244 | .move = mgag200_bo_move, | 233 | .move = NULL, |
245 | .verify_access = mgag200_bo_verify_access, | 234 | .verify_access = mgag200_bo_verify_access, |
246 | .io_mem_reserve = &mgag200_ttm_io_mem_reserve, | 235 | .io_mem_reserve = &mgag200_ttm_io_mem_reserve, |
247 | .io_mem_free = &mgag200_ttm_io_mem_free, | 236 | .io_mem_free = &mgag200_ttm_io_mem_free, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 5e3f3e826476..cdd551ef5bc8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -1082,7 +1082,6 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, | |||
1082 | ret = ttm_bo_move_accel_cleanup(bo, | 1082 | ret = ttm_bo_move_accel_cleanup(bo, |
1083 | &fence->base, | 1083 | &fence->base, |
1084 | evict, | 1084 | evict, |
1085 | no_wait_gpu, | ||
1086 | new_mem); | 1085 | new_mem); |
1087 | nouveau_fence_unref(&fence); | 1086 | nouveau_fence_unref(&fence); |
1088 | } | 1087 | } |
@@ -1289,6 +1288,10 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
1289 | struct nouveau_drm_tile *new_tile = NULL; | 1288 | struct nouveau_drm_tile *new_tile = NULL; |
1290 | int ret = 0; | 1289 | int ret = 0; |
1291 | 1290 | ||
1291 | ret = ttm_bo_wait(bo, intr, no_wait_gpu); | ||
1292 | if (ret) | ||
1293 | return ret; | ||
1294 | |||
1292 | if (nvbo->pin_refcnt) | 1295 | if (nvbo->pin_refcnt) |
1293 | NV_WARN(drm, "Moving pinned object %p!\n", nvbo); | 1296 | NV_WARN(drm, "Moving pinned object %p!\n", nvbo); |
1294 | 1297 | ||
@@ -1324,7 +1327,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
1324 | /* Fallback to software copy. */ | 1327 | /* Fallback to software copy. */ |
1325 | ret = ttm_bo_wait(bo, intr, no_wait_gpu); | 1328 | ret = ttm_bo_wait(bo, intr, no_wait_gpu); |
1326 | if (ret == 0) | 1329 | if (ret == 0) |
1327 | ret = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); | 1330 | ret = ttm_bo_move_memcpy(bo, evict, intr, no_wait_gpu, new_mem); |
1328 | 1331 | ||
1329 | out: | 1332 | out: |
1330 | if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { | 1333 | 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 0738d74c8d04..d50c9679e631 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c | |||
@@ -350,11 +350,19 @@ static int qxl_bo_move(struct ttm_buffer_object *bo, | |||
350 | struct ttm_mem_reg *new_mem) | 350 | struct ttm_mem_reg *new_mem) |
351 | { | 351 | { |
352 | struct ttm_mem_reg *old_mem = &bo->mem; | 352 | struct ttm_mem_reg *old_mem = &bo->mem; |
353 | int ret; | ||
354 | |||
355 | ret = ttm_bo_wait(bo, interruptible, no_wait_gpu); | ||
356 | if (ret) | ||
357 | return ret; | ||
358 | |||
359 | |||
353 | if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { | 360 | if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { |
354 | qxl_move_null(bo, new_mem); | 361 | qxl_move_null(bo, new_mem); |
355 | return 0; | 362 | return 0; |
356 | } | 363 | } |
357 | return ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); | 364 | return ttm_bo_move_memcpy(bo, evict, interruptible, |
365 | no_wait_gpu, new_mem); | ||
358 | } | 366 | } |
359 | 367 | ||
360 | static void qxl_bo_move_notify(struct ttm_buffer_object *bo, | 368 | static void qxl_bo_move_notify(struct ttm_buffer_object *bo, |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index ba192a35c607..0c1b9ff433af 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -53,6 +53,7 @@ MODULE_FIRMWARE("radeon/bonaire_mc.bin"); | |||
53 | MODULE_FIRMWARE("radeon/bonaire_rlc.bin"); | 53 | MODULE_FIRMWARE("radeon/bonaire_rlc.bin"); |
54 | MODULE_FIRMWARE("radeon/bonaire_sdma.bin"); | 54 | MODULE_FIRMWARE("radeon/bonaire_sdma.bin"); |
55 | MODULE_FIRMWARE("radeon/bonaire_smc.bin"); | 55 | MODULE_FIRMWARE("radeon/bonaire_smc.bin"); |
56 | MODULE_FIRMWARE("radeon/bonaire_k_smc.bin"); | ||
56 | 57 | ||
57 | MODULE_FIRMWARE("radeon/HAWAII_pfp.bin"); | 58 | MODULE_FIRMWARE("radeon/HAWAII_pfp.bin"); |
58 | MODULE_FIRMWARE("radeon/HAWAII_me.bin"); | 59 | MODULE_FIRMWARE("radeon/HAWAII_me.bin"); |
@@ -72,6 +73,7 @@ MODULE_FIRMWARE("radeon/hawaii_mc.bin"); | |||
72 | MODULE_FIRMWARE("radeon/hawaii_rlc.bin"); | 73 | MODULE_FIRMWARE("radeon/hawaii_rlc.bin"); |
73 | MODULE_FIRMWARE("radeon/hawaii_sdma.bin"); | 74 | MODULE_FIRMWARE("radeon/hawaii_sdma.bin"); |
74 | MODULE_FIRMWARE("radeon/hawaii_smc.bin"); | 75 | MODULE_FIRMWARE("radeon/hawaii_smc.bin"); |
76 | MODULE_FIRMWARE("radeon/hawaii_k_smc.bin"); | ||
75 | 77 | ||
76 | MODULE_FIRMWARE("radeon/KAVERI_pfp.bin"); | 78 | MODULE_FIRMWARE("radeon/KAVERI_pfp.bin"); |
77 | MODULE_FIRMWARE("radeon/KAVERI_me.bin"); | 79 | MODULE_FIRMWARE("radeon/KAVERI_me.bin"); |
@@ -1990,12 +1992,17 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
1990 | int new_fw = 0; | 1992 | int new_fw = 0; |
1991 | int err; | 1993 | int err; |
1992 | int num_fw; | 1994 | int num_fw; |
1995 | bool new_smc = false; | ||
1993 | 1996 | ||
1994 | DRM_DEBUG("\n"); | 1997 | DRM_DEBUG("\n"); |
1995 | 1998 | ||
1996 | switch (rdev->family) { | 1999 | switch (rdev->family) { |
1997 | case CHIP_BONAIRE: | 2000 | case CHIP_BONAIRE: |
1998 | chip_name = "BONAIRE"; | 2001 | chip_name = "BONAIRE"; |
2002 | if ((rdev->pdev->revision == 0x80) || | ||
2003 | (rdev->pdev->revision == 0x81) || | ||
2004 | (rdev->pdev->device == 0x665f)) | ||
2005 | new_smc = true; | ||
1999 | new_chip_name = "bonaire"; | 2006 | new_chip_name = "bonaire"; |
2000 | pfp_req_size = CIK_PFP_UCODE_SIZE * 4; | 2007 | pfp_req_size = CIK_PFP_UCODE_SIZE * 4; |
2001 | me_req_size = CIK_ME_UCODE_SIZE * 4; | 2008 | me_req_size = CIK_ME_UCODE_SIZE * 4; |
@@ -2010,6 +2017,8 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
2010 | break; | 2017 | break; |
2011 | case CHIP_HAWAII: | 2018 | case CHIP_HAWAII: |
2012 | chip_name = "HAWAII"; | 2019 | chip_name = "HAWAII"; |
2020 | if (rdev->pdev->revision == 0x80) | ||
2021 | new_smc = true; | ||
2013 | new_chip_name = "hawaii"; | 2022 | new_chip_name = "hawaii"; |
2014 | pfp_req_size = CIK_PFP_UCODE_SIZE * 4; | 2023 | pfp_req_size = CIK_PFP_UCODE_SIZE * 4; |
2015 | me_req_size = CIK_ME_UCODE_SIZE * 4; | 2024 | me_req_size = CIK_ME_UCODE_SIZE * 4; |
@@ -2259,7 +2268,10 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
2259 | } | 2268 | } |
2260 | } | 2269 | } |
2261 | 2270 | ||
2262 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name); | 2271 | if (new_smc) |
2272 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_k_smc.bin", new_chip_name); | ||
2273 | else | ||
2274 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name); | ||
2263 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); | 2275 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); |
2264 | if (err) { | 2276 | if (err) { |
2265 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); | 2277 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); |
@@ -8354,7 +8366,8 @@ static int cik_startup(struct radeon_device *rdev) | |||
8354 | } | 8366 | } |
8355 | } | 8367 | } |
8356 | rdev->rlc.cs_data = ci_cs_data; | 8368 | rdev->rlc.cs_data = ci_cs_data; |
8357 | rdev->rlc.cp_table_size = CP_ME_TABLE_SIZE * 5 * 4; | 8369 | rdev->rlc.cp_table_size = ALIGN(CP_ME_TABLE_SIZE * 5 * 4, 2048); /* CP JT */ |
8370 | rdev->rlc.cp_table_size += 64 * 1024; /* GDS */ | ||
8358 | r = sumo_rlc_init(rdev); | 8371 | r = sumo_rlc_init(rdev); |
8359 | if (r) { | 8372 | if (r) { |
8360 | DRM_ERROR("Failed to init rlc BOs!\n"); | 8373 | DRM_ERROR("Failed to init rlc BOs!\n"); |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 0d3f744de35a..d960d3915408 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -2209,6 +2209,12 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2209 | } | 2209 | } |
2210 | break; | 2210 | break; |
2211 | } | 2211 | } |
2212 | case PACKET3_PFP_SYNC_ME: | ||
2213 | if (pkt->count) { | ||
2214 | DRM_ERROR("bad PFP_SYNC_ME\n"); | ||
2215 | return -EINVAL; | ||
2216 | } | ||
2217 | break; | ||
2212 | case PACKET3_SURFACE_SYNC: | 2218 | case PACKET3_SURFACE_SYNC: |
2213 | if (pkt->count != 3) { | 2219 | if (pkt->count != 3) { |
2214 | DRM_ERROR("bad SURFACE_SYNC\n"); | 2220 | DRM_ERROR("bad SURFACE_SYNC\n"); |
@@ -3381,6 +3387,7 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev, | |||
3381 | case PACKET3_MPEG_INDEX: | 3387 | case PACKET3_MPEG_INDEX: |
3382 | case PACKET3_WAIT_REG_MEM: | 3388 | case PACKET3_WAIT_REG_MEM: |
3383 | case PACKET3_MEM_WRITE: | 3389 | case PACKET3_MEM_WRITE: |
3390 | case PACKET3_PFP_SYNC_ME: | ||
3384 | case PACKET3_SURFACE_SYNC: | 3391 | case PACKET3_SURFACE_SYNC: |
3385 | case PACKET3_EVENT_WRITE: | 3392 | case PACKET3_EVENT_WRITE: |
3386 | case PACKET3_EVENT_WRITE_EOP: | 3393 | case PACKET3_EVENT_WRITE_EOP: |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 0b174e14e9a6..c8e3d394cde7 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -1624,6 +1624,7 @@ | |||
1624 | */ | 1624 | */ |
1625 | # define PACKET3_CP_DMA_CMD_SAIC (1 << 28) | 1625 | # define PACKET3_CP_DMA_CMD_SAIC (1 << 28) |
1626 | # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) | 1626 | # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) |
1627 | #define PACKET3_PFP_SYNC_ME 0x42 | ||
1627 | #define PACKET3_SURFACE_SYNC 0x43 | 1628 | #define PACKET3_SURFACE_SYNC 0x43 |
1628 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) | 1629 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) |
1629 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) | 1630 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 95f4fea89302..86dcdf38b732 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/acpi.h> | 11 | #include <linux/acpi.h> |
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/delay.h> | ||
13 | 14 | ||
14 | #include "radeon_acpi.h" | 15 | #include "radeon_acpi.h" |
15 | 16 | ||
@@ -27,6 +28,7 @@ struct radeon_atpx_functions { | |||
27 | struct radeon_atpx { | 28 | struct radeon_atpx { |
28 | acpi_handle handle; | 29 | acpi_handle handle; |
29 | struct radeon_atpx_functions functions; | 30 | struct radeon_atpx_functions functions; |
31 | bool is_hybrid; | ||
30 | }; | 32 | }; |
31 | 33 | ||
32 | static struct radeon_atpx_priv { | 34 | static struct radeon_atpx_priv { |
@@ -62,6 +64,14 @@ bool radeon_has_atpx(void) { | |||
62 | return radeon_atpx_priv.atpx_detected; | 64 | return radeon_atpx_priv.atpx_detected; |
63 | } | 65 | } |
64 | 66 | ||
67 | bool radeon_has_atpx_dgpu_power_cntl(void) { | ||
68 | return radeon_atpx_priv.atpx.functions.power_cntl; | ||
69 | } | ||
70 | |||
71 | bool radeon_is_atpx_hybrid(void) { | ||
72 | return radeon_atpx_priv.atpx.is_hybrid; | ||
73 | } | ||
74 | |||
65 | /** | 75 | /** |
66 | * radeon_atpx_call - call an ATPX method | 76 | * radeon_atpx_call - call an ATPX method |
67 | * | 77 | * |
@@ -141,18 +151,12 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas | |||
141 | */ | 151 | */ |
142 | static int radeon_atpx_validate(struct radeon_atpx *atpx) | 152 | static int radeon_atpx_validate(struct radeon_atpx *atpx) |
143 | { | 153 | { |
144 | /* make sure required functions are enabled */ | 154 | u32 valid_bits = 0; |
145 | /* dGPU power control is required */ | ||
146 | if (atpx->functions.power_cntl == false) { | ||
147 | printk("ATPX dGPU power cntl not present, forcing\n"); | ||
148 | atpx->functions.power_cntl = true; | ||
149 | } | ||
150 | 155 | ||
151 | if (atpx->functions.px_params) { | 156 | if (atpx->functions.px_params) { |
152 | union acpi_object *info; | 157 | union acpi_object *info; |
153 | struct atpx_px_params output; | 158 | struct atpx_px_params output; |
154 | size_t size; | 159 | size_t size; |
155 | u32 valid_bits; | ||
156 | 160 | ||
157 | info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); | 161 | info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); |
158 | if (!info) | 162 | if (!info) |
@@ -171,19 +175,42 @@ static int radeon_atpx_validate(struct radeon_atpx *atpx) | |||
171 | memcpy(&output, info->buffer.pointer, size); | 175 | memcpy(&output, info->buffer.pointer, size); |
172 | 176 | ||
173 | valid_bits = output.flags & output.valid_flags; | 177 | valid_bits = output.flags & output.valid_flags; |
174 | /* if separate mux flag is set, mux controls are required */ | ||
175 | if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { | ||
176 | atpx->functions.i2c_mux_cntl = true; | ||
177 | atpx->functions.disp_mux_cntl = true; | ||
178 | } | ||
179 | /* if any outputs are muxed, mux controls are required */ | ||
180 | if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | | ||
181 | ATPX_TV_SIGNAL_MUXED | | ||
182 | ATPX_DFP_SIGNAL_MUXED)) | ||
183 | atpx->functions.disp_mux_cntl = true; | ||
184 | 178 | ||
185 | kfree(info); | 179 | kfree(info); |
186 | } | 180 | } |
181 | |||
182 | /* if separate mux flag is set, mux controls are required */ | ||
183 | if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { | ||
184 | atpx->functions.i2c_mux_cntl = true; | ||
185 | atpx->functions.disp_mux_cntl = true; | ||
186 | } | ||
187 | /* if any outputs are muxed, mux controls are required */ | ||
188 | if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | | ||
189 | ATPX_TV_SIGNAL_MUXED | | ||
190 | ATPX_DFP_SIGNAL_MUXED)) | ||
191 | atpx->functions.disp_mux_cntl = true; | ||
192 | |||
193 | /* some bioses set these bits rather than flagging power_cntl as supported */ | ||
194 | if (valid_bits & (ATPX_DYNAMIC_PX_SUPPORTED | | ||
195 | ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED)) | ||
196 | atpx->functions.power_cntl = true; | ||
197 | |||
198 | atpx->is_hybrid = false; | ||
199 | if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { | ||
200 | printk("ATPX Hybrid Graphics\n"); | ||
201 | #if 1 | ||
202 | /* This is a temporary hack until the D3 cold support | ||
203 | * makes it upstream. The ATPX power_control method seems | ||
204 | * to still work on even if the system should be using | ||
205 | * the new standardized hybrid D3 cold ACPI interface. | ||
206 | */ | ||
207 | atpx->functions.power_cntl = true; | ||
208 | #else | ||
209 | atpx->functions.power_cntl = false; | ||
210 | #endif | ||
211 | atpx->is_hybrid = true; | ||
212 | } | ||
213 | |||
187 | return 0; | 214 | return 0; |
188 | } | 215 | } |
189 | 216 | ||
@@ -258,6 +285,10 @@ static int radeon_atpx_set_discrete_state(struct radeon_atpx *atpx, u8 state) | |||
258 | if (!info) | 285 | if (!info) |
259 | return -EIO; | 286 | return -EIO; |
260 | kfree(info); | 287 | kfree(info); |
288 | |||
289 | /* 200ms delay is required after off */ | ||
290 | if (state == 0) | ||
291 | msleep(200); | ||
261 | } | 292 | } |
262 | return 0; | 293 | return 0; |
263 | } | 294 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 81a63d7f5cd9..b79f3b002471 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -2064,7 +2064,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
2064 | RADEON_OUTPUT_CSC_BYPASS); | 2064 | RADEON_OUTPUT_CSC_BYPASS); |
2065 | /* no HPD on analog connectors */ | 2065 | /* no HPD on analog connectors */ |
2066 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | 2066 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
2067 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
2068 | connector->interlace_allowed = true; | 2067 | connector->interlace_allowed = true; |
2069 | connector->doublescan_allowed = true; | 2068 | connector->doublescan_allowed = true; |
2070 | break; | 2069 | break; |
@@ -2314,8 +2313,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
2314 | } | 2313 | } |
2315 | 2314 | ||
2316 | if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { | 2315 | if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { |
2317 | if (i2c_bus->valid) | 2316 | if (i2c_bus->valid) { |
2318 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 2317 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | |
2318 | DRM_CONNECTOR_POLL_DISCONNECT; | ||
2319 | } | ||
2319 | } else | 2320 | } else |
2320 | connector->polled = DRM_CONNECTOR_POLL_HPD; | 2321 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
2321 | 2322 | ||
@@ -2391,7 +2392,6 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
2391 | 1); | 2392 | 1); |
2392 | /* no HPD on analog connectors */ | 2393 | /* no HPD on analog connectors */ |
2393 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | 2394 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
2394 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
2395 | connector->interlace_allowed = true; | 2395 | connector->interlace_allowed = true; |
2396 | connector->doublescan_allowed = true; | 2396 | connector->doublescan_allowed = true; |
2397 | break; | 2397 | break; |
@@ -2476,10 +2476,13 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
2476 | } | 2476 | } |
2477 | 2477 | ||
2478 | if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { | 2478 | if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { |
2479 | if (i2c_bus->valid) | 2479 | if (i2c_bus->valid) { |
2480 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 2480 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | |
2481 | DRM_CONNECTOR_POLL_DISCONNECT; | ||
2482 | } | ||
2481 | } else | 2483 | } else |
2482 | connector->polled = DRM_CONNECTOR_POLL_HPD; | 2484 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
2485 | |||
2483 | connector->display_info.subpixel_order = subpixel_order; | 2486 | connector->display_info.subpixel_order = subpixel_order; |
2484 | drm_connector_register(connector); | 2487 | drm_connector_register(connector); |
2485 | } | 2488 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a455dc7d4aa1..c01a7c6abb49 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -93,9 +93,10 @@ | |||
93 | * 2.43.0 - RADEON_INFO_GPU_RESET_COUNTER | 93 | * 2.43.0 - RADEON_INFO_GPU_RESET_COUNTER |
94 | * 2.44.0 - SET_APPEND_CNT packet3 support | 94 | * 2.44.0 - SET_APPEND_CNT packet3 support |
95 | * 2.45.0 - Allow setting shader registers using DMA/COPY packet3 on SI | 95 | * 2.45.0 - Allow setting shader registers using DMA/COPY packet3 on SI |
96 | * 2.46.0 - Add PFP_SYNC_ME support on evergreen | ||
96 | */ | 97 | */ |
97 | #define KMS_DRIVER_MAJOR 2 | 98 | #define KMS_DRIVER_MAJOR 2 |
98 | #define KMS_DRIVER_MINOR 45 | 99 | #define KMS_DRIVER_MINOR 46 |
99 | #define KMS_DRIVER_PATCHLEVEL 0 | 100 | #define KMS_DRIVER_PATCHLEVEL 0 |
100 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 101 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
101 | int radeon_driver_unload_kms(struct drm_device *dev); | 102 | int radeon_driver_unload_kms(struct drm_device *dev); |
@@ -162,9 +163,13 @@ void radeon_debugfs_cleanup(struct drm_minor *minor); | |||
162 | #if defined(CONFIG_VGA_SWITCHEROO) | 163 | #if defined(CONFIG_VGA_SWITCHEROO) |
163 | void radeon_register_atpx_handler(void); | 164 | void radeon_register_atpx_handler(void); |
164 | void radeon_unregister_atpx_handler(void); | 165 | void radeon_unregister_atpx_handler(void); |
166 | bool radeon_has_atpx_dgpu_power_cntl(void); | ||
167 | bool radeon_is_atpx_hybrid(void); | ||
165 | #else | 168 | #else |
166 | static inline void radeon_register_atpx_handler(void) {} | 169 | static inline void radeon_register_atpx_handler(void) {} |
167 | static inline void radeon_unregister_atpx_handler(void) {} | 170 | static inline void radeon_unregister_atpx_handler(void) {} |
171 | static inline bool radeon_has_atpx_dgpu_power_cntl(void) { return false; } | ||
172 | static inline bool radeon_is_atpx_hybrid(void) { return false; } | ||
168 | #endif | 173 | #endif |
169 | 174 | ||
170 | int radeon_no_wb; | 175 | int radeon_no_wb; |
@@ -404,7 +409,10 @@ static int radeon_pmops_runtime_suspend(struct device *dev) | |||
404 | pci_save_state(pdev); | 409 | pci_save_state(pdev); |
405 | pci_disable_device(pdev); | 410 | pci_disable_device(pdev); |
406 | pci_ignore_hotplug(pdev); | 411 | pci_ignore_hotplug(pdev); |
407 | pci_set_power_state(pdev, PCI_D3cold); | 412 | if (radeon_is_atpx_hybrid()) |
413 | pci_set_power_state(pdev, PCI_D3cold); | ||
414 | else if (!radeon_has_atpx_dgpu_power_cntl()) | ||
415 | pci_set_power_state(pdev, PCI_D3hot); | ||
408 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; | 416 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; |
409 | 417 | ||
410 | return 0; | 418 | return 0; |
@@ -421,7 +429,9 @@ static int radeon_pmops_runtime_resume(struct device *dev) | |||
421 | 429 | ||
422 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 430 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
423 | 431 | ||
424 | pci_set_power_state(pdev, PCI_D0); | 432 | if (radeon_is_atpx_hybrid() || |
433 | !radeon_has_atpx_dgpu_power_cntl()) | ||
434 | pci_set_power_state(pdev, PCI_D0); | ||
425 | pci_restore_state(pdev); | 435 | pci_restore_state(pdev); |
426 | ret = pci_enable_device(pdev); | 436 | ret = pci_enable_device(pdev); |
427 | if (ret) | 437 | if (ret) |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 590b0377fbe2..ffdad81ef964 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -300,8 +300,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
300 | if (IS_ERR(fence)) | 300 | if (IS_ERR(fence)) |
301 | return PTR_ERR(fence); | 301 | return PTR_ERR(fence); |
302 | 302 | ||
303 | r = ttm_bo_move_accel_cleanup(bo, &fence->base, | 303 | r = ttm_bo_move_accel_cleanup(bo, &fence->base, evict, new_mem); |
304 | evict, no_wait_gpu, new_mem); | ||
305 | radeon_fence_unref(&fence); | 304 | radeon_fence_unref(&fence); |
306 | return r; | 305 | return r; |
307 | } | 306 | } |
@@ -403,6 +402,10 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, | |||
403 | struct ttm_mem_reg *old_mem = &bo->mem; | 402 | struct ttm_mem_reg *old_mem = &bo->mem; |
404 | int r; | 403 | int r; |
405 | 404 | ||
405 | r = ttm_bo_wait(bo, interruptible, no_wait_gpu); | ||
406 | if (r) | ||
407 | return r; | ||
408 | |||
406 | /* Can't move a pinned BO */ | 409 | /* Can't move a pinned BO */ |
407 | rbo = container_of(bo, struct radeon_bo, tbo); | 410 | rbo = container_of(bo, struct radeon_bo, tbo); |
408 | if (WARN_ON_ONCE(rbo->pin_count > 0)) | 411 | if (WARN_ON_ONCE(rbo->pin_count > 0)) |
@@ -441,7 +444,8 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, | |||
441 | 444 | ||
442 | if (r) { | 445 | if (r) { |
443 | memcpy: | 446 | memcpy: |
444 | r = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); | 447 | r = ttm_bo_move_memcpy(bo, evict, interruptible, |
448 | no_wait_gpu, new_mem); | ||
445 | if (r) { | 449 | if (r) { |
446 | return r; | 450 | return r; |
447 | } | 451 | } |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index b30e719dd56d..2523ca96c6c7 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -50,6 +50,7 @@ MODULE_FIRMWARE("radeon/tahiti_ce.bin"); | |||
50 | MODULE_FIRMWARE("radeon/tahiti_mc.bin"); | 50 | MODULE_FIRMWARE("radeon/tahiti_mc.bin"); |
51 | MODULE_FIRMWARE("radeon/tahiti_rlc.bin"); | 51 | MODULE_FIRMWARE("radeon/tahiti_rlc.bin"); |
52 | MODULE_FIRMWARE("radeon/tahiti_smc.bin"); | 52 | MODULE_FIRMWARE("radeon/tahiti_smc.bin"); |
53 | MODULE_FIRMWARE("radeon/tahiti_k_smc.bin"); | ||
53 | 54 | ||
54 | MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin"); | 55 | MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin"); |
55 | MODULE_FIRMWARE("radeon/PITCAIRN_me.bin"); | 56 | MODULE_FIRMWARE("radeon/PITCAIRN_me.bin"); |
@@ -65,6 +66,7 @@ MODULE_FIRMWARE("radeon/pitcairn_ce.bin"); | |||
65 | MODULE_FIRMWARE("radeon/pitcairn_mc.bin"); | 66 | MODULE_FIRMWARE("radeon/pitcairn_mc.bin"); |
66 | MODULE_FIRMWARE("radeon/pitcairn_rlc.bin"); | 67 | MODULE_FIRMWARE("radeon/pitcairn_rlc.bin"); |
67 | MODULE_FIRMWARE("radeon/pitcairn_smc.bin"); | 68 | MODULE_FIRMWARE("radeon/pitcairn_smc.bin"); |
69 | MODULE_FIRMWARE("radeon/pitcairn_k_smc.bin"); | ||
68 | 70 | ||
69 | MODULE_FIRMWARE("radeon/VERDE_pfp.bin"); | 71 | MODULE_FIRMWARE("radeon/VERDE_pfp.bin"); |
70 | MODULE_FIRMWARE("radeon/VERDE_me.bin"); | 72 | MODULE_FIRMWARE("radeon/VERDE_me.bin"); |
@@ -80,6 +82,7 @@ MODULE_FIRMWARE("radeon/verde_ce.bin"); | |||
80 | MODULE_FIRMWARE("radeon/verde_mc.bin"); | 82 | MODULE_FIRMWARE("radeon/verde_mc.bin"); |
81 | MODULE_FIRMWARE("radeon/verde_rlc.bin"); | 83 | MODULE_FIRMWARE("radeon/verde_rlc.bin"); |
82 | MODULE_FIRMWARE("radeon/verde_smc.bin"); | 84 | MODULE_FIRMWARE("radeon/verde_smc.bin"); |
85 | MODULE_FIRMWARE("radeon/verde_k_smc.bin"); | ||
83 | 86 | ||
84 | MODULE_FIRMWARE("radeon/OLAND_pfp.bin"); | 87 | MODULE_FIRMWARE("radeon/OLAND_pfp.bin"); |
85 | MODULE_FIRMWARE("radeon/OLAND_me.bin"); | 88 | MODULE_FIRMWARE("radeon/OLAND_me.bin"); |
@@ -95,6 +98,7 @@ MODULE_FIRMWARE("radeon/oland_ce.bin"); | |||
95 | MODULE_FIRMWARE("radeon/oland_mc.bin"); | 98 | MODULE_FIRMWARE("radeon/oland_mc.bin"); |
96 | MODULE_FIRMWARE("radeon/oland_rlc.bin"); | 99 | MODULE_FIRMWARE("radeon/oland_rlc.bin"); |
97 | MODULE_FIRMWARE("radeon/oland_smc.bin"); | 100 | MODULE_FIRMWARE("radeon/oland_smc.bin"); |
101 | MODULE_FIRMWARE("radeon/oland_k_smc.bin"); | ||
98 | 102 | ||
99 | MODULE_FIRMWARE("radeon/HAINAN_pfp.bin"); | 103 | MODULE_FIRMWARE("radeon/HAINAN_pfp.bin"); |
100 | MODULE_FIRMWARE("radeon/HAINAN_me.bin"); | 104 | MODULE_FIRMWARE("radeon/HAINAN_me.bin"); |
@@ -110,6 +114,7 @@ MODULE_FIRMWARE("radeon/hainan_ce.bin"); | |||
110 | MODULE_FIRMWARE("radeon/hainan_mc.bin"); | 114 | MODULE_FIRMWARE("radeon/hainan_mc.bin"); |
111 | MODULE_FIRMWARE("radeon/hainan_rlc.bin"); | 115 | MODULE_FIRMWARE("radeon/hainan_rlc.bin"); |
112 | MODULE_FIRMWARE("radeon/hainan_smc.bin"); | 116 | MODULE_FIRMWARE("radeon/hainan_smc.bin"); |
117 | MODULE_FIRMWARE("radeon/hainan_k_smc.bin"); | ||
113 | 118 | ||
114 | static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh); | 119 | static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh); |
115 | static void si_pcie_gen3_enable(struct radeon_device *rdev); | 120 | static void si_pcie_gen3_enable(struct radeon_device *rdev); |
@@ -1653,12 +1658,16 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
1653 | char fw_name[30]; | 1658 | char fw_name[30]; |
1654 | int err; | 1659 | int err; |
1655 | int new_fw = 0; | 1660 | int new_fw = 0; |
1661 | bool new_smc = false; | ||
1656 | 1662 | ||
1657 | DRM_DEBUG("\n"); | 1663 | DRM_DEBUG("\n"); |
1658 | 1664 | ||
1659 | switch (rdev->family) { | 1665 | switch (rdev->family) { |
1660 | case CHIP_TAHITI: | 1666 | case CHIP_TAHITI: |
1661 | chip_name = "TAHITI"; | 1667 | chip_name = "TAHITI"; |
1668 | /* XXX: figure out which Tahitis need the new ucode */ | ||
1669 | if (0) | ||
1670 | new_smc = true; | ||
1662 | new_chip_name = "tahiti"; | 1671 | new_chip_name = "tahiti"; |
1663 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; | 1672 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; |
1664 | me_req_size = SI_PM4_UCODE_SIZE * 4; | 1673 | me_req_size = SI_PM4_UCODE_SIZE * 4; |
@@ -1670,6 +1679,13 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
1670 | break; | 1679 | break; |
1671 | case CHIP_PITCAIRN: | 1680 | case CHIP_PITCAIRN: |
1672 | chip_name = "PITCAIRN"; | 1681 | chip_name = "PITCAIRN"; |
1682 | if ((rdev->pdev->revision == 0x81) || | ||
1683 | (rdev->pdev->device == 0x6810) || | ||
1684 | (rdev->pdev->device == 0x6811) || | ||
1685 | (rdev->pdev->device == 0x6816) || | ||
1686 | (rdev->pdev->device == 0x6817) || | ||
1687 | (rdev->pdev->device == 0x6806)) | ||
1688 | new_smc = true; | ||
1673 | new_chip_name = "pitcairn"; | 1689 | new_chip_name = "pitcairn"; |
1674 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; | 1690 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; |
1675 | me_req_size = SI_PM4_UCODE_SIZE * 4; | 1691 | me_req_size = SI_PM4_UCODE_SIZE * 4; |
@@ -1681,6 +1697,16 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
1681 | break; | 1697 | break; |
1682 | case CHIP_VERDE: | 1698 | case CHIP_VERDE: |
1683 | chip_name = "VERDE"; | 1699 | chip_name = "VERDE"; |
1700 | if ((rdev->pdev->revision == 0x81) || | ||
1701 | (rdev->pdev->revision == 0x83) || | ||
1702 | (rdev->pdev->revision == 0x87) || | ||
1703 | (rdev->pdev->device == 0x6820) || | ||
1704 | (rdev->pdev->device == 0x6821) || | ||
1705 | (rdev->pdev->device == 0x6822) || | ||
1706 | (rdev->pdev->device == 0x6823) || | ||
1707 | (rdev->pdev->device == 0x682A) || | ||
1708 | (rdev->pdev->device == 0x682B)) | ||
1709 | new_smc = true; | ||
1684 | new_chip_name = "verde"; | 1710 | new_chip_name = "verde"; |
1685 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; | 1711 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; |
1686 | me_req_size = SI_PM4_UCODE_SIZE * 4; | 1712 | me_req_size = SI_PM4_UCODE_SIZE * 4; |
@@ -1692,6 +1718,13 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
1692 | break; | 1718 | break; |
1693 | case CHIP_OLAND: | 1719 | case CHIP_OLAND: |
1694 | chip_name = "OLAND"; | 1720 | chip_name = "OLAND"; |
1721 | if ((rdev->pdev->revision == 0xC7) || | ||
1722 | (rdev->pdev->revision == 0x80) || | ||
1723 | (rdev->pdev->revision == 0x81) || | ||
1724 | (rdev->pdev->revision == 0x83) || | ||
1725 | (rdev->pdev->device == 0x6604) || | ||
1726 | (rdev->pdev->device == 0x6605)) | ||
1727 | new_smc = true; | ||
1695 | new_chip_name = "oland"; | 1728 | new_chip_name = "oland"; |
1696 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; | 1729 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; |
1697 | me_req_size = SI_PM4_UCODE_SIZE * 4; | 1730 | me_req_size = SI_PM4_UCODE_SIZE * 4; |
@@ -1702,6 +1735,13 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
1702 | break; | 1735 | break; |
1703 | case CHIP_HAINAN: | 1736 | case CHIP_HAINAN: |
1704 | chip_name = "HAINAN"; | 1737 | chip_name = "HAINAN"; |
1738 | if ((rdev->pdev->revision == 0x81) || | ||
1739 | (rdev->pdev->revision == 0x83) || | ||
1740 | (rdev->pdev->revision == 0xC3) || | ||
1741 | (rdev->pdev->device == 0x6664) || | ||
1742 | (rdev->pdev->device == 0x6665) || | ||
1743 | (rdev->pdev->device == 0x6667)) | ||
1744 | new_smc = true; | ||
1705 | new_chip_name = "hainan"; | 1745 | new_chip_name = "hainan"; |
1706 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; | 1746 | pfp_req_size = SI_PFP_UCODE_SIZE * 4; |
1707 | me_req_size = SI_PM4_UCODE_SIZE * 4; | 1747 | me_req_size = SI_PM4_UCODE_SIZE * 4; |
@@ -1847,7 +1887,10 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
1847 | } | 1887 | } |
1848 | } | 1888 | } |
1849 | 1889 | ||
1850 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name); | 1890 | if (new_smc) |
1891 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_k_smc.bin", new_chip_name); | ||
1892 | else | ||
1893 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name); | ||
1851 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); | 1894 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); |
1852 | if (err) { | 1895 | if (err) { |
1853 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); | 1896 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 39386f50af87..e340d0d66429 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -147,9 +147,9 @@ static void ttm_bo_release_list(struct kref *list_kref) | |||
147 | BUG_ON(!list_empty(&bo->lru)); | 147 | BUG_ON(!list_empty(&bo->lru)); |
148 | BUG_ON(!list_empty(&bo->ddestroy)); | 148 | BUG_ON(!list_empty(&bo->ddestroy)); |
149 | 149 | ||
150 | if (bo->ttm) | 150 | ttm_tt_destroy(bo->ttm); |
151 | ttm_tt_destroy(bo->ttm); | ||
152 | atomic_dec(&bo->glob->bo_count); | 151 | atomic_dec(&bo->glob->bo_count); |
152 | fence_put(bo->moving); | ||
153 | if (bo->resv == &bo->ttm_resv) | 153 | if (bo->resv == &bo->ttm_resv) |
154 | reservation_object_fini(&bo->ttm_resv); | 154 | reservation_object_fini(&bo->ttm_resv); |
155 | mutex_destroy(&bo->wu_mutex); | 155 | mutex_destroy(&bo->wu_mutex); |
@@ -360,7 +360,8 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, | |||
360 | ret = bdev->driver->move(bo, evict, interruptible, | 360 | ret = bdev->driver->move(bo, evict, interruptible, |
361 | no_wait_gpu, mem); | 361 | no_wait_gpu, mem); |
362 | else | 362 | else |
363 | ret = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, mem); | 363 | ret = ttm_bo_move_memcpy(bo, evict, interruptible, |
364 | no_wait_gpu, mem); | ||
364 | 365 | ||
365 | if (ret) { | 366 | if (ret) { |
366 | if (bdev->driver->move_notify) { | 367 | if (bdev->driver->move_notify) { |
@@ -396,8 +397,7 @@ moved: | |||
396 | 397 | ||
397 | out_err: | 398 | out_err: |
398 | new_man = &bdev->man[bo->mem.mem_type]; | 399 | new_man = &bdev->man[bo->mem.mem_type]; |
399 | if ((new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && bo->ttm) { | 400 | if (new_man->flags & TTM_MEMTYPE_FLAG_FIXED) { |
400 | ttm_tt_unbind(bo->ttm); | ||
401 | ttm_tt_destroy(bo->ttm); | 401 | ttm_tt_destroy(bo->ttm); |
402 | bo->ttm = NULL; | 402 | bo->ttm = NULL; |
403 | } | 403 | } |
@@ -418,11 +418,8 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) | |||
418 | if (bo->bdev->driver->move_notify) | 418 | if (bo->bdev->driver->move_notify) |
419 | bo->bdev->driver->move_notify(bo, NULL); | 419 | bo->bdev->driver->move_notify(bo, NULL); |
420 | 420 | ||
421 | if (bo->ttm) { | 421 | ttm_tt_destroy(bo->ttm); |
422 | ttm_tt_unbind(bo->ttm); | 422 | bo->ttm = NULL; |
423 | ttm_tt_destroy(bo->ttm); | ||
424 | bo->ttm = NULL; | ||
425 | } | ||
426 | ttm_bo_mem_put(bo, &bo->mem); | 423 | ttm_bo_mem_put(bo, &bo->mem); |
427 | 424 | ||
428 | ww_mutex_unlock (&bo->resv->lock); | 425 | ww_mutex_unlock (&bo->resv->lock); |
@@ -688,15 +685,6 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, | |||
688 | struct ttm_placement placement; | 685 | struct ttm_placement placement; |
689 | int ret = 0; | 686 | int ret = 0; |
690 | 687 | ||
691 | ret = ttm_bo_wait(bo, interruptible, no_wait_gpu); | ||
692 | |||
693 | if (unlikely(ret != 0)) { | ||
694 | if (ret != -ERESTARTSYS) { | ||
695 | pr_err("Failed to expire sync object before buffer eviction\n"); | ||
696 | } | ||
697 | goto out; | ||
698 | } | ||
699 | |||
700 | lockdep_assert_held(&bo->resv->lock.base); | 688 | lockdep_assert_held(&bo->resv->lock.base); |
701 | 689 | ||
702 | evict_mem = bo->mem; | 690 | evict_mem = bo->mem; |
@@ -720,7 +708,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, | |||
720 | 708 | ||
721 | ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, interruptible, | 709 | ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, interruptible, |
722 | no_wait_gpu); | 710 | no_wait_gpu); |
723 | if (ret) { | 711 | if (unlikely(ret)) { |
724 | if (ret != -ERESTARTSYS) | 712 | if (ret != -ERESTARTSYS) |
725 | pr_err("Buffer eviction failed\n"); | 713 | pr_err("Buffer eviction failed\n"); |
726 | ttm_bo_mem_put(bo, &evict_mem); | 714 | ttm_bo_mem_put(bo, &evict_mem); |
@@ -800,6 +788,34 @@ void ttm_bo_mem_put(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem) | |||
800 | EXPORT_SYMBOL(ttm_bo_mem_put); | 788 | EXPORT_SYMBOL(ttm_bo_mem_put); |
801 | 789 | ||
802 | /** | 790 | /** |
791 | * Add the last move fence to the BO and reserve a new shared slot. | ||
792 | */ | ||
793 | static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, | ||
794 | struct ttm_mem_type_manager *man, | ||
795 | struct ttm_mem_reg *mem) | ||
796 | { | ||
797 | struct fence *fence; | ||
798 | int ret; | ||
799 | |||
800 | spin_lock(&man->move_lock); | ||
801 | fence = fence_get(man->move); | ||
802 | spin_unlock(&man->move_lock); | ||
803 | |||
804 | if (fence) { | ||
805 | reservation_object_add_shared_fence(bo->resv, fence); | ||
806 | |||
807 | ret = reservation_object_reserve_shared(bo->resv); | ||
808 | if (unlikely(ret)) | ||
809 | return ret; | ||
810 | |||
811 | fence_put(bo->moving); | ||
812 | bo->moving = fence; | ||
813 | } | ||
814 | |||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | /** | ||
803 | * Repeatedly evict memory from the LRU for @mem_type until we create enough | 819 | * Repeatedly evict memory from the LRU for @mem_type until we create enough |
804 | * space, or we've evicted everything and there isn't enough space. | 820 | * space, or we've evicted everything and there isn't enough space. |
805 | */ | 821 | */ |
@@ -825,10 +841,8 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, | |||
825 | if (unlikely(ret != 0)) | 841 | if (unlikely(ret != 0)) |
826 | return ret; | 842 | return ret; |
827 | } while (1); | 843 | } while (1); |
828 | if (mem->mm_node == NULL) | ||
829 | return -ENOMEM; | ||
830 | mem->mem_type = mem_type; | 844 | mem->mem_type = mem_type; |
831 | return 0; | 845 | return ttm_bo_add_move_fence(bo, man, mem); |
832 | } | 846 | } |
833 | 847 | ||
834 | static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man, | 848 | static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man, |
@@ -898,6 +912,10 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, | |||
898 | bool has_erestartsys = false; | 912 | bool has_erestartsys = false; |
899 | int i, ret; | 913 | int i, ret; |
900 | 914 | ||
915 | ret = reservation_object_reserve_shared(bo->resv); | ||
916 | if (unlikely(ret)) | ||
917 | return ret; | ||
918 | |||
901 | mem->mm_node = NULL; | 919 | mem->mm_node = NULL; |
902 | for (i = 0; i < placement->num_placement; ++i) { | 920 | for (i = 0; i < placement->num_placement; ++i) { |
903 | const struct ttm_place *place = &placement->placement[i]; | 921 | const struct ttm_place *place = &placement->placement[i]; |
@@ -931,9 +949,15 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, | |||
931 | ret = (*man->func->get_node)(man, bo, place, mem); | 949 | ret = (*man->func->get_node)(man, bo, place, mem); |
932 | if (unlikely(ret)) | 950 | if (unlikely(ret)) |
933 | return ret; | 951 | return ret; |
934 | 952 | ||
935 | if (mem->mm_node) | 953 | if (mem->mm_node) { |
954 | ret = ttm_bo_add_move_fence(bo, man, mem); | ||
955 | if (unlikely(ret)) { | ||
956 | (*man->func->put_node)(man, mem); | ||
957 | return ret; | ||
958 | } | ||
936 | break; | 959 | break; |
960 | } | ||
937 | } | 961 | } |
938 | 962 | ||
939 | if ((type_ok && (mem_type == TTM_PL_SYSTEM)) || mem->mm_node) { | 963 | if ((type_ok && (mem_type == TTM_PL_SYSTEM)) || mem->mm_node) { |
@@ -1000,20 +1024,6 @@ static int ttm_bo_move_buffer(struct ttm_buffer_object *bo, | |||
1000 | 1024 | ||
1001 | lockdep_assert_held(&bo->resv->lock.base); | 1025 | lockdep_assert_held(&bo->resv->lock.base); |
1002 | 1026 | ||
1003 | /* | ||
1004 | * Don't wait for the BO on initial allocation. This is important when | ||
1005 | * the BO has an imported reservation object. | ||
1006 | */ | ||
1007 | if (bo->mem.mem_type != TTM_PL_SYSTEM || bo->ttm != NULL) { | ||
1008 | /* | ||
1009 | * FIXME: It's possible to pipeline buffer moves. | ||
1010 | * Have the driver move function wait for idle when necessary, | ||
1011 | * instead of doing it here. | ||
1012 | */ | ||
1013 | ret = ttm_bo_wait(bo, interruptible, no_wait_gpu); | ||
1014 | if (ret) | ||
1015 | return ret; | ||
1016 | } | ||
1017 | mem.num_pages = bo->num_pages; | 1027 | mem.num_pages = bo->num_pages; |
1018 | mem.size = mem.num_pages << PAGE_SHIFT; | 1028 | mem.size = mem.num_pages << PAGE_SHIFT; |
1019 | mem.page_alignment = bo->mem.page_alignment; | 1029 | mem.page_alignment = bo->mem.page_alignment; |
@@ -1165,7 +1175,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, | |||
1165 | bo->mem.page_alignment = page_alignment; | 1175 | bo->mem.page_alignment = page_alignment; |
1166 | bo->mem.bus.io_reserved_vm = false; | 1176 | bo->mem.bus.io_reserved_vm = false; |
1167 | bo->mem.bus.io_reserved_count = 0; | 1177 | bo->mem.bus.io_reserved_count = 0; |
1168 | bo->priv_flags = 0; | 1178 | bo->moving = NULL; |
1169 | bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED); | 1179 | bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED); |
1170 | bo->persistent_swap_storage = persistent_swap_storage; | 1180 | bo->persistent_swap_storage = persistent_swap_storage; |
1171 | bo->acc_size = acc_size; | 1181 | bo->acc_size = acc_size; |
@@ -1277,6 +1287,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, | |||
1277 | { | 1287 | { |
1278 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; | 1288 | struct ttm_mem_type_manager *man = &bdev->man[mem_type]; |
1279 | struct ttm_bo_global *glob = bdev->glob; | 1289 | struct ttm_bo_global *glob = bdev->glob; |
1290 | struct fence *fence; | ||
1280 | int ret; | 1291 | int ret; |
1281 | 1292 | ||
1282 | /* | 1293 | /* |
@@ -1297,6 +1308,23 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, | |||
1297 | spin_lock(&glob->lru_lock); | 1308 | spin_lock(&glob->lru_lock); |
1298 | } | 1309 | } |
1299 | spin_unlock(&glob->lru_lock); | 1310 | spin_unlock(&glob->lru_lock); |
1311 | |||
1312 | spin_lock(&man->move_lock); | ||
1313 | fence = fence_get(man->move); | ||
1314 | spin_unlock(&man->move_lock); | ||
1315 | |||
1316 | if (fence) { | ||
1317 | ret = fence_wait(fence, false); | ||
1318 | fence_put(fence); | ||
1319 | if (ret) { | ||
1320 | if (allow_errors) { | ||
1321 | return ret; | ||
1322 | } else { | ||
1323 | pr_err("Cleanup eviction failed\n"); | ||
1324 | } | ||
1325 | } | ||
1326 | } | ||
1327 | |||
1300 | return 0; | 1328 | return 0; |
1301 | } | 1329 | } |
1302 | 1330 | ||
@@ -1316,6 +1344,7 @@ int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type) | |||
1316 | mem_type); | 1344 | mem_type); |
1317 | return ret; | 1345 | return ret; |
1318 | } | 1346 | } |
1347 | fence_put(man->move); | ||
1319 | 1348 | ||
1320 | man->use_type = false; | 1349 | man->use_type = false; |
1321 | man->has_type = false; | 1350 | man->has_type = false; |
@@ -1361,6 +1390,7 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, | |||
1361 | man->io_reserve_fastpath = true; | 1390 | man->io_reserve_fastpath = true; |
1362 | man->use_io_reserve_lru = false; | 1391 | man->use_io_reserve_lru = false; |
1363 | mutex_init(&man->io_reserve_mutex); | 1392 | mutex_init(&man->io_reserve_mutex); |
1393 | spin_lock_init(&man->move_lock); | ||
1364 | INIT_LIST_HEAD(&man->io_reserve_lru); | 1394 | INIT_LIST_HEAD(&man->io_reserve_lru); |
1365 | 1395 | ||
1366 | ret = bdev->driver->init_mem_type(bdev, type, man); | 1396 | ret = bdev->driver->init_mem_type(bdev, type, man); |
@@ -1379,6 +1409,7 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, | |||
1379 | man->size = p_size; | 1409 | man->size = p_size; |
1380 | 1410 | ||
1381 | INIT_LIST_HEAD(&man->lru); | 1411 | INIT_LIST_HEAD(&man->lru); |
1412 | man->move = NULL; | ||
1382 | 1413 | ||
1383 | return 0; | 1414 | return 0; |
1384 | } | 1415 | } |
@@ -1572,47 +1603,17 @@ EXPORT_SYMBOL(ttm_bo_unmap_virtual); | |||
1572 | int ttm_bo_wait(struct ttm_buffer_object *bo, | 1603 | int ttm_bo_wait(struct ttm_buffer_object *bo, |
1573 | bool interruptible, bool no_wait) | 1604 | bool interruptible, bool no_wait) |
1574 | { | 1605 | { |
1575 | struct reservation_object_list *fobj; | 1606 | long timeout = no_wait ? 0 : 15 * HZ; |
1576 | struct reservation_object *resv; | ||
1577 | struct fence *excl; | ||
1578 | long timeout = 15 * HZ; | ||
1579 | int i; | ||
1580 | |||
1581 | resv = bo->resv; | ||
1582 | fobj = reservation_object_get_list(resv); | ||
1583 | excl = reservation_object_get_excl(resv); | ||
1584 | if (excl) { | ||
1585 | if (!fence_is_signaled(excl)) { | ||
1586 | if (no_wait) | ||
1587 | return -EBUSY; | ||
1588 | |||
1589 | timeout = fence_wait_timeout(excl, | ||
1590 | interruptible, timeout); | ||
1591 | } | ||
1592 | } | ||
1593 | |||
1594 | for (i = 0; fobj && timeout > 0 && i < fobj->shared_count; ++i) { | ||
1595 | struct fence *fence; | ||
1596 | fence = rcu_dereference_protected(fobj->shared[i], | ||
1597 | reservation_object_held(resv)); | ||
1598 | |||
1599 | if (!fence_is_signaled(fence)) { | ||
1600 | if (no_wait) | ||
1601 | return -EBUSY; | ||
1602 | |||
1603 | timeout = fence_wait_timeout(fence, | ||
1604 | interruptible, timeout); | ||
1605 | } | ||
1606 | } | ||
1607 | 1607 | ||
1608 | timeout = reservation_object_wait_timeout_rcu(bo->resv, true, | ||
1609 | interruptible, timeout); | ||
1608 | if (timeout < 0) | 1610 | if (timeout < 0) |
1609 | return timeout; | 1611 | return timeout; |
1610 | 1612 | ||
1611 | if (timeout == 0) | 1613 | if (timeout == 0) |
1612 | return -EBUSY; | 1614 | return -EBUSY; |
1613 | 1615 | ||
1614 | reservation_object_add_excl_fence(resv, NULL); | 1616 | reservation_object_add_excl_fence(bo->resv, NULL); |
1615 | clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); | ||
1616 | return 0; | 1617 | return 0; |
1617 | } | 1618 | } |
1618 | EXPORT_SYMBOL(ttm_bo_wait); | 1619 | EXPORT_SYMBOL(ttm_bo_wait); |
@@ -1682,14 +1683,9 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) | |||
1682 | ttm_bo_list_ref_sub(bo, put_count, true); | 1683 | ttm_bo_list_ref_sub(bo, put_count, true); |
1683 | 1684 | ||
1684 | /** | 1685 | /** |
1685 | * Wait for GPU, then move to system cached. | 1686 | * Move to system cached |
1686 | */ | 1687 | */ |
1687 | 1688 | ||
1688 | ret = ttm_bo_wait(bo, false, false); | ||
1689 | |||
1690 | if (unlikely(ret != 0)) | ||
1691 | goto out; | ||
1692 | |||
1693 | if ((bo->mem.placement & swap_placement) != swap_placement) { | 1689 | if ((bo->mem.placement & swap_placement) != swap_placement) { |
1694 | struct ttm_mem_reg evict_mem; | 1690 | struct ttm_mem_reg evict_mem; |
1695 | 1691 | ||
@@ -1704,6 +1700,14 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) | |||
1704 | goto out; | 1700 | goto out; |
1705 | } | 1701 | } |
1706 | 1702 | ||
1703 | /** | ||
1704 | * Make sure BO is idle. | ||
1705 | */ | ||
1706 | |||
1707 | ret = ttm_bo_wait(bo, false, false); | ||
1708 | if (unlikely(ret != 0)) | ||
1709 | goto out; | ||
1710 | |||
1707 | ttm_bo_unmap_virtual(bo); | 1711 | ttm_bo_unmap_virtual(bo); |
1708 | 1712 | ||
1709 | /** | 1713 | /** |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index d9831559706e..4da0e784f9e7 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -53,7 +53,6 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo, | |||
53 | int ret; | 53 | int ret; |
54 | 54 | ||
55 | if (old_mem->mem_type != TTM_PL_SYSTEM) { | 55 | if (old_mem->mem_type != TTM_PL_SYSTEM) { |
56 | ttm_tt_unbind(ttm); | ||
57 | ttm_bo_free_old_node(bo); | 56 | ttm_bo_free_old_node(bo); |
58 | ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM, | 57 | ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM, |
59 | TTM_PL_MASK_MEM); | 58 | TTM_PL_MASK_MEM); |
@@ -321,7 +320,8 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, | |||
321 | } | 320 | } |
322 | 321 | ||
323 | int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, | 322 | int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, |
324 | bool evict, bool no_wait_gpu, | 323 | bool evict, bool interruptible, |
324 | bool no_wait_gpu, | ||
325 | struct ttm_mem_reg *new_mem) | 325 | struct ttm_mem_reg *new_mem) |
326 | { | 326 | { |
327 | struct ttm_bo_device *bdev = bo->bdev; | 327 | struct ttm_bo_device *bdev = bo->bdev; |
@@ -337,6 +337,10 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, | |||
337 | unsigned long add = 0; | 337 | unsigned long add = 0; |
338 | int dir; | 338 | int dir; |
339 | 339 | ||
340 | ret = ttm_bo_wait(bo, interruptible, no_wait_gpu); | ||
341 | if (ret) | ||
342 | return ret; | ||
343 | |||
340 | ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap); | 344 | ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap); |
341 | if (ret) | 345 | if (ret) |
342 | return ret; | 346 | return ret; |
@@ -401,8 +405,7 @@ out2: | |||
401 | *old_mem = *new_mem; | 405 | *old_mem = *new_mem; |
402 | new_mem->mm_node = NULL; | 406 | new_mem->mm_node = NULL; |
403 | 407 | ||
404 | if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) { | 408 | if (man->flags & TTM_MEMTYPE_FLAG_FIXED) { |
405 | ttm_tt_unbind(ttm); | ||
406 | ttm_tt_destroy(ttm); | 409 | ttm_tt_destroy(ttm); |
407 | bo->ttm = NULL; | 410 | bo->ttm = NULL; |
408 | } | 411 | } |
@@ -462,6 +465,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, | |||
462 | INIT_LIST_HEAD(&fbo->lru); | 465 | INIT_LIST_HEAD(&fbo->lru); |
463 | INIT_LIST_HEAD(&fbo->swap); | 466 | INIT_LIST_HEAD(&fbo->swap); |
464 | INIT_LIST_HEAD(&fbo->io_reserve_lru); | 467 | INIT_LIST_HEAD(&fbo->io_reserve_lru); |
468 | fbo->moving = NULL; | ||
465 | drm_vma_node_reset(&fbo->vma_node); | 469 | drm_vma_node_reset(&fbo->vma_node); |
466 | atomic_set(&fbo->cpu_writers, 0); | 470 | atomic_set(&fbo->cpu_writers, 0); |
467 | 471 | ||
@@ -634,7 +638,6 @@ EXPORT_SYMBOL(ttm_bo_kunmap); | |||
634 | int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, | 638 | int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, |
635 | struct fence *fence, | 639 | struct fence *fence, |
636 | bool evict, | 640 | bool evict, |
637 | bool no_wait_gpu, | ||
638 | struct ttm_mem_reg *new_mem) | 641 | struct ttm_mem_reg *new_mem) |
639 | { | 642 | { |
640 | struct ttm_bo_device *bdev = bo->bdev; | 643 | struct ttm_bo_device *bdev = bo->bdev; |
@@ -649,9 +652,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, | |||
649 | if (ret) | 652 | if (ret) |
650 | return ret; | 653 | return ret; |
651 | 654 | ||
652 | if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && | 655 | if (man->flags & TTM_MEMTYPE_FLAG_FIXED) { |
653 | (bo->ttm != NULL)) { | ||
654 | ttm_tt_unbind(bo->ttm); | ||
655 | ttm_tt_destroy(bo->ttm); | 656 | ttm_tt_destroy(bo->ttm); |
656 | bo->ttm = NULL; | 657 | bo->ttm = NULL; |
657 | } | 658 | } |
@@ -665,7 +666,8 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, | |||
665 | * operation has completed. | 666 | * operation has completed. |
666 | */ | 667 | */ |
667 | 668 | ||
668 | set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); | 669 | fence_put(bo->moving); |
670 | bo->moving = fence_get(fence); | ||
669 | 671 | ||
670 | ret = ttm_buffer_object_transfer(bo, &ghost_obj); | 672 | ret = ttm_buffer_object_transfer(bo, &ghost_obj); |
671 | if (ret) | 673 | if (ret) |
@@ -694,3 +696,95 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, | |||
694 | return 0; | 696 | return 0; |
695 | } | 697 | } |
696 | EXPORT_SYMBOL(ttm_bo_move_accel_cleanup); | 698 | EXPORT_SYMBOL(ttm_bo_move_accel_cleanup); |
699 | |||
700 | int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, | ||
701 | struct fence *fence, bool evict, | ||
702 | struct ttm_mem_reg *new_mem) | ||
703 | { | ||
704 | struct ttm_bo_device *bdev = bo->bdev; | ||
705 | struct ttm_mem_reg *old_mem = &bo->mem; | ||
706 | |||
707 | struct ttm_mem_type_manager *from = &bdev->man[old_mem->mem_type]; | ||
708 | struct ttm_mem_type_manager *to = &bdev->man[new_mem->mem_type]; | ||
709 | |||
710 | int ret; | ||
711 | |||
712 | reservation_object_add_excl_fence(bo->resv, fence); | ||
713 | |||
714 | if (!evict) { | ||
715 | struct ttm_buffer_object *ghost_obj; | ||
716 | |||
717 | /** | ||
718 | * This should help pipeline ordinary buffer moves. | ||
719 | * | ||
720 | * Hang old buffer memory on a new buffer object, | ||
721 | * and leave it to be released when the GPU | ||
722 | * operation has completed. | ||
723 | */ | ||
724 | |||
725 | fence_put(bo->moving); | ||
726 | bo->moving = fence_get(fence); | ||
727 | |||
728 | ret = ttm_buffer_object_transfer(bo, &ghost_obj); | ||
729 | if (ret) | ||
730 | return ret; | ||
731 | |||
732 | reservation_object_add_excl_fence(ghost_obj->resv, fence); | ||
733 | |||
734 | /** | ||
735 | * If we're not moving to fixed memory, the TTM object | ||
736 | * needs to stay alive. Otherwhise hang it on the ghost | ||
737 | * bo to be unbound and destroyed. | ||
738 | */ | ||
739 | |||
740 | if (!(to->flags & TTM_MEMTYPE_FLAG_FIXED)) | ||
741 | ghost_obj->ttm = NULL; | ||
742 | else | ||
743 | bo->ttm = NULL; | ||
744 | |||
745 | ttm_bo_unreserve(ghost_obj); | ||
746 | ttm_bo_unref(&ghost_obj); | ||
747 | |||
748 | } else if (from->flags & TTM_MEMTYPE_FLAG_FIXED) { | ||
749 | |||
750 | /** | ||
751 | * BO doesn't have a TTM we need to bind/unbind. Just remember | ||
752 | * this eviction and free up the allocation | ||
753 | */ | ||
754 | |||
755 | spin_lock(&from->move_lock); | ||
756 | if (!from->move || fence_is_later(fence, from->move)) { | ||
757 | fence_put(from->move); | ||
758 | from->move = fence_get(fence); | ||
759 | } | ||
760 | spin_unlock(&from->move_lock); | ||
761 | |||
762 | ttm_bo_free_old_node(bo); | ||
763 | |||
764 | fence_put(bo->moving); | ||
765 | bo->moving = fence_get(fence); | ||
766 | |||
767 | } else { | ||
768 | /** | ||
769 | * Last resort, wait for the move to be completed. | ||
770 | * | ||
771 | * Should never happen in pratice. | ||
772 | */ | ||
773 | |||
774 | ret = ttm_bo_wait(bo, false, false); | ||
775 | if (ret) | ||
776 | return ret; | ||
777 | |||
778 | if (to->flags & TTM_MEMTYPE_FLAG_FIXED) { | ||
779 | ttm_tt_destroy(bo->ttm); | ||
780 | bo->ttm = NULL; | ||
781 | } | ||
782 | ttm_bo_free_old_node(bo); | ||
783 | } | ||
784 | |||
785 | *old_mem = *new_mem; | ||
786 | new_mem->mm_node = NULL; | ||
787 | |||
788 | return 0; | ||
789 | } | ||
790 | EXPORT_SYMBOL(ttm_bo_pipeline_move); | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 3216878bced3..a6ed9d5e5167 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c | |||
@@ -48,15 +48,14 @@ static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo, | |||
48 | { | 48 | { |
49 | int ret = 0; | 49 | int ret = 0; |
50 | 50 | ||
51 | if (likely(!test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags))) | 51 | if (likely(!bo->moving)) |
52 | goto out_unlock; | 52 | goto out_unlock; |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * Quick non-stalling check for idle. | 55 | * Quick non-stalling check for idle. |
56 | */ | 56 | */ |
57 | ret = ttm_bo_wait(bo, false, true); | 57 | if (fence_is_signaled(bo->moving)) |
58 | if (likely(ret == 0)) | 58 | goto out_clear; |
59 | goto out_unlock; | ||
60 | 59 | ||
61 | /* | 60 | /* |
62 | * If possible, avoid waiting for GPU with mmap_sem | 61 | * If possible, avoid waiting for GPU with mmap_sem |
@@ -68,17 +67,23 @@ static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo, | |||
68 | goto out_unlock; | 67 | goto out_unlock; |
69 | 68 | ||
70 | up_read(&vma->vm_mm->mmap_sem); | 69 | up_read(&vma->vm_mm->mmap_sem); |
71 | (void) ttm_bo_wait(bo, true, false); | 70 | (void) fence_wait(bo->moving, true); |
72 | goto out_unlock; | 71 | goto out_unlock; |
73 | } | 72 | } |
74 | 73 | ||
75 | /* | 74 | /* |
76 | * Ordinary wait. | 75 | * Ordinary wait. |
77 | */ | 76 | */ |
78 | ret = ttm_bo_wait(bo, true, false); | 77 | ret = fence_wait(bo->moving, true); |
79 | if (unlikely(ret != 0)) | 78 | if (unlikely(ret != 0)) { |
80 | ret = (ret != -ERESTARTSYS) ? VM_FAULT_SIGBUS : | 79 | ret = (ret != -ERESTARTSYS) ? VM_FAULT_SIGBUS : |
81 | VM_FAULT_NOPAGE; | 80 | VM_FAULT_NOPAGE; |
81 | goto out_unlock; | ||
82 | } | ||
83 | |||
84 | out_clear: | ||
85 | fence_put(bo->moving); | ||
86 | bo->moving = NULL; | ||
82 | 87 | ||
83 | out_unlock: | 88 | out_unlock: |
84 | return ret; | 89 | return ret; |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 077ae9b2865d..d28d4333dcce 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -166,11 +166,15 @@ EXPORT_SYMBOL(ttm_tt_set_placement_caching); | |||
166 | 166 | ||
167 | void ttm_tt_destroy(struct ttm_tt *ttm) | 167 | void ttm_tt_destroy(struct ttm_tt *ttm) |
168 | { | 168 | { |
169 | if (unlikely(ttm == NULL)) | 169 | int ret; |
170 | |||
171 | if (ttm == NULL) | ||
170 | return; | 172 | return; |
171 | 173 | ||
172 | if (ttm->state == tt_bound) { | 174 | if (ttm->state == tt_bound) { |
173 | ttm_tt_unbind(ttm); | 175 | ret = ttm->func->unbind(ttm); |
176 | BUG_ON(ret); | ||
177 | ttm->state = tt_unbound; | ||
174 | } | 178 | } |
175 | 179 | ||
176 | if (ttm->state == tt_unbound) | 180 | if (ttm->state == tt_unbound) |
@@ -251,17 +255,6 @@ void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma) | |||
251 | } | 255 | } |
252 | EXPORT_SYMBOL(ttm_dma_tt_fini); | 256 | EXPORT_SYMBOL(ttm_dma_tt_fini); |
253 | 257 | ||
254 | void ttm_tt_unbind(struct ttm_tt *ttm) | ||
255 | { | ||
256 | int ret; | ||
257 | |||
258 | if (ttm->state == tt_bound) { | ||
259 | ret = ttm->func->unbind(ttm); | ||
260 | BUG_ON(ret); | ||
261 | ttm->state = tt_unbound; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) | 258 | int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) |
266 | { | 259 | { |
267 | int ret = 0; | 260 | int ret = 0; |
diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c b/drivers/gpu/drm/virtio/virtgpu_ttm.c index a0580815629f..80482ac5f95d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ttm.c +++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c | |||
@@ -375,6 +375,12 @@ static int virtio_gpu_bo_move(struct ttm_buffer_object *bo, | |||
375 | bool no_wait_gpu, | 375 | bool no_wait_gpu, |
376 | struct ttm_mem_reg *new_mem) | 376 | struct ttm_mem_reg *new_mem) |
377 | { | 377 | { |
378 | int ret; | ||
379 | |||
380 | ret = ttm_bo_wait(bo, interruptible, no_wait_gpu); | ||
381 | if (ret) | ||
382 | return ret; | ||
383 | |||
378 | virtio_gpu_move_null(bo, new_mem); | 384 | virtio_gpu_move_null(bo, new_mem); |
379 | return 0; | 385 | return 0; |
380 | } | 386 | } |
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index c801d9028e37..97aaf5c3d45b 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h | |||
@@ -173,7 +173,7 @@ struct ttm_tt; | |||
173 | * @lru: List head for the lru list. | 173 | * @lru: List head for the lru list. |
174 | * @ddestroy: List head for the delayed destroy list. | 174 | * @ddestroy: List head for the delayed destroy list. |
175 | * @swap: List head for swap LRU list. | 175 | * @swap: List head for swap LRU list. |
176 | * @priv_flags: Flags describing buffer object internal state. | 176 | * @moving: Fence set when BO is moving |
177 | * @vma_node: Address space manager node. | 177 | * @vma_node: Address space manager node. |
178 | * @offset: The current GPU offset, which can have different meanings | 178 | * @offset: The current GPU offset, which can have different meanings |
179 | * depending on the memory type. For SYSTEM type memory, it should be 0. | 179 | * depending on the memory type. For SYSTEM type memory, it should be 0. |
@@ -239,7 +239,7 @@ struct ttm_buffer_object { | |||
239 | * Members protected by a bo reservation. | 239 | * Members protected by a bo reservation. |
240 | */ | 240 | */ |
241 | 241 | ||
242 | unsigned long priv_flags; | 242 | struct fence *moving; |
243 | 243 | ||
244 | struct drm_vma_offset_node vma_node; | 244 | struct drm_vma_offset_node vma_node; |
245 | 245 | ||
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 513f7f96b80a..e2ebe6666e2b 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h | |||
@@ -258,8 +258,10 @@ struct ttm_mem_type_manager_func { | |||
258 | * reserved by the TTM vm system. | 258 | * reserved by the TTM vm system. |
259 | * @io_reserve_lru: Optional lru list for unreserving io mem regions. | 259 | * @io_reserve_lru: Optional lru list for unreserving io mem regions. |
260 | * @io_reserve_fastpath: Only use bdev::driver::io_mem_reserve to obtain | 260 | * @io_reserve_fastpath: Only use bdev::driver::io_mem_reserve to obtain |
261 | * @move_lock: lock for move fence | ||
261 | * static information. bdev::driver::io_mem_free is never used. | 262 | * static information. bdev::driver::io_mem_free is never used. |
262 | * @lru: The lru list for this memory type. | 263 | * @lru: The lru list for this memory type. |
264 | * @move: The fence of the last pipelined move operation. | ||
263 | * | 265 | * |
264 | * This structure is used to identify and manage memory types for a device. | 266 | * This structure is used to identify and manage memory types for a device. |
265 | * It's set up by the ttm_bo_driver::init_mem_type method. | 267 | * It's set up by the ttm_bo_driver::init_mem_type method. |
@@ -286,6 +288,7 @@ struct ttm_mem_type_manager { | |||
286 | struct mutex io_reserve_mutex; | 288 | struct mutex io_reserve_mutex; |
287 | bool use_io_reserve_lru; | 289 | bool use_io_reserve_lru; |
288 | bool io_reserve_fastpath; | 290 | bool io_reserve_fastpath; |
291 | spinlock_t move_lock; | ||
289 | 292 | ||
290 | /* | 293 | /* |
291 | * Protected by @io_reserve_mutex: | 294 | * Protected by @io_reserve_mutex: |
@@ -298,6 +301,11 @@ struct ttm_mem_type_manager { | |||
298 | */ | 301 | */ |
299 | 302 | ||
300 | struct list_head lru; | 303 | struct list_head lru; |
304 | |||
305 | /* | ||
306 | * Protected by @move_lock. | ||
307 | */ | ||
308 | struct fence *move; | ||
301 | }; | 309 | }; |
302 | 310 | ||
303 | /** | 311 | /** |
@@ -503,9 +511,6 @@ struct ttm_bo_global { | |||
503 | 511 | ||
504 | #define TTM_NUM_MEM_TYPES 8 | 512 | #define TTM_NUM_MEM_TYPES 8 |
505 | 513 | ||
506 | #define TTM_BO_PRIV_FLAG_MOVING 0 /* Buffer object is moving and needs | ||
507 | idling before CPU mapping */ | ||
508 | #define TTM_BO_PRIV_FLAG_MAX 1 | ||
509 | /** | 514 | /** |
510 | * struct ttm_bo_device - Buffer object driver device-specific data. | 515 | * struct ttm_bo_device - Buffer object driver device-specific data. |
511 | * | 516 | * |
@@ -623,15 +628,6 @@ extern int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem); | |||
623 | extern void ttm_tt_destroy(struct ttm_tt *ttm); | 628 | extern void ttm_tt_destroy(struct ttm_tt *ttm); |
624 | 629 | ||
625 | /** | 630 | /** |
626 | * ttm_ttm_unbind: | ||
627 | * | ||
628 | * @ttm: The struct ttm_tt. | ||
629 | * | ||
630 | * Unbind a struct ttm_tt. | ||
631 | */ | ||
632 | extern void ttm_tt_unbind(struct ttm_tt *ttm); | ||
633 | |||
634 | /** | ||
635 | * ttm_tt_swapin: | 631 | * ttm_tt_swapin: |
636 | * | 632 | * |
637 | * @ttm: The struct ttm_tt. | 633 | * @ttm: The struct ttm_tt. |
@@ -979,6 +975,7 @@ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, | |||
979 | * | 975 | * |
980 | * @bo: A pointer to a struct ttm_buffer_object. | 976 | * @bo: A pointer to a struct ttm_buffer_object. |
981 | * @evict: 1: This is an eviction. Don't try to pipeline. | 977 | * @evict: 1: This is an eviction. Don't try to pipeline. |
978 | * @interruptible: Sleep interruptible if waiting. | ||
982 | * @no_wait_gpu: Return immediately if the GPU is busy. | 979 | * @no_wait_gpu: Return immediately if the GPU is busy. |
983 | * @new_mem: struct ttm_mem_reg indicating where to move. | 980 | * @new_mem: struct ttm_mem_reg indicating where to move. |
984 | * | 981 | * |
@@ -993,7 +990,8 @@ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, | |||
993 | */ | 990 | */ |
994 | 991 | ||
995 | extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, | 992 | extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, |
996 | bool evict, bool no_wait_gpu, | 993 | bool evict, bool interruptible, |
994 | bool no_wait_gpu, | ||
997 | struct ttm_mem_reg *new_mem); | 995 | struct ttm_mem_reg *new_mem); |
998 | 996 | ||
999 | /** | 997 | /** |
@@ -1011,7 +1009,6 @@ extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo); | |||
1011 | * @bo: A pointer to a struct ttm_buffer_object. | 1009 | * @bo: A pointer to a struct ttm_buffer_object. |
1012 | * @fence: A fence object that signals when moving is complete. | 1010 | * @fence: A fence object that signals when moving is complete. |
1013 | * @evict: This is an evict move. Don't return until the buffer is idle. | 1011 | * @evict: This is an evict move. Don't return until the buffer is idle. |
1014 | * @no_wait_gpu: Return immediately if the GPU is busy. | ||
1015 | * @new_mem: struct ttm_mem_reg indicating where to move. | 1012 | * @new_mem: struct ttm_mem_reg indicating where to move. |
1016 | * | 1013 | * |
1017 | * Accelerated move function to be called when an accelerated move | 1014 | * Accelerated move function to be called when an accelerated move |
@@ -1023,9 +1020,24 @@ extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo); | |||
1023 | */ | 1020 | */ |
1024 | 1021 | ||
1025 | extern int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, | 1022 | extern int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, |
1026 | struct fence *fence, | 1023 | struct fence *fence, bool evict, |
1027 | bool evict, bool no_wait_gpu, | ||
1028 | struct ttm_mem_reg *new_mem); | 1024 | struct ttm_mem_reg *new_mem); |
1025 | |||
1026 | /** | ||
1027 | * ttm_bo_pipeline_move. | ||
1028 | * | ||
1029 | * @bo: A pointer to a struct ttm_buffer_object. | ||
1030 | * @fence: A fence object that signals when moving is complete. | ||
1031 | * @evict: This is an evict move. Don't return until the buffer is idle. | ||
1032 | * @new_mem: struct ttm_mem_reg indicating where to move. | ||
1033 | * | ||
1034 | * Function for pipelining accelerated moves. Either free the memory | ||
1035 | * immediately or hang it on a temporary buffer object. | ||
1036 | */ | ||
1037 | int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, | ||
1038 | struct fence *fence, bool evict, | ||
1039 | struct ttm_mem_reg *new_mem); | ||
1040 | |||
1029 | /** | 1041 | /** |
1030 | * ttm_io_prot | 1042 | * ttm_io_prot |
1031 | * | 1043 | * |
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index cdecf87576e8..462246aa200e 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h | |||
@@ -487,6 +487,22 @@ struct drm_amdgpu_cs_chunk_data { | |||
487 | #define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8 | 487 | #define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8 |
488 | #define AMDGPU_INFO_MMR_SH_INDEX_MASK 0xff | 488 | #define AMDGPU_INFO_MMR_SH_INDEX_MASK 0xff |
489 | 489 | ||
490 | struct drm_amdgpu_query_fw { | ||
491 | /** AMDGPU_INFO_FW_* */ | ||
492 | __u32 fw_type; | ||
493 | /** | ||
494 | * Index of the IP if there are more IPs of | ||
495 | * the same type. | ||
496 | */ | ||
497 | __u32 ip_instance; | ||
498 | /** | ||
499 | * Index of the engine. Whether this is used depends | ||
500 | * on the firmware type. (e.g. MEC, SDMA) | ||
501 | */ | ||
502 | __u32 index; | ||
503 | __u32 _pad; | ||
504 | }; | ||
505 | |||
490 | /* Input structure for the INFO ioctl */ | 506 | /* Input structure for the INFO ioctl */ |
491 | struct drm_amdgpu_info { | 507 | struct drm_amdgpu_info { |
492 | /* Where the return value will be stored */ | 508 | /* Where the return value will be stored */ |
@@ -522,21 +538,7 @@ struct drm_amdgpu_info { | |||
522 | __u32 flags; | 538 | __u32 flags; |
523 | } read_mmr_reg; | 539 | } read_mmr_reg; |
524 | 540 | ||
525 | struct { | 541 | struct drm_amdgpu_query_fw query_fw; |
526 | /** AMDGPU_INFO_FW_* */ | ||
527 | __u32 fw_type; | ||
528 | /** | ||
529 | * Index of the IP if there are more IPs of | ||
530 | * the same type. | ||
531 | */ | ||
532 | __u32 ip_instance; | ||
533 | /** | ||
534 | * Index of the engine. Whether this is used depends | ||
535 | * on the firmware type. (e.g. MEC, SDMA) | ||
536 | */ | ||
537 | __u32 index; | ||
538 | __u32 _pad; | ||
539 | } query_fw; | ||
540 | }; | 542 | }; |
541 | }; | 543 | }; |
542 | 544 | ||