diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
66 files changed, 4826 insertions, 4450 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 04c270757030..66f729eaf00b 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -2,10 +2,13 @@ # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/asic_reg \ - -Idrivers/gpu/drm/amd/include \ - -Idrivers/gpu/drm/amd/amdgpu \ - -Idrivers/gpu/drm/amd/scheduler +FULL_AMD_PATH=$(src)/.. + +ccflags-y := -Iinclude/drm -I$(FULL_AMD_PATH)/include/asic_reg \ + -I$(FULL_AMD_PATH)/include \ + -I$(FULL_AMD_PATH)/amdgpu \ + -I$(FULL_AMD_PATH)/scheduler \ + -I$(FULL_AMD_PATH)/powerplay/inc amdgpu-y := amdgpu_drv.o @@ -44,6 +47,7 @@ amdgpu-y += \ # add SMC block amdgpu-y += \ amdgpu_dpm.o \ + amdgpu_powerplay.o \ cz_smc.o cz_dpm.o \ tonga_smc.o tonga_dpm.o \ fiji_smc.o fiji_dpm.o \ @@ -94,6 +98,14 @@ amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o +ifneq ($(CONFIG_DRM_AMD_POWERPLAY),) + +include $(FULL_AMD_PATH)/powerplay/Makefile + +amdgpu-y += $(AMD_POWERPLAY_FILES) + +endif + obj-$(CONFIG_DRM_AMDGPU)+= amdgpu.o CFLAGS_amdgpu_trace_points.o := -I$(src) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 615ce6d464fb..313b0cc8d676 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -52,6 +52,7 @@ #include "amdgpu_irq.h" #include "amdgpu_ucode.h" #include "amdgpu_gds.h" +#include "amd_powerplay.h" #include "gpu_scheduler.h" @@ -85,6 +86,7 @@ extern int amdgpu_enable_scheduler; extern int amdgpu_sched_jobs; extern int amdgpu_sched_hw_submission; extern int amdgpu_enable_semaphores; +extern int amdgpu_powerplay; #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -389,7 +391,6 @@ struct amdgpu_clock { * Fences. */ struct amdgpu_fence_driver { - struct amdgpu_ring *ring; uint64_t gpu_addr; volatile uint32_t *cpu_addr; /* sync_seq is protected by ring emission lock */ @@ -398,7 +399,7 @@ struct amdgpu_fence_driver { bool initialized; struct amdgpu_irq_src *irq_src; unsigned irq_type; - struct delayed_work lockup_work; + struct timer_list fallback_timer; wait_queue_head_t fence_queue; }; @@ -497,6 +498,7 @@ struct amdgpu_bo_va_mapping { /* bo virtual addresses in a specific vm */ struct amdgpu_bo_va { + struct mutex mutex; /* protected by bo being reserved */ struct list_head bo_list; struct fence *last_pt_update; @@ -539,6 +541,7 @@ struct amdgpu_bo { /* Constant after initialization */ struct amdgpu_device *adev; struct drm_gem_object gem_base; + struct amdgpu_bo *parent; struct ttm_bo_kmap_obj dma_buf_vmap; pid_t pid; @@ -917,7 +920,7 @@ struct amdgpu_ring { #define AMDGPU_VM_FAULT_STOP_ALWAYS 2 struct amdgpu_vm_pt { - struct amdgpu_bo *bo; + struct amdgpu_bo_list_entry entry; uint64_t addr; }; @@ -926,13 +929,9 @@ struct amdgpu_vm_id { uint64_t pd_gpu_addr; /* last flushed PD/PT update */ struct fence *flushed_updates; - /* last use of vmid */ - struct fence *last_id_use; }; struct amdgpu_vm { - struct mutex mutex; - struct rb_root va; /* protecting invalidated */ @@ -957,33 +956,82 @@ struct amdgpu_vm { /* for id and flush management per ring */ struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; + /* for interval tree */ + spinlock_t it_lock; + /* protecting freed */ + spinlock_t freed_lock; }; struct amdgpu_vm_manager { - struct fence *active[AMDGPU_NUM_VM]; - uint32_t max_pfn; + struct { + struct fence *active; + atomic_long_t owner; + } ids[AMDGPU_NUM_VM]; + + uint32_t max_pfn; /* number of VMIDs */ - unsigned nvm; + unsigned nvm; /* vram base address for page table entry */ - u64 vram_base_offset; + u64 vram_base_offset; /* is vm enabled? */ - bool enabled; - /* for hw to save the PD addr on suspend/resume */ - uint32_t saved_table_addr[AMDGPU_NUM_VM]; + bool enabled; /* vm pte handling */ const struct amdgpu_vm_pte_funcs *vm_pte_funcs; struct amdgpu_ring *vm_pte_funcs_ring; }; +void amdgpu_vm_manager_fini(struct amdgpu_device *adev); +int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm); +void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); +void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, + struct list_head *validated, + struct amdgpu_bo_list_entry *entry); +void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates); +void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, + struct amdgpu_vm *vm); +int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, + struct amdgpu_sync *sync); +void amdgpu_vm_flush(struct amdgpu_ring *ring, + struct amdgpu_vm *vm, + struct fence *updates); +void amdgpu_vm_fence(struct amdgpu_device *adev, + struct amdgpu_vm *vm, + struct fence *fence); +uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr); +int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, + struct amdgpu_vm *vm); +int amdgpu_vm_clear_freed(struct amdgpu_device *adev, + struct amdgpu_vm *vm); +int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, struct amdgpu_vm *vm, + struct amdgpu_sync *sync); +int amdgpu_vm_bo_update(struct amdgpu_device *adev, + struct amdgpu_bo_va *bo_va, + struct ttm_mem_reg *mem); +void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, + struct amdgpu_bo *bo); +struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, + struct amdgpu_bo *bo); +struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, + struct amdgpu_vm *vm, + struct amdgpu_bo *bo); +int amdgpu_vm_bo_map(struct amdgpu_device *adev, + struct amdgpu_bo_va *bo_va, + uint64_t addr, uint64_t offset, + uint64_t size, uint32_t flags); +int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, + struct amdgpu_bo_va *bo_va, + uint64_t addr); +void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, + struct amdgpu_bo_va *bo_va); +int amdgpu_vm_free_job(struct amdgpu_job *job); + /* * context related structures */ -#define AMDGPU_CTX_MAX_CS_PENDING 16 - struct amdgpu_ctx_ring { uint64_t sequence; - struct fence *fences[AMDGPU_CTX_MAX_CS_PENDING]; + struct fence **fences; struct amd_sched_entity entity; }; @@ -992,6 +1040,7 @@ struct amdgpu_ctx { struct amdgpu_device *adev; unsigned reset_counter; spinlock_t ring_lock; + struct fence **fences; struct amdgpu_ctx_ring rings[AMDGPU_MAX_RINGS]; }; @@ -1002,7 +1051,7 @@ struct amdgpu_ctx_mgr { struct idr ctx_handles; }; -int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, +int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, struct amdgpu_ctx *ctx); void amdgpu_ctx_fini(struct amdgpu_ctx *ctx); @@ -1209,8 +1258,9 @@ struct amdgpu_cs_parser { unsigned nchunks; struct amdgpu_cs_chunk *chunks; /* relocations */ - struct amdgpu_bo_list_entry *vm_bos; + struct amdgpu_bo_list_entry vm_pd; struct list_head validated; + struct fence *fence; struct amdgpu_ib *ibs; uint32_t num_ibs; @@ -1218,7 +1268,8 @@ struct amdgpu_cs_parser { struct ww_acquire_ctx ticket; /* user fence */ - struct amdgpu_user_fence uf; + struct amdgpu_user_fence uf; + struct amdgpu_bo_list_entry uf_entry; }; struct amdgpu_job { @@ -1226,7 +1277,7 @@ struct amdgpu_job { struct amdgpu_device *adev; struct amdgpu_ib *ibs; uint32_t num_ibs; - struct mutex job_lock; + void *owner; struct amdgpu_user_fence uf; int (*free_job)(struct amdgpu_job *job); }; @@ -1254,31 +1305,7 @@ struct amdgpu_wb { int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb); void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb); -/** - * struct amdgpu_pm - power management datas - * It keeps track of various data needed to take powermanagement decision. - */ -enum amdgpu_pm_state_type { - /* not used for dpm */ - POWER_STATE_TYPE_DEFAULT, - POWER_STATE_TYPE_POWERSAVE, - /* user selectable states */ - POWER_STATE_TYPE_BATTERY, - POWER_STATE_TYPE_BALANCED, - POWER_STATE_TYPE_PERFORMANCE, - /* internal states */ - POWER_STATE_TYPE_INTERNAL_UVD, - POWER_STATE_TYPE_INTERNAL_UVD_SD, - POWER_STATE_TYPE_INTERNAL_UVD_HD, - POWER_STATE_TYPE_INTERNAL_UVD_HD2, - POWER_STATE_TYPE_INTERNAL_UVD_MVC, - POWER_STATE_TYPE_INTERNAL_BOOT, - POWER_STATE_TYPE_INTERNAL_THERMAL, - POWER_STATE_TYPE_INTERNAL_ACPI, - POWER_STATE_TYPE_INTERNAL_ULV, - POWER_STATE_TYPE_INTERNAL_3DPERF, -}; enum amdgpu_int_thermal_type { THERMAL_TYPE_NONE, @@ -1560,8 +1587,8 @@ struct amdgpu_dpm { /* vce requirements */ struct amdgpu_vce_state vce_states[AMDGPU_MAX_VCE_LEVELS]; enum amdgpu_vce_level vce_level; - enum amdgpu_pm_state_type state; - enum amdgpu_pm_state_type user_state; + enum amd_pm_state_type state; + enum amd_pm_state_type user_state; u32 platform_caps; u32 voltage_response_time; u32 backbias_response_time; @@ -1614,8 +1641,13 @@ struct amdgpu_pm { const struct firmware *fw; /* SMC firmware */ uint32_t fw_version; const struct amdgpu_dpm_funcs *funcs; + uint32_t pcie_gen_mask; + uint32_t pcie_mlw_mask; + struct amd_pp_display_configuration pm_display_cfg;/* set by DAL */ }; +void amdgpu_get_pcie_info(struct amdgpu_device *adev); + /* * UVD */ @@ -1783,6 +1815,8 @@ struct amdgpu_cu_info { */ struct amdgpu_asic_funcs { bool (*read_disabled_bios)(struct amdgpu_device *adev); + bool (*read_bios_from_rom)(struct amdgpu_device *adev, + u8 *bios, u32 length_bytes); int (*read_register)(struct amdgpu_device *adev, u32 se_num, u32 sh_num, u32 reg_offset, u32 *value); void (*set_vga_state)(struct amdgpu_device *adev, bool state); @@ -2013,6 +2047,10 @@ struct amdgpu_device { /* interrupts */ struct amdgpu_irq irq; + /* powerplay */ + struct amd_powerplay powerplay; + bool pp_enabled; + /* dpm */ struct amdgpu_pm pm; u32 cg_flags; @@ -2189,6 +2227,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) +#define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v))) #define amdgpu_asic_get_cu_info(adev, info) (adev)->asic_funcs->get_cu_info((adev), (info)) #define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid)) @@ -2230,24 +2269,78 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) #define amdgpu_display_resume_mc_access(adev, s) (adev)->mode_info.funcs->resume_mc_access((adev), (s)) #define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib), (s), (d), (b)) #define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b)) -#define amdgpu_dpm_get_temperature(adev) (adev)->pm.funcs->get_temperature((adev)) #define amdgpu_dpm_pre_set_power_state(adev) (adev)->pm.funcs->pre_set_power_state((adev)) #define amdgpu_dpm_set_power_state(adev) (adev)->pm.funcs->set_power_state((adev)) #define amdgpu_dpm_post_set_power_state(adev) (adev)->pm.funcs->post_set_power_state((adev)) #define amdgpu_dpm_display_configuration_changed(adev) (adev)->pm.funcs->display_configuration_changed((adev)) -#define amdgpu_dpm_get_sclk(adev, l) (adev)->pm.funcs->get_sclk((adev), (l)) -#define amdgpu_dpm_get_mclk(adev, l) (adev)->pm.funcs->get_mclk((adev), (l)) #define amdgpu_dpm_print_power_state(adev, ps) (adev)->pm.funcs->print_power_state((adev), (ps)) -#define amdgpu_dpm_debugfs_print_current_performance_level(adev, m) (adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m)) -#define amdgpu_dpm_force_performance_level(adev, l) (adev)->pm.funcs->force_performance_level((adev), (l)) #define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev)) -#define amdgpu_dpm_powergate_uvd(adev, g) (adev)->pm.funcs->powergate_uvd((adev), (g)) -#define amdgpu_dpm_powergate_vce(adev, g) (adev)->pm.funcs->powergate_vce((adev), (g)) #define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e)) -#define amdgpu_dpm_set_fan_control_mode(adev, m) (adev)->pm.funcs->set_fan_control_mode((adev), (m)) -#define amdgpu_dpm_get_fan_control_mode(adev) (adev)->pm.funcs->get_fan_control_mode((adev)) -#define amdgpu_dpm_set_fan_speed_percent(adev, s) (adev)->pm.funcs->set_fan_speed_percent((adev), (s)) -#define amdgpu_dpm_get_fan_speed_percent(adev, s) (adev)->pm.funcs->get_fan_speed_percent((adev), (s)) + +#define amdgpu_dpm_get_temperature(adev) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->get_temperature((adev)->powerplay.pp_handle) : \ + (adev)->pm.funcs->get_temperature((adev)) + +#define amdgpu_dpm_set_fan_control_mode(adev, m) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->set_fan_control_mode((adev)->powerplay.pp_handle, (m)) : \ + (adev)->pm.funcs->set_fan_control_mode((adev), (m)) + +#define amdgpu_dpm_get_fan_control_mode(adev) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->get_fan_control_mode((adev)->powerplay.pp_handle) : \ + (adev)->pm.funcs->get_fan_control_mode((adev)) + +#define amdgpu_dpm_set_fan_speed_percent(adev, s) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->set_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \ + (adev)->pm.funcs->set_fan_speed_percent((adev), (s)) + +#define amdgpu_dpm_get_fan_speed_percent(adev, s) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->get_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \ + (adev)->pm.funcs->get_fan_speed_percent((adev), (s)) + +#define amdgpu_dpm_get_sclk(adev, l) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (l)) : \ + (adev)->pm.funcs->get_sclk((adev), (l)) + +#define amdgpu_dpm_get_mclk(adev, l) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (l)) : \ + (adev)->pm.funcs->get_mclk((adev), (l)) + + +#define amdgpu_dpm_force_performance_level(adev, l) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->force_performance_level((adev)->powerplay.pp_handle, (l)) : \ + (adev)->pm.funcs->force_performance_level((adev), (l)) + +#define amdgpu_dpm_powergate_uvd(adev, g) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->powergate_uvd((adev)->powerplay.pp_handle, (g)) : \ + (adev)->pm.funcs->powergate_uvd((adev), (g)) + +#define amdgpu_dpm_powergate_vce(adev, g) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->powergate_vce((adev)->powerplay.pp_handle, (g)) : \ + (adev)->pm.funcs->powergate_vce((adev), (g)) + +#define amdgpu_dpm_debugfs_print_current_performance_level(adev, m) \ + (adev)->pp_enabled ? \ + (adev)->powerplay.pp_funcs->print_current_performance_level((adev)->powerplay.pp_handle, (m)) : \ + (adev)->pm.funcs->debugfs_print_current_performance_level((adev), (m)) + +#define amdgpu_dpm_get_current_power_state(adev) \ + (adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle) + +#define amdgpu_dpm_get_performance_level(adev) \ + (adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle) + +#define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \ + (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output)) #define amdgpu_gds_switch(adev, r, v, d, w, a) (adev)->gds.funcs->patch_gds_switch((r), (v), (d), (w), (a)) @@ -2257,11 +2350,6 @@ void amdgpu_pci_config_reset(struct amdgpu_device *adev); bool amdgpu_card_posted(struct amdgpu_device *adev); void amdgpu_update_display_priority(struct amdgpu_device *adev); bool amdgpu_boot_test_post_card(struct amdgpu_device *adev); -struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, - struct drm_file *filp, - struct amdgpu_ctx *ctx, - struct amdgpu_ib *ibs, - uint32_t num_ibs); int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data); int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, @@ -2319,49 +2407,6 @@ long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); /* - * vm - */ -int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm); -void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); -struct amdgpu_bo_list_entry *amdgpu_vm_get_bos(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct list_head *head); -int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, - struct amdgpu_sync *sync); -void amdgpu_vm_flush(struct amdgpu_ring *ring, - struct amdgpu_vm *vm, - struct fence *updates); -void amdgpu_vm_fence(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct amdgpu_fence *fence); -uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr); -int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, - struct amdgpu_vm *vm); -int amdgpu_vm_clear_freed(struct amdgpu_device *adev, - struct amdgpu_vm *vm); -int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, - struct amdgpu_vm *vm, struct amdgpu_sync *sync); -int amdgpu_vm_bo_update(struct amdgpu_device *adev, - struct amdgpu_bo_va *bo_va, - struct ttm_mem_reg *mem); -void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, - struct amdgpu_bo *bo); -struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, - struct amdgpu_bo *bo); -struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct amdgpu_bo *bo); -int amdgpu_vm_bo_map(struct amdgpu_device *adev, - struct amdgpu_bo_va *bo_va, - uint64_t addr, uint64_t offset, - uint64_t size, uint32_t flags); -int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, - struct amdgpu_bo_va *bo_va, - uint64_t addr); -void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, - struct amdgpu_bo_va *bo_va); -int amdgpu_vm_free_job(struct amdgpu_job *job); -/* * functions used by amdgpu_encoder.c */ struct amdgpu_afmt_acr { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index a142d5ae148d..5cd7b736a9de 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -29,66 +29,10 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> #include "amdgpu.h" -#include "amdgpu_acpi.h" +#include "amd_acpi.h" #include "atom.h" -#define ACPI_AC_CLASS "ac_adapter" - extern void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev); - -struct atif_verify_interface { - u16 size; /* structure size in bytes (includes size field) */ - u16 version; /* version */ - u32 notification_mask; /* supported notifications mask */ - u32 function_bits; /* supported functions bit vector */ -} __packed; - -struct atif_system_params { - u16 size; /* structure size in bytes (includes size field) */ - u32 valid_mask; /* valid flags mask */ - u32 flags; /* flags */ - u8 command_code; /* notify command code */ -} __packed; - -struct atif_sbios_requests { - u16 size; /* structure size in bytes (includes size field) */ - u32 pending; /* pending sbios requests */ - u8 panel_exp_mode; /* panel expansion mode */ - u8 thermal_gfx; /* thermal state: target gfx controller */ - u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */ - u8 forced_power_gfx; /* forced power state: target gfx controller */ - u8 forced_power_state; /* forced power state: state id */ - u8 system_power_src; /* system power source */ - u8 backlight_level; /* panel backlight level (0-255) */ -} __packed; - -#define ATIF_NOTIFY_MASK 0x3 -#define ATIF_NOTIFY_NONE 0 -#define ATIF_NOTIFY_81 1 -#define ATIF_NOTIFY_N 2 - -struct atcs_verify_interface { - u16 size; /* structure size in bytes (includes size field) */ - u16 version; /* version */ - u32 function_bits; /* supported functions bit vector */ -} __packed; - -#define ATCS_VALID_FLAGS_MASK 0x3 - -struct atcs_pref_req_input { - u16 size; /* structure size in bytes (includes size field) */ - u16 client_id; /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ - u16 valid_flags_mask; /* valid flags mask */ - u16 flags; /* flags */ - u8 req_type; /* request type */ - u8 perf_req; /* performance request */ -} __packed; - -struct atcs_pref_req_output { - u16 size; /* structure size in bytes (includes size field) */ - u8 ret_val; /* return value */ -} __packed; - /* Call the ATIF method */ /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h deleted file mode 100644 index 01a29c3d7011..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.h +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright 2012 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef AMDGPU_ACPI_H -#define AMDGPU_ACPI_H - -struct amdgpu_device; -struct acpi_bus_event; - -int amdgpu_atif_handler(struct amdgpu_device *adev, - struct acpi_bus_event *event); - -/* AMD hw uses four ACPI control methods: - * 1. ATIF - * ARG0: (ACPI_INTEGER) function code - * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes - * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes - * ATIF provides an entry point for the gfx driver to interact with the sbios. - * The AMD ACPI notification mechanism uses Notify (VGA, 0x81) or a custom - * notification. Which notification is used as indicated by the ATIF Control - * Method GET_SYSTEM_PARAMETERS. When the driver receives Notify (VGA, 0x81) or - * a custom notification it invokes ATIF Control Method GET_SYSTEM_BIOS_REQUESTS - * to identify pending System BIOS requests and associated parameters. For - * example, if one of the pending requests is DISPLAY_SWITCH_REQUEST, the driver - * will perform display device detection and invoke ATIF Control Method - * SELECT_ACTIVE_DISPLAYS. - * - * 2. ATPX - * ARG0: (ACPI_INTEGER) function code - * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes - * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes - * ATPX methods are used on PowerXpress systems to handle mux switching and - * discrete GPU power control. - * - * 3. ATRM - * ARG0: (ACPI_INTEGER) offset of vbios rom data - * ARG1: (ACPI_BUFFER) size of the buffer to fill (up to 4K). - * OUTPUT: (ACPI_BUFFER) output buffer - * ATRM provides an interfacess to access the discrete GPU vbios image on - * PowerXpress systems with multiple GPUs. - * - * 4. ATCS - * ARG0: (ACPI_INTEGER) function code - * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes - * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes - * ATCS provides an interface to AMD chipset specific functionality. - * - */ -/* ATIF */ -#define ATIF_FUNCTION_VERIFY_INTERFACE 0x0 -/* ARG0: ATIF_FUNCTION_VERIFY_INTERFACE - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * WORD - version - * DWORD - supported notifications mask - * DWORD - supported functions bit vector - */ -/* Notifications mask */ -# define ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED (1 << 0) -# define ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED (1 << 1) -# define ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED (1 << 2) -# define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED (1 << 3) -# define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED (1 << 4) -# define ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED (1 << 5) -# define ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED (1 << 6) -# define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED (1 << 7) -# define ATIF_DGPU_DISPLAY_EVENT_SUPPORTED (1 << 8) -/* supported functions vector */ -# define ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED (1 << 0) -# define ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED (1 << 1) -# define ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED (1 << 2) -# define ATIF_GET_LID_STATE_SUPPORTED (1 << 3) -# define ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED (1 << 4) -# define ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED (1 << 5) -# define ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED (1 << 6) -# define ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED (1 << 7) -# define ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED (1 << 12) -# define ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED (1 << 14) -#define ATIF_FUNCTION_GET_SYSTEM_PARAMETERS 0x1 -/* ARG0: ATIF_FUNCTION_GET_SYSTEM_PARAMETERS - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * DWORD - valid flags mask - * DWORD - flags - * - * OR - * - * WORD - structure size in bytes (includes size field) - * DWORD - valid flags mask - * DWORD - flags - * BYTE - notify command code - * - * flags - * bits 1:0: - * 0 - Notify(VGA, 0x81) is not used for notification - * 1 - Notify(VGA, 0x81) is used for notification - * 2 - Notify(VGA, n) is used for notification where - * n (0xd0-0xd9) is specified in notify command code. - * bit 2: - * 1 - lid changes not reported though int10 - */ -#define ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS 0x2 -/* ARG0: ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * DWORD - pending sbios requests - * BYTE - panel expansion mode - * BYTE - thermal state: target gfx controller - * BYTE - thermal state: state id (0: exit state, non-0: state) - * BYTE - forced power state: target gfx controller - * BYTE - forced power state: state id - * BYTE - system power source - * BYTE - panel backlight level (0-255) - */ -/* pending sbios requests */ -# define ATIF_DISPLAY_SWITCH_REQUEST (1 << 0) -# define ATIF_EXPANSION_MODE_CHANGE_REQUEST (1 << 1) -# define ATIF_THERMAL_STATE_CHANGE_REQUEST (1 << 2) -# define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST (1 << 3) -# define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST (1 << 4) -# define ATIF_DISPLAY_CONF_CHANGE_REQUEST (1 << 5) -# define ATIF_PX_GFX_SWITCH_REQUEST (1 << 6) -# define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST (1 << 7) -# define ATIF_DGPU_DISPLAY_EVENT (1 << 8) -/* panel expansion mode */ -# define ATIF_PANEL_EXPANSION_DISABLE 0 -# define ATIF_PANEL_EXPANSION_FULL 1 -# define ATIF_PANEL_EXPANSION_ASPECT 2 -/* target gfx controller */ -# define ATIF_TARGET_GFX_SINGLE 0 -# define ATIF_TARGET_GFX_PX_IGPU 1 -# define ATIF_TARGET_GFX_PX_DGPU 2 -/* system power source */ -# define ATIF_POWER_SOURCE_AC 1 -# define ATIF_POWER_SOURCE_DC 2 -# define ATIF_POWER_SOURCE_RESTRICTED_AC_1 3 -# define ATIF_POWER_SOURCE_RESTRICTED_AC_2 4 -#define ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS 0x3 -/* ARG0: ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS - * ARG1: - * WORD - structure size in bytes (includes size field) - * WORD - selected displays - * WORD - connected displays - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * WORD - selected displays - */ -# define ATIF_LCD1 (1 << 0) -# define ATIF_CRT1 (1 << 1) -# define ATIF_TV (1 << 2) -# define ATIF_DFP1 (1 << 3) -# define ATIF_CRT2 (1 << 4) -# define ATIF_LCD2 (1 << 5) -# define ATIF_DFP2 (1 << 7) -# define ATIF_CV (1 << 8) -# define ATIF_DFP3 (1 << 9) -# define ATIF_DFP4 (1 << 10) -# define ATIF_DFP5 (1 << 11) -# define ATIF_DFP6 (1 << 12) -#define ATIF_FUNCTION_GET_LID_STATE 0x4 -/* ARG0: ATIF_FUNCTION_GET_LID_STATE - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * BYTE - lid state (0: open, 1: closed) - * - * GET_LID_STATE only works at boot and resume, for general lid - * status, use the kernel provided status - */ -#define ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS 0x5 -/* ARG0: ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * BYTE - 0 - * BYTE - TV standard - */ -# define ATIF_TV_STD_NTSC 0 -# define ATIF_TV_STD_PAL 1 -# define ATIF_TV_STD_PALM 2 -# define ATIF_TV_STD_PAL60 3 -# define ATIF_TV_STD_NTSCJ 4 -# define ATIF_TV_STD_PALCN 5 -# define ATIF_TV_STD_PALN 6 -# define ATIF_TV_STD_SCART_RGB 9 -#define ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS 0x6 -/* ARG0: ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS - * ARG1: - * WORD - structure size in bytes (includes size field) - * BYTE - 0 - * BYTE - TV standard - * OUTPUT: none - */ -#define ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS 0x7 -/* ARG0: ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * BYTE - panel expansion mode - */ -#define ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS 0x8 -/* ARG0: ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS - * ARG1: - * WORD - structure size in bytes (includes size field) - * BYTE - panel expansion mode - * OUTPUT: none - */ -#define ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION 0xD -/* ARG0: ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION - * ARG1: - * WORD - structure size in bytes (includes size field) - * WORD - gfx controller id - * BYTE - current temperature (degress Celsius) - * OUTPUT: none - */ -#define ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES 0xF -/* ARG0: ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES - * ARG1: none - * OUTPUT: - * WORD - number of gfx devices - * WORD - device structure size in bytes (excludes device size field) - * DWORD - flags \ - * WORD - bus number } repeated structure - * WORD - device number / - */ -/* flags */ -# define ATIF_PX_REMOVABLE_GRAPHICS_DEVICE (1 << 0) -# define ATIF_XGP_PORT (1 << 1) -# define ATIF_VGA_ENABLED_GRAPHICS_DEVICE (1 << 2) -# define ATIF_XGP_PORT_IN_DOCK (1 << 3) - -/* ATPX */ -#define ATPX_FUNCTION_VERIFY_INTERFACE 0x0 -/* ARG0: ATPX_FUNCTION_VERIFY_INTERFACE - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * WORD - version - * DWORD - supported functions bit vector - */ -/* supported functions vector */ -# define ATPX_GET_PX_PARAMETERS_SUPPORTED (1 << 0) -# define ATPX_POWER_CONTROL_SUPPORTED (1 << 1) -# define ATPX_DISPLAY_MUX_CONTROL_SUPPORTED (1 << 2) -# define ATPX_I2C_MUX_CONTROL_SUPPORTED (1 << 3) -# define ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED (1 << 4) -# define ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED (1 << 5) -# define ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED (1 << 7) -# define ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED (1 << 8) -#define ATPX_FUNCTION_GET_PX_PARAMETERS 0x1 -/* ARG0: ATPX_FUNCTION_GET_PX_PARAMETERS - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * DWORD - valid flags mask - * DWORD - flags - */ -/* flags */ -# define ATPX_LVDS_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 0) -# define ATPX_CRT1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 1) -# define ATPX_DVI1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 2) -# define ATPX_CRT1_RGB_SIGNAL_MUXED (1 << 3) -# define ATPX_TV_SIGNAL_MUXED (1 << 4) -# define ATPX_DFP_SIGNAL_MUXED (1 << 5) -# define ATPX_SEPARATE_MUX_FOR_I2C (1 << 6) -# define ATPX_DYNAMIC_PX_SUPPORTED (1 << 7) -# define ATPX_ACF_NOT_SUPPORTED (1 << 8) -# define ATPX_FIXED_NOT_SUPPORTED (1 << 9) -# define ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED (1 << 10) -# define ATPX_DGPU_REQ_POWER_FOR_DISPLAYS (1 << 11) -#define ATPX_FUNCTION_POWER_CONTROL 0x2 -/* ARG0: ATPX_FUNCTION_POWER_CONTROL - * ARG1: - * WORD - structure size in bytes (includes size field) - * BYTE - dGPU power state (0: power off, 1: power on) - * OUTPUT: none - */ -#define ATPX_FUNCTION_DISPLAY_MUX_CONTROL 0x3 -/* ARG0: ATPX_FUNCTION_DISPLAY_MUX_CONTROL - * ARG1: - * WORD - structure size in bytes (includes size field) - * WORD - display mux control (0: iGPU, 1: dGPU) - * OUTPUT: none - */ -# define ATPX_INTEGRATED_GPU 0 -# define ATPX_DISCRETE_GPU 1 -#define ATPX_FUNCTION_I2C_MUX_CONTROL 0x4 -/* ARG0: ATPX_FUNCTION_I2C_MUX_CONTROL - * ARG1: - * WORD - structure size in bytes (includes size field) - * WORD - i2c/aux/hpd mux control (0: iGPU, 1: dGPU) - * OUTPUT: none - */ -#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION 0x5 -/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION - * ARG1: - * WORD - structure size in bytes (includes size field) - * WORD - target gpu (0: iGPU, 1: dGPU) - * OUTPUT: none - */ -#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION 0x6 -/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION - * ARG1: - * WORD - structure size in bytes (includes size field) - * WORD - target gpu (0: iGPU, 1: dGPU) - * OUTPUT: none - */ -#define ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING 0x8 -/* ARG0: ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING - * ARG1: none - * OUTPUT: - * WORD - number of display connectors - * WORD - connector structure size in bytes (excludes connector size field) - * BYTE - flags \ - * BYTE - ATIF display vector bit position } repeated - * BYTE - adapter id (0: iGPU, 1-n: dGPU ordered by pcie bus number) } structure - * WORD - connector ACPI id / - */ -/* flags */ -# define ATPX_DISPLAY_OUTPUT_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 0) -# define ATPX_DISPLAY_HPD_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 1) -# define ATPX_DISPLAY_I2C_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 2) -#define ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS 0x9 -/* ARG0: ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS - * ARG1: none - * OUTPUT: - * WORD - number of HPD/DDC ports - * WORD - port structure size in bytes (excludes port size field) - * BYTE - ATIF display vector bit position \ - * BYTE - hpd id } reapeated structure - * BYTE - ddc id / - * - * available on A+A systems only - */ -/* hpd id */ -# define ATPX_HPD_NONE 0 -# define ATPX_HPD1 1 -# define ATPX_HPD2 2 -# define ATPX_HPD3 3 -# define ATPX_HPD4 4 -# define ATPX_HPD5 5 -# define ATPX_HPD6 6 -/* ddc id */ -# define ATPX_DDC_NONE 0 -# define ATPX_DDC1 1 -# define ATPX_DDC2 2 -# define ATPX_DDC3 3 -# define ATPX_DDC4 4 -# define ATPX_DDC5 5 -# define ATPX_DDC6 6 -# define ATPX_DDC7 7 -# define ATPX_DDC8 8 - -/* ATCS */ -#define ATCS_FUNCTION_VERIFY_INTERFACE 0x0 -/* ARG0: ATCS_FUNCTION_VERIFY_INTERFACE - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * WORD - version - * DWORD - supported functions bit vector - */ -/* supported functions vector */ -# define ATCS_GET_EXTERNAL_STATE_SUPPORTED (1 << 0) -# define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED (1 << 1) -# define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED (1 << 2) -# define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED (1 << 3) -#define ATCS_FUNCTION_GET_EXTERNAL_STATE 0x1 -/* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE - * ARG1: none - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * DWORD - valid flags mask - * DWORD - flags (0: undocked, 1: docked) - */ -/* flags */ -# define ATCS_DOCKED (1 << 0) -#define ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST 0x2 -/* ARG0: ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST - * ARG1: - * WORD - structure size in bytes (includes size field) - * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) - * WORD - valid flags mask - * WORD - flags - * BYTE - request type - * BYTE - performance request - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * BYTE - return value - */ -/* flags */ -# define ATCS_ADVERTISE_CAPS (1 << 0) -# define ATCS_WAIT_FOR_COMPLETION (1 << 1) -/* request type */ -# define ATCS_PCIE_LINK_SPEED 1 -/* performance request */ -# define ATCS_REMOVE 0 -# define ATCS_FORCE_LOW_POWER 1 -# define ATCS_PERF_LEVEL_1 2 /* PCIE Gen 1 */ -# define ATCS_PERF_LEVEL_2 3 /* PCIE Gen 2 */ -# define ATCS_PERF_LEVEL_3 4 /* PCIE Gen 3 */ -/* return value */ -# define ATCS_REQUEST_REFUSED 1 -# define ATCS_REQUEST_COMPLETE 2 -# define ATCS_REQUEST_IN_PROGRESS 3 -#define ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION 0x3 -/* ARG0: ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION - * ARG1: none - * OUTPUT: none - */ -#define ATCS_FUNCTION_SET_PCIE_BUS_WIDTH 0x4 -/* ARG0: ATCS_FUNCTION_SET_PCIE_BUS_WIDTH - * ARG1: - * WORD - structure size in bytes (includes size field) - * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) - * BYTE - number of active lanes - * OUTPUT: - * WORD - structure size in bytes (includes size field) - * BYTE - number of active lanes - */ - -#endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 5a8fbadbd27b..3c895863fcf5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -11,7 +11,7 @@ #include <linux/acpi.h> #include <linux/pci.h> -#include "amdgpu_acpi.h" +#include "amd_acpi.h" struct amdgpu_atpx_functions { bool px_params; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c index c44c0c6afd1b..80add22375ee 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c @@ -35,6 +35,13 @@ * BIOS. */ +#define AMD_VBIOS_SIGNATURE " 761295520" +#define AMD_VBIOS_SIGNATURE_OFFSET 0x30 +#define AMD_VBIOS_SIGNATURE_SIZE sizeof(AMD_VBIOS_SIGNATURE) +#define AMD_VBIOS_SIGNATURE_END (AMD_VBIOS_SIGNATURE_OFFSET + AMD_VBIOS_SIGNATURE_SIZE) +#define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA) +#define AMD_VBIOS_LENGTH(p) ((p)[2] << 9) + /* If you boot an IGP board with a discrete card as the primary, * the IGP rom is not accessible via the rom bar as the IGP rom is * part of the system bios. On boot, the system bios puts a @@ -58,7 +65,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev) return false; } - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { + if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) { iounmap(bios); return false; } @@ -74,7 +81,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev) bool amdgpu_read_bios(struct amdgpu_device *adev) { - uint8_t __iomem *bios, val1, val2; + uint8_t __iomem *bios, val[2]; size_t size; adev->bios = NULL; @@ -84,10 +91,10 @@ bool amdgpu_read_bios(struct amdgpu_device *adev) return false; } - val1 = readb(&bios[0]); - val2 = readb(&bios[1]); + val[0] = readb(&bios[0]); + val[1] = readb(&bios[1]); - if (size == 0 || val1 != 0x55 || val2 != 0xaa) { + if (size == 0 || !AMD_IS_VALID_VBIOS(val)) { pci_unmap_rom(adev->pdev, bios); return false; } @@ -101,6 +108,38 @@ bool amdgpu_read_bios(struct amdgpu_device *adev) return true; } +static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev) +{ + u8 header[AMD_VBIOS_SIGNATURE_END+1] = {0}; + int len; + + if (!adev->asic_funcs->read_bios_from_rom) + return false; + + /* validate VBIOS signature */ + if (amdgpu_asic_read_bios_from_rom(adev, &header[0], sizeof(header)) == false) + return false; + header[AMD_VBIOS_SIGNATURE_END] = 0; + + if ((!AMD_IS_VALID_VBIOS(header)) || + 0 != memcmp((char *)&header[AMD_VBIOS_SIGNATURE_OFFSET], + AMD_VBIOS_SIGNATURE, + strlen(AMD_VBIOS_SIGNATURE))) + return false; + + /* valid vbios, go on */ + len = AMD_VBIOS_LENGTH(header); + len = ALIGN(len, 4); + adev->bios = kmalloc(len, GFP_KERNEL); + if (!adev->bios) { + DRM_ERROR("no memory to allocate for BIOS\n"); + return false; + } + + /* read complete BIOS */ + return amdgpu_asic_read_bios_from_rom(adev, adev->bios, len); +} + static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) { uint8_t __iomem *bios; @@ -113,7 +152,7 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) return false; } - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { + if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) { return false; } adev->bios = kmemdup(bios, size, GFP_KERNEL); @@ -230,7 +269,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) break; } - if (i == 0 || adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) { + if (i == 0 || !AMD_IS_VALID_VBIOS(adev->bios)) { kfree(adev->bios); return false; } @@ -320,6 +359,9 @@ bool amdgpu_get_bios(struct amdgpu_device *adev) if (r == false) r = amdgpu_read_bios(adev); if (r == false) { + r = amdgpu_read_bios_from_rom(adev); + } + if (r == false) { r = amdgpu_read_disabled_bios(adev); } if (r == false) { @@ -330,7 +372,7 @@ bool amdgpu_get_bios(struct amdgpu_device *adev) adev->bios = NULL; return false; } - if (adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) { + if (!AMD_IS_VALID_VBIOS(adev->bios)) { printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]); goto free_bios; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 8e995148f56e..a081dda9fa2f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -24,6 +24,7 @@ #include <linux/list.h> #include <linux/slab.h> #include <linux/pci.h> +#include <linux/acpi.h> #include <drm/drmP.h> #include <linux/firmware.h> #include <drm/amdgpu_drm.h> @@ -32,7 +33,6 @@ #include "atom.h" #include "amdgpu_ucode.h" - struct amdgpu_cgs_device { struct cgs_device base; struct amdgpu_device *adev; @@ -398,6 +398,41 @@ static void amdgpu_cgs_write_pci_config_dword(void *cgs_device, unsigned addr, WARN(ret, "pci_write_config_dword error"); } + +static int amdgpu_cgs_get_pci_resource(void *cgs_device, + enum cgs_resource_type resource_type, + uint64_t size, + uint64_t offset, + uint64_t *resource_base) +{ + CGS_FUNC_ADEV; + + if (resource_base == NULL) + return -EINVAL; + + switch (resource_type) { + case CGS_RESOURCE_TYPE_MMIO: + if (adev->rmmio_size == 0) + return -ENOENT; + if ((offset + size) > adev->rmmio_size) + return -EINVAL; + *resource_base = adev->rmmio_base; + return 0; + case CGS_RESOURCE_TYPE_DOORBELL: + if (adev->doorbell.size == 0) + return -ENOENT; + if ((offset + size) > adev->doorbell.size) + return -EINVAL; + *resource_base = adev->doorbell.base; + return 0; + case CGS_RESOURCE_TYPE_FB: + case CGS_RESOURCE_TYPE_IO: + case CGS_RESOURCE_TYPE_ROM: + default: + return -EINVAL; + } +} + static const void *amdgpu_cgs_atom_get_data_table(void *cgs_device, unsigned table, uint16_t *size, uint8_t *frev, uint8_t *crev) @@ -703,6 +738,9 @@ static int amdgpu_cgs_get_firmware_info(void *cgs_device, case CHIP_TONGA: strcpy(fw_name, "amdgpu/tonga_smc.bin"); break; + case CHIP_FIJI: + strcpy(fw_name, "amdgpu/fiji_smc.bin"); + break; default: DRM_ERROR("SMC firmware not supported\n"); return -EINVAL; @@ -736,6 +774,288 @@ static int amdgpu_cgs_get_firmware_info(void *cgs_device, return 0; } +static int amdgpu_cgs_query_system_info(void *cgs_device, + struct cgs_system_info *sys_info) +{ + CGS_FUNC_ADEV; + + if (NULL == sys_info) + return -ENODEV; + + if (sizeof(struct cgs_system_info) != sys_info->size) + return -ENODEV; + + switch (sys_info->info_id) { + case CGS_SYSTEM_INFO_ADAPTER_BDF_ID: + sys_info->value = adev->pdev->devfn | (adev->pdev->bus->number << 8); + break; + case CGS_SYSTEM_INFO_PCIE_GEN_INFO: + sys_info->value = adev->pm.pcie_gen_mask; + break; + case CGS_SYSTEM_INFO_PCIE_MLW: + sys_info->value = adev->pm.pcie_mlw_mask; + break; + default: + return -ENODEV; + } + + return 0; +} + +static int amdgpu_cgs_get_active_displays_info(void *cgs_device, + struct cgs_display_info *info) +{ + CGS_FUNC_ADEV; + struct amdgpu_crtc *amdgpu_crtc; + struct drm_device *ddev = adev->ddev; + struct drm_crtc *crtc; + uint32_t line_time_us, vblank_lines; + + if (info == NULL) + return -EINVAL; + + if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, + &ddev->mode_config.crtc_list, head) { + amdgpu_crtc = to_amdgpu_crtc(crtc); + if (crtc->enabled) { + info->active_display_mask |= (1 << amdgpu_crtc->crtc_id); + info->display_count++; + } + if (info->mode_info != NULL && + crtc->enabled && amdgpu_crtc->enabled && + amdgpu_crtc->hw_mode.clock) { + line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / + amdgpu_crtc->hw_mode.clock; + vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - + amdgpu_crtc->hw_mode.crtc_vdisplay + + (amdgpu_crtc->v_border * 2); + info->mode_info->vblank_time_us = vblank_lines * line_time_us; + info->mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); + info->mode_info->ref_clock = adev->clock.spll.reference_freq; + info->mode_info++; + } + } + } + + return 0; +} + +/** \brief evaluate acpi namespace object, handle or pathname must be valid + * \param cgs_device + * \param info input/output arguments for the control method + * \return status + */ + +#if defined(CONFIG_ACPI) +static int amdgpu_cgs_acpi_eval_object(void *cgs_device, + struct cgs_acpi_method_info *info) +{ + CGS_FUNC_ADEV; + acpi_handle handle; + struct acpi_object_list input; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *params = NULL; + union acpi_object *obj = NULL; + uint8_t name[5] = {'\0'}; + struct cgs_acpi_method_argument *argument = NULL; + uint32_t i, count; + acpi_status status; + int result; + uint32_t func_no = 0xFFFFFFFF; + + handle = ACPI_HANDLE(&adev->pdev->dev); + if (!handle) + return -ENODEV; + + memset(&input, 0, sizeof(struct acpi_object_list)); + + /* validate input info */ + if (info->size != sizeof(struct cgs_acpi_method_info)) + return -EINVAL; + + input.count = info->input_count; + if (info->input_count > 0) { + if (info->pinput_argument == NULL) + return -EINVAL; + argument = info->pinput_argument; + func_no = argument->value; + for (i = 0; i < info->input_count; i++) { + if (((argument->type == ACPI_TYPE_STRING) || + (argument->type == ACPI_TYPE_BUFFER)) && + (argument->pointer == NULL)) + return -EINVAL; + argument++; + } + } + + if (info->output_count > 0) { + if (info->poutput_argument == NULL) + return -EINVAL; + argument = info->poutput_argument; + for (i = 0; i < info->output_count; i++) { + if (((argument->type == ACPI_TYPE_STRING) || + (argument->type == ACPI_TYPE_BUFFER)) + && (argument->pointer == NULL)) + return -EINVAL; + argument++; + } + } + + /* The path name passed to acpi_evaluate_object should be null terminated */ + if ((info->field & CGS_ACPI_FIELD_METHOD_NAME) != 0) { + strncpy(name, (char *)&(info->name), sizeof(uint32_t)); + name[4] = '\0'; + } + + /* parse input parameters */ + if (input.count > 0) { + input.pointer = params = + kzalloc(sizeof(union acpi_object) * input.count, GFP_KERNEL); + if (params == NULL) + return -EINVAL; + + argument = info->pinput_argument; + + for (i = 0; i < input.count; i++) { + params->type = argument->type; + switch (params->type) { + case ACPI_TYPE_INTEGER: + params->integer.value = argument->value; + break; + case ACPI_TYPE_STRING: + params->string.length = argument->method_length; + params->string.pointer = argument->pointer; + break; + case ACPI_TYPE_BUFFER: + params->buffer.length = argument->method_length; + params->buffer.pointer = argument->pointer; + break; + default: + break; + } + params++; + argument++; + } + } + + /* parse output info */ + count = info->output_count; + argument = info->poutput_argument; + + /* evaluate the acpi method */ + status = acpi_evaluate_object(handle, name, &input, &output); + + if (ACPI_FAILURE(status)) { + result = -EIO; + goto error; + } + + /* return the output info */ + obj = output.pointer; + + if (count > 1) { + if ((obj->type != ACPI_TYPE_PACKAGE) || + (obj->package.count != count)) { + result = -EIO; + goto error; + } + params = obj->package.elements; + } else + params = obj; + + if (params == NULL) { + result = -EIO; + goto error; + } + + for (i = 0; i < count; i++) { + if (argument->type != params->type) { + result = -EIO; + goto error; + } + switch (params->type) { + case ACPI_TYPE_INTEGER: + argument->value = params->integer.value; + break; + case ACPI_TYPE_STRING: + if ((params->string.length != argument->data_length) || + (params->string.pointer == NULL)) { + result = -EIO; + goto error; + } + strncpy(argument->pointer, + params->string.pointer, + params->string.length); + break; + case ACPI_TYPE_BUFFER: + if (params->buffer.pointer == NULL) { + result = -EIO; + goto error; + } + memcpy(argument->pointer, + params->buffer.pointer, + argument->data_length); + break; + default: + break; + } + argument++; + params++; + } + +error: + if (obj != NULL) + kfree(obj); + kfree((void *)input.pointer); + return result; +} +#else +static int amdgpu_cgs_acpi_eval_object(void *cgs_device, + struct cgs_acpi_method_info *info) +{ + return -EIO; +} +#endif + +int amdgpu_cgs_call_acpi_method(void *cgs_device, + uint32_t acpi_method, + uint32_t acpi_function, + void *pinput, void *poutput, + uint32_t output_count, + uint32_t input_size, + uint32_t output_size) +{ + struct cgs_acpi_method_argument acpi_input[2] = { {0}, {0} }; + struct cgs_acpi_method_argument acpi_output = {0}; + struct cgs_acpi_method_info info = {0}; + + acpi_input[0].type = CGS_ACPI_TYPE_INTEGER; + acpi_input[0].method_length = sizeof(uint32_t); + acpi_input[0].data_length = sizeof(uint32_t); + acpi_input[0].value = acpi_function; + + acpi_input[1].type = CGS_ACPI_TYPE_BUFFER; + acpi_input[1].method_length = CGS_ACPI_MAX_BUFFER_SIZE; + acpi_input[1].data_length = input_size; + acpi_input[1].pointer = pinput; + + acpi_output.type = CGS_ACPI_TYPE_BUFFER; + acpi_output.method_length = CGS_ACPI_MAX_BUFFER_SIZE; + acpi_output.data_length = output_size; + acpi_output.pointer = poutput; + + info.size = sizeof(struct cgs_acpi_method_info); + info.field = CGS_ACPI_FIELD_METHOD_NAME | CGS_ACPI_FIELD_INPUT_ARGUMENT_COUNT; + info.input_count = 2; + info.name = acpi_method; + info.pinput_argument = acpi_input; + info.output_count = output_count; + info.poutput_argument = &acpi_output; + + return amdgpu_cgs_acpi_eval_object(cgs_device, &info); +} + static const struct cgs_ops amdgpu_cgs_ops = { amdgpu_cgs_gpu_mem_info, amdgpu_cgs_gmap_kmem, @@ -756,6 +1076,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { amdgpu_cgs_write_pci_config_byte, amdgpu_cgs_write_pci_config_word, amdgpu_cgs_write_pci_config_dword, + amdgpu_cgs_get_pci_resource, amdgpu_cgs_atom_get_data_table, amdgpu_cgs_atom_get_cmd_table_revs, amdgpu_cgs_atom_exec_cmd_table, @@ -768,7 +1089,10 @@ static const struct cgs_ops amdgpu_cgs_ops = { amdgpu_cgs_set_camera_voltages, amdgpu_cgs_get_firmware_info, amdgpu_cgs_set_powergating_state, - amdgpu_cgs_set_clockgating_state + amdgpu_cgs_set_clockgating_state, + amdgpu_cgs_get_active_displays_info, + amdgpu_cgs_call_acpi_method, + amdgpu_cgs_query_system_info, }; static const struct cgs_os_ops amdgpu_cgs_os_ops = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index dfc4d02c7a38..6f89f8e034d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -127,28 +127,35 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, return 0; } -struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, - struct drm_file *filp, - struct amdgpu_ctx *ctx, - struct amdgpu_ib *ibs, - uint32_t num_ibs) +static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, + struct drm_amdgpu_cs_chunk_fence *fence_data) { - struct amdgpu_cs_parser *parser; - int i; + struct drm_gem_object *gobj; + uint32_t handle; + + handle = fence_data->handle; + gobj = drm_gem_object_lookup(p->adev->ddev, p->filp, + fence_data->handle); + if (gobj == NULL) + return -EINVAL; - parser = kzalloc(sizeof(struct amdgpu_cs_parser), GFP_KERNEL); - if (!parser) - return NULL; + p->uf.bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); + p->uf.offset = fence_data->offset; - parser->adev = adev; - parser->filp = filp; - parser->ctx = ctx; - parser->ibs = ibs; - parser->num_ibs = num_ibs; - for (i = 0; i < num_ibs; i++) - ibs[i].ctx = ctx; + if (amdgpu_ttm_tt_has_userptr(p->uf.bo->tbo.ttm)) { + drm_gem_object_unreference_unlocked(gobj); + return -EINVAL; + } - return parser; + p->uf_entry.robj = amdgpu_bo_ref(p->uf.bo); + p->uf_entry.prefered_domains = AMDGPU_GEM_DOMAIN_GTT; + p->uf_entry.allowed_domains = AMDGPU_GEM_DOMAIN_GTT; + p->uf_entry.priority = 0; + p->uf_entry.tv.bo = &p->uf_entry.robj->tbo; + p->uf_entry.tv.shared = true; + + drm_gem_object_unreference_unlocked(gobj); + return 0; } int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) @@ -231,26 +238,15 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) case AMDGPU_CHUNK_ID_FENCE: size = sizeof(struct drm_amdgpu_cs_chunk_fence); - if (p->chunks[i].length_dw * sizeof(uint32_t) >= size) { - uint32_t handle; - struct drm_gem_object *gobj; - struct drm_amdgpu_cs_chunk_fence *fence_data; - - fence_data = (void *)p->chunks[i].kdata; - handle = fence_data->handle; - gobj = drm_gem_object_lookup(p->adev->ddev, - p->filp, handle); - if (gobj == NULL) { - ret = -EINVAL; - goto free_partial_kdata; - } - - p->uf.bo = gem_to_amdgpu_bo(gobj); - p->uf.offset = fence_data->offset; - } else { + if (p->chunks[i].length_dw * sizeof(uint32_t) < size) { ret = -EINVAL; goto free_partial_kdata; } + + ret = amdgpu_cs_user_fence_chunk(p, (void *)p->chunks[i].kdata); + if (ret) + goto free_partial_kdata; + break; case AMDGPU_CHUNK_ID_DEPENDENCIES: @@ -410,26 +406,32 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p) amdgpu_cs_buckets_get_list(&buckets, &p->validated); } - p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm, - &p->validated); + INIT_LIST_HEAD(&duplicates); + amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); + + if (p->uf.bo) + list_add(&p->uf_entry.tv.head, &p->validated); if (need_mmap_lock) down_read(¤t->mm->mmap_sem); - INIT_LIST_HEAD(&duplicates); r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates); if (unlikely(r != 0)) goto error_reserve; - r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &p->validated); + amdgpu_vm_get_pt_bos(&fpriv->vm, &duplicates); + + r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &duplicates); if (r) goto error_validate; - r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &duplicates); + r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &p->validated); error_validate: - if (r) + if (r) { + amdgpu_vm_move_pt_bos_in_lru(p->adev, &fpriv->vm); ttm_eu_backoff_reservation(&p->ticket, &p->validated); + } error_reserve: if (need_mmap_lock) @@ -463,8 +465,21 @@ static int cmp_size_smaller_first(void *priv, struct list_head *a, return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages; } -static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int error, bool backoff) +/** + * cs_parser_fini() - clean parser states + * @parser: parser structure holding parsing context. + * @error: error number + * + * If error is set than unvalidate buffer, otherwise just free memory + * used by parsing context. + **/ +static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff) { + struct amdgpu_fpriv *fpriv = parser->filp->driver_priv; + unsigned i; + + amdgpu_vm_move_pt_bos_in_lru(parser->adev, &fpriv->vm); + if (!error) { /* Sort the buffer list from the smallest to largest buffer, * which affects the order of buffers in the LRU list. @@ -479,51 +494,28 @@ static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int err list_sort(NULL, &parser->validated, cmp_size_smaller_first); ttm_eu_fence_buffer_objects(&parser->ticket, - &parser->validated, - &parser->ibs[parser->num_ibs-1].fence->base); + &parser->validated, + parser->fence); } else if (backoff) { ttm_eu_backoff_reservation(&parser->ticket, &parser->validated); } -} + fence_put(parser->fence); -static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser) -{ - unsigned i; if (parser->ctx) amdgpu_ctx_put(parser->ctx); if (parser->bo_list) amdgpu_bo_list_put(parser->bo_list); - drm_free_large(parser->vm_bos); for (i = 0; i < parser->nchunks; i++) drm_free_large(parser->chunks[i].kdata); kfree(parser->chunks); - if (!amdgpu_enable_scheduler) - { - if (parser->ibs) - for (i = 0; i < parser->num_ibs; i++) - amdgpu_ib_free(parser->adev, &parser->ibs[i]); - kfree(parser->ibs); - if (parser->uf.bo) - drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base); - } - - kfree(parser); -} - -/** - * cs_parser_fini() - clean parser states - * @parser: parser structure holding parsing context. - * @error: error number - * - * If error is set than unvalidate buffer, otherwise just free memory - * used by parsing context. - **/ -static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff) -{ - amdgpu_cs_parser_fini_early(parser, error, backoff); - amdgpu_cs_parser_fini_late(parser); + if (parser->ibs) + for (i = 0; i < parser->num_ibs; i++) + amdgpu_ib_free(parser->adev, &parser->ibs[i]); + kfree(parser->ibs); + amdgpu_bo_unref(&parser->uf.bo); + amdgpu_bo_unref(&parser->uf_entry.robj); } static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, @@ -610,15 +602,9 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, } r = amdgpu_bo_vm_update_pte(parser, vm); - if (r) { - goto out; - } - amdgpu_cs_sync_rings(parser); - if (!amdgpu_enable_scheduler) - r = amdgpu_ib_schedule(adev, parser->num_ibs, parser->ibs, - parser->filp); + if (!r) + amdgpu_cs_sync_rings(parser); -out: return r; } @@ -818,7 +804,7 @@ static int amdgpu_cs_free_job(struct amdgpu_job *job) amdgpu_ib_free(job->adev, &job->ibs[i]); kfree(job->ibs); if (job->uf.bo) - drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base); + amdgpu_bo_unref(&job->uf.bo); return 0; } @@ -826,38 +812,35 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct amdgpu_device *adev = dev->dev_private; union drm_amdgpu_cs *cs = data; - struct amdgpu_fpriv *fpriv = filp->driver_priv; - struct amdgpu_vm *vm = &fpriv->vm; - struct amdgpu_cs_parser *parser; + struct amdgpu_cs_parser parser = {}; bool reserved_buffers = false; int i, r; if (!adev->accel_working) return -EBUSY; - parser = amdgpu_cs_parser_create(adev, filp, NULL, NULL, 0); - if (!parser) - return -ENOMEM; - r = amdgpu_cs_parser_init(parser, data); + parser.adev = adev; + parser.filp = filp; + + r = amdgpu_cs_parser_init(&parser, data); if (r) { DRM_ERROR("Failed to initialize parser !\n"); - amdgpu_cs_parser_fini(parser, r, false); + amdgpu_cs_parser_fini(&parser, r, false); r = amdgpu_cs_handle_lockup(adev, r); return r; } - mutex_lock(&vm->mutex); - r = amdgpu_cs_parser_relocs(parser); + r = amdgpu_cs_parser_relocs(&parser); if (r == -ENOMEM) DRM_ERROR("Not enough memory for command submission!\n"); else if (r && r != -ERESTARTSYS) DRM_ERROR("Failed to process the buffer list %d!\n", r); else if (!r) { reserved_buffers = true; - r = amdgpu_cs_ib_fill(adev, parser); + r = amdgpu_cs_ib_fill(adev, &parser); } if (!r) { - r = amdgpu_cs_dependencies(adev, parser); + r = amdgpu_cs_dependencies(adev, &parser); if (r) DRM_ERROR("Failed in the dependencies handling %d!\n", r); } @@ -865,63 +848,71 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r) goto out; - for (i = 0; i < parser->num_ibs; i++) - trace_amdgpu_cs(parser, i); + for (i = 0; i < parser.num_ibs; i++) + trace_amdgpu_cs(&parser, i); - r = amdgpu_cs_ib_vm_chunk(adev, parser); + r = amdgpu_cs_ib_vm_chunk(adev, &parser); if (r) goto out; - if (amdgpu_enable_scheduler && parser->num_ibs) { + if (amdgpu_enable_scheduler && parser.num_ibs) { + struct amdgpu_ring * ring = parser.ibs->ring; + struct amd_sched_fence *fence; struct amdgpu_job *job; - struct amdgpu_ring * ring = parser->ibs->ring; + job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); if (!job) { r = -ENOMEM; goto out; } + job->base.sched = &ring->sched; - job->base.s_entity = &parser->ctx->rings[ring->idx].entity; - job->adev = parser->adev; - job->ibs = parser->ibs; - job->num_ibs = parser->num_ibs; - job->base.owner = parser->filp; - mutex_init(&job->job_lock); + job->base.s_entity = &parser.ctx->rings[ring->idx].entity; + job->adev = parser.adev; + job->owner = parser.filp; + job->free_job = amdgpu_cs_free_job; + + job->ibs = parser.ibs; + job->num_ibs = parser.num_ibs; + parser.ibs = NULL; + parser.num_ibs = 0; + if (job->ibs[job->num_ibs - 1].user) { - memcpy(&job->uf, &parser->uf, - sizeof(struct amdgpu_user_fence)); + job->uf = parser.uf; job->ibs[job->num_ibs - 1].user = &job->uf; + parser.uf.bo = NULL; } - job->free_job = amdgpu_cs_free_job; - mutex_lock(&job->job_lock); - r = amd_sched_entity_push_job(&job->base); - if (r) { - mutex_unlock(&job->job_lock); + fence = amd_sched_fence_create(job->base.s_entity, + parser.filp); + if (!fence) { + r = -ENOMEM; amdgpu_cs_free_job(job); kfree(job); goto out; } - cs->out.handle = - amdgpu_ctx_add_fence(parser->ctx, ring, - &job->base.s_fence->base); - parser->ibs[parser->num_ibs - 1].sequence = cs->out.handle; + job->base.s_fence = fence; + parser.fence = fence_get(&fence->base); - list_sort(NULL, &parser->validated, cmp_size_smaller_first); - ttm_eu_fence_buffer_objects(&parser->ticket, - &parser->validated, - &job->base.s_fence->base); + cs->out.handle = amdgpu_ctx_add_fence(parser.ctx, ring, + &fence->base); + job->ibs[job->num_ibs - 1].sequence = cs->out.handle; - mutex_unlock(&job->job_lock); - amdgpu_cs_parser_fini_late(parser); - mutex_unlock(&vm->mutex); - return 0; + trace_amdgpu_cs_ioctl(job); + amd_sched_entity_push_job(&job->base); + + } else { + struct amdgpu_fence *fence; + + r = amdgpu_ib_schedule(adev, parser.num_ibs, parser.ibs, + parser.filp); + fence = parser.ibs[parser.num_ibs - 1].fence; + parser.fence = fence_get(&fence->base); + cs->out.handle = parser.ibs[parser.num_ibs - 1].sequence; } - cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; out: - amdgpu_cs_parser_fini(parser, r, reserved_buffers); - mutex_unlock(&vm->mutex); + amdgpu_cs_parser_fini(&parser, r, reserved_buffers); r = amdgpu_cs_handle_lockup(adev, r); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index fec65f01c031..17d1fb12128a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -25,7 +25,7 @@ #include <drm/drmP.h> #include "amdgpu.h" -int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, +int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, struct amdgpu_ctx *ctx) { unsigned i, j; @@ -35,17 +35,25 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, ctx->adev = adev; kref_init(&ctx->refcount); spin_lock_init(&ctx->ring_lock); - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) - ctx->rings[i].sequence = 1; + ctx->fences = kzalloc(sizeof(struct fence *) * amdgpu_sched_jobs * + AMDGPU_MAX_RINGS, GFP_KERNEL); + if (!ctx->fences) + return -ENOMEM; + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + ctx->rings[i].sequence = 1; + ctx->rings[i].fences = (void *)ctx->fences + sizeof(struct fence *) * + amdgpu_sched_jobs * i; + } if (amdgpu_enable_scheduler) { /* create context entity for each ring */ for (i = 0; i < adev->num_rings; i++) { struct amd_sched_rq *rq; - if (kernel) - rq = &adev->rings[i]->sched.kernel_rq; - else - rq = &adev->rings[i]->sched.sched_rq; + if (pri >= AMD_SCHED_MAX_PRIORITY) { + kfree(ctx->fences); + return -EINVAL; + } + rq = &adev->rings[i]->sched.sched_rq[pri]; r = amd_sched_entity_init(&adev->rings[i]->sched, &ctx->rings[i].entity, rq, amdgpu_sched_jobs); @@ -57,7 +65,7 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel, for (j = 0; j < i; j++) amd_sched_entity_fini(&adev->rings[j]->sched, &ctx->rings[j].entity); - kfree(ctx); + kfree(ctx->fences); return r; } } @@ -73,8 +81,9 @@ void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) return; for (i = 0; i < AMDGPU_MAX_RINGS; ++i) - for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j) + for (j = 0; j < amdgpu_sched_jobs; ++j) fence_put(ctx->rings[i].fences[j]); + kfree(ctx->fences); if (amdgpu_enable_scheduler) { for (i = 0; i < adev->num_rings; i++) @@ -103,9 +112,13 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, return r; } *id = (uint32_t)r; - r = amdgpu_ctx_init(adev, false, ctx); + r = amdgpu_ctx_init(adev, AMD_SCHED_PRIORITY_NORMAL, ctx); + if (r) { + idr_remove(&mgr->ctx_handles, *id); + *id = 0; + kfree(ctx); + } mutex_unlock(&mgr->lock); - return r; } @@ -239,7 +252,7 @@ uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, unsigned idx = 0; struct fence *other = NULL; - idx = seq % AMDGPU_CTX_MAX_CS_PENDING; + idx = seq & (amdgpu_sched_jobs - 1); other = cring->fences[idx]; if (other) { signed long r; @@ -274,12 +287,12 @@ struct fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, } - if (seq + AMDGPU_CTX_MAX_CS_PENDING < cring->sequence) { + if (seq + amdgpu_sched_jobs < cring->sequence) { spin_unlock(&ctx->ring_lock); return NULL; } - fence = fence_get(cring->fences[seq % AMDGPU_CTX_MAX_CS_PENDING]); + fence = fence_get(cring->fences[seq & (amdgpu_sched_jobs - 1)]); spin_unlock(&ctx->ring_lock); return fence; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index d5b421330145..65531463f88e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -38,6 +38,7 @@ #include "amdgpu_i2c.h" #include "atom.h" #include "amdgpu_atombios.h" +#include "amd_pcie.h" #ifdef CONFIG_DRM_AMDGPU_CIK #include "cik.h" #endif @@ -949,6 +950,15 @@ static bool amdgpu_check_pot_argument(int arg) */ static void amdgpu_check_arguments(struct amdgpu_device *adev) { + if (amdgpu_sched_jobs < 4) { + dev_warn(adev->dev, "sched jobs (%d) must be at least 4\n", + amdgpu_sched_jobs); + amdgpu_sched_jobs = 4; + } else if (!amdgpu_check_pot_argument(amdgpu_sched_jobs)){ + dev_warn(adev->dev, "sched jobs (%d) must be a power of 2\n", + amdgpu_sched_jobs); + amdgpu_sched_jobs = roundup_pow_of_two(amdgpu_sched_jobs); + } /* vramlimit must be a power of two */ if (!amdgpu_check_pot_argument(amdgpu_vram_limit)) { dev_warn(adev->dev, "vram limit (%d) must be a power of 2\n", @@ -1214,12 +1224,14 @@ static int amdgpu_early_init(struct amdgpu_device *adev) } else { if (adev->ip_blocks[i].funcs->early_init) { r = adev->ip_blocks[i].funcs->early_init((void *)adev); - if (r == -ENOENT) + if (r == -ENOENT) { adev->ip_block_status[i].valid = false; - else if (r) + } else if (r) { + DRM_ERROR("early_init %d failed %d\n", i, r); return r; - else + } else { adev->ip_block_status[i].valid = true; + } } else { adev->ip_block_status[i].valid = true; } @@ -1237,20 +1249,28 @@ static int amdgpu_init(struct amdgpu_device *adev) if (!adev->ip_block_status[i].valid) continue; r = adev->ip_blocks[i].funcs->sw_init((void *)adev); - if (r) + if (r) { + DRM_ERROR("sw_init %d failed %d\n", i, r); return r; + } adev->ip_block_status[i].sw = true; /* need to do gmc hw init early so we can allocate gpu mem */ if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { r = amdgpu_vram_scratch_init(adev); - if (r) + if (r) { + DRM_ERROR("amdgpu_vram_scratch_init failed %d\n", r); return r; + } r = adev->ip_blocks[i].funcs->hw_init((void *)adev); - if (r) + if (r) { + DRM_ERROR("hw_init %d failed %d\n", i, r); return r; + } r = amdgpu_wb_init(adev); - if (r) + if (r) { + DRM_ERROR("amdgpu_wb_init failed %d\n", r); return r; + } adev->ip_block_status[i].hw = true; } } @@ -1262,8 +1282,10 @@ static int amdgpu_init(struct amdgpu_device *adev) if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) continue; r = adev->ip_blocks[i].funcs->hw_init((void *)adev); - if (r) + if (r) { + DRM_ERROR("hw_init %d failed %d\n", i, r); return r; + } adev->ip_block_status[i].hw = true; } @@ -1280,12 +1302,16 @@ static int amdgpu_late_init(struct amdgpu_device *adev) /* enable clockgating to save power */ r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, AMD_CG_STATE_GATE); - if (r) + if (r) { + DRM_ERROR("set_clockgating_state(gate) %d failed %d\n", i, r); return r; + } if (adev->ip_blocks[i].funcs->late_init) { r = adev->ip_blocks[i].funcs->late_init((void *)adev); - if (r) + if (r) { + DRM_ERROR("late_init %d failed %d\n", i, r); return r; + } } } @@ -1306,10 +1332,15 @@ static int amdgpu_fini(struct amdgpu_device *adev) /* ungate blocks before hw fini so that we can shutdown the blocks safely */ r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, AMD_CG_STATE_UNGATE); - if (r) + if (r) { + DRM_ERROR("set_clockgating_state(ungate) %d failed %d\n", i, r); return r; + } r = adev->ip_blocks[i].funcs->hw_fini((void *)adev); /* XXX handle errors */ + if (r) { + DRM_DEBUG("hw_fini %d failed %d\n", i, r); + } adev->ip_block_status[i].hw = false; } @@ -1318,6 +1349,9 @@ static int amdgpu_fini(struct amdgpu_device *adev) continue; r = adev->ip_blocks[i].funcs->sw_fini((void *)adev); /* XXX handle errors */ + if (r) { + DRM_DEBUG("sw_fini %d failed %d\n", i, r); + } adev->ip_block_status[i].sw = false; adev->ip_block_status[i].valid = false; } @@ -1335,9 +1369,15 @@ static int amdgpu_suspend(struct amdgpu_device *adev) /* ungate blocks so that suspend can properly shut them down */ r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, AMD_CG_STATE_UNGATE); + if (r) { + DRM_ERROR("set_clockgating_state(ungate) %d failed %d\n", i, r); + } /* XXX handle errors */ r = adev->ip_blocks[i].funcs->suspend(adev); /* XXX handle errors */ + if (r) { + DRM_ERROR("suspend %d failed %d\n", i, r); + } } return 0; @@ -1351,8 +1391,10 @@ static int amdgpu_resume(struct amdgpu_device *adev) if (!adev->ip_block_status[i].valid) continue; r = adev->ip_blocks[i].funcs->resume(adev); - if (r) + if (r) { + DRM_ERROR("resume %d failed %d\n", i, r); return r; + } } return 0; @@ -1484,8 +1526,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, return -EINVAL; } r = amdgpu_atombios_init(adev); - if (r) + if (r) { + dev_err(adev->dev, "amdgpu_atombios_init failed\n"); return r; + } /* Post card if necessary */ if (!amdgpu_card_posted(adev)) { @@ -1499,21 +1543,26 @@ int amdgpu_device_init(struct amdgpu_device *adev, /* Initialize clocks */ r = amdgpu_atombios_get_clock_info(adev); - if (r) + if (r) { + dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n"); return r; + } /* init i2c buses */ amdgpu_atombios_i2c_init(adev); /* Fence driver */ r = amdgpu_fence_driver_init(adev); - if (r) + if (r) { + dev_err(adev->dev, "amdgpu_fence_driver_init failed\n"); return r; + } /* init the mode config */ drm_mode_config_init(adev->ddev); r = amdgpu_init(adev); if (r) { + dev_err(adev->dev, "amdgpu_init failed\n"); amdgpu_fini(adev); return r; } @@ -1528,7 +1577,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, return r; } - r = amdgpu_ctx_init(adev, true, &adev->kernel_ctx); + r = amdgpu_ctx_init(adev, AMD_SCHED_PRIORITY_KERNEL, &adev->kernel_ctx); if (r) { dev_err(adev->dev, "failed to create kernel context (%d).\n", r); return r; @@ -1570,8 +1619,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, * explicit gating rather than handling it automatically. */ r = amdgpu_late_init(adev); - if (r) + if (r) { + dev_err(adev->dev, "amdgpu_late_init failed\n"); return r; + } return 0; } @@ -1788,6 +1839,7 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon) } drm_kms_helper_poll_enable(dev); + drm_helper_hpd_irq_event(dev); if (fbcon) { amdgpu_fbdev_set_suspend(adev, 0); @@ -1881,6 +1933,83 @@ retry: return r; } +void amdgpu_get_pcie_info(struct amdgpu_device *adev) +{ + u32 mask; + int ret; + + if (pci_is_root_bus(adev->pdev->bus)) + return; + + if (amdgpu_pcie_gen2 == 0) + return; + + if (adev->flags & AMD_IS_APU) + return; + + ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); + if (!ret) { + adev->pm.pcie_gen_mask = (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 | + CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 | + CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3); + + if (mask & DRM_PCIE_SPEED_25) + adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1; + if (mask & DRM_PCIE_SPEED_50) + adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2; + if (mask & DRM_PCIE_SPEED_80) + adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3; + } + ret = drm_pcie_get_max_link_width(adev->ddev, &mask); + if (!ret) { + switch (mask) { + case 32: + adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); + break; + case 16: + adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); + break; + case 12: + adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); + break; + case 8: + adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); + break; + case 4: + adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); + break; + case 2: + adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | + CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); + break; + case 1: + adev->pm.pcie_mlw_mask = CAIL_PCIE_LINK_WIDTH_SUPPORT_X1; + break; + default: + break; + } + } +} /* * Debugfs diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index e173a5a02f0d..acd066d0a805 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -73,6 +73,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work) struct drm_crtc *crtc = &amdgpuCrtc->base; unsigned long flags; unsigned i; + int vpos, hpos, stat, min_udelay; + struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id]; amdgpu_flip_wait_fence(adev, &work->excl); for (i = 0; i < work->shared_count; ++i) @@ -81,6 +83,41 @@ static void amdgpu_flip_work_func(struct work_struct *__work) /* We borrow the event spin lock for protecting flip_status */ spin_lock_irqsave(&crtc->dev->event_lock, flags); + /* If this happens to execute within the "virtually extended" vblank + * interval before the start of the real vblank interval then it needs + * to delay programming the mmio flip until the real vblank is entered. + * This prevents completing a flip too early due to the way we fudge + * our vblank counter and vblank timestamps in order to work around the + * problem that the hw fires vblank interrupts before actual start of + * vblank (when line buffer refilling is done for a frame). It + * complements the fudging logic in amdgpu_get_crtc_scanoutpos() for + * timestamping and amdgpu_get_vblank_counter_kms() for vblank counts. + * + * In practice this won't execute very often unless on very fast + * machines because the time window for this to happen is very small. + */ + for (;;) { + /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank + * start in hpos, and to the "fudged earlier" vblank start in + * vpos. + */ + stat = amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id, + GET_DISTANCE_TO_VBLANKSTART, + &vpos, &hpos, NULL, NULL, + &crtc->hwmode); + + if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != + (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) || + !(vpos >= 0 && hpos <= 0)) + break; + + /* Sleep at least until estimated real start of hw vblank */ + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); + usleep_range(min_udelay, 2 * min_udelay); + spin_lock_irqsave(&crtc->dev->event_lock, flags); + }; + /* do the flip (mmio) */ adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); /* set the flip status */ @@ -109,7 +146,7 @@ static void amdgpu_unpin_work_func(struct work_struct *__work) } else DRM_ERROR("failed to reserve buffer after flip\n"); - drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); + amdgpu_bo_unref(&work->old_rbo); kfree(work->shared); kfree(work); } @@ -148,8 +185,8 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, obj = old_amdgpu_fb->obj; /* take a reference to the old object */ - drm_gem_object_reference(obj); work->old_rbo = gem_to_amdgpu_bo(obj); + amdgpu_bo_ref(work->old_rbo); new_amdgpu_fb = to_amdgpu_framebuffer(fb); obj = new_amdgpu_fb->obj; @@ -222,7 +259,7 @@ pflip_cleanup: amdgpu_bo_unreserve(new_rbo); cleanup: - drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); + amdgpu_bo_unref(&work->old_rbo); fence_put(work->excl); for (i = 0; i < work->shared_count; ++i) fence_put(work->shared[i]); @@ -481,7 +518,7 @@ static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { int amdgpu_framebuffer_init(struct drm_device *dev, struct amdgpu_framebuffer *rfb, - struct drm_mode_fb_cmd2 *mode_cmd, + const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *obj) { int ret; @@ -498,7 +535,7 @@ amdgpu_framebuffer_init(struct drm_device *dev, static struct drm_framebuffer * amdgpu_user_framebuffer_create(struct drm_device *dev, struct drm_file *file_priv, - struct drm_mode_fb_cmd2 *mode_cmd) + const struct drm_mode_fb_cmd2 *mode_cmd) { struct drm_gem_object *obj; struct amdgpu_framebuffer *amdgpu_fb; @@ -712,6 +749,15 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * \param dev Device to query. * \param pipe Crtc to query. * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). + * For driver internal use only also supports these flags: + * + * USE_REAL_VBLANKSTART to use the real start of vblank instead + * of a fudged earlier start of vblank. + * + * GET_DISTANCE_TO_VBLANKSTART to return distance to the + * fudged earlier start of vblank in *vpos and the distance + * to true start of vblank in *hpos. + * * \param *vpos Location where vertical scanout position should be stored. * \param *hpos Location where horizontal scanout position should go. * \param *stime Target location for timestamp taken immediately before @@ -776,10 +822,40 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, vbl_end = 0; } + /* Called from driver internal vblank counter query code? */ + if (flags & GET_DISTANCE_TO_VBLANKSTART) { + /* Caller wants distance from real vbl_start in *hpos */ + *hpos = *vpos - vbl_start; + } + + /* Fudge vblank to start a few scanlines earlier to handle the + * problem that vblank irqs fire a few scanlines before start + * of vblank. Some driver internal callers need the true vblank + * start to be used and signal this via the USE_REAL_VBLANKSTART flag. + * + * The cause of the "early" vblank irq is that the irq is triggered + * by the line buffer logic when the line buffer read position enters + * the vblank, whereas our crtc scanout position naturally lags the + * line buffer read position. + */ + if (!(flags & USE_REAL_VBLANKSTART)) + vbl_start -= adev->mode_info.crtcs[pipe]->lb_vblank_lead_lines; + /* Test scanout position against vblank region. */ if ((*vpos < vbl_start) && (*vpos >= vbl_end)) in_vbl = false; + /* In vblank? */ + if (in_vbl) + ret |= DRM_SCANOUTPOS_IN_VBLANK; + + /* Called from driver internal vblank counter query code? */ + if (flags & GET_DISTANCE_TO_VBLANKSTART) { + /* Caller wants distance from fudged earlier vbl_start */ + *vpos -= vbl_start; + return ret; + } + /* Check if inside vblank area and apply corrective offsets: * vpos will then be >=0 in video scanout area, but negative * within vblank area, counting down the number of lines until @@ -795,32 +871,6 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, /* Correct for shifted end of vbl at vbl_end. */ *vpos = *vpos - vbl_end; - /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_IN_VBLANK; - - /* Is vpos outside nominal vblank area, but less than - * 1/100 of a frame height away from start of vblank? - * If so, assume this isn't a massively delayed vblank - * interrupt, but a vblank interrupt that fired a few - * microseconds before true start of vblank. Compensate - * by adding a full frame duration to the final timestamp. - * Happens, e.g., on ATI R500, R600. - * - * We only do this if DRM_CALLED_FROM_VBLIRQ. - */ - if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { - vbl_start = mode->crtc_vdisplay; - vtotal = mode->crtc_vtotal; - - if (vbl_start - *vpos < vtotal / 100) { - *vpos -= vtotal; - - /* Signal this correction as "applied". */ - ret |= 0x8; - } - } - return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 0508c5cd103a..b5dbbb573491 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -79,9 +79,10 @@ int amdgpu_vm_fault_stop = 0; int amdgpu_vm_debug = 0; int amdgpu_exp_hw_support = 0; int amdgpu_enable_scheduler = 1; -int amdgpu_sched_jobs = 16; +int amdgpu_sched_jobs = 32; int amdgpu_sched_hw_submission = 2; int amdgpu_enable_semaphores = 0; +int amdgpu_powerplay = -1; MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); @@ -155,7 +156,7 @@ module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); MODULE_PARM_DESC(enable_scheduler, "enable SW GPU scheduler (1 = enable (default), 0 = disable)"); module_param_named(enable_scheduler, amdgpu_enable_scheduler, int, 0444); -MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 16)"); +MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)"); module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444); MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default 2)"); @@ -164,6 +165,11 @@ module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); MODULE_PARM_DESC(enable_semaphores, "Enable semaphores (1 = enable, 0 = disable (default))"); module_param_named(enable_semaphores, amdgpu_enable_semaphores, int, 0644); +#ifdef CONFIG_DRM_AMD_POWERPLAY +MODULE_PARM_DESC(powerplay, "Powerplay component (1 = enable, 0 = disable, -1 = auto (default))"); +module_param_named(powerplay, amdgpu_powerplay, int, 0444); +#endif + static struct pci_device_id pciidlist[] = { #ifdef CONFIG_DRM_AMDGPU_CIK /* Kaveri */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index 093a8c618931..cfb6caad2a73 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -45,7 +45,6 @@ struct amdgpu_fbdev { struct drm_fb_helper helper; struct amdgpu_framebuffer rfb; - struct list_head fbdev_list; struct amdgpu_device *adev; }; @@ -264,7 +263,7 @@ out_unref: } if (fb && ret) { - drm_gem_object_unreference(gobj); + drm_gem_object_unreference_unlocked(gobj); drm_framebuffer_unregister_private(fb); drm_framebuffer_cleanup(fb); kfree(fb); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 257d72205bb5..3671f9f220bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -47,6 +47,9 @@ * that the the relevant GPU caches have been flushed. */ +static struct kmem_cache *amdgpu_fence_slab; +static atomic_t amdgpu_fence_slab_ref = ATOMIC_INIT(0); + /** * amdgpu_fence_write - write a fence value * @@ -85,24 +88,6 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring) } /** - * amdgpu_fence_schedule_check - schedule lockup check - * - * @ring: pointer to struct amdgpu_ring - * - * Queues a delayed work item to check for lockups. - */ -static void amdgpu_fence_schedule_check(struct amdgpu_ring *ring) -{ - /* - * Do not reset the timer here with mod_delayed_work, - * this can livelock in an interaction with TTM delayed destroy. - */ - queue_delayed_work(system_power_efficient_wq, - &ring->fence_drv.lockup_work, - AMDGPU_FENCE_JIFFIES_TIMEOUT); -} - -/** * amdgpu_fence_emit - emit a fence on the requested ring * * @ring: ring the fence is associated with @@ -118,7 +103,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner, struct amdgpu_device *adev = ring->adev; /* we are protected by the ring emission mutex */ - *fence = kmalloc(sizeof(struct amdgpu_fence), GFP_KERNEL); + *fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); if ((*fence) == NULL) { return -ENOMEM; } @@ -132,11 +117,23 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner, amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, (*fence)->seq, AMDGPU_FENCE_FLAG_INT); - trace_amdgpu_fence_emit(ring->adev->ddev, ring->idx, (*fence)->seq); return 0; } /** + * amdgpu_fence_schedule_fallback - schedule fallback check + * + * @ring: pointer to struct amdgpu_ring + * + * Start a timer as fallback to our interrupts. + */ +static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring) +{ + mod_timer(&ring->fence_drv.fallback_timer, + jiffies + AMDGPU_FENCE_JIFFIES_TIMEOUT); +} + +/** * amdgpu_fence_activity - check for fence activity * * @ring: pointer to struct amdgpu_ring @@ -202,45 +199,38 @@ static bool amdgpu_fence_activity(struct amdgpu_ring *ring) } while (atomic64_xchg(&ring->fence_drv.last_seq, seq) > seq); if (seq < last_emitted) - amdgpu_fence_schedule_check(ring); + amdgpu_fence_schedule_fallback(ring); return wake; } /** - * amdgpu_fence_check_lockup - check for hardware lockup + * amdgpu_fence_process - process a fence * - * @work: delayed work item + * @adev: amdgpu_device pointer + * @ring: ring index the fence is associated with * - * Checks for fence activity and if there is none probe - * the hardware if a lockup occured. + * Checks the current fence value and wakes the fence queue + * if the sequence number has increased (all asics). */ -static void amdgpu_fence_check_lockup(struct work_struct *work) +void amdgpu_fence_process(struct amdgpu_ring *ring) { - struct amdgpu_fence_driver *fence_drv; - struct amdgpu_ring *ring; - - fence_drv = container_of(work, struct amdgpu_fence_driver, - lockup_work.work); - ring = fence_drv->ring; - if (amdgpu_fence_activity(ring)) wake_up_all(&ring->fence_drv.fence_queue); } /** - * amdgpu_fence_process - process a fence + * amdgpu_fence_fallback - fallback for hardware interrupts * - * @adev: amdgpu_device pointer - * @ring: ring index the fence is associated with + * @work: delayed work item * - * Checks the current fence value and wakes the fence queue - * if the sequence number has increased (all asics). + * Checks for fence activity. */ -void amdgpu_fence_process(struct amdgpu_ring *ring) +static void amdgpu_fence_fallback(unsigned long arg) { - if (amdgpu_fence_activity(ring)) - wake_up_all(&ring->fence_drv.fence_queue); + struct amdgpu_ring *ring = (void *)arg; + + amdgpu_fence_process(ring); } /** @@ -290,7 +280,7 @@ static int amdgpu_fence_ring_wait_seq(struct amdgpu_ring *ring, uint64_t seq) if (atomic64_read(&ring->fence_drv.last_seq) >= seq) return 0; - amdgpu_fence_schedule_check(ring); + amdgpu_fence_schedule_fallback(ring); wait_event(ring->fence_drv.fence_queue, ( (signaled = amdgpu_fence_seq_signaled(ring, seq)))); @@ -491,9 +481,8 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring) atomic64_set(&ring->fence_drv.last_seq, 0); ring->fence_drv.initialized = false; - INIT_DELAYED_WORK(&ring->fence_drv.lockup_work, - amdgpu_fence_check_lockup); - ring->fence_drv.ring = ring; + setup_timer(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, + (unsigned long)ring); init_waitqueue_head(&ring->fence_drv.fence_queue); @@ -536,6 +525,13 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring) */ int amdgpu_fence_driver_init(struct amdgpu_device *adev) { + if (atomic_inc_return(&amdgpu_fence_slab_ref) == 1) { + amdgpu_fence_slab = kmem_cache_create( + "amdgpu_fence", sizeof(struct amdgpu_fence), 0, + SLAB_HWCACHE_ALIGN, NULL); + if (!amdgpu_fence_slab) + return -ENOMEM; + } if (amdgpu_debugfs_fence_init(adev)) dev_err(adev->dev, "fence debugfs file creation failed\n"); @@ -554,9 +550,12 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) { int i, r; + if (atomic_dec_and_test(&amdgpu_fence_slab_ref)) + kmem_cache_destroy(amdgpu_fence_slab); mutex_lock(&adev->ring_lock); for (i = 0; i < AMDGPU_MAX_RINGS; i++) { struct amdgpu_ring *ring = adev->rings[i]; + if (!ring || !ring->fence_drv.initialized) continue; r = amdgpu_fence_wait_empty(ring); @@ -568,6 +567,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); amd_sched_fini(&ring->sched); + del_timer_sync(&ring->fence_drv.fallback_timer); ring->fence_drv.initialized = false; } mutex_unlock(&adev->ring_lock); @@ -751,18 +751,25 @@ static bool amdgpu_fence_enable_signaling(struct fence *f) fence->fence_wake.func = amdgpu_fence_check_signaled; __add_wait_queue(&ring->fence_drv.fence_queue, &fence->fence_wake); fence_get(f); - amdgpu_fence_schedule_check(ring); + if (!timer_pending(&ring->fence_drv.fallback_timer)) + amdgpu_fence_schedule_fallback(ring); FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx); return true; } +static void amdgpu_fence_release(struct fence *f) +{ + struct amdgpu_fence *fence = to_amdgpu_fence(f); + kmem_cache_free(amdgpu_fence_slab, fence); +} + const struct fence_ops amdgpu_fence_ops = { .get_driver_name = amdgpu_fence_get_driver_name, .get_timeline_name = amdgpu_fence_get_timeline_name, .enable_signaling = amdgpu_fence_enable_signaling, .signaled = amdgpu_fence_is_signaled, .wait = fence_default_wait, - .release = NULL, + .release = amdgpu_fence_release, }; /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 087332858853..7380f782cd14 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -115,12 +115,9 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_bo_va *bo_va; int r; - mutex_lock(&vm->mutex); r = amdgpu_bo_reserve(rbo, false); - if (r) { - mutex_unlock(&vm->mutex); + if (r) return r; - } bo_va = amdgpu_vm_bo_find(vm, rbo); if (!bo_va) { @@ -129,7 +126,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri ++bo_va->ref_count; } amdgpu_bo_unreserve(rbo); - mutex_unlock(&vm->mutex); return 0; } @@ -142,10 +138,8 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_bo_va *bo_va; int r; - mutex_lock(&vm->mutex); r = amdgpu_bo_reserve(rbo, true); if (r) { - mutex_unlock(&vm->mutex); dev_err(adev->dev, "leaking bo va because " "we fail to reserve bo (%d)\n", r); return; @@ -157,7 +151,6 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, } } amdgpu_bo_unreserve(rbo); - mutex_unlock(&vm->mutex); } static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) @@ -242,8 +235,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, AMDGPU_GEM_USERPTR_REGISTER)) return -EINVAL; - if (!(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || - !(args->flags & AMDGPU_GEM_USERPTR_REGISTER)) { + if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && ( + !(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || + !(args->flags & AMDGPU_GEM_USERPTR_REGISTER))) { /* if we want to write to it we must require anonymous memory and install a MMU notifier */ @@ -454,7 +448,7 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint32_t operation) { struct ttm_validate_buffer tv, *entry; - struct amdgpu_bo_list_entry *vm_bos; + struct amdgpu_bo_list_entry vm_pd; struct ww_acquire_ctx ticket; struct list_head list, duplicates; unsigned domain; @@ -467,15 +461,14 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, tv.shared = true; list_add(&tv.head, &list); - vm_bos = amdgpu_vm_get_bos(adev, bo_va->vm, &list); - if (!vm_bos) - return; + amdgpu_vm_get_pd_bo(bo_va->vm, &list, &vm_pd); /* Provide duplicates to avoid -EALREADY */ r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); if (r) - goto error_free; + goto error_print; + amdgpu_vm_get_pt_bos(bo_va->vm, &duplicates); list_for_each_entry(entry, &list, head) { domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); /* if anything is swapped out don't swap it in here, @@ -483,6 +476,17 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, if (domain == AMDGPU_GEM_DOMAIN_CPU) goto error_unreserve; } + list_for_each_entry(entry, &duplicates, head) { + domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); + /* if anything is swapped out don't swap it in here, + just abort and wait for the next CS */ + if (domain == AMDGPU_GEM_DOMAIN_CPU) + goto error_unreserve; + } + + r = amdgpu_vm_update_page_directory(adev, bo_va->vm); + if (r) + goto error_unreserve; r = amdgpu_vm_clear_freed(adev, bo_va->vm); if (r) @@ -494,9 +498,7 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, error_unreserve: ttm_eu_backoff_reservation(&ticket, &list); -error_free: - drm_free_large(vm_bos); - +error_print: if (r && r != -ERESTARTSYS) DRM_ERROR("Couldn't update BO_VA (%d)\n", r); } @@ -512,6 +514,9 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, struct amdgpu_fpriv *fpriv = filp->driver_priv; struct amdgpu_bo *rbo; struct amdgpu_bo_va *bo_va; + struct ttm_validate_buffer tv, tv_pd; + struct ww_acquire_ctx ticket; + struct list_head list, duplicates; uint32_t invalid_flags, va_flags = 0; int r = 0; @@ -547,19 +552,28 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, gobj = drm_gem_object_lookup(dev, filp, args->handle); if (gobj == NULL) return -ENOENT; - mutex_lock(&fpriv->vm.mutex); rbo = gem_to_amdgpu_bo(gobj); - r = amdgpu_bo_reserve(rbo, false); + INIT_LIST_HEAD(&list); + INIT_LIST_HEAD(&duplicates); + tv.bo = &rbo->tbo; + tv.shared = true; + list_add(&tv.head, &list); + + if (args->operation == AMDGPU_VA_OP_MAP) { + tv_pd.bo = &fpriv->vm.page_directory->tbo; + tv_pd.shared = true; + list_add(&tv_pd.head, &list); + } + r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); if (r) { - mutex_unlock(&fpriv->vm.mutex); drm_gem_object_unreference_unlocked(gobj); return r; } bo_va = amdgpu_vm_bo_find(&fpriv->vm, rbo); if (!bo_va) { - amdgpu_bo_unreserve(rbo); - mutex_unlock(&fpriv->vm.mutex); + ttm_eu_backoff_reservation(&ticket, &list); + drm_gem_object_unreference_unlocked(gobj); return -ENOENT; } @@ -581,10 +595,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, default: break; } - + ttm_eu_backoff_reservation(&ticket, &list); if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) amdgpu_gem_va_update_vm(adev, bo_va, args->operation); - mutex_unlock(&fpriv->vm.mutex); + drm_gem_object_unreference_unlocked(gobj); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index e65987743871..9e25edafa721 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -62,7 +62,7 @@ int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, int r; if (size) { - r = amdgpu_sa_bo_new(adev, &adev->ring_tmp_bo, + r = amdgpu_sa_bo_new(&adev->ring_tmp_bo, &ib->sa_bo, size, 256); if (r) { dev_err(adev->dev, "failed to get a new IB (%d)\n", r); @@ -216,7 +216,7 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, } if (ib->vm) - amdgpu_vm_fence(adev, ib->vm, ib->fence); + amdgpu_vm_fence(adev, ib->vm, &ib->fence->base); amdgpu_ring_unlock_commit(ring); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 7c42ff670080..f594cfaa97e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -25,6 +25,7 @@ * Alex Deucher * Jerome Glisse */ +#include <linux/irq.h> #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> #include <drm/amdgpu_drm.h> @@ -312,6 +313,7 @@ int amdgpu_irq_add_id(struct amdgpu_device *adev, unsigned src_id, } adev->irq.sources[src_id] = source; + return 0; } @@ -335,15 +337,19 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, return; } - src = adev->irq.sources[src_id]; - if (!src) { - DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id); - return; - } + if (adev->irq.virq[src_id]) { + generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id)); + } else { + src = adev->irq.sources[src_id]; + if (!src) { + DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id); + return; + } - r = src->funcs->process(adev, src, entry); - if (r) - DRM_ERROR("error processing interrupt (%d)\n", r); + r = src->funcs->process(adev, src, entry); + if (r) + DRM_ERROR("error processing interrupt (%d)\n", r); + } } /** @@ -461,3 +467,90 @@ bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src, return !!atomic_read(&src->enabled_types[type]); } + +/* gen irq */ +static void amdgpu_irq_mask(struct irq_data *irqd) +{ + /* XXX */ +} + +static void amdgpu_irq_unmask(struct irq_data *irqd) +{ + /* XXX */ +} + +static struct irq_chip amdgpu_irq_chip = { + .name = "amdgpu-ih", + .irq_mask = amdgpu_irq_mask, + .irq_unmask = amdgpu_irq_unmask, +}; + +static int amdgpu_irqdomain_map(struct irq_domain *d, + unsigned int irq, irq_hw_number_t hwirq) +{ + if (hwirq >= AMDGPU_MAX_IRQ_SRC_ID) + return -EPERM; + + irq_set_chip_and_handler(irq, + &amdgpu_irq_chip, handle_simple_irq); + return 0; +} + +static struct irq_domain_ops amdgpu_hw_irqdomain_ops = { + .map = amdgpu_irqdomain_map, +}; + +/** + * amdgpu_irq_add_domain - create a linear irq domain + * + * @adev: amdgpu device pointer + * + * Create an irq domain for GPU interrupt sources + * that may be driven by another driver (e.g., ACP). + */ +int amdgpu_irq_add_domain(struct amdgpu_device *adev) +{ + adev->irq.domain = irq_domain_add_linear(NULL, AMDGPU_MAX_IRQ_SRC_ID, + &amdgpu_hw_irqdomain_ops, adev); + if (!adev->irq.domain) { + DRM_ERROR("GPU irq add domain failed\n"); + return -ENODEV; + } + + return 0; +} + +/** + * amdgpu_irq_remove_domain - remove the irq domain + * + * @adev: amdgpu device pointer + * + * Remove the irq domain for GPU interrupt sources + * that may be driven by another driver (e.g., ACP). + */ +void amdgpu_irq_remove_domain(struct amdgpu_device *adev) +{ + if (adev->irq.domain) { + irq_domain_remove(adev->irq.domain); + adev->irq.domain = NULL; + } +} + +/** + * amdgpu_irq_create_mapping - create a mapping between a domain irq and a + * Linux irq + * + * @adev: amdgpu device pointer + * @src_id: IH source id + * + * Create a mapping between a domain irq (GPU IH src id) and a Linux irq + * Use this for components that generate a GPU interrupt, but are driven + * by a different driver (e.g., ACP). + * Returns the Linux irq. + */ +unsigned amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned src_id) +{ + adev->irq.virq[src_id] = irq_create_mapping(adev->irq.domain, src_id); + + return adev->irq.virq[src_id]; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index 17b01aef4278..e124b59f39c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h @@ -24,6 +24,7 @@ #ifndef __AMDGPU_IRQ_H__ #define __AMDGPU_IRQ_H__ +#include <linux/irqdomain.h> #include "amdgpu_ih.h" #define AMDGPU_MAX_IRQ_SRC_ID 0x100 @@ -65,6 +66,10 @@ struct amdgpu_irq { /* interrupt ring */ struct amdgpu_ih_ring ih; const struct amdgpu_ih_funcs *ih_funcs; + + /* gen irq stuff */ + struct irq_domain *domain; /* GPU irq controller domain */ + unsigned virq[AMDGPU_MAX_IRQ_SRC_ID]; }; void amdgpu_irq_preinstall(struct drm_device *dev); @@ -90,4 +95,8 @@ int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src, bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src, unsigned type); +int amdgpu_irq_add_domain(struct amdgpu_device *adev); +void amdgpu_irq_remove_domain(struct amdgpu_device *adev); +unsigned amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned src_id); + #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 1618e2294a16..e23843f4d877 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -611,13 +611,59 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev, u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) { struct amdgpu_device *adev = dev->dev_private; + int vpos, hpos, stat; + u32 count; if (pipe >= adev->mode_info.num_crtc) { DRM_ERROR("Invalid crtc %u\n", pipe); return -EINVAL; } - return amdgpu_display_vblank_get_counter(adev, pipe); + /* The hw increments its frame counter at start of vsync, not at start + * of vblank, as is required by DRM core vblank counter handling. + * Cook the hw count here to make it appear to the caller as if it + * incremented at start of vblank. We measure distance to start of + * vblank in vpos. vpos therefore will be >= 0 between start of vblank + * and start of vsync, so vpos >= 0 means to bump the hw frame counter + * result by 1 to give the proper appearance to caller. + */ + if (adev->mode_info.crtcs[pipe]) { + /* Repeat readout if needed to provide stable result if + * we cross start of vsync during the queries. + */ + do { + count = amdgpu_display_vblank_get_counter(adev, pipe); + /* Ask amdgpu_get_crtc_scanoutpos to return vpos as + * distance to start of vblank, instead of regular + * vertical scanout pos. + */ + stat = amdgpu_get_crtc_scanoutpos( + dev, pipe, GET_DISTANCE_TO_VBLANKSTART, + &vpos, &hpos, NULL, NULL, + &adev->mode_info.crtcs[pipe]->base.hwmode); + } while (count != amdgpu_display_vblank_get_counter(adev, pipe)); + + if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != + (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) { + DRM_DEBUG_VBL("Query failed! stat %d\n", stat); + } else { + DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n", + pipe, vpos); + + /* Bump counter if we are at >= leading edge of vblank, + * but before vsync where vpos would turn negative and + * the hw counter really increments. + */ + if (vpos >= 0) + count++; + } + } else { + /* Fallback to use value as is. */ + count = amdgpu_display_vblank_get_counter(adev, pipe); + DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n"); + } + + return count; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index b62c1710cab6..fdc1be8550da 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -35,6 +35,7 @@ #include <drm/drm_dp_helper.h> #include <drm/drm_fixed.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_fb_helper.h> #include <drm/drm_plane_helper.h> #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> @@ -407,6 +408,7 @@ struct amdgpu_crtc { u32 line_time; u32 wm_low; u32 wm_high; + u32 lb_vblank_lead_lines; struct drm_display_mode hw_mode; }; @@ -528,6 +530,10 @@ struct amdgpu_framebuffer { #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ ((em) == ATOM_ENCODER_MODE_DP_MST)) +/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ +#define USE_REAL_VBLANKSTART (1 << 30) +#define GET_DISTANCE_TO_VBLANKSTART (1 << 31) + void amdgpu_link_encoder_connector(struct drm_device *dev); struct drm_connector * @@ -551,7 +557,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, int amdgpu_framebuffer_init(struct drm_device *dev, struct amdgpu_framebuffer *rfb, - struct drm_mode_fb_cmd2 *mode_cmd, + const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *obj); int amdgpufb_remove(struct drm_device *dev, struct drm_framebuffer *fb); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 0d524384ff79..c3ce103b6a33 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -100,6 +100,7 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) list_del_init(&bo->list); mutex_unlock(&bo->adev->gem.mutex); drm_gem_object_release(&bo->gem_base); + amdgpu_bo_unref(&bo->parent); kfree(bo->metadata); kfree(bo); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 3c2ff4567798..5107fb291bdb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -96,6 +96,7 @@ static inline void amdgpu_bo_unreserve(struct amdgpu_bo *bo) */ static inline u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) { + WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM); return bo->tbo.offset; } @@ -189,10 +190,9 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev, struct amdgpu_sa_manager *sa_manager); int amdgpu_sa_bo_manager_suspend(struct amdgpu_device *adev, struct amdgpu_sa_manager *sa_manager); -int amdgpu_sa_bo_new(struct amdgpu_device *adev, - struct amdgpu_sa_manager *sa_manager, - struct amdgpu_sa_bo **sa_bo, - unsigned size, unsigned align); +int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, + struct amdgpu_sa_bo **sa_bo, + unsigned size, unsigned align); void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo, struct fence *fence); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 22a8c7d3a3ab..7d8d84eaea4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -30,10 +30,16 @@ #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> +#include "amd_powerplay.h" + static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev); void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev) { + if (adev->pp_enabled) + /* TODO */ + return; + if (adev->pm.dpm_enabled) { mutex_lock(&adev->pm.mutex); if (power_supply_is_system_supplied() > 0) @@ -52,7 +58,12 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; - enum amdgpu_pm_state_type pm = adev->pm.dpm.user_state; + enum amd_pm_state_type pm; + + if (adev->pp_enabled) { + pm = amdgpu_dpm_get_current_power_state(adev); + } else + pm = adev->pm.dpm.user_state; return snprintf(buf, PAGE_SIZE, "%s\n", (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : @@ -66,40 +77,57 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; + enum amd_pm_state_type state; - mutex_lock(&adev->pm.mutex); if (strncmp("battery", buf, strlen("battery")) == 0) - adev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY; + state = POWER_STATE_TYPE_BATTERY; else if (strncmp("balanced", buf, strlen("balanced")) == 0) - adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED; + state = POWER_STATE_TYPE_BALANCED; else if (strncmp("performance", buf, strlen("performance")) == 0) - adev->pm.dpm.user_state = POWER_STATE_TYPE_PERFORMANCE; + state = POWER_STATE_TYPE_PERFORMANCE; else { - mutex_unlock(&adev->pm.mutex); count = -EINVAL; goto fail; } - mutex_unlock(&adev->pm.mutex); - /* Can't set dpm state when the card is off */ - if (!(adev->flags & AMD_IS_PX) || - (ddev->switch_power_state == DRM_SWITCH_POWER_ON)) - amdgpu_pm_compute_clocks(adev); + if (adev->pp_enabled) { + amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); + } else { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.user_state = state; + mutex_unlock(&adev->pm.mutex); + + /* Can't set dpm state when the card is off */ + if (!(adev->flags & AMD_IS_PX) || + (ddev->switch_power_state == DRM_SWITCH_POWER_ON)) + amdgpu_pm_compute_clocks(adev); + } fail: return count; } static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; - enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level; - return snprintf(buf, PAGE_SIZE, "%s\n", - (level == AMDGPU_DPM_FORCED_LEVEL_AUTO) ? "auto" : - (level == AMDGPU_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); + if (adev->pp_enabled) { + enum amd_dpm_forced_level level; + + level = amdgpu_dpm_get_performance_level(adev); + return snprintf(buf, PAGE_SIZE, "%s\n", + (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : + (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); + } else { + enum amdgpu_dpm_forced_level level; + + level = adev->pm.dpm.forced_level; + return snprintf(buf, PAGE_SIZE, "%s\n", + (level == AMDGPU_DPM_FORCED_LEVEL_AUTO) ? "auto" : + (level == AMDGPU_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); + } } static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, @@ -112,7 +140,6 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, enum amdgpu_dpm_forced_level level; int ret = 0; - mutex_lock(&adev->pm.mutex); if (strncmp("low", buf, strlen("low")) == 0) { level = AMDGPU_DPM_FORCED_LEVEL_LOW; } else if (strncmp("high", buf, strlen("high")) == 0) { @@ -123,7 +150,11 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, count = -EINVAL; goto fail; } - if (adev->pm.funcs->force_performance_level) { + + if (adev->pp_enabled) + amdgpu_dpm_force_performance_level(adev, level); + else { + mutex_lock(&adev->pm.mutex); if (adev->pm.dpm.thermal_active) { count = -EINVAL; goto fail; @@ -131,6 +162,9 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, ret = amdgpu_dpm_force_performance_level(adev, level); if (ret) count = -EINVAL; + else + adev->pm.dpm.forced_level = level; + mutex_unlock(&adev->pm.mutex); } fail: mutex_unlock(&adev->pm.mutex); @@ -150,10 +184,10 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev, struct amdgpu_device *adev = dev_get_drvdata(dev); int temp; - if (adev->pm.funcs->get_temperature) - temp = amdgpu_dpm_get_temperature(adev); - else + if (!adev->pp_enabled && !adev->pm.funcs->get_temperature) temp = 0; + else + temp = amdgpu_dpm_get_temperature(adev); return snprintf(buf, PAGE_SIZE, "%d\n", temp); } @@ -181,8 +215,10 @@ static ssize_t amdgpu_hwmon_get_pwm1_enable(struct device *dev, struct amdgpu_device *adev = dev_get_drvdata(dev); u32 pwm_mode = 0; - if (adev->pm.funcs->get_fan_control_mode) - pwm_mode = amdgpu_dpm_get_fan_control_mode(adev); + if (!adev->pp_enabled && !adev->pm.funcs->get_fan_control_mode) + return -EINVAL; + + pwm_mode = amdgpu_dpm_get_fan_control_mode(adev); /* never 0 (full-speed), fuse or smc-controlled always */ return sprintf(buf, "%i\n", pwm_mode == FDO_PWM_MODE_STATIC ? 1 : 2); @@ -197,7 +233,7 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev, int err; int value; - if(!adev->pm.funcs->set_fan_control_mode) + if (!adev->pp_enabled && !adev->pm.funcs->set_fan_control_mode) return -EINVAL; err = kstrtoint(buf, 10, &value); @@ -290,11 +326,11 @@ static struct attribute *hwmon_attributes[] = { static umode_t hwmon_attributes_visible(struct kobject *kobj, struct attribute *attr, int index) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct amdgpu_device *adev = dev_get_drvdata(dev); umode_t effective_mode = attr->mode; - /* Skip attributes if DPM is not enabled */ + /* Skip limit attributes if DPM is not enabled */ if (!adev->pm.dpm_enabled && (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr || attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr || @@ -304,6 +340,9 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) return 0; + if (adev->pp_enabled) + return effective_mode; + /* Skip fan attributes if fan is not present */ if (adev->pm.no_fan && (attr == &sensor_dev_attr_pwm1.dev_attr.attr || @@ -351,7 +390,7 @@ void amdgpu_dpm_thermal_work_handler(struct work_struct *work) container_of(work, struct amdgpu_device, pm.dpm.thermal.work); /* switch to the thermal state */ - enum amdgpu_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL; + enum amd_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL; if (!adev->pm.dpm_enabled) return; @@ -379,7 +418,7 @@ void amdgpu_dpm_thermal_work_handler(struct work_struct *work) } static struct amdgpu_ps *amdgpu_dpm_pick_power_state(struct amdgpu_device *adev, - enum amdgpu_pm_state_type dpm_state) + enum amd_pm_state_type dpm_state) { int i; struct amdgpu_ps *ps; @@ -516,7 +555,7 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) { int i; struct amdgpu_ps *ps; - enum amdgpu_pm_state_type dpm_state; + enum amd_pm_state_type dpm_state; int ret; /* if dpm init failed */ @@ -635,49 +674,54 @@ done: void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) { - if (adev->pm.funcs->powergate_uvd) { - mutex_lock(&adev->pm.mutex); - /* enable/disable UVD */ + if (adev->pp_enabled) amdgpu_dpm_powergate_uvd(adev, !enable); - mutex_unlock(&adev->pm.mutex); - } else { - if (enable) { + else { + if (adev->pm.funcs->powergate_uvd) { mutex_lock(&adev->pm.mutex); - adev->pm.dpm.uvd_active = true; - adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD; + /* enable/disable UVD */ + amdgpu_dpm_powergate_uvd(adev, !enable); mutex_unlock(&adev->pm.mutex); } else { - mutex_lock(&adev->pm.mutex); - adev->pm.dpm.uvd_active = false; - mutex_unlock(&adev->pm.mutex); + if (enable) { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.uvd_active = true; + adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD; + mutex_unlock(&adev->pm.mutex); + } else { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.uvd_active = false; + mutex_unlock(&adev->pm.mutex); + } + amdgpu_pm_compute_clocks(adev); } - amdgpu_pm_compute_clocks(adev); } } void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) { - if (adev->pm.funcs->powergate_vce) { - mutex_lock(&adev->pm.mutex); - /* enable/disable VCE */ + if (adev->pp_enabled) amdgpu_dpm_powergate_vce(adev, !enable); - - mutex_unlock(&adev->pm.mutex); - } else { - if (enable) { + else { + if (adev->pm.funcs->powergate_vce) { mutex_lock(&adev->pm.mutex); - adev->pm.dpm.vce_active = true; - /* XXX select vce level based on ring/task */ - adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL; + amdgpu_dpm_powergate_vce(adev, !enable); mutex_unlock(&adev->pm.mutex); } else { - mutex_lock(&adev->pm.mutex); - adev->pm.dpm.vce_active = false; - mutex_unlock(&adev->pm.mutex); + if (enable) { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.vce_active = true; + /* XXX select vce level based on ring/task */ + adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL; + mutex_unlock(&adev->pm.mutex); + } else { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.vce_active = false; + mutex_unlock(&adev->pm.mutex); + } + amdgpu_pm_compute_clocks(adev); } - - amdgpu_pm_compute_clocks(adev); } } @@ -685,10 +729,13 @@ void amdgpu_pm_print_power_states(struct amdgpu_device *adev) { int i; - for (i = 0; i < adev->pm.dpm.num_ps; i++) { - printk("== power state %d ==\n", i); + if (adev->pp_enabled) + /* TO DO */ + return; + + for (i = 0; i < adev->pm.dpm.num_ps; i++) amdgpu_dpm_print_power_state(adev, &adev->pm.dpm.ps[i]); - } + } int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) @@ -698,8 +745,11 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) if (adev->pm.sysfs_initialized) return 0; - if (adev->pm.funcs->get_temperature == NULL) - return 0; + if (!adev->pp_enabled) { + if (adev->pm.funcs->get_temperature == NULL) + return 0; + } + adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev, DRIVER_NAME, adev, hwmon_groups); @@ -748,32 +798,43 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) if (!adev->pm.dpm_enabled) return; - mutex_lock(&adev->pm.mutex); + if (adev->pp_enabled) { + int i = 0; - /* update active crtc counts */ - adev->pm.dpm.new_active_crtcs = 0; - adev->pm.dpm.new_active_crtc_count = 0; - if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { - list_for_each_entry(crtc, - &ddev->mode_config.crtc_list, head) { - amdgpu_crtc = to_amdgpu_crtc(crtc); - if (crtc->enabled) { - adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id); - adev->pm.dpm.new_active_crtc_count++; + amdgpu_display_bandwidth_update(adev); + mutex_lock(&adev->ring_lock); + for (i = 0; i < AMDGPU_MAX_RINGS; i++) { + struct amdgpu_ring *ring = adev->rings[i]; + if (ring && ring->ready) + amdgpu_fence_wait_empty(ring); } - } - } + mutex_unlock(&adev->ring_lock); - /* update battery/ac status */ - if (power_supply_is_system_supplied() > 0) - adev->pm.dpm.ac_power = true; - else - adev->pm.dpm.ac_power = false; - - amdgpu_dpm_change_power_state_locked(adev); + amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL); + } else { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.new_active_crtcs = 0; + adev->pm.dpm.new_active_crtc_count = 0; + if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, + &ddev->mode_config.crtc_list, head) { + amdgpu_crtc = to_amdgpu_crtc(crtc); + if (crtc->enabled) { + adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id); + adev->pm.dpm.new_active_crtc_count++; + } + } + } + /* update battery/ac status */ + if (power_supply_is_system_supplied() > 0) + adev->pm.dpm.ac_power = true; + else + adev->pm.dpm.ac_power = false; - mutex_unlock(&adev->pm.mutex); + amdgpu_dpm_change_power_state_locked(adev); + mutex_unlock(&adev->pm.mutex); + } } /* @@ -787,7 +848,13 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct amdgpu_device *adev = dev->dev_private; - if (adev->pm.dpm_enabled) { + if (!adev->pm.dpm_enabled) { + seq_printf(m, "dpm not enabled\n"); + return 0; + } + if (adev->pp_enabled) { + amdgpu_dpm_debugfs_print_current_performance_level(adev, m); + } else { mutex_lock(&adev->pm.mutex); if (adev->pm.funcs->debugfs_print_current_performance_level) amdgpu_dpm_debugfs_print_current_performance_level(adev, m); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c new file mode 100644 index 000000000000..5ee9a0690278 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -0,0 +1,317 @@ +/* + * Copyright 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ +#include "atom.h" +#include "amdgpu.h" +#include "amd_shared.h" +#include <linux/module.h> +#include <linux/moduleparam.h> +#include "amdgpu_pm.h" +#include <drm/amdgpu_drm.h> +#include "amdgpu_powerplay.h" +#include "cik_dpm.h" +#include "vi_dpm.h" + +static int amdgpu_powerplay_init(struct amdgpu_device *adev) +{ + int ret = 0; + struct amd_powerplay *amd_pp; + + amd_pp = &(adev->powerplay); + + if (adev->pp_enabled) { +#ifdef CONFIG_DRM_AMD_POWERPLAY + struct amd_pp_init *pp_init; + + pp_init = kzalloc(sizeof(struct amd_pp_init), GFP_KERNEL); + + if (pp_init == NULL) + return -ENOMEM; + + pp_init->chip_family = adev->family; + pp_init->chip_id = adev->asic_type; + pp_init->device = amdgpu_cgs_create_device(adev); + + ret = amd_powerplay_init(pp_init, amd_pp); + kfree(pp_init); +#endif + } else { + amd_pp->pp_handle = (void *)adev; + + switch (adev->asic_type) { +#ifdef CONFIG_DRM_AMDGPU_CIK + case CHIP_BONAIRE: + case CHIP_HAWAII: + amd_pp->ip_funcs = &ci_dpm_ip_funcs; + break; + case CHIP_KABINI: + case CHIP_MULLINS: + case CHIP_KAVERI: + amd_pp->ip_funcs = &kv_dpm_ip_funcs; + break; +#endif + case CHIP_TOPAZ: + amd_pp->ip_funcs = &iceland_dpm_ip_funcs; + break; + case CHIP_TONGA: + amd_pp->ip_funcs = &tonga_dpm_ip_funcs; + break; + case CHIP_FIJI: + amd_pp->ip_funcs = &fiji_dpm_ip_funcs; + break; + case CHIP_CARRIZO: + case CHIP_STONEY: + amd_pp->ip_funcs = &cz_dpm_ip_funcs; + break; + default: + ret = -EINVAL; + break; + } + } + return ret; +} + +static int amdgpu_pp_early_init(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int ret = 0; + +#ifdef CONFIG_DRM_AMD_POWERPLAY + switch (adev->asic_type) { + case CHIP_TONGA: + case CHIP_FIJI: + adev->pp_enabled = (amdgpu_powerplay > 0) ? true : false; + break; + default: + adev->pp_enabled = (amdgpu_powerplay > 0) ? true : false; + break; + } +#else + adev->pp_enabled = false; +#endif + + ret = amdgpu_powerplay_init(adev); + if (ret) + return ret; + + if (adev->powerplay.ip_funcs->early_init) + ret = adev->powerplay.ip_funcs->early_init( + adev->powerplay.pp_handle); + return ret; +} + + +static int amdgpu_pp_late_init(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->late_init) + ret = adev->powerplay.ip_funcs->late_init( + adev->powerplay.pp_handle); + +#ifdef CONFIG_DRM_AMD_POWERPLAY + if (adev->pp_enabled) + amdgpu_pm_sysfs_init(adev); +#endif + return ret; +} + +static int amdgpu_pp_sw_init(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->sw_init) + ret = adev->powerplay.ip_funcs->sw_init( + adev->powerplay.pp_handle); + +#ifdef CONFIG_DRM_AMD_POWERPLAY + if (adev->pp_enabled) { + if (amdgpu_dpm == 0) + adev->pm.dpm_enabled = false; + else + adev->pm.dpm_enabled = true; + } +#endif + + return ret; +} + +static int amdgpu_pp_sw_fini(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->sw_fini) + ret = adev->powerplay.ip_funcs->sw_fini( + adev->powerplay.pp_handle); + if (ret) + return ret; + +#ifdef CONFIG_DRM_AMD_POWERPLAY + if (adev->pp_enabled) { + amdgpu_pm_sysfs_fini(adev); + amd_powerplay_fini(adev->powerplay.pp_handle); + } +#endif + + return ret; +} + +static int amdgpu_pp_hw_init(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->pp_enabled && adev->firmware.smu_load) + amdgpu_ucode_init_bo(adev); + + if (adev->powerplay.ip_funcs->hw_init) + ret = adev->powerplay.ip_funcs->hw_init( + adev->powerplay.pp_handle); + + return ret; +} + +static int amdgpu_pp_hw_fini(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->hw_fini) + ret = adev->powerplay.ip_funcs->hw_fini( + adev->powerplay.pp_handle); + + if (adev->pp_enabled && adev->firmware.smu_load) + amdgpu_ucode_fini_bo(adev); + + return ret; +} + +static int amdgpu_pp_suspend(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->suspend) + ret = adev->powerplay.ip_funcs->suspend( + adev->powerplay.pp_handle); + return ret; +} + +static int amdgpu_pp_resume(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->resume) + ret = adev->powerplay.ip_funcs->resume( + adev->powerplay.pp_handle); + return ret; +} + +static int amdgpu_pp_set_clockgating_state(void *handle, + enum amd_clockgating_state state) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->set_clockgating_state) + ret = adev->powerplay.ip_funcs->set_clockgating_state( + adev->powerplay.pp_handle, state); + return ret; +} + +static int amdgpu_pp_set_powergating_state(void *handle, + enum amd_powergating_state state) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->set_powergating_state) + ret = adev->powerplay.ip_funcs->set_powergating_state( + adev->powerplay.pp_handle, state); + return ret; +} + + +static bool amdgpu_pp_is_idle(void *handle) +{ + bool ret = true; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->is_idle) + ret = adev->powerplay.ip_funcs->is_idle( + adev->powerplay.pp_handle); + return ret; +} + +static int amdgpu_pp_wait_for_idle(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->wait_for_idle) + ret = adev->powerplay.ip_funcs->wait_for_idle( + adev->powerplay.pp_handle); + return ret; +} + +static int amdgpu_pp_soft_reset(void *handle) +{ + int ret = 0; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->soft_reset) + ret = adev->powerplay.ip_funcs->soft_reset( + adev->powerplay.pp_handle); + return ret; +} + +static void amdgpu_pp_print_status(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->powerplay.ip_funcs->print_status) + adev->powerplay.ip_funcs->print_status( + adev->powerplay.pp_handle); +} + +const struct amd_ip_funcs amdgpu_pp_ip_funcs = { + .early_init = amdgpu_pp_early_init, + .late_init = amdgpu_pp_late_init, + .sw_init = amdgpu_pp_sw_init, + .sw_fini = amdgpu_pp_sw_fini, + .hw_init = amdgpu_pp_hw_init, + .hw_fini = amdgpu_pp_hw_fini, + .suspend = amdgpu_pp_suspend, + .resume = amdgpu_pp_resume, + .is_idle = amdgpu_pp_is_idle, + .wait_for_idle = amdgpu_pp_wait_for_idle, + .soft_reset = amdgpu_pp_soft_reset, + .print_status = amdgpu_pp_print_status, + .set_clockgating_state = amdgpu_pp_set_clockgating_state, + .set_powergating_state = amdgpu_pp_set_powergating_state, +}; diff --git a/drivers/gpu/drm/amd/amdgpu/smu8.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.h index d758d07b6a31..da5cf47cfd99 100644 --- a/drivers/gpu/drm/amd/amdgpu/smu8.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 Advanced Micro Devices, Inc. + * Copyright 2015 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -19,54 +19,15 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * + * Authors: AMD + * */ -#ifndef SMU8_H -#define SMU8_H - -#pragma pack(push, 1) - -#define ENABLE_DEBUG_FEATURES - -struct SMU8_Firmware_Header { - uint32_t Version; - uint32_t ImageSize; - uint32_t CodeSize; - uint32_t HeaderSize; - uint32_t EntryPoint; - uint32_t Rtos; - uint32_t UcodeLoadStatus; - uint32_t DpmTable; - uint32_t FanTable; - uint32_t PmFuseTable; - uint32_t Globals; - uint32_t Reserved[20]; - uint32_t Signature; -}; - -struct SMU8_MultimediaPowerLogData { - uint32_t avgTotalPower; - uint32_t avgGpuPower; - uint32_t avgUvdPower; - uint32_t avgVcePower; - - uint32_t avgSclk; - uint32_t avgDclk; - uint32_t avgVclk; - uint32_t avgEclk; - - uint32_t startTimeHi; - uint32_t startTimeLo; - - uint32_t endTimeHi; - uint32_t endTimeLo; -}; - -#define SMU8_FIRMWARE_HEADER_LOCATION 0x1FF80 -#define SMU8_UNBCSR_START_ADDR 0xC0100000 +#ifndef __AMDGPU_POPWERPLAY_H__ +#define __AMDGPU_POPWERPLAY_H__ -#define SMN_MP1_SRAM_START_ADDR 0x10000000 +#include "amd_shared.h" -#pragma pack(pop) +extern const struct amd_ip_funcs amdgpu_pp_ip_funcs; -#endif +#endif /* __AMDSOC_DM_H__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 0212b31dc194..8b88edb0434b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c @@ -311,8 +311,7 @@ static bool amdgpu_sa_bo_next_hole(struct amdgpu_sa_manager *sa_manager, return false; } -int amdgpu_sa_bo_new(struct amdgpu_device *adev, - struct amdgpu_sa_manager *sa_manager, +int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, struct amdgpu_sa_bo **sa_bo, unsigned size, unsigned align) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index dcf4a8aca680..438c05254695 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -26,6 +26,7 @@ #include <linux/sched.h> #include <drm/drmP.h> #include "amdgpu.h" +#include "amdgpu_trace.h" static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) { @@ -44,11 +45,8 @@ static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) return NULL; } job = to_amdgpu_job(sched_job); - mutex_lock(&job->job_lock); - r = amdgpu_ib_schedule(job->adev, - job->num_ibs, - job->ibs, - job->base.owner); + trace_amdgpu_sched_run_job(job); + r = amdgpu_ib_schedule(job->adev, job->num_ibs, job->ibs, job->owner); if (r) { DRM_ERROR("Error scheduling IBs (%d)\n", r); goto err; @@ -61,8 +59,6 @@ err: if (job->free_job) job->free_job(job); - mutex_unlock(&job->job_lock); - fence_put(&job->base.s_fence->base); kfree(job); return fence ? &fence->base : NULL; } @@ -88,21 +84,19 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, return -ENOMEM; job->base.sched = &ring->sched; job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; + job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); + if (!job->base.s_fence) { + kfree(job); + return -ENOMEM; + } + *f = fence_get(&job->base.s_fence->base); + job->adev = adev; job->ibs = ibs; job->num_ibs = num_ibs; - job->base.owner = owner; - mutex_init(&job->job_lock); + job->owner = owner; job->free_job = free_job; - mutex_lock(&job->job_lock); - r = amd_sched_entity_push_job(&job->base); - if (r) { - mutex_unlock(&job->job_lock); - kfree(job); - return r; - } - *f = fence_get(&job->base.s_fence->base); - mutex_unlock(&job->job_lock); + amd_sched_entity_push_job(&job->base); } else { r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c index ff3ca52ec6fe..1caaf201b708 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c @@ -40,7 +40,7 @@ int amdgpu_semaphore_create(struct amdgpu_device *adev, if (*semaphore == NULL) { return -ENOMEM; } - r = amdgpu_sa_bo_new(adev, &adev->ring_tmp_bo, + r = amdgpu_sa_bo_new(&adev->ring_tmp_bo, &(*semaphore)->sa_bo, 8, 8); if (r) { kfree(*semaphore); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index a6697fd05217..181ce39ef5e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -293,7 +293,8 @@ int amdgpu_sync_rings(struct amdgpu_sync *sync, fence = to_amdgpu_fence(sync->sync_to[i]); /* check if we really need to sync */ - if (!amdgpu_fence_need_sync(fence, ring)) + if (!amdgpu_enable_scheduler && + !amdgpu_fence_need_sync(fence, ring)) continue; /* prevent GPU deadlocks */ @@ -302,8 +303,14 @@ int amdgpu_sync_rings(struct amdgpu_sync *sync, return -EINVAL; } - if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores || - (count >= AMDGPU_NUM_SYNCS)) { + if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores) { + r = fence_wait(sync->sync_to[i], true); + if (r) + return r; + continue; + } + + if (count >= AMDGPU_NUM_SYNCS) { /* not enough room, wait manually */ r = fence_wait(&fence->base, false); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index 76ecbaf72a2e..8f9834ab1bd5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h @@ -48,6 +48,57 @@ TRACE_EVENT(amdgpu_cs, __entry->fences) ); +TRACE_EVENT(amdgpu_cs_ioctl, + TP_PROTO(struct amdgpu_job *job), + TP_ARGS(job), + TP_STRUCT__entry( + __field(struct amdgpu_device *, adev) + __field(struct amd_sched_job *, sched_job) + __field(struct amdgpu_ib *, ib) + __field(struct fence *, fence) + __field(char *, ring_name) + __field(u32, num_ibs) + ), + + TP_fast_assign( + __entry->adev = job->adev; + __entry->sched_job = &job->base; + __entry->ib = job->ibs; + __entry->fence = &job->base.s_fence->base; + __entry->ring_name = job->ibs[0].ring->name; + __entry->num_ibs = job->num_ibs; + ), + TP_printk("adev=%p, sched_job=%p, first ib=%p, sched fence=%p, ring name:%s, num_ibs:%u", + __entry->adev, __entry->sched_job, __entry->ib, + __entry->fence, __entry->ring_name, __entry->num_ibs) +); + +TRACE_EVENT(amdgpu_sched_run_job, + TP_PROTO(struct amdgpu_job *job), + TP_ARGS(job), + TP_STRUCT__entry( + __field(struct amdgpu_device *, adev) + __field(struct amd_sched_job *, sched_job) + __field(struct amdgpu_ib *, ib) + __field(struct fence *, fence) + __field(char *, ring_name) + __field(u32, num_ibs) + ), + + TP_fast_assign( + __entry->adev = job->adev; + __entry->sched_job = &job->base; + __entry->ib = job->ibs; + __entry->fence = &job->base.s_fence->base; + __entry->ring_name = job->ibs[0].ring->name; + __entry->num_ibs = job->num_ibs; + ), + TP_printk("adev=%p, sched_job=%p, first ib=%p, sched fence=%p, ring name:%s, num_ibs:%u", + __entry->adev, __entry->sched_job, __entry->ib, + __entry->fence, __entry->ring_name, __entry->num_ibs) +); + + TRACE_EVENT(amdgpu_vm_grab_id, TP_PROTO(unsigned vmid, int ring), TP_ARGS(vmid, ring), @@ -196,49 +247,6 @@ TRACE_EVENT(amdgpu_bo_list_set, TP_printk("list=%p, bo=%p", __entry->list, __entry->bo) ); -DECLARE_EVENT_CLASS(amdgpu_fence_request, - - TP_PROTO(struct drm_device *dev, int ring, u32 seqno), - - TP_ARGS(dev, ring, seqno), - - TP_STRUCT__entry( - __field(u32, dev) - __field(int, ring) - __field(u32, seqno) - ), - - TP_fast_assign( - __entry->dev = dev->primary->index; - __entry->ring = ring; - __entry->seqno = seqno; - ), - - TP_printk("dev=%u, ring=%d, seqno=%u", - __entry->dev, __entry->ring, __entry->seqno) -); - -DEFINE_EVENT(amdgpu_fence_request, amdgpu_fence_emit, - - TP_PROTO(struct drm_device *dev, int ring, u32 seqno), - - TP_ARGS(dev, ring, seqno) -); - -DEFINE_EVENT(amdgpu_fence_request, amdgpu_fence_wait_begin, - - TP_PROTO(struct drm_device *dev, int ring, u32 seqno), - - TP_ARGS(dev, ring, seqno) -); - -DEFINE_EVENT(amdgpu_fence_request, amdgpu_fence_wait_end, - - TP_PROTO(struct drm_device *dev, int ring, u32 seqno), - - TP_ARGS(dev, ring, seqno) -); - DECLARE_EVENT_CLASS(amdgpu_semaphore_request, TP_PROTO(int ring, struct amdgpu_semaphore *sem), diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 81bb8e9fc26d..8a1752ff3d8e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -587,9 +587,13 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem); int r; - if (gtt->userptr) - amdgpu_ttm_tt_pin_userptr(ttm); - + if (gtt->userptr) { + r = amdgpu_ttm_tt_pin_userptr(ttm); + if (r) { + DRM_ERROR("failed to pin userptr\n"); + return r; + } + } gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); if (!ttm->num_pages) { WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", @@ -797,11 +801,12 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, if (mem && mem->mem_type != TTM_PL_SYSTEM) flags |= AMDGPU_PTE_VALID; - if (mem && mem->mem_type == TTM_PL_TT) + if (mem && mem->mem_type == TTM_PL_TT) { flags |= AMDGPU_PTE_SYSTEM; - if (!ttm || ttm->caching_state == tt_cached) - flags |= AMDGPU_PTE_SNOOPED; + if (ttm->caching_state == tt_cached) + flags |= AMDGPU_PTE_SNOOPED; + } if (adev->asic_type >= CHIP_TOPAZ) flags |= AMDGPU_PTE_EXECUTABLE; @@ -1073,10 +1078,10 @@ static int amdgpu_mm_dump_table(struct seq_file *m, void *data) ret = drm_mm_dump_table(m, mm); spin_unlock(&glob->lru_lock); if (ttm_pl == TTM_PL_VRAM) - seq_printf(m, "man size:%llu pages, ram usage:%luMB, vis usage:%luMB\n", + seq_printf(m, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n", adev->mman.bdev.man[ttm_pl].size, - atomic64_read(&adev->vram_usage) >> 20, - atomic64_read(&adev->vram_vis_usage) >> 20); + (u64)atomic64_read(&adev->vram_usage) >> 20, + (u64)atomic64_read(&adev->vram_vis_usage) >> 20); return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 03f0c3bae516..a745eeeb5d82 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -392,7 +392,10 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */ ib->ptr[ib->length_dw++] = handle; - ib->ptr[ib->length_dw++] = 0x00000030; /* len */ + if ((ring->adev->vce.fw_version >> 24) >= 52) + ib->ptr[ib->length_dw++] = 0x00000040; /* len */ + else + ib->ptr[ib->length_dw++] = 0x00000030; /* len */ ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */ ib->ptr[ib->length_dw++] = 0x00000000; ib->ptr[ib->length_dw++] = 0x00000042; @@ -404,6 +407,12 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, ib->ptr[ib->length_dw++] = 0x00000100; ib->ptr[ib->length_dw++] = 0x0000000c; ib->ptr[ib->length_dw++] = 0x00000000; + if ((ring->adev->vce.fw_version >> 24) >= 52) { + ib->ptr[ib->length_dw++] = 0x00000000; + ib->ptr[ib->length_dw++] = 0x00000000; + ib->ptr[ib->length_dw++] = 0x00000000; + ib->ptr[ib->length_dw++] = 0x00000000; + } ib->ptr[ib->length_dw++] = 0x00000014; /* len */ ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 633a32a48560..aefc668e6b5d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -75,50 +75,77 @@ static unsigned amdgpu_vm_directory_size(struct amdgpu_device *adev) } /** - * amdgpu_vm_get_bos - add the vm BOs to a validation list + * amdgpu_vm_get_pd_bo - add the VM PD to a validation list * * @vm: vm providing the BOs - * @head: head of validation list + * @validated: head of validation list + * @entry: entry to add * * Add the page directory to the list of BOs to - * validate for command submission (cayman+). + * validate for command submission. */ -struct amdgpu_bo_list_entry *amdgpu_vm_get_bos(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct list_head *head) +void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, + struct list_head *validated, + struct amdgpu_bo_list_entry *entry) { - struct amdgpu_bo_list_entry *list; - unsigned i, idx; + entry->robj = vm->page_directory; + entry->prefered_domains = AMDGPU_GEM_DOMAIN_VRAM; + entry->allowed_domains = AMDGPU_GEM_DOMAIN_VRAM; + entry->priority = 0; + entry->tv.bo = &vm->page_directory->tbo; + entry->tv.shared = true; + list_add(&entry->tv.head, validated); +} - list = drm_malloc_ab(vm->max_pde_used + 2, - sizeof(struct amdgpu_bo_list_entry)); - if (!list) { - return NULL; - } +/** + * amdgpu_vm_get_bos - add the vm BOs to a duplicates list + * + * @vm: vm providing the BOs + * @duplicates: head of duplicates list + * + * Add the page directory to the BO duplicates list + * for command submission. + */ +void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates) +{ + unsigned i; /* add the vm page table to the list */ - list[0].robj = vm->page_directory; - list[0].prefered_domains = AMDGPU_GEM_DOMAIN_VRAM; - list[0].allowed_domains = AMDGPU_GEM_DOMAIN_VRAM; - list[0].priority = 0; - list[0].tv.bo = &vm->page_directory->tbo; - list[0].tv.shared = true; - list_add(&list[0].tv.head, head); - - for (i = 0, idx = 1; i <= vm->max_pde_used; i++) { - if (!vm->page_tables[i].bo) + for (i = 0; i <= vm->max_pde_used; ++i) { + struct amdgpu_bo_list_entry *entry = &vm->page_tables[i].entry; + + if (!entry->robj) continue; - list[idx].robj = vm->page_tables[i].bo; - list[idx].prefered_domains = AMDGPU_GEM_DOMAIN_VRAM; - list[idx].allowed_domains = AMDGPU_GEM_DOMAIN_VRAM; - list[idx].priority = 0; - list[idx].tv.bo = &list[idx].robj->tbo; - list[idx].tv.shared = true; - list_add(&list[idx++].tv.head, head); + list_add(&entry->tv.head, duplicates); } - return list; +} + +/** + * amdgpu_vm_move_pt_bos_in_lru - move the PT BOs to the LRU tail + * + * @adev: amdgpu device instance + * @vm: vm providing the BOs + * + * Move the PT BOs to the tail of the LRU. + */ +void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, + struct amdgpu_vm *vm) +{ + struct ttm_bo_global *glob = adev->mman.bdev.glob; + unsigned i; + + spin_lock(&glob->lru_lock); + for (i = 0; i <= vm->max_pde_used; ++i) { + struct amdgpu_bo_list_entry *entry = &vm->page_tables[i].entry; + + if (!entry->robj) + continue; + + ttm_bo_move_to_lru_tail(&entry->robj->tbo); + } + spin_unlock(&glob->lru_lock); } /** @@ -143,10 +170,15 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, unsigned i; /* check if the id is still valid */ - if (vm_id->id && vm_id->last_id_use && - vm_id->last_id_use == adev->vm_manager.active[vm_id->id]) { - trace_amdgpu_vm_grab_id(vm_id->id, ring->idx); - return 0; + if (vm_id->id) { + unsigned id = vm_id->id; + long owner; + + owner = atomic_long_read(&adev->vm_manager.ids[id].owner); + if (owner == (long)vm) { + trace_amdgpu_vm_grab_id(vm_id->id, ring->idx); + return 0; + } } /* we definately need to flush */ @@ -154,7 +186,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, /* skip over VMID 0, since it is the system VM */ for (i = 1; i < adev->vm_manager.nvm; ++i) { - struct fence *fence = adev->vm_manager.active[i]; + struct fence *fence = adev->vm_manager.ids[i].active; struct amdgpu_ring *fring; if (fence == NULL) { @@ -176,7 +208,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, if (choices[i]) { struct fence *fence; - fence = adev->vm_manager.active[choices[i]]; + fence = adev->vm_manager.ids[choices[i]].active; vm_id->id = choices[i]; trace_amdgpu_vm_grab_id(choices[i], ring->idx); @@ -207,24 +239,21 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; struct fence *flushed_updates = vm_id->flushed_updates; - bool is_earlier = false; + bool is_later; - if (flushed_updates && updates) { - BUG_ON(flushed_updates->context != updates->context); - is_earlier = (updates->seqno - flushed_updates->seqno <= - INT_MAX) ? true : false; - } - - if (pd_addr != vm_id->pd_gpu_addr || !flushed_updates || - is_earlier) { + if (!flushed_updates) + is_later = true; + else if (!updates) + is_later = false; + else + is_later = fence_is_later(updates, flushed_updates); + if (pd_addr != vm_id->pd_gpu_addr || is_later) { trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id->id); - if (is_earlier) { + if (is_later) { vm_id->flushed_updates = fence_get(updates); fence_put(flushed_updates); } - if (!flushed_updates) - vm_id->flushed_updates = fence_get(updates); vm_id->pd_gpu_addr = pd_addr; amdgpu_ring_emit_vm_flush(ring, vm_id->id, vm_id->pd_gpu_addr); } @@ -244,16 +273,14 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, */ void amdgpu_vm_fence(struct amdgpu_device *adev, struct amdgpu_vm *vm, - struct amdgpu_fence *fence) + struct fence *fence) { - unsigned ridx = fence->ring->idx; - unsigned vm_id = vm->ids[ridx].id; - - fence_put(adev->vm_manager.active[vm_id]); - adev->vm_manager.active[vm_id] = fence_get(&fence->base); + struct amdgpu_ring *ring = amdgpu_ring_from_fence(fence); + unsigned vm_id = vm->ids[ring->idx].id; - fence_put(vm->ids[ridx].last_id_use); - vm->ids[ridx].last_id_use = fence_get(&fence->base); + fence_put(adev->vm_manager.ids[vm_id].active); + adev->vm_manager.ids[vm_id].active = fence_get(fence); + atomic_long_set(&adev->vm_manager.ids[vm_id].owner, (long)vm); } /** @@ -332,6 +359,8 @@ int amdgpu_vm_free_job(struct amdgpu_job *job) * * @adev: amdgpu_device pointer * @bo: bo to clear + * + * need to reserve bo first before calling it. */ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, struct amdgpu_bo *bo) @@ -343,24 +372,20 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, uint64_t addr; int r; - r = amdgpu_bo_reserve(bo, false); - if (r) - return r; - r = reservation_object_reserve_shared(bo->tbo.resv); if (r) return r; r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); if (r) - goto error_unreserve; + goto error; addr = amdgpu_bo_gpu_offset(bo); entries = amdgpu_bo_size(bo) / 8; ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); if (!ib) - goto error_unreserve; + goto error; r = amdgpu_ib_get(ring, NULL, entries * 2 + 64, ib); if (r) @@ -378,16 +403,14 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, if (!r) amdgpu_bo_fence(bo, fence, true); fence_put(fence); - if (amdgpu_enable_scheduler) { - amdgpu_bo_unreserve(bo); + if (amdgpu_enable_scheduler) return 0; - } + error_free: amdgpu_ib_free(adev, ib); kfree(ib); -error_unreserve: - amdgpu_bo_unreserve(bo); +error: return r; } @@ -465,7 +488,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, /* walk over the address space and update the page directory */ for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) { - struct amdgpu_bo *bo = vm->page_tables[pt_idx].bo; + struct amdgpu_bo *bo = vm->page_tables[pt_idx].entry.robj; uint64_t pde, pt; if (bo == NULL) @@ -642,7 +665,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_device *adev, /* walk over the address space and update the page tables */ for (addr = start; addr < end; ) { uint64_t pt_idx = addr >> amdgpu_vm_block_size; - struct amdgpu_bo *pt = vm->page_tables[pt_idx].bo; + struct amdgpu_bo *pt = vm->page_tables[pt_idx].entry.robj; unsigned nptes; uint64_t pte; int r; @@ -889,17 +912,21 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping *mapping; int r; + spin_lock(&vm->freed_lock); while (!list_empty(&vm->freed)) { mapping = list_first_entry(&vm->freed, struct amdgpu_bo_va_mapping, list); list_del(&mapping->list); - + spin_unlock(&vm->freed_lock); r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); kfree(mapping); if (r) return r; + spin_lock(&vm->freed_lock); } + spin_unlock(&vm->freed_lock); + return 0; } @@ -926,8 +953,9 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va, vm_status); spin_unlock(&vm->status_lock); - + mutex_lock(&bo_va->mutex); r = amdgpu_vm_bo_update(adev, bo_va, NULL); + mutex_unlock(&bo_va->mutex); if (r) return r; @@ -971,7 +999,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, INIT_LIST_HEAD(&bo_va->valids); INIT_LIST_HEAD(&bo_va->invalids); INIT_LIST_HEAD(&bo_va->vm_status); - + mutex_init(&bo_va->mutex); list_add_tail(&bo_va->bo_list, &bo->va); return bo_va; @@ -989,7 +1017,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, * Add a mapping of the BO at the specefied addr into the VM. * Returns 0 for success, error for failure. * - * Object has to be reserved and gets unreserved by this function! + * Object has to be reserved and unreserved outside! */ int amdgpu_vm_bo_map(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, @@ -1005,30 +1033,27 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, /* validate the parameters */ if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || - size == 0 || size & AMDGPU_GPU_PAGE_MASK) { - amdgpu_bo_unreserve(bo_va->bo); + size == 0 || size & AMDGPU_GPU_PAGE_MASK) return -EINVAL; - } /* make sure object fit at this offset */ - eaddr = saddr + size; - if ((saddr >= eaddr) || (offset + size > amdgpu_bo_size(bo_va->bo))) { - amdgpu_bo_unreserve(bo_va->bo); + eaddr = saddr + size - 1; + if ((saddr >= eaddr) || (offset + size > amdgpu_bo_size(bo_va->bo))) return -EINVAL; - } last_pfn = eaddr / AMDGPU_GPU_PAGE_SIZE; - if (last_pfn > adev->vm_manager.max_pfn) { - dev_err(adev->dev, "va above limit (0x%08X > 0x%08X)\n", + if (last_pfn >= adev->vm_manager.max_pfn) { + dev_err(adev->dev, "va above limit (0x%08X >= 0x%08X)\n", last_pfn, adev->vm_manager.max_pfn); - amdgpu_bo_unreserve(bo_va->bo); return -EINVAL; } saddr /= AMDGPU_GPU_PAGE_SIZE; eaddr /= AMDGPU_GPU_PAGE_SIZE; - it = interval_tree_iter_first(&vm->va, saddr, eaddr - 1); + spin_lock(&vm->it_lock); + it = interval_tree_iter_first(&vm->va, saddr, eaddr); + spin_unlock(&vm->it_lock); if (it) { struct amdgpu_bo_va_mapping *tmp; tmp = container_of(it, struct amdgpu_bo_va_mapping, it); @@ -1036,26 +1061,28 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, dev_err(adev->dev, "bo %p va 0x%010Lx-0x%010Lx conflict with " "0x%010lx-0x%010lx\n", bo_va->bo, saddr, eaddr, tmp->it.start, tmp->it.last + 1); - amdgpu_bo_unreserve(bo_va->bo); r = -EINVAL; goto error; } mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); if (!mapping) { - amdgpu_bo_unreserve(bo_va->bo); r = -ENOMEM; goto error; } INIT_LIST_HEAD(&mapping->list); mapping->it.start = saddr; - mapping->it.last = eaddr - 1; + mapping->it.last = eaddr; mapping->offset = offset; mapping->flags = flags; + mutex_lock(&bo_va->mutex); list_add(&mapping->list, &bo_va->invalids); + mutex_unlock(&bo_va->mutex); + spin_lock(&vm->it_lock); interval_tree_insert(&mapping->it, &vm->va); + spin_unlock(&vm->it_lock); trace_amdgpu_vm_bo_map(bo_va, mapping); /* Make sure the page tables are allocated */ @@ -1067,41 +1094,51 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, if (eaddr > vm->max_pde_used) vm->max_pde_used = eaddr; - amdgpu_bo_unreserve(bo_va->bo); - /* walk over the address space and allocate the page tables */ for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) { struct reservation_object *resv = vm->page_directory->tbo.resv; + struct amdgpu_bo_list_entry *entry; struct amdgpu_bo *pt; - if (vm->page_tables[pt_idx].bo) + entry = &vm->page_tables[pt_idx].entry; + if (entry->robj) continue; - ww_mutex_lock(&resv->lock, NULL); r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8, AMDGPU_GPU_PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_CREATE_NO_CPU_ACCESS, NULL, resv, &pt); - ww_mutex_unlock(&resv->lock); if (r) goto error_free; + /* Keep a reference to the page table to avoid freeing + * them up in the wrong order. + */ + pt->parent = amdgpu_bo_ref(vm->page_directory); + r = amdgpu_vm_clear_bo(adev, pt); if (r) { amdgpu_bo_unref(&pt); goto error_free; } + entry->robj = pt; + entry->prefered_domains = AMDGPU_GEM_DOMAIN_VRAM; + entry->allowed_domains = AMDGPU_GEM_DOMAIN_VRAM; + entry->priority = 0; + entry->tv.bo = &entry->robj->tbo; + entry->tv.shared = true; vm->page_tables[pt_idx].addr = 0; - vm->page_tables[pt_idx].bo = pt; } return 0; error_free: list_del(&mapping->list); + spin_lock(&vm->it_lock); interval_tree_remove(&mapping->it, &vm->va); + spin_unlock(&vm->it_lock); trace_amdgpu_vm_bo_unmap(bo_va, mapping); kfree(mapping); @@ -1119,7 +1156,7 @@ error: * Remove a mapping of the BO at the specefied addr from the VM. * Returns 0 for success, error for failure. * - * Object has to be reserved and gets unreserved by this function! + * Object has to be reserved and unreserved outside! */ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, @@ -1130,7 +1167,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, bool valid = true; saddr /= AMDGPU_GPU_PAGE_SIZE; - + mutex_lock(&bo_va->mutex); list_for_each_entry(mapping, &bo_va->valids, list) { if (mapping->it.start == saddr) break; @@ -1145,20 +1182,24 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, } if (&mapping->list == &bo_va->invalids) { - amdgpu_bo_unreserve(bo_va->bo); + mutex_unlock(&bo_va->mutex); return -ENOENT; } } - + mutex_unlock(&bo_va->mutex); list_del(&mapping->list); + spin_lock(&vm->it_lock); interval_tree_remove(&mapping->it, &vm->va); + spin_unlock(&vm->it_lock); trace_amdgpu_vm_bo_unmap(bo_va, mapping); - if (valid) + if (valid) { + spin_lock(&vm->freed_lock); list_add(&mapping->list, &vm->freed); - else + spin_unlock(&vm->freed_lock); + } else { kfree(mapping); - amdgpu_bo_unreserve(bo_va->bo); + } return 0; } @@ -1187,17 +1228,23 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { list_del(&mapping->list); + spin_lock(&vm->it_lock); interval_tree_remove(&mapping->it, &vm->va); + spin_unlock(&vm->it_lock); trace_amdgpu_vm_bo_unmap(bo_va, mapping); + spin_lock(&vm->freed_lock); list_add(&mapping->list, &vm->freed); + spin_unlock(&vm->freed_lock); } list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { list_del(&mapping->list); + spin_lock(&vm->it_lock); interval_tree_remove(&mapping->it, &vm->va); + spin_unlock(&vm->it_lock); kfree(mapping); } - fence_put(bo_va->last_pt_update); + mutex_destroy(&bo_va->mutex); kfree(bo_va); } @@ -1241,15 +1288,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { vm->ids[i].id = 0; vm->ids[i].flushed_updates = NULL; - vm->ids[i].last_id_use = NULL; } - mutex_init(&vm->mutex); vm->va = RB_ROOT; spin_lock_init(&vm->status_lock); INIT_LIST_HEAD(&vm->invalidated); INIT_LIST_HEAD(&vm->cleared); INIT_LIST_HEAD(&vm->freed); - + spin_lock_init(&vm->it_lock); + spin_lock_init(&vm->freed_lock); pd_size = amdgpu_vm_directory_size(adev); pd_entries = amdgpu_vm_num_pdes(adev); @@ -1269,8 +1315,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) NULL, NULL, &vm->page_directory); if (r) return r; - + r = amdgpu_bo_reserve(vm->page_directory, false); + if (r) { + amdgpu_bo_unref(&vm->page_directory); + vm->page_directory = NULL; + return r; + } r = amdgpu_vm_clear_bo(adev, vm->page_directory); + amdgpu_bo_unreserve(vm->page_directory); if (r) { amdgpu_bo_unref(&vm->page_directory); vm->page_directory = NULL; @@ -1308,16 +1360,32 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) } for (i = 0; i < amdgpu_vm_num_pdes(adev); i++) - amdgpu_bo_unref(&vm->page_tables[i].bo); + amdgpu_bo_unref(&vm->page_tables[i].entry.robj); kfree(vm->page_tables); amdgpu_bo_unref(&vm->page_directory); fence_put(vm->page_directory_fence); - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + unsigned id = vm->ids[i].id; + + atomic_long_cmpxchg(&adev->vm_manager.ids[id].owner, + (long)vm, 0); fence_put(vm->ids[i].flushed_updates); - fence_put(vm->ids[i].last_id_use); } - mutex_destroy(&vm->mutex); +} + +/** + * amdgpu_vm_manager_fini - cleanup VM manager + * + * @adev: amdgpu_device pointer + * + * Cleanup the VM manager and free resources. + */ +void amdgpu_vm_manager_fini(struct amdgpu_device *adev) +{ + unsigned i; + + for (i = 0; i < AMDGPU_NUM_VM; ++i) + fence_put(adev->vm_manager.ids[i].active); } diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c index 92b6acadfc52..21aacc1f45c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c @@ -243,7 +243,7 @@ static void amdgpu_atombios_dp_get_adjust_train(const u8 link_status[DP_LINK_STA /* convert bits per color to bits per pixel */ /* get bpc from the EDID */ -static int amdgpu_atombios_dp_convert_bpc_to_bpp(int bpc) +static unsigned amdgpu_atombios_dp_convert_bpc_to_bpp(int bpc) { if (bpc == 0) return 24; @@ -251,64 +251,32 @@ static int amdgpu_atombios_dp_convert_bpc_to_bpp(int bpc) return bpc * 3; } -/* get the max pix clock supported by the link rate and lane num */ -static int amdgpu_atombios_dp_get_max_dp_pix_clock(int link_rate, - int lane_num, - int bpp) -{ - return (link_rate * lane_num * 8) / bpp; -} - /***** amdgpu specific DP functions *****/ -/* First get the min lane# when low rate is used according to pixel clock - * (prefer low rate), second check max lane# supported by DP panel, - * if the max lane# < low rate lane# then use max lane# instead. - */ -static int amdgpu_atombios_dp_get_dp_lane_number(struct drm_connector *connector, +static int amdgpu_atombios_dp_get_dp_link_config(struct drm_connector *connector, const u8 dpcd[DP_DPCD_SIZE], - int pix_clock) -{ - int bpp = amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector)); - int max_link_rate = drm_dp_max_link_rate(dpcd); - int max_lane_num = drm_dp_max_lane_count(dpcd); - int lane_num; - int max_dp_pix_clock; - - for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) { - max_dp_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp); - if (pix_clock <= max_dp_pix_clock) - break; - } - - return lane_num; -} - -static int amdgpu_atombios_dp_get_dp_link_clock(struct drm_connector *connector, - const u8 dpcd[DP_DPCD_SIZE], - int pix_clock) + unsigned pix_clock, + unsigned *dp_lanes, unsigned *dp_rate) { - int bpp = amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector)); - int lane_num, max_pix_clock; - - if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) == - ENCODER_OBJECT_ID_NUTMEG) - return 270000; - - lane_num = amdgpu_atombios_dp_get_dp_lane_number(connector, dpcd, pix_clock); - max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(162000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 162000; - max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(270000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 270000; - if (amdgpu_connector_is_dp12_capable(connector)) { - max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(540000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 540000; + unsigned bpp = + amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector)); + static const unsigned link_rates[3] = { 162000, 270000, 540000 }; + unsigned max_link_rate = drm_dp_max_link_rate(dpcd); + unsigned max_lane_num = drm_dp_max_lane_count(dpcd); + unsigned lane_num, i, max_pix_clock; + + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { + for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; + if (max_pix_clock >= pix_clock) { + *dp_lanes = lane_num; + *dp_rate = link_rates[i]; + return 0; + } + } } - return drm_dp_max_link_rate(dpcd); + return -EINVAL; } static u8 amdgpu_atombios_dp_encoder_service(struct amdgpu_device *adev, @@ -422,6 +390,7 @@ void amdgpu_atombios_dp_set_link_config(struct drm_connector *connector, { struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); struct amdgpu_connector_atom_dig *dig_connector; + int ret; if (!amdgpu_connector->con_priv) return; @@ -429,10 +398,14 @@ void amdgpu_atombios_dp_set_link_config(struct drm_connector *connector, if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { - dig_connector->dp_clock = - amdgpu_atombios_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); - dig_connector->dp_lane_count = - amdgpu_atombios_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock); + ret = amdgpu_atombios_dp_get_dp_link_config(connector, dig_connector->dpcd, + mode->clock, + &dig_connector->dp_lane_count, + &dig_connector->dp_clock); + if (ret) { + dig_connector->dp_clock = 0; + dig_connector->dp_lane_count = 0; + } } } @@ -441,14 +414,17 @@ int amdgpu_atombios_dp_mode_valid_helper(struct drm_connector *connector, { struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); struct amdgpu_connector_atom_dig *dig_connector; - int dp_clock; + unsigned dp_lanes, dp_clock; + int ret; if (!amdgpu_connector->con_priv) return MODE_CLOCK_HIGH; dig_connector = amdgpu_connector->con_priv; - dp_clock = - amdgpu_atombios_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); + ret = amdgpu_atombios_dp_get_dp_link_config(connector, dig_connector->dpcd, + mode->clock, &dp_lanes, &dp_clock); + if (ret) + return MODE_CLOCK_HIGH; if ((dp_clock == 540000) && (!amdgpu_connector_is_dp12_capable(connector))) diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index a1a35a5df8e7..8b4731d4e10e 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -1395,7 +1395,6 @@ static void ci_thermal_stop_thermal_controller(struct amdgpu_device *adev) ci_fan_ctrl_set_default_mode(adev); } -#if 0 static int ci_read_smc_soft_register(struct amdgpu_device *adev, u16 reg_offset, u32 *value) { @@ -1405,7 +1404,6 @@ static int ci_read_smc_soft_register(struct amdgpu_device *adev, pi->soft_regs_start + reg_offset, value, pi->sram_end); } -#endif static int ci_write_smc_soft_register(struct amdgpu_device *adev, u16 reg_offset, u32 value) @@ -6084,11 +6082,23 @@ ci_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, struct amdgpu_ps *rps = &pi->current_rps; u32 sclk = ci_get_average_sclk_freq(adev); u32 mclk = ci_get_average_mclk_freq(adev); + u32 activity_percent = 50; + int ret; + + ret = ci_read_smc_soft_register(adev, offsetof(SMU7_SoftRegisters, AverageGraphicsA), + &activity_percent); + + if (ret == 0) { + activity_percent += 0x80; + activity_percent >>= 8; + activity_percent = activity_percent > 100 ? 100 : activity_percent; + } seq_printf(m, "uvd %sabled\n", pi->uvd_enabled ? "en" : "dis"); seq_printf(m, "vce %sabled\n", rps->vce_active ? "en" : "dis"); seq_printf(m, "power level avg sclk: %u mclk: %u\n", sclk, mclk); + seq_printf(m, "GPU load: %u %%\n", activity_percent); } static void ci_dpm_print_power_state(struct amdgpu_device *adev, @@ -6569,12 +6579,12 @@ static int ci_dpm_set_interrupt_state(struct amdgpu_device *adev, switch (state) { case AMDGPU_IRQ_STATE_DISABLE: cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); - cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; + cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); break; case AMDGPU_IRQ_STATE_ENABLE: cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); - cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; + cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); break; default: @@ -6586,12 +6596,12 @@ static int ci_dpm_set_interrupt_state(struct amdgpu_device *adev, switch (state) { case AMDGPU_IRQ_STATE_DISABLE: cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); - cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; + cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); break; case AMDGPU_IRQ_STATE_ENABLE: cg_thermal_int = RREG32_SMC(ixCG_THERMAL_INT); - cg_thermal_int |= CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; + cg_thermal_int &= ~CG_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; WREG32_SMC(ixCG_THERMAL_INT, cg_thermal_int); break; default: diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 484710cfdf82..fd9c9588ef46 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c @@ -32,6 +32,7 @@ #include "amdgpu_vce.h" #include "cikd.h" #include "atom.h" +#include "amd_pcie.h" #include "cik.h" #include "gmc_v7_0.h" @@ -65,6 +66,7 @@ #include "oss/oss_2_0_sh_mask.h" #include "amdgpu_amdkfd.h" +#include "amdgpu_powerplay.h" /* * Indirect registers accessor @@ -929,6 +931,37 @@ static bool cik_read_disabled_bios(struct amdgpu_device *adev) return r; } +static bool cik_read_bios_from_rom(struct amdgpu_device *adev, + u8 *bios, u32 length_bytes) +{ + u32 *dw_ptr; + unsigned long flags; + u32 i, length_dw; + + if (bios == NULL) + return false; + if (length_bytes == 0) + return false; + /* APU vbios image is part of sbios image */ + if (adev->flags & AMD_IS_APU) + return false; + + dw_ptr = (u32 *)bios; + length_dw = ALIGN(length_bytes, 4) / 4; + /* take the smc lock since we are using the smc index */ + spin_lock_irqsave(&adev->smc_idx_lock, flags); + /* set rom index to 0 */ + WREG32(mmSMC_IND_INDEX_0, ixROM_INDEX); + WREG32(mmSMC_IND_DATA_0, 0); + /* set index to data for continous read */ + WREG32(mmSMC_IND_INDEX_0, ixROM_DATA); + for (i = 0; i < length_dw; i++) + dw_ptr[i] = RREG32(mmSMC_IND_DATA_0); + spin_unlock_irqrestore(&adev->smc_idx_lock, flags); + + return true; +} + static struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { {mmGRBM_STATUS, false}, {mmGB_ADDR_CONFIG, false}, @@ -1563,8 +1596,8 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) { struct pci_dev *root = adev->pdev->bus->self; int bridge_pos, gpu_pos; - u32 speed_cntl, mask, current_data_rate; - int ret, i; + u32 speed_cntl, current_data_rate; + int i; u16 tmp16; if (pci_is_root_bus(adev->pdev->bus)) @@ -1576,23 +1609,20 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) if (adev->flags & AMD_IS_APU) return; - ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); - if (ret != 0) - return; - - if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80))) + if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) return; speed_cntl = RREG32_PCIE(ixPCIE_LC_SPEED_CNTL); current_data_rate = (speed_cntl & PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) >> PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; - if (mask & DRM_PCIE_SPEED_80) { + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) { if (current_data_rate == 2) { DRM_INFO("PCIE gen 3 link speeds already enabled\n"); return; } DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n"); - } else if (mask & DRM_PCIE_SPEED_50) { + } else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) { if (current_data_rate == 1) { DRM_INFO("PCIE gen 2 link speeds already enabled\n"); return; @@ -1608,7 +1638,7 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) if (!gpu_pos) return; - if (mask & DRM_PCIE_SPEED_80) { + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) { /* re-try equalization if gen3 is not already enabled */ if (current_data_rate != 2) { u16 bridge_cfg, gpu_cfg; @@ -1703,9 +1733,9 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); tmp16 &= ~0xf; - if (mask & DRM_PCIE_SPEED_80) + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) tmp16 |= 3; /* gen3 */ - else if (mask & DRM_PCIE_SPEED_50) + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) tmp16 |= 2; /* gen2 */ else tmp16 |= 1; /* gen1 */ @@ -1922,7 +1952,7 @@ static const struct amdgpu_ip_block_version bonaire_ip_blocks[] = .major = 7, .minor = 0, .rev = 0, - .funcs = &ci_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -1990,7 +2020,7 @@ static const struct amdgpu_ip_block_version hawaii_ip_blocks[] = .major = 7, .minor = 0, .rev = 0, - .funcs = &ci_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -2058,7 +2088,7 @@ static const struct amdgpu_ip_block_version kabini_ip_blocks[] = .major = 7, .minor = 0, .rev = 0, - .funcs = &kv_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -2126,7 +2156,7 @@ static const struct amdgpu_ip_block_version mullins_ip_blocks[] = .major = 7, .minor = 0, .rev = 0, - .funcs = &kv_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -2194,7 +2224,7 @@ static const struct amdgpu_ip_block_version kaveri_ip_blocks[] = .major = 7, .minor = 0, .rev = 0, - .funcs = &kv_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -2267,6 +2297,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) static const struct amdgpu_asic_funcs cik_asic_funcs = { .read_disabled_bios = &cik_read_disabled_bios, + .read_bios_from_rom = &cik_read_bios_from_rom, .read_register = &cik_read_register, .reset = &cik_asic_reset, .set_vga_state = &cik_vga_set_state, @@ -2417,6 +2448,8 @@ static int cik_common_early_init(void *handle) return -EINVAL; } + amdgpu_get_pcie_info(adev); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c index 8993c50cb89f..30c9b3beeef9 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c @@ -274,6 +274,11 @@ static void cik_ih_set_rptr(struct amdgpu_device *adev) static int cik_ih_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int ret; + + ret = amdgpu_irq_add_domain(adev); + if (ret) + return ret; cik_ih_set_interrupt_funcs(adev); @@ -300,6 +305,7 @@ static int cik_ih_sw_fini(void *handle) amdgpu_irq_fini(adev); amdgpu_ih_ring_fini(adev); + amdgpu_irq_remove_domain(adev); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index 8035d4d6a4f5..4dd17f2dd905 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c @@ -1078,6 +1078,37 @@ static uint32_t cz_get_eclk_level(struct amdgpu_device *adev, return i; } +static uint32_t cz_get_uvd_level(struct amdgpu_device *adev, + uint32_t clock, uint16_t msg) +{ + int i = 0; + struct amdgpu_uvd_clock_voltage_dependency_table *table = + &adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table; + + switch (msg) { + case PPSMC_MSG_SetUvdSoftMin: + case PPSMC_MSG_SetUvdHardMin: + for (i = 0; i < table->count; i++) + if (clock <= table->entries[i].vclk) + break; + if (i == table->count) + i = table->count - 1; + break; + case PPSMC_MSG_SetUvdSoftMax: + case PPSMC_MSG_SetUvdHardMax: + for (i = table->count - 1; i >= 0; i--) + if (clock >= table->entries[i].vclk) + break; + if (i < 0) + i = 0; + break; + default: + break; + } + + return i; +} + static int cz_program_bootup_state(struct amdgpu_device *adev) { struct cz_power_info *pi = cz_get_pi(adev); @@ -1739,6 +1770,200 @@ static int cz_dpm_unforce_dpm_levels(struct amdgpu_device *adev) return 0; } +static int cz_dpm_uvd_force_highest(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + int ret = 0; + + if (pi->uvd_dpm.soft_min_clk != pi->uvd_dpm.soft_max_clk) { + pi->uvd_dpm.soft_min_clk = + pi->uvd_dpm.soft_max_clk; + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetUvdSoftMin, + cz_get_uvd_level(adev, + pi->uvd_dpm.soft_min_clk, + PPSMC_MSG_SetUvdSoftMin)); + if (ret) + return ret; + } + + return ret; +} + +static int cz_dpm_uvd_force_lowest(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + int ret = 0; + + if (pi->uvd_dpm.soft_max_clk != pi->uvd_dpm.soft_min_clk) { + pi->uvd_dpm.soft_max_clk = pi->uvd_dpm.soft_min_clk; + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetUvdSoftMax, + cz_get_uvd_level(adev, + pi->uvd_dpm.soft_max_clk, + PPSMC_MSG_SetUvdSoftMax)); + if (ret) + return ret; + } + + return ret; +} + +static uint32_t cz_dpm_get_max_uvd_level(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + + if (!pi->max_uvd_level) { + cz_send_msg_to_smc(adev, PPSMC_MSG_GetMaxUvdLevel); + pi->max_uvd_level = cz_get_argument(adev) + 1; + } + + if (pi->max_uvd_level > CZ_MAX_HARDWARE_POWERLEVELS) { + DRM_ERROR("Invalid max uvd level!\n"); + return -EINVAL; + } + + return pi->max_uvd_level; +} + +static int cz_dpm_unforce_uvd_dpm_levels(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + struct amdgpu_uvd_clock_voltage_dependency_table *dep_table = + &adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table; + uint32_t level = 0; + int ret = 0; + + pi->uvd_dpm.soft_min_clk = dep_table->entries[0].vclk; + level = cz_dpm_get_max_uvd_level(adev) - 1; + if (level < dep_table->count) + pi->uvd_dpm.soft_max_clk = dep_table->entries[level].vclk; + else + pi->uvd_dpm.soft_max_clk = + dep_table->entries[dep_table->count - 1].vclk; + + /* get min/max sclk soft value + * notify SMU to execute */ + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetUvdSoftMin, + cz_get_uvd_level(adev, + pi->uvd_dpm.soft_min_clk, + PPSMC_MSG_SetUvdSoftMin)); + if (ret) + return ret; + + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetUvdSoftMax, + cz_get_uvd_level(adev, + pi->uvd_dpm.soft_max_clk, + PPSMC_MSG_SetUvdSoftMax)); + if (ret) + return ret; + + DRM_DEBUG("DPM uvd unforce state min=%d, max=%d.\n", + pi->uvd_dpm.soft_min_clk, + pi->uvd_dpm.soft_max_clk); + + return 0; +} + +static int cz_dpm_vce_force_highest(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + int ret = 0; + + if (pi->vce_dpm.soft_min_clk != pi->vce_dpm.soft_max_clk) { + pi->vce_dpm.soft_min_clk = + pi->vce_dpm.soft_max_clk; + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetEclkSoftMin, + cz_get_eclk_level(adev, + pi->vce_dpm.soft_min_clk, + PPSMC_MSG_SetEclkSoftMin)); + if (ret) + return ret; + } + + return ret; +} + +static int cz_dpm_vce_force_lowest(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + int ret = 0; + + if (pi->vce_dpm.soft_max_clk != pi->vce_dpm.soft_min_clk) { + pi->vce_dpm.soft_max_clk = pi->vce_dpm.soft_min_clk; + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetEclkSoftMax, + cz_get_uvd_level(adev, + pi->vce_dpm.soft_max_clk, + PPSMC_MSG_SetEclkSoftMax)); + if (ret) + return ret; + } + + return ret; +} + +static uint32_t cz_dpm_get_max_vce_level(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + + if (!pi->max_vce_level) { + cz_send_msg_to_smc(adev, PPSMC_MSG_GetMaxEclkLevel); + pi->max_vce_level = cz_get_argument(adev) + 1; + } + + if (pi->max_vce_level > CZ_MAX_HARDWARE_POWERLEVELS) { + DRM_ERROR("Invalid max vce level!\n"); + return -EINVAL; + } + + return pi->max_vce_level; +} + +static int cz_dpm_unforce_vce_dpm_levels(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + struct amdgpu_vce_clock_voltage_dependency_table *dep_table = + &adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; + uint32_t level = 0; + int ret = 0; + + pi->vce_dpm.soft_min_clk = dep_table->entries[0].ecclk; + level = cz_dpm_get_max_vce_level(adev) - 1; + if (level < dep_table->count) + pi->vce_dpm.soft_max_clk = dep_table->entries[level].ecclk; + else + pi->vce_dpm.soft_max_clk = + dep_table->entries[dep_table->count - 1].ecclk; + + /* get min/max sclk soft value + * notify SMU to execute */ + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetEclkSoftMin, + cz_get_eclk_level(adev, + pi->vce_dpm.soft_min_clk, + PPSMC_MSG_SetEclkSoftMin)); + if (ret) + return ret; + + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetEclkSoftMax, + cz_get_eclk_level(adev, + pi->vce_dpm.soft_max_clk, + PPSMC_MSG_SetEclkSoftMax)); + if (ret) + return ret; + + DRM_DEBUG("DPM vce unforce state min=%d, max=%d.\n", + pi->vce_dpm.soft_min_clk, + pi->vce_dpm.soft_max_clk); + + return 0; +} + static int cz_dpm_force_dpm_level(struct amdgpu_device *adev, enum amdgpu_dpm_forced_level level) { @@ -1746,25 +1971,70 @@ static int cz_dpm_force_dpm_level(struct amdgpu_device *adev, switch (level) { case AMDGPU_DPM_FORCED_LEVEL_HIGH: + /* sclk */ ret = cz_dpm_unforce_dpm_levels(adev); if (ret) return ret; ret = cz_dpm_force_highest(adev); if (ret) return ret; + + /* uvd */ + ret = cz_dpm_unforce_uvd_dpm_levels(adev); + if (ret) + return ret; + ret = cz_dpm_uvd_force_highest(adev); + if (ret) + return ret; + + /* vce */ + ret = cz_dpm_unforce_vce_dpm_levels(adev); + if (ret) + return ret; + ret = cz_dpm_vce_force_highest(adev); + if (ret) + return ret; break; case AMDGPU_DPM_FORCED_LEVEL_LOW: + /* sclk */ ret = cz_dpm_unforce_dpm_levels(adev); if (ret) return ret; ret = cz_dpm_force_lowest(adev); if (ret) return ret; + + /* uvd */ + ret = cz_dpm_unforce_uvd_dpm_levels(adev); + if (ret) + return ret; + ret = cz_dpm_uvd_force_lowest(adev); + if (ret) + return ret; + + /* vce */ + ret = cz_dpm_unforce_vce_dpm_levels(adev); + if (ret) + return ret; + ret = cz_dpm_vce_force_lowest(adev); + if (ret) + return ret; break; case AMDGPU_DPM_FORCED_LEVEL_AUTO: + /* sclk */ ret = cz_dpm_unforce_dpm_levels(adev); if (ret) return ret; + + /* uvd */ + ret = cz_dpm_unforce_uvd_dpm_levels(adev); + if (ret) + return ret; + + /* vce */ + ret = cz_dpm_unforce_vce_dpm_levels(adev); + if (ret) + return ret; break; default: break; @@ -1905,7 +2175,8 @@ static int cz_update_vce_dpm(struct amdgpu_device *adev) pi->vce_dpm.hard_min_clk = table->entries[table->count-1].ecclk; } else { /* non-stable p-state cases. without vce.Arbiter.EcclkHardMin */ - pi->vce_dpm.hard_min_clk = table->entries[0].ecclk; + /* leave it as set by user */ + /*pi->vce_dpm.hard_min_clk = table->entries[0].ecclk;*/ } cz_send_msg_to_smc_with_parameter(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.h b/drivers/gpu/drm/amd/amdgpu/cz_dpm.h index 99e1afc89629..5df8c1faab51 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.h @@ -183,6 +183,8 @@ struct cz_power_info { uint32_t voltage_drop_threshold; uint32_t gfx_pg_threshold; uint32_t max_sclk_level; + uint32_t max_uvd_level; + uint32_t max_vce_level; /* flags */ bool didt_enabled; bool video_start; diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c index bc751bfbcae2..c79638f8e732 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c @@ -253,8 +253,14 @@ static void cz_ih_set_rptr(struct amdgpu_device *adev) static int cz_ih_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int ret; + + ret = amdgpu_irq_add_domain(adev); + if (ret) + return ret; cz_ih_set_interrupt_funcs(adev); + return 0; } @@ -278,6 +284,7 @@ static int cz_ih_sw_fini(void *handle) amdgpu_irq_fini(adev); amdgpu_ih_ring_fini(adev); + amdgpu_irq_remove_domain(adev); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ppsmc.h b/drivers/gpu/drm/amd/amdgpu/cz_ppsmc.h deleted file mode 100644 index 273616ab43db..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/cz_ppsmc.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2014 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef CZ_PP_SMC_H -#define CZ_PP_SMC_H - -#pragma pack(push, 1) - -/* Fan control algorithm:*/ -#define FDO_MODE_HARDWARE 0 -#define FDO_MODE_PIECE_WISE_LINEAR 1 - -enum FAN_CONTROL { - FAN_CONTROL_FUZZY, - FAN_CONTROL_TABLE -}; - -enum DPM_ARRAY { - DPM_ARRAY_HARD_MAX, - DPM_ARRAY_HARD_MIN, - DPM_ARRAY_SOFT_MAX, - DPM_ARRAY_SOFT_MIN -}; - -/* - * Return codes for driver to SMC communication. - * Leave these #define-s, enums might not be exactly 8-bits on the microcontroller. - */ -#define PPSMC_Result_OK ((uint16_t)0x01) -#define PPSMC_Result_NoMore ((uint16_t)0x02) -#define PPSMC_Result_NotNow ((uint16_t)0x03) -#define PPSMC_Result_Failed ((uint16_t)0xFF) -#define PPSMC_Result_UnknownCmd ((uint16_t)0xFE) -#define PPSMC_Result_UnknownVT ((uint16_t)0xFD) - -#define PPSMC_isERROR(x) ((uint16_t)0x80 & (x)) - -/* - * Supported driver messages - */ -#define PPSMC_MSG_Test ((uint16_t) 0x1) -#define PPSMC_MSG_GetFeatureStatus ((uint16_t) 0x2) -#define PPSMC_MSG_EnableAllSmuFeatures ((uint16_t) 0x3) -#define PPSMC_MSG_DisableAllSmuFeatures ((uint16_t) 0x4) -#define PPSMC_MSG_OptimizeBattery ((uint16_t) 0x5) -#define PPSMC_MSG_MaximizePerf ((uint16_t) 0x6) -#define PPSMC_MSG_UVDPowerOFF ((uint16_t) 0x7) -#define PPSMC_MSG_UVDPowerON ((uint16_t) 0x8) -#define PPSMC_MSG_VCEPowerOFF ((uint16_t) 0x9) -#define PPSMC_MSG_VCEPowerON ((uint16_t) 0xA) -#define PPSMC_MSG_ACPPowerOFF ((uint16_t) 0xB) -#define PPSMC_MSG_ACPPowerON ((uint16_t) 0xC) -#define PPSMC_MSG_SDMAPowerOFF ((uint16_t) 0xD) -#define PPSMC_MSG_SDMAPowerON ((uint16_t) 0xE) -#define PPSMC_MSG_XDMAPowerOFF ((uint16_t) 0xF) -#define PPSMC_MSG_XDMAPowerON ((uint16_t) 0x10) -#define PPSMC_MSG_SetMinDeepSleepSclk ((uint16_t) 0x11) -#define PPSMC_MSG_SetSclkSoftMin ((uint16_t) 0x12) -#define PPSMC_MSG_SetSclkSoftMax ((uint16_t) 0x13) -#define PPSMC_MSG_SetSclkHardMin ((uint16_t) 0x14) -#define PPSMC_MSG_SetSclkHardMax ((uint16_t) 0x15) -#define PPSMC_MSG_SetLclkSoftMin ((uint16_t) 0x16) -#define PPSMC_MSG_SetLclkSoftMax ((uint16_t) 0x17) -#define PPSMC_MSG_SetLclkHardMin ((uint16_t) 0x18) -#define PPSMC_MSG_SetLclkHardMax ((uint16_t) 0x19) -#define PPSMC_MSG_SetUvdSoftMin ((uint16_t) 0x1A) -#define PPSMC_MSG_SetUvdSoftMax ((uint16_t) 0x1B) -#define PPSMC_MSG_SetUvdHardMin ((uint16_t) 0x1C) -#define PPSMC_MSG_SetUvdHardMax ((uint16_t) 0x1D) -#define PPSMC_MSG_SetEclkSoftMin ((uint16_t) 0x1E) -#define PPSMC_MSG_SetEclkSoftMax ((uint16_t) 0x1F) -#define PPSMC_MSG_SetEclkHardMin ((uint16_t) 0x20) -#define PPSMC_MSG_SetEclkHardMax ((uint16_t) 0x21) -#define PPSMC_MSG_SetAclkSoftMin ((uint16_t) 0x22) -#define PPSMC_MSG_SetAclkSoftMax ((uint16_t) 0x23) -#define PPSMC_MSG_SetAclkHardMin ((uint16_t) 0x24) -#define PPSMC_MSG_SetAclkHardMax ((uint16_t) 0x25) -#define PPSMC_MSG_SetNclkSoftMin ((uint16_t) 0x26) -#define PPSMC_MSG_SetNclkSoftMax ((uint16_t) 0x27) -#define PPSMC_MSG_SetNclkHardMin ((uint16_t) 0x28) -#define PPSMC_MSG_SetNclkHardMax ((uint16_t) 0x29) -#define PPSMC_MSG_SetPstateSoftMin ((uint16_t) 0x2A) -#define PPSMC_MSG_SetPstateSoftMax ((uint16_t) 0x2B) -#define PPSMC_MSG_SetPstateHardMin ((uint16_t) 0x2C) -#define PPSMC_MSG_SetPstateHardMax ((uint16_t) 0x2D) -#define PPSMC_MSG_DisableLowMemoryPstate ((uint16_t) 0x2E) -#define PPSMC_MSG_EnableLowMemoryPstate ((uint16_t) 0x2F) -#define PPSMC_MSG_UcodeAddressLow ((uint16_t) 0x30) -#define PPSMC_MSG_UcodeAddressHigh ((uint16_t) 0x31) -#define PPSMC_MSG_UcodeLoadStatus ((uint16_t) 0x32) -#define PPSMC_MSG_DriverDramAddrHi ((uint16_t) 0x33) -#define PPSMC_MSG_DriverDramAddrLo ((uint16_t) 0x34) -#define PPSMC_MSG_CondExecDramAddrHi ((uint16_t) 0x35) -#define PPSMC_MSG_CondExecDramAddrLo ((uint16_t) 0x36) -#define PPSMC_MSG_LoadUcodes ((uint16_t) 0x37) -#define PPSMC_MSG_DriverResetMode ((uint16_t) 0x38) -#define PPSMC_MSG_PowerStateNotify ((uint16_t) 0x39) -#define PPSMC_MSG_SetDisplayPhyConfig ((uint16_t) 0x3A) -#define PPSMC_MSG_GetMaxSclkLevel ((uint16_t) 0x3B) -#define PPSMC_MSG_GetMaxLclkLevel ((uint16_t) 0x3C) -#define PPSMC_MSG_GetMaxUvdLevel ((uint16_t) 0x3D) -#define PPSMC_MSG_GetMaxEclkLevel ((uint16_t) 0x3E) -#define PPSMC_MSG_GetMaxAclkLevel ((uint16_t) 0x3F) -#define PPSMC_MSG_GetMaxNclkLevel ((uint16_t) 0x40) -#define PPSMC_MSG_GetMaxPstate ((uint16_t) 0x41) -#define PPSMC_MSG_DramAddrHiVirtual ((uint16_t) 0x42) -#define PPSMC_MSG_DramAddrLoVirtual ((uint16_t) 0x43) -#define PPSMC_MSG_DramAddrHiPhysical ((uint16_t) 0x44) -#define PPSMC_MSG_DramAddrLoPhysical ((uint16_t) 0x45) -#define PPSMC_MSG_DramBufferSize ((uint16_t) 0x46) -#define PPSMC_MSG_SetMmPwrLogDramAddrHi ((uint16_t) 0x47) -#define PPSMC_MSG_SetMmPwrLogDramAddrLo ((uint16_t) 0x48) -#define PPSMC_MSG_SetClkTableAddrHi ((uint16_t) 0x49) -#define PPSMC_MSG_SetClkTableAddrLo ((uint16_t) 0x4A) -#define PPSMC_MSG_GetConservativePowerLimit ((uint16_t) 0x4B) - -#define PPSMC_MSG_InitJobs ((uint16_t) 0x252) -#define PPSMC_MSG_ExecuteJob ((uint16_t) 0x254) - -#define PPSMC_MSG_NBDPM_Enable ((uint16_t) 0x140) -#define PPSMC_MSG_NBDPM_Disable ((uint16_t) 0x141) - -#define PPSMC_MSG_DPM_FPS_Mode ((uint16_t) 0x15d) -#define PPSMC_MSG_DPM_Activity_Mode ((uint16_t) 0x15e) - -#define PPSMC_MSG_PmStatusLogStart ((uint16_t) 0x170) -#define PPSMC_MSG_PmStatusLogSample ((uint16_t) 0x171) - -#define PPSMC_MSG_AllowLowSclkInterrupt ((uint16_t) 0x184) -#define PPSMC_MSG_MmPowerMonitorStart ((uint16_t) 0x18F) -#define PPSMC_MSG_MmPowerMonitorStop ((uint16_t) 0x190) -#define PPSMC_MSG_MmPowerMonitorRestart ((uint16_t) 0x191) - -#define PPSMC_MSG_SetClockGateMask ((uint16_t) 0x260) -#define PPSMC_MSG_SetFpsThresholdLo ((uint16_t) 0x264) -#define PPSMC_MSG_SetFpsThresholdHi ((uint16_t) 0x265) -#define PPSMC_MSG_SetLowSclkIntrThreshold ((uint16_t) 0x266) - -#define PPSMC_MSG_ClkTableXferToDram ((uint16_t) 0x267) -#define PPSMC_MSG_ClkTableXferToSmu ((uint16_t) 0x268) -#define PPSMC_MSG_GetAverageGraphicsActivity ((uint16_t) 0x269) -#define PPSMC_MSG_GetAverageGioActivity ((uint16_t) 0x26A) -#define PPSMC_MSG_SetLoggerBufferSize ((uint16_t) 0x26B) -#define PPSMC_MSG_SetLoggerAddressHigh ((uint16_t) 0x26C) -#define PPSMC_MSG_SetLoggerAddressLow ((uint16_t) 0x26D) -#define PPSMC_MSG_SetWatermarkFrequency ((uint16_t) 0x26E) - -/* REMOVE LATER*/ -#define PPSMC_MSG_DPM_ForceState ((uint16_t) 0x104) - -/* Feature Enable Masks*/ -#define NB_DPM_MASK 0x00000800 -#define VDDGFX_MASK 0x00800000 -#define VCE_DPM_MASK 0x00400000 -#define ACP_DPM_MASK 0x00040000 -#define UVD_DPM_MASK 0x00010000 -#define GFX_CU_PG_MASK 0x00004000 -#define SCLK_DPM_MASK 0x00080000 - -#if !defined(SMC_MICROCODE) -#pragma pack(pop) - -#endif - -#endif diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index cb0f7747e3dc..093599aba64b 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -1250,7 +1250,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, u32 pixel_period; u32 line_time = 0; u32 latency_watermark_a = 0, latency_watermark_b = 0; - u32 tmp, wm_mask; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { pixel_period = 1000000 / (u32)mode->clock; @@ -1333,6 +1333,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, (adev->mode_info.disp_priority == 2)) { DRM_DEBUG_KMS("force priority to high\n"); } + lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); } /* select wm A */ @@ -1357,6 +1358,8 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, amdgpu_crtc->line_time = line_time; amdgpu_crtc->wm_high = latency_watermark_a; amdgpu_crtc->wm_low = latency_watermark_b; + /* Save number of lines the linebuffer leads before the scanout */ + amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; } /** @@ -3726,7 +3729,7 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev, case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); drm_encoder_helper_add(encoder, &dce_v10_0_dac_helper_funcs); break; case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: @@ -3737,15 +3740,15 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev, if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { amdgpu_encoder->rmx_type = RMX_FULL; drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_LVDS, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_lcd_info(amdgpu_encoder); } else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder); } else { drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs, - DRM_MODE_ENCODER_TMDS); + DRM_MODE_ENCODER_TMDS, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder); } drm_encoder_helper_add(encoder, &dce_v10_0_dig_helper_funcs); @@ -3763,13 +3766,13 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev, amdgpu_encoder->is_ext_encoder = true; if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_LVDS, NULL); else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); else drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs, - DRM_MODE_ENCODER_TMDS); + DRM_MODE_ENCODER_TMDS, NULL); drm_encoder_helper_add(encoder, &dce_v10_0_ext_helper_funcs); break; } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 5af3721851d6..8e67249d4367 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -211,9 +211,9 @@ static bool dce_v11_0_is_counter_moving(struct amdgpu_device *adev, int crtc) */ static void dce_v11_0_vblank_wait(struct amdgpu_device *adev, int crtc) { - unsigned i = 0; + unsigned i = 100; - if (crtc >= adev->mode_info.num_crtc) + if (crtc < 0 || crtc >= adev->mode_info.num_crtc) return; if (!(RREG32(mmCRTC_CONTROL + crtc_offsets[crtc]) & CRTC_CONTROL__CRTC_MASTER_EN_MASK)) @@ -223,14 +223,16 @@ static void dce_v11_0_vblank_wait(struct amdgpu_device *adev, int crtc) * wait for another frame. */ while (dce_v11_0_is_in_vblank(adev, crtc)) { - if (i++ % 100 == 0) { + if (i++ == 100) { + i = 0; if (!dce_v11_0_is_counter_moving(adev, crtc)) break; } } while (!dce_v11_0_is_in_vblank(adev, crtc)) { - if (i++ % 100 == 0) { + if (i++ == 100) { + i = 0; if (!dce_v11_0_is_counter_moving(adev, crtc)) break; } @@ -239,7 +241,7 @@ static void dce_v11_0_vblank_wait(struct amdgpu_device *adev, int crtc) static u32 dce_v11_0_vblank_get_counter(struct amdgpu_device *adev, int crtc) { - if (crtc >= adev->mode_info.num_crtc) + if (crtc < 0 || crtc >= adev->mode_info.num_crtc) return 0; else return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]); @@ -1238,7 +1240,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, u32 pixel_period; u32 line_time = 0; u32 latency_watermark_a = 0, latency_watermark_b = 0; - u32 tmp, wm_mask; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { pixel_period = 1000000 / (u32)mode->clock; @@ -1321,6 +1323,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, (adev->mode_info.disp_priority == 2)) { DRM_DEBUG_KMS("force priority to high\n"); } + lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); } /* select wm A */ @@ -1345,6 +1348,8 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, amdgpu_crtc->line_time = line_time; amdgpu_crtc->wm_high = latency_watermark_a; amdgpu_crtc->wm_low = latency_watermark_b; + /* Save number of lines the linebuffer leads before the scanout */ + amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; } /** @@ -3381,7 +3386,7 @@ static void dce_v11_0_crtc_vblank_int_ack(struct amdgpu_device *adev, { u32 tmp; - if (crtc >= adev->mode_info.num_crtc) { + if (crtc < 0 || crtc >= adev->mode_info.num_crtc) { DRM_DEBUG("invalid crtc %d\n", crtc); return; } @@ -3396,7 +3401,7 @@ static void dce_v11_0_crtc_vline_int_ack(struct amdgpu_device *adev, { u32 tmp; - if (crtc >= adev->mode_info.num_crtc) { + if (crtc < 0 || crtc >= adev->mode_info.num_crtc) { DRM_DEBUG("invalid crtc %d\n", crtc); return; } @@ -3719,7 +3724,7 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev, case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); drm_encoder_helper_add(encoder, &dce_v11_0_dac_helper_funcs); break; case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: @@ -3730,15 +3735,15 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev, if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { amdgpu_encoder->rmx_type = RMX_FULL; drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_LVDS, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_lcd_info(amdgpu_encoder); } else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder); } else { drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs, - DRM_MODE_ENCODER_TMDS); + DRM_MODE_ENCODER_TMDS, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder); } drm_encoder_helper_add(encoder, &dce_v11_0_dig_helper_funcs); @@ -3756,13 +3761,13 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev, amdgpu_encoder->is_ext_encoder = true; if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_LVDS, NULL); else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); else drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs, - DRM_MODE_ENCODER_TMDS); + DRM_MODE_ENCODER_TMDS, NULL); drm_encoder_helper_add(encoder, &dce_v11_0_ext_helper_funcs); break; } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 4f7b49a6dc50..d0e128c24813 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -1193,7 +1193,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, u32 pixel_period; u32 line_time = 0; u32 latency_watermark_a = 0, latency_watermark_b = 0; - u32 tmp, wm_mask; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { pixel_period = 1000000 / (u32)mode->clock; @@ -1276,6 +1276,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, (adev->mode_info.disp_priority == 2)) { DRM_DEBUG_KMS("force priority to high\n"); } + lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); } /* select wm A */ @@ -1302,6 +1303,8 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, amdgpu_crtc->line_time = line_time; amdgpu_crtc->wm_high = latency_watermark_a; amdgpu_crtc->wm_low = latency_watermark_b; + /* Save number of lines the linebuffer leads before the scanout */ + amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; } /** @@ -3656,7 +3659,7 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev, case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); drm_encoder_helper_add(encoder, &dce_v8_0_dac_helper_funcs); break; case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: @@ -3667,15 +3670,15 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev, if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { amdgpu_encoder->rmx_type = RMX_FULL; drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_LVDS, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_lcd_info(amdgpu_encoder); } else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder); } else { drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs, - DRM_MODE_ENCODER_TMDS); + DRM_MODE_ENCODER_TMDS, NULL); amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder); } drm_encoder_helper_add(encoder, &dce_v8_0_dig_helper_funcs); @@ -3693,13 +3696,13 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev, amdgpu_encoder->is_ext_encoder = true; if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_LVDS, NULL); else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs, - DRM_MODE_ENCODER_DAC); + DRM_MODE_ENCODER_DAC, NULL); else drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs, - DRM_MODE_ENCODER_TMDS); + DRM_MODE_ENCODER_TMDS, NULL); drm_encoder_helper_add(encoder, &dce_v8_0_ext_helper_funcs); break; } diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c index 8f9845d9a986..4b0e45a27129 100644 --- a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c @@ -24,7 +24,7 @@ #include <linux/firmware.h> #include "drmP.h" #include "amdgpu.h" -#include "fiji_smumgr.h" +#include "fiji_smum.h" MODULE_FIRMWARE("amdgpu/fiji_smc.bin"); diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_ppsmc.h b/drivers/gpu/drm/amd/amdgpu/fiji_ppsmc.h deleted file mode 100644 index 3c4824082990..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/fiji_ppsmc.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2014 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef FIJI_PP_SMC_H -#define FIJI_PP_SMC_H - -#pragma pack(push, 1) - -#define PPSMC_SWSTATE_FLAG_DC 0x01 -#define PPSMC_SWSTATE_FLAG_UVD 0x02 -#define PPSMC_SWSTATE_FLAG_VCE 0x04 - -#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL 0x00 -#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL 0x01 -#define PPSMC_THERMAL_PROTECT_TYPE_NONE 0xff - -#define PPSMC_SYSTEMFLAG_GPIO_DC 0x01 -#define PPSMC_SYSTEMFLAG_STEPVDDC 0x02 -#define PPSMC_SYSTEMFLAG_GDDR5 0x04 - -#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP 0x08 - -#define PPSMC_SYSTEMFLAG_REGULATOR_HOT 0x10 -#define PPSMC_SYSTEMFLAG_REGULATOR_HOT_ANALOG 0x20 - -#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK 0x07 -#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK 0x08 - -#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE 0x00 -#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE 0x01 - -#define PPSMC_DPM2FLAGS_TDPCLMP 0x01 -#define PPSMC_DPM2FLAGS_PWRSHFT 0x02 -#define PPSMC_DPM2FLAGS_OCP 0x04 - -#define PPSMC_DISPLAY_WATERMARK_LOW 0 -#define PPSMC_DISPLAY_WATERMARK_HIGH 1 - -#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP 0x01 -#define PPSMC_STATEFLAG_POWERBOOST 0x02 -#define PPSMC_STATEFLAG_PSKIP_ON_TDP_FAULT 0x04 -#define PPSMC_STATEFLAG_POWERSHIFT 0x08 -#define PPSMC_STATEFLAG_SLOW_READ_MARGIN 0x10 -#define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 0x20 -#define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS 0x40 - -#define FDO_MODE_HARDWARE 0 -#define FDO_MODE_PIECE_WISE_LINEAR 1 - -enum FAN_CONTROL { - FAN_CONTROL_FUZZY, - FAN_CONTROL_TABLE -}; - -//Gemini Modes -#define PPSMC_GeminiModeNone 0 //Single GPU board -#define PPSMC_GeminiModeMaster 1 //Master GPU on a Gemini board -#define PPSMC_GeminiModeSlave 2 //Slave GPU on a Gemini board - -#define PPSMC_Result_OK ((uint16_t)0x01) -#define PPSMC_Result_NoMore ((uint16_t)0x02) -#define PPSMC_Result_NotNow ((uint16_t)0x03) -#define PPSMC_Result_Failed ((uint16_t)0xFF) -#define PPSMC_Result_UnknownCmd ((uint16_t)0xFE) -#define PPSMC_Result_UnknownVT ((uint16_t)0xFD) - -typedef uint16_t PPSMC_Result; - -#define PPSMC_isERROR(x) ((uint16_t)0x80 & (x)) - -#define PPSMC_MSG_Halt ((uint16_t)0x10) -#define PPSMC_MSG_Resume ((uint16_t)0x11) -#define PPSMC_MSG_EnableDPMLevel ((uint16_t)0x12) -#define PPSMC_MSG_ZeroLevelsDisabled ((uint16_t)0x13) -#define PPSMC_MSG_OneLevelsDisabled ((uint16_t)0x14) -#define PPSMC_MSG_TwoLevelsDisabled ((uint16_t)0x15) -#define PPSMC_MSG_EnableThermalInterrupt ((uint16_t)0x16) -#define PPSMC_MSG_RunningOnAC ((uint16_t)0x17) -#define PPSMC_MSG_LevelUp ((uint16_t)0x18) -#define PPSMC_MSG_LevelDown ((uint16_t)0x19) -#define PPSMC_MSG_ResetDPMCounters ((uint16_t)0x1a) -#define PPSMC_MSG_SwitchToSwState ((uint16_t)0x20) -#define PPSMC_MSG_SwitchToSwStateLast ((uint16_t)0x3f) -#define PPSMC_MSG_SwitchToInitialState ((uint16_t)0x40) -#define PPSMC_MSG_NoForcedLevel ((uint16_t)0x41) -#define PPSMC_MSG_ForceHigh ((uint16_t)0x42) -#define PPSMC_MSG_ForceMediumOrHigh ((uint16_t)0x43) -#define PPSMC_MSG_SwitchToMinimumPower ((uint16_t)0x51) -#define PPSMC_MSG_ResumeFromMinimumPower ((uint16_t)0x52) -#define PPSMC_MSG_EnableCac ((uint16_t)0x53) -#define PPSMC_MSG_DisableCac ((uint16_t)0x54) -#define PPSMC_DPMStateHistoryStart ((uint16_t)0x55) -#define PPSMC_DPMStateHistoryStop ((uint16_t)0x56) -#define PPSMC_CACHistoryStart ((uint16_t)0x57) -#define PPSMC_CACHistoryStop ((uint16_t)0x58) -#define PPSMC_TDPClampingActive ((uint16_t)0x59) -#define PPSMC_TDPClampingInactive ((uint16_t)0x5A) -#define PPSMC_StartFanControl ((uint16_t)0x5B) -#define PPSMC_StopFanControl ((uint16_t)0x5C) -#define PPSMC_NoDisplay ((uint16_t)0x5D) -#define PPSMC_HasDisplay ((uint16_t)0x5E) -#define PPSMC_MSG_UVDPowerOFF ((uint16_t)0x60) -#define PPSMC_MSG_UVDPowerON ((uint16_t)0x61) -#define PPSMC_MSG_EnableULV ((uint16_t)0x62) -#define PPSMC_MSG_DisableULV ((uint16_t)0x63) -#define PPSMC_MSG_EnterULV ((uint16_t)0x64) -#define PPSMC_MSG_ExitULV ((uint16_t)0x65) -#define PPSMC_PowerShiftActive ((uint16_t)0x6A) -#define PPSMC_PowerShiftInactive ((uint16_t)0x6B) -#define PPSMC_OCPActive ((uint16_t)0x6C) -#define PPSMC_OCPInactive ((uint16_t)0x6D) -#define PPSMC_CACLongTermAvgEnable ((uint16_t)0x6E) -#define PPSMC_CACLongTermAvgDisable ((uint16_t)0x6F) -#define PPSMC_MSG_InferredStateSweep_Start ((uint16_t)0x70) -#define PPSMC_MSG_InferredStateSweep_Stop ((uint16_t)0x71) -#define PPSMC_MSG_SwitchToLowestInfState ((uint16_t)0x72) -#define PPSMC_MSG_SwitchToNonInfState ((uint16_t)0x73) -#define PPSMC_MSG_AllStateSweep_Start ((uint16_t)0x74) -#define PPSMC_MSG_AllStateSweep_Stop ((uint16_t)0x75) -#define PPSMC_MSG_SwitchNextLowerInfState ((uint16_t)0x76) -#define PPSMC_MSG_SwitchNextHigherInfState ((uint16_t)0x77) -#define PPSMC_MSG_MclkRetrainingTest ((uint16_t)0x78) -#define PPSMC_MSG_ForceTDPClamping ((uint16_t)0x79) -#define PPSMC_MSG_CollectCAC_PowerCorreln ((uint16_t)0x7A) -#define PPSMC_MSG_CollectCAC_WeightCalib ((uint16_t)0x7B) -#define PPSMC_MSG_CollectCAC_SQonly ((uint16_t)0x7C) -#define PPSMC_MSG_CollectCAC_TemperaturePwr ((uint16_t)0x7D) -#define PPSMC_MSG_ExtremitiesTest_Start ((uint16_t)0x7E) -#define PPSMC_MSG_ExtremitiesTest_Stop ((uint16_t)0x7F) -#define PPSMC_FlushDataCache ((uint16_t)0x80) -#define PPSMC_FlushInstrCache ((uint16_t)0x81) -#define PPSMC_MSG_SetEnabledLevels ((uint16_t)0x82) -#define PPSMC_MSG_SetForcedLevels ((uint16_t)0x83) -#define PPSMC_MSG_ResetToDefaults ((uint16_t)0x84) -#define PPSMC_MSG_SetForcedLevelsAndJump ((uint16_t)0x85) -#define PPSMC_MSG_SetCACHistoryMode ((uint16_t)0x86) -#define PPSMC_MSG_EnableDTE ((uint16_t)0x87) -#define PPSMC_MSG_DisableDTE ((uint16_t)0x88) -#define PPSMC_MSG_SmcSpaceSetAddress ((uint16_t)0x89) -#define PPSMC_MSG_SmcSpaceWriteDWordInc ((uint16_t)0x8A) -#define PPSMC_MSG_SmcSpaceWriteWordInc ((uint16_t)0x8B) -#define PPSMC_MSG_SmcSpaceWriteByteInc ((uint16_t)0x8C) - -#define PPSMC_MSG_BREAK ((uint16_t)0xF8) - -#define PPSMC_MSG_Test ((uint16_t)0x100) -#define PPSMC_MSG_DRV_DRAM_ADDR_HI ((uint16_t)0x250) -#define PPSMC_MSG_DRV_DRAM_ADDR_LO ((uint16_t)0x251) -#define PPSMC_MSG_SMU_DRAM_ADDR_HI ((uint16_t)0x252) -#define PPSMC_MSG_SMU_DRAM_ADDR_LO ((uint16_t)0x253) -#define PPSMC_MSG_LoadUcodes ((uint16_t)0x254) - -typedef uint16_t PPSMC_Msg; - -#define PPSMC_EVENT_STATUS_THERMAL 0x00000001 -#define PPSMC_EVENT_STATUS_REGULATORHOT 0x00000002 -#define PPSMC_EVENT_STATUS_DC 0x00000004 -#define PPSMC_EVENT_STATUS_GPIO17 0x00000008 - -#pragma pack(pop) - -#endif diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c index bda1249eb871..e35340afd3db 100644 --- a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c @@ -25,7 +25,7 @@ #include "drmP.h" #include "amdgpu.h" #include "fiji_ppsmc.h" -#include "fiji_smumgr.h" +#include "fiji_smum.h" #include "smu_ucode_xfer_vi.h" #include "amdgpu_ucode.h" diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smumgr.h b/drivers/gpu/drm/amd/amdgpu/fiji_smum.h index 1cef03deeac3..1cef03deeac3 100644 --- a/drivers/gpu/drm/amd/amdgpu/fiji_smumgr.h +++ b/drivers/gpu/drm/amd/amdgpu/fiji_smum.h diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 6776cf756d40..13235d84e5a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -66,6 +66,27 @@ #define MACRO_TILE_ASPECT(x) ((x) << GB_MACROTILE_MODE0__MACRO_TILE_ASPECT__SHIFT) #define NUM_BANKS(x) ((x) << GB_MACROTILE_MODE0__NUM_BANKS__SHIFT) +#define RLC_CGTT_MGCG_OVERRIDE__CPF_MASK 0x00000001L +#define RLC_CGTT_MGCG_OVERRIDE__RLC_MASK 0x00000002L +#define RLC_CGTT_MGCG_OVERRIDE__MGCG_MASK 0x00000004L +#define RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK 0x00000008L +#define RLC_CGTT_MGCG_OVERRIDE__CGLS_MASK 0x00000010L +#define RLC_CGTT_MGCG_OVERRIDE__GRBM_MASK 0x00000020L + +/* BPM SERDES CMD */ +#define SET_BPM_SERDES_CMD 1 +#define CLE_BPM_SERDES_CMD 0 + +/* BPM Register Address*/ +enum { + BPM_REG_CGLS_EN = 0, /* Enable/Disable CGLS */ + BPM_REG_CGLS_ON, /* ON/OFF CGLS: shall be controlled by RLC FW */ + BPM_REG_CGCG_OVERRIDE, /* Set/Clear CGCG Override */ + BPM_REG_MGCG_OVERRIDE, /* Set/Clear MGCG Override */ + BPM_REG_FGCG_OVERRIDE, /* Set/Clear FGCG Override */ + BPM_REG_FGCG_MAX +}; + MODULE_FIRMWARE("amdgpu/carrizo_ce.bin"); MODULE_FIRMWARE("amdgpu/carrizo_pfp.bin"); MODULE_FIRMWARE("amdgpu/carrizo_me.bin"); @@ -268,7 +289,6 @@ static const u32 fiji_mgcg_cgcg_init[] = mmCGTT_CP_CLK_CTRL, 0xffffffff, 0x00000100, mmCGTT_CPC_CLK_CTRL, 0xffffffff, 0x00000100, mmCGTT_CPF_CLK_CTRL, 0xffffffff, 0x40000100, - mmCGTT_DRM_CLK_CTRL0, 0xffffffff, 0x00600100, mmCGTT_GDS_CLK_CTRL, 0xffffffff, 0x00000100, mmCGTT_IA_CLK_CTRL, 0xffffffff, 0x06000100, mmCGTT_PA_CLK_CTRL, 0xffffffff, 0x00000100, @@ -296,10 +316,6 @@ static const u32 fiji_mgcg_cgcg_init[] = mmCGTS_SM_CTRL_REG, 0xffffffff, 0x96e00200, mmCP_RB_WPTR_POLL_CNTL, 0xffffffff, 0x00900100, mmRLC_CGCG_CGLS_CTRL, 0xffffffff, 0x0020003c, - mmPCIE_INDEX, 0xffffffff, 0x0140001c, - mmPCIE_DATA, 0x000f0000, 0x00000000, - mmCGTT_DRM_CLK_CTRL0, 0xff000fff, 0x00000100, - mmHDP_XDP_CGTT_BLK_CTRL, 0xc0000fff, 0x00000104, mmCP_MEM_SLP_CNTL, 0x00000001, 0x00000001, }; @@ -969,6 +985,322 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev) return 0; } +static const u32 vgpr_init_compute_shader[] = +{ + 0x7e000209, 0x7e020208, + 0x7e040207, 0x7e060206, + 0x7e080205, 0x7e0a0204, + 0x7e0c0203, 0x7e0e0202, + 0x7e100201, 0x7e120200, + 0x7e140209, 0x7e160208, + 0x7e180207, 0x7e1a0206, + 0x7e1c0205, 0x7e1e0204, + 0x7e200203, 0x7e220202, + 0x7e240201, 0x7e260200, + 0x7e280209, 0x7e2a0208, + 0x7e2c0207, 0x7e2e0206, + 0x7e300205, 0x7e320204, + 0x7e340203, 0x7e360202, + 0x7e380201, 0x7e3a0200, + 0x7e3c0209, 0x7e3e0208, + 0x7e400207, 0x7e420206, + 0x7e440205, 0x7e460204, + 0x7e480203, 0x7e4a0202, + 0x7e4c0201, 0x7e4e0200, + 0x7e500209, 0x7e520208, + 0x7e540207, 0x7e560206, + 0x7e580205, 0x7e5a0204, + 0x7e5c0203, 0x7e5e0202, + 0x7e600201, 0x7e620200, + 0x7e640209, 0x7e660208, + 0x7e680207, 0x7e6a0206, + 0x7e6c0205, 0x7e6e0204, + 0x7e700203, 0x7e720202, + 0x7e740201, 0x7e760200, + 0x7e780209, 0x7e7a0208, + 0x7e7c0207, 0x7e7e0206, + 0xbf8a0000, 0xbf810000, +}; + +static const u32 sgpr_init_compute_shader[] = +{ + 0xbe8a0100, 0xbe8c0102, + 0xbe8e0104, 0xbe900106, + 0xbe920108, 0xbe940100, + 0xbe960102, 0xbe980104, + 0xbe9a0106, 0xbe9c0108, + 0xbe9e0100, 0xbea00102, + 0xbea20104, 0xbea40106, + 0xbea60108, 0xbea80100, + 0xbeaa0102, 0xbeac0104, + 0xbeae0106, 0xbeb00108, + 0xbeb20100, 0xbeb40102, + 0xbeb60104, 0xbeb80106, + 0xbeba0108, 0xbebc0100, + 0xbebe0102, 0xbec00104, + 0xbec20106, 0xbec40108, + 0xbec60100, 0xbec80102, + 0xbee60004, 0xbee70005, + 0xbeea0006, 0xbeeb0007, + 0xbee80008, 0xbee90009, + 0xbefc0000, 0xbf8a0000, + 0xbf810000, 0x00000000, +}; + +static const u32 vgpr_init_regs[] = +{ + mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xffffffff, + mmCOMPUTE_RESOURCE_LIMITS, 0, + mmCOMPUTE_NUM_THREAD_X, 256*4, + mmCOMPUTE_NUM_THREAD_Y, 1, + mmCOMPUTE_NUM_THREAD_Z, 1, + mmCOMPUTE_PGM_RSRC2, 20, + mmCOMPUTE_USER_DATA_0, 0xedcedc00, + mmCOMPUTE_USER_DATA_1, 0xedcedc01, + mmCOMPUTE_USER_DATA_2, 0xedcedc02, + mmCOMPUTE_USER_DATA_3, 0xedcedc03, + mmCOMPUTE_USER_DATA_4, 0xedcedc04, + mmCOMPUTE_USER_DATA_5, 0xedcedc05, + mmCOMPUTE_USER_DATA_6, 0xedcedc06, + mmCOMPUTE_USER_DATA_7, 0xedcedc07, + mmCOMPUTE_USER_DATA_8, 0xedcedc08, + mmCOMPUTE_USER_DATA_9, 0xedcedc09, +}; + +static const u32 sgpr1_init_regs[] = +{ + mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0x0f, + mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, + mmCOMPUTE_NUM_THREAD_X, 256*5, + mmCOMPUTE_NUM_THREAD_Y, 1, + mmCOMPUTE_NUM_THREAD_Z, 1, + mmCOMPUTE_PGM_RSRC2, 20, + mmCOMPUTE_USER_DATA_0, 0xedcedc00, + mmCOMPUTE_USER_DATA_1, 0xedcedc01, + mmCOMPUTE_USER_DATA_2, 0xedcedc02, + mmCOMPUTE_USER_DATA_3, 0xedcedc03, + mmCOMPUTE_USER_DATA_4, 0xedcedc04, + mmCOMPUTE_USER_DATA_5, 0xedcedc05, + mmCOMPUTE_USER_DATA_6, 0xedcedc06, + mmCOMPUTE_USER_DATA_7, 0xedcedc07, + mmCOMPUTE_USER_DATA_8, 0xedcedc08, + mmCOMPUTE_USER_DATA_9, 0xedcedc09, +}; + +static const u32 sgpr2_init_regs[] = +{ + mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xf0, + mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, + mmCOMPUTE_NUM_THREAD_X, 256*5, + mmCOMPUTE_NUM_THREAD_Y, 1, + mmCOMPUTE_NUM_THREAD_Z, 1, + mmCOMPUTE_PGM_RSRC2, 20, + mmCOMPUTE_USER_DATA_0, 0xedcedc00, + mmCOMPUTE_USER_DATA_1, 0xedcedc01, + mmCOMPUTE_USER_DATA_2, 0xedcedc02, + mmCOMPUTE_USER_DATA_3, 0xedcedc03, + mmCOMPUTE_USER_DATA_4, 0xedcedc04, + mmCOMPUTE_USER_DATA_5, 0xedcedc05, + mmCOMPUTE_USER_DATA_6, 0xedcedc06, + mmCOMPUTE_USER_DATA_7, 0xedcedc07, + mmCOMPUTE_USER_DATA_8, 0xedcedc08, + mmCOMPUTE_USER_DATA_9, 0xedcedc09, +}; + +static const u32 sec_ded_counter_registers[] = +{ + mmCPC_EDC_ATC_CNT, + mmCPC_EDC_SCRATCH_CNT, + mmCPC_EDC_UCODE_CNT, + mmCPF_EDC_ATC_CNT, + mmCPF_EDC_ROQ_CNT, + mmCPF_EDC_TAG_CNT, + mmCPG_EDC_ATC_CNT, + mmCPG_EDC_DMA_CNT, + mmCPG_EDC_TAG_CNT, + mmDC_EDC_CSINVOC_CNT, + mmDC_EDC_RESTORE_CNT, + mmDC_EDC_STATE_CNT, + mmGDS_EDC_CNT, + mmGDS_EDC_GRBM_CNT, + mmGDS_EDC_OA_DED, + mmSPI_EDC_CNT, + mmSQC_ATC_EDC_GATCL1_CNT, + mmSQC_EDC_CNT, + mmSQ_EDC_DED_CNT, + mmSQ_EDC_INFO, + mmSQ_EDC_SEC_CNT, + mmTCC_EDC_CNT, + mmTCP_ATC_EDC_GATCL1_CNT, + mmTCP_EDC_CNT, + mmTD_EDC_CNT +}; + +static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) +{ + struct amdgpu_ring *ring = &adev->gfx.compute_ring[0]; + struct amdgpu_ib ib; + struct fence *f = NULL; + int r, i; + u32 tmp; + unsigned total_size, vgpr_offset, sgpr_offset; + u64 gpu_addr; + + /* only supported on CZ */ + if (adev->asic_type != CHIP_CARRIZO) + return 0; + + /* bail if the compute ring is not ready */ + if (!ring->ready) + return 0; + + tmp = RREG32(mmGB_EDC_MODE); + WREG32(mmGB_EDC_MODE, 0); + + total_size = + (((ARRAY_SIZE(vgpr_init_regs) / 2) * 3) + 4 + 5 + 2) * 4; + total_size += + (((ARRAY_SIZE(sgpr1_init_regs) / 2) * 3) + 4 + 5 + 2) * 4; + total_size += + (((ARRAY_SIZE(sgpr2_init_regs) / 2) * 3) + 4 + 5 + 2) * 4; + total_size = ALIGN(total_size, 256); + vgpr_offset = total_size; + total_size += ALIGN(sizeof(vgpr_init_compute_shader), 256); + sgpr_offset = total_size; + total_size += sizeof(sgpr_init_compute_shader); + + /* allocate an indirect buffer to put the commands in */ + memset(&ib, 0, sizeof(ib)); + r = amdgpu_ib_get(ring, NULL, total_size, &ib); + if (r) { + DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); + return r; + } + + /* load the compute shaders */ + for (i = 0; i < ARRAY_SIZE(vgpr_init_compute_shader); i++) + ib.ptr[i + (vgpr_offset / 4)] = vgpr_init_compute_shader[i]; + + for (i = 0; i < ARRAY_SIZE(sgpr_init_compute_shader); i++) + ib.ptr[i + (sgpr_offset / 4)] = sgpr_init_compute_shader[i]; + + /* init the ib length to 0 */ + ib.length_dw = 0; + + /* VGPR */ + /* write the register state for the compute dispatch */ + for (i = 0; i < ARRAY_SIZE(vgpr_init_regs); i += 2) { + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1); + ib.ptr[ib.length_dw++] = vgpr_init_regs[i] - PACKET3_SET_SH_REG_START; + ib.ptr[ib.length_dw++] = vgpr_init_regs[i + 1]; + } + /* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */ + gpu_addr = (ib.gpu_addr + (u64)vgpr_offset) >> 8; + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2); + ib.ptr[ib.length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; + ib.ptr[ib.length_dw++] = lower_32_bits(gpu_addr); + ib.ptr[ib.length_dw++] = upper_32_bits(gpu_addr); + + /* write dispatch packet */ + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3); + ib.ptr[ib.length_dw++] = 8; /* x */ + ib.ptr[ib.length_dw++] = 1; /* y */ + ib.ptr[ib.length_dw++] = 1; /* z */ + ib.ptr[ib.length_dw++] = + REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1); + + /* write CS partial flush packet */ + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0); + ib.ptr[ib.length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4); + + /* SGPR1 */ + /* write the register state for the compute dispatch */ + for (i = 0; i < ARRAY_SIZE(sgpr1_init_regs); i += 2) { + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1); + ib.ptr[ib.length_dw++] = sgpr1_init_regs[i] - PACKET3_SET_SH_REG_START; + ib.ptr[ib.length_dw++] = sgpr1_init_regs[i + 1]; + } + /* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */ + gpu_addr = (ib.gpu_addr + (u64)sgpr_offset) >> 8; + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2); + ib.ptr[ib.length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; + ib.ptr[ib.length_dw++] = lower_32_bits(gpu_addr); + ib.ptr[ib.length_dw++] = upper_32_bits(gpu_addr); + + /* write dispatch packet */ + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3); + ib.ptr[ib.length_dw++] = 8; /* x */ + ib.ptr[ib.length_dw++] = 1; /* y */ + ib.ptr[ib.length_dw++] = 1; /* z */ + ib.ptr[ib.length_dw++] = + REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1); + + /* write CS partial flush packet */ + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0); + ib.ptr[ib.length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4); + + /* SGPR2 */ + /* write the register state for the compute dispatch */ + for (i = 0; i < ARRAY_SIZE(sgpr2_init_regs); i += 2) { + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 1); + ib.ptr[ib.length_dw++] = sgpr2_init_regs[i] - PACKET3_SET_SH_REG_START; + ib.ptr[ib.length_dw++] = sgpr2_init_regs[i + 1]; + } + /* write the shader start address: mmCOMPUTE_PGM_LO, mmCOMPUTE_PGM_HI */ + gpu_addr = (ib.gpu_addr + (u64)sgpr_offset) >> 8; + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_SET_SH_REG, 2); + ib.ptr[ib.length_dw++] = mmCOMPUTE_PGM_LO - PACKET3_SET_SH_REG_START; + ib.ptr[ib.length_dw++] = lower_32_bits(gpu_addr); + ib.ptr[ib.length_dw++] = upper_32_bits(gpu_addr); + + /* write dispatch packet */ + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_DISPATCH_DIRECT, 3); + ib.ptr[ib.length_dw++] = 8; /* x */ + ib.ptr[ib.length_dw++] = 1; /* y */ + ib.ptr[ib.length_dw++] = 1; /* z */ + ib.ptr[ib.length_dw++] = + REG_SET_FIELD(0, COMPUTE_DISPATCH_INITIATOR, COMPUTE_SHADER_EN, 1); + + /* write CS partial flush packet */ + ib.ptr[ib.length_dw++] = PACKET3(PACKET3_EVENT_WRITE, 0); + ib.ptr[ib.length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4); + + /* shedule the ib on the ring */ + r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, &ib, 1, NULL, + AMDGPU_FENCE_OWNER_UNDEFINED, + &f); + if (r) { + DRM_ERROR("amdgpu: ib submit failed (%d).\n", r); + goto fail; + } + + /* wait for the GPU to finish processing the IB */ + r = fence_wait(f, false); + if (r) { + DRM_ERROR("amdgpu: fence wait failed (%d).\n", r); + goto fail; + } + + tmp = REG_SET_FIELD(tmp, GB_EDC_MODE, DED_MODE, 2); + tmp = REG_SET_FIELD(tmp, GB_EDC_MODE, PROP_FED, 1); + WREG32(mmGB_EDC_MODE, tmp); + + tmp = RREG32(mmCC_GC_EDC_CONFIG); + tmp = REG_SET_FIELD(tmp, CC_GC_EDC_CONFIG, DIS_EDC, 0) | 1; + WREG32(mmCC_GC_EDC_CONFIG, tmp); + + + /* read back registers to clear the counters */ + for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++) + RREG32(sec_ded_counter_registers[i]); + +fail: + fence_put(f); + amdgpu_ib_free(adev, &ib); + + return r; +} + static void gfx_v8_0_gpu_early_init(struct amdgpu_device *adev) { u32 gb_addr_config; @@ -1000,7 +1332,7 @@ static void gfx_v8_0_gpu_early_init(struct amdgpu_device *adev) adev->gfx.config.max_cu_per_sh = 16; adev->gfx.config.max_sh_per_se = 1; adev->gfx.config.max_backends_per_se = 4; - adev->gfx.config.max_texture_channel_caches = 8; + adev->gfx.config.max_texture_channel_caches = 16; adev->gfx.config.max_gprs = 256; adev->gfx.config.max_gs_threads = 32; adev->gfx.config.max_hw_contexts = 8; @@ -1328,1128 +1660,923 @@ static int gfx_v8_0_sw_fini(void *handle) static void gfx_v8_0_tiling_mode_table_init(struct amdgpu_device *adev) { - const u32 num_tile_mode_states = 32; - const u32 num_secondary_tile_mode_states = 16; - u32 reg_offset, gb_tile_moden, split_equal_to_row_size; + uint32_t *modearray, *mod2array; + const u32 num_tile_mode_states = ARRAY_SIZE(adev->gfx.config.tile_mode_array); + const u32 num_secondary_tile_mode_states = ARRAY_SIZE(adev->gfx.config.macrotile_mode_array); + u32 reg_offset; - switch (adev->gfx.config.mem_row_size_in_kb) { - case 1: - split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB; - break; - case 2: - default: - split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB; - break; - case 4: - split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB; - break; - } + modearray = adev->gfx.config.tile_mode_array; + mod2array = adev->gfx.config.macrotile_mode_array; + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + modearray[reg_offset] = 0; + + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + mod2array[reg_offset] = 0; switch (adev->asic_type) { case CHIP_TOPAZ: - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 1: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 2: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 3: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 4: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 5: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 6: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 8: - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - PIPE_CONFIG(ADDR_SURF_P2)); - break; - case 9: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 10: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 11: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 13: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 14: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 15: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 16: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 18: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 19: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 20: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 21: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 22: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 24: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 25: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 26: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 27: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 28: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 29: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 7: - case 12: - case 17: - case 23: - /* unused idx */ - continue; - default: - gb_tile_moden = 0; - break; - }; - adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden); - } - for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 1: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 2: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 3: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 4: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 5: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 6: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 8: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 9: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 10: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 11: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 12: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 13: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 14: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 7: - /* unused idx */ - continue; - default: - gb_tile_moden = 0; - break; - }; - adev->gfx.config.macrotile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); - } + modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[6] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P2)); + modearray[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[15] = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[18] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[19] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[20] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[21] = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[22] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[24] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[25] = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[26] = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + + mod2array[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + if (reg_offset != 7 && reg_offset != 12 && reg_offset != 17 && + reg_offset != 23) + WREG32(mmGB_TILE_MODE0 + reg_offset, modearray[reg_offset]); + + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + if (reg_offset != 7) + WREG32(mmGB_MACROTILE_MODE0 + reg_offset, mod2array[reg_offset]); + + break; case CHIP_FIJI: + modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[6] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[7] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16)); + modearray[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[12] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[15] = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[17] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[18] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[19] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[20] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[21] = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[22] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[23] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[24] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[25] = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[26] = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[30] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + + mod2array[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + WREG32(mmGB_TILE_MODE0 + reg_offset, modearray[reg_offset]); + + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + if (reg_offset != 7) + WREG32(mmGB_MACROTILE_MODE0 + reg_offset, mod2array[reg_offset]); + + break; case CHIP_TONGA: - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 1: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 2: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 3: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 4: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 5: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 6: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 7: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 8: - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16)); - break; - case 9: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 10: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 11: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 12: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 13: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 14: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 15: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 16: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 17: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 18: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 19: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 20: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 21: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 22: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 23: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 24: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 25: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 26: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 27: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 28: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 29: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 30: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - default: - gb_tile_moden = 0; - break; - }; - adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden); - } - for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 1: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 2: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 3: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 4: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 5: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 6: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 8: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 9: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 10: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 11: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 12: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 13: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_4_BANK)); - break; - case 14: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_4_BANK)); - break; - case 7: - /* unused idx */ - continue; - default: - gb_tile_moden = 0; - break; - }; - adev->gfx.config.macrotile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); - } + modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[6] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[7] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16)); + modearray[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[12] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[15] = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[17] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[18] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[19] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[20] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[21] = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[22] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[23] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[24] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[25] = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[26] = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[30] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + + mod2array[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + mod2array[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + WREG32(mmGB_TILE_MODE0 + reg_offset, modearray[reg_offset]); + + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + if (reg_offset != 7) + WREG32(mmGB_MACROTILE_MODE0 + reg_offset, mod2array[reg_offset]); + break; case CHIP_STONEY: - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 1: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 2: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 3: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 4: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 5: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 6: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 8: - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - PIPE_CONFIG(ADDR_SURF_P2)); - break; - case 9: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 10: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 11: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 13: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 14: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 15: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 16: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 18: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 19: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 20: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 21: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 22: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 24: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 25: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 26: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 27: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 28: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 29: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 7: - case 12: - case 17: - case 23: - /* unused idx */ - continue; - default: - gb_tile_moden = 0; - break; - }; - adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden); - } - for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 1: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 2: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 3: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 4: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 5: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 6: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 8: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 9: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 10: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 11: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 12: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 13: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 14: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 7: - /* unused idx */ - continue; - default: - gb_tile_moden = 0; - break; - }; - adev->gfx.config.macrotile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); - } + modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[6] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P2)); + modearray[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[15] = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[18] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[19] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[20] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[21] = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[22] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[24] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[25] = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[26] = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + + mod2array[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + if (reg_offset != 7 && reg_offset != 12 && reg_offset != 17 && + reg_offset != 23) + WREG32(mmGB_TILE_MODE0 + reg_offset, modearray[reg_offset]); + + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + if (reg_offset != 7) + WREG32(mmGB_MACROTILE_MODE0 + reg_offset, mod2array[reg_offset]); + break; - case CHIP_CARRIZO: default: - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 1: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 2: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 3: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 4: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 5: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 6: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 8: - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - PIPE_CONFIG(ADDR_SURF_P2)); - break; - case 9: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 10: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 11: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 13: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 14: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 15: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 16: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 18: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 19: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 20: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 21: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 22: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 24: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 25: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 26: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 27: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 28: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 29: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 7: - case 12: - case 17: - case 23: - /* unused idx */ - continue; - default: - gb_tile_moden = 0; - break; - }; - adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden); - } - for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 1: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 2: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 3: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 4: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 5: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 6: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 8: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 9: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 10: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 11: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 12: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 13: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 14: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 7: - /* unused idx */ - continue; - default: - gb_tile_moden = 0; - break; - }; - adev->gfx.config.macrotile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); - } + dev_warn(adev->dev, + "Unknown chip type (%d) in function gfx_v8_0_tiling_mode_table_init() falling through to CHIP_CARRIZO\n", + adev->asic_type); + + case CHIP_CARRIZO: + modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[6] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_2KB) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + modearray[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P2)); + modearray[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[15] = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + modearray[18] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[19] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[20] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[21] = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[22] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[24] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[25] = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[26] = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + modearray[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + modearray[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + + mod2array[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + mod2array[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + mod2array[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + if (reg_offset != 7 && reg_offset != 12 && reg_offset != 17 && + reg_offset != 23) + WREG32(mmGB_TILE_MODE0 + reg_offset, modearray[reg_offset]); + + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + if (reg_offset != 7) + WREG32(mmGB_MACROTILE_MODE0 + reg_offset, mod2array[reg_offset]); + + break; } } static u32 gfx_v8_0_create_bitmask(u32 bit_width) { - u32 i, mask = 0; - - for (i = 0; i < bit_width; i++) { - mask <<= 1; - mask |= 1; - } - return mask; + return (u32)((1ULL << bit_width) - 1); } void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num) @@ -2524,7 +2651,7 @@ static void gfx_v8_0_setup_rb(struct amdgpu_device *adev, mutex_lock(&adev->grbm_idx_mutex); for (i = 0; i < se_num; i++) { gfx_v8_0_select_se_sh(adev, i, 0xffffffff); - data = 0; + data = RREG32(mmPA_SC_RASTER_CONFIG); for (j = 0; j < sh_per_se; j++) { switch (enabled_rbs & 3) { case 0: @@ -2712,17 +2839,11 @@ static void gfx_v8_0_enable_gui_idle_interrupt(struct amdgpu_device *adev, { u32 tmp = RREG32(mmCP_INT_CNTL_RING0); - if (enable) { - tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE, 1); - tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_EMPTY_INT_ENABLE, 1); - tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CMP_BUSY_INT_ENABLE, 1); - tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, GFX_IDLE_INT_ENABLE, 1); - } else { - tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE, 0); - tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_EMPTY_INT_ENABLE, 0); - tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CMP_BUSY_INT_ENABLE, 0); - tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, GFX_IDLE_INT_ENABLE, 0); - } + tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE, enable ? 1 : 0); + tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_EMPTY_INT_ENABLE, enable ? 1 : 0); + tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CMP_BUSY_INT_ENABLE, enable ? 1 : 0); + tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, GFX_IDLE_INT_ENABLE, enable ? 1 : 0); + WREG32(mmCP_INT_CNTL_RING0, tmp); } @@ -2802,16 +2923,18 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev) gfx_v8_0_rlc_reset(adev); - if (!adev->firmware.smu_load) { - /* legacy rlc firmware loading */ - r = gfx_v8_0_rlc_load_microcode(adev); - if (r) - return r; - } else { - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_RLC_G); - if (r) - return -EINVAL; + if (!adev->pp_enabled) { + if (!adev->firmware.smu_load) { + /* legacy rlc firmware loading */ + r = gfx_v8_0_rlc_load_microcode(adev); + if (r) + return r; + } else { + r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, + AMDGPU_UCODE_ID_RLC_G); + if (r) + return -EINVAL; + } } gfx_v8_0_rlc_start(adev); @@ -2971,10 +3094,13 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) amdgpu_ring_write(ring, mmPA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START); switch (adev->asic_type) { case CHIP_TONGA: - case CHIP_FIJI: amdgpu_ring_write(ring, 0x16000012); amdgpu_ring_write(ring, 0x0000002A); break; + case CHIP_FIJI: + amdgpu_ring_write(ring, 0x3a00161a); + amdgpu_ring_write(ring, 0x0000002e); + break; case CHIP_TOPAZ: case CHIP_CARRIZO: amdgpu_ring_write(ring, 0x00000002); @@ -3653,6 +3779,11 @@ static int gfx_v8_0_cp_compute_resume(struct amdgpu_device *adev) tmp = REG_SET_FIELD(tmp, CP_HQD_PERSISTENT_STATE, PRELOAD_SIZE, 0x53); WREG32(mmCP_HQD_PERSISTENT_STATE, tmp); mqd->cp_hqd_persistent_state = tmp; + if (adev->asic_type == CHIP_STONEY) { + tmp = RREG32(mmCP_ME1_PIPE3_INT_CNTL); + tmp = REG_SET_FIELD(tmp, CP_ME1_PIPE3_INT_CNTL, GENERIC2_INT_ENABLE, 1); + WREG32(mmCP_ME1_PIPE3_INT_CNTL, tmp); + } /* activate the queue */ mqd->cp_hqd_active = 1; @@ -3694,35 +3825,37 @@ static int gfx_v8_0_cp_resume(struct amdgpu_device *adev) if (!(adev->flags & AMD_IS_APU)) gfx_v8_0_enable_gui_idle_interrupt(adev, false); - if (!adev->firmware.smu_load) { - /* legacy firmware loading */ - r = gfx_v8_0_cp_gfx_load_microcode(adev); - if (r) - return r; - - r = gfx_v8_0_cp_compute_load_microcode(adev); - if (r) - return r; - } else { - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_CE); - if (r) - return -EINVAL; - - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_PFP); - if (r) - return -EINVAL; - - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_ME); - if (r) - return -EINVAL; + if (!adev->pp_enabled) { + if (!adev->firmware.smu_load) { + /* legacy firmware loading */ + r = gfx_v8_0_cp_gfx_load_microcode(adev); + if (r) + return r; - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - AMDGPU_UCODE_ID_CP_MEC1); - if (r) - return -EINVAL; + r = gfx_v8_0_cp_compute_load_microcode(adev); + if (r) + return r; + } else { + r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, + AMDGPU_UCODE_ID_CP_CE); + if (r) + return -EINVAL; + + r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, + AMDGPU_UCODE_ID_CP_PFP); + if (r) + return -EINVAL; + + r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, + AMDGPU_UCODE_ID_CP_ME); + if (r) + return -EINVAL; + + r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, + AMDGPU_UCODE_ID_CP_MEC1); + if (r) + return -EINVAL; + } } r = gfx_v8_0_cp_gfx_resume(adev); @@ -4170,15 +4303,261 @@ static int gfx_v8_0_early_init(void *handle) return 0; } +static int gfx_v8_0_late_init(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int r; + + /* requires IBs so do in late init after IB pool is initialized */ + r = gfx_v8_0_do_edc_gpr_workarounds(adev); + if (r) + return r; + + return 0; +} + static int gfx_v8_0_set_powergating_state(void *handle, enum amd_powergating_state state) { return 0; } +static void fiji_send_serdes_cmd(struct amdgpu_device *adev, + uint32_t reg_addr, uint32_t cmd) +{ + uint32_t data; + + gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); + + WREG32(mmRLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); + WREG32(mmRLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); + + data = RREG32(mmRLC_SERDES_WR_CTRL); + data &= ~(RLC_SERDES_WR_CTRL__WRITE_COMMAND_MASK | + RLC_SERDES_WR_CTRL__READ_COMMAND_MASK | + RLC_SERDES_WR_CTRL__P1_SELECT_MASK | + RLC_SERDES_WR_CTRL__P2_SELECT_MASK | + RLC_SERDES_WR_CTRL__RDDATA_RESET_MASK | + RLC_SERDES_WR_CTRL__POWER_DOWN_MASK | + RLC_SERDES_WR_CTRL__POWER_UP_MASK | + RLC_SERDES_WR_CTRL__SHORT_FORMAT_MASK | + RLC_SERDES_WR_CTRL__BPM_DATA_MASK | + RLC_SERDES_WR_CTRL__REG_ADDR_MASK | + RLC_SERDES_WR_CTRL__SRBM_OVERRIDE_MASK); + data |= (RLC_SERDES_WR_CTRL__RSVD_BPM_ADDR_MASK | + (cmd << RLC_SERDES_WR_CTRL__BPM_DATA__SHIFT) | + (reg_addr << RLC_SERDES_WR_CTRL__REG_ADDR__SHIFT) | + (0xff << RLC_SERDES_WR_CTRL__BPM_ADDR__SHIFT)); + + WREG32(mmRLC_SERDES_WR_CTRL, data); +} + +static void fiji_update_medium_grain_clock_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + /* It is disabled by HW by default */ + if (enable) { + /* 1 - RLC memory Light sleep */ + temp = data = RREG32(mmRLC_MEM_SLP_CNTL); + data |= RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK; + if (temp != data) + WREG32(mmRLC_MEM_SLP_CNTL, data); + + /* 2 - CP memory Light sleep */ + temp = data = RREG32(mmCP_MEM_SLP_CNTL); + data |= CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK; + if (temp != data) + WREG32(mmCP_MEM_SLP_CNTL, data); + + /* 3 - RLC_CGTT_MGCG_OVERRIDE */ + temp = data = RREG32(mmRLC_CGTT_MGCG_OVERRIDE); + data &= ~(RLC_CGTT_MGCG_OVERRIDE__CPF_MASK | + RLC_CGTT_MGCG_OVERRIDE__RLC_MASK | + RLC_CGTT_MGCG_OVERRIDE__MGCG_MASK | + RLC_CGTT_MGCG_OVERRIDE__GRBM_MASK); + + if (temp != data) + WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data); + + /* 4 - wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ + gfx_v8_0_wait_for_rlc_serdes(adev); + + /* 5 - clear mgcg override */ + fiji_send_serdes_cmd(adev, BPM_REG_MGCG_OVERRIDE, CLE_BPM_SERDES_CMD); + + /* 6 - Enable CGTS(Tree Shade) MGCG /MGLS */ + temp = data = RREG32(mmCGTS_SM_CTRL_REG); + data &= ~(CGTS_SM_CTRL_REG__SM_MODE_MASK); + data |= (0x2 << CGTS_SM_CTRL_REG__SM_MODE__SHIFT); + data |= CGTS_SM_CTRL_REG__SM_MODE_ENABLE_MASK; + data &= ~CGTS_SM_CTRL_REG__OVERRIDE_MASK; + data &= ~CGTS_SM_CTRL_REG__LS_OVERRIDE_MASK; + data |= CGTS_SM_CTRL_REG__ON_MONITOR_ADD_EN_MASK; + data |= (0x96 << CGTS_SM_CTRL_REG__ON_MONITOR_ADD__SHIFT); + if (temp != data) + WREG32(mmCGTS_SM_CTRL_REG, data); + udelay(50); + + /* 7 - wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ + gfx_v8_0_wait_for_rlc_serdes(adev); + } else { + /* 1 - MGCG_OVERRIDE[0] for CP and MGCG_OVERRIDE[1] for RLC */ + temp = data = RREG32(mmRLC_CGTT_MGCG_OVERRIDE); + data |= (RLC_CGTT_MGCG_OVERRIDE__CPF_MASK | + RLC_CGTT_MGCG_OVERRIDE__RLC_MASK | + RLC_CGTT_MGCG_OVERRIDE__MGCG_MASK | + RLC_CGTT_MGCG_OVERRIDE__GRBM_MASK); + if (temp != data) + WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data); + + /* 2 - disable MGLS in RLC */ + data = RREG32(mmRLC_MEM_SLP_CNTL); + if (data & RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK) { + data &= ~RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK; + WREG32(mmRLC_MEM_SLP_CNTL, data); + } + + /* 3 - disable MGLS in CP */ + data = RREG32(mmCP_MEM_SLP_CNTL); + if (data & CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK) { + data &= ~CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK; + WREG32(mmCP_MEM_SLP_CNTL, data); + } + + /* 4 - Disable CGTS(Tree Shade) MGCG and MGLS */ + temp = data = RREG32(mmCGTS_SM_CTRL_REG); + data |= (CGTS_SM_CTRL_REG__OVERRIDE_MASK | + CGTS_SM_CTRL_REG__LS_OVERRIDE_MASK); + if (temp != data) + WREG32(mmCGTS_SM_CTRL_REG, data); + + /* 5 - wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ + gfx_v8_0_wait_for_rlc_serdes(adev); + + /* 6 - set mgcg override */ + fiji_send_serdes_cmd(adev, BPM_REG_MGCG_OVERRIDE, SET_BPM_SERDES_CMD); + + udelay(50); + + /* 7- wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ + gfx_v8_0_wait_for_rlc_serdes(adev); + } +} + +static void fiji_update_coarse_grain_clock_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, temp1, data, data1; + + temp = data = RREG32(mmRLC_CGCG_CGLS_CTRL); + + if (enable) { + /* 1 enable cntx_empty_int_enable/cntx_busy_int_enable/ + * Cmp_busy/GFX_Idle interrupts + */ + gfx_v8_0_enable_gui_idle_interrupt(adev, true); + + temp1 = data1 = RREG32(mmRLC_CGTT_MGCG_OVERRIDE); + data1 &= ~RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK; + if (temp1 != data1) + WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1); + + /* 2 wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ + gfx_v8_0_wait_for_rlc_serdes(adev); + + /* 3 - clear cgcg override */ + fiji_send_serdes_cmd(adev, BPM_REG_CGCG_OVERRIDE, CLE_BPM_SERDES_CMD); + + /* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ + gfx_v8_0_wait_for_rlc_serdes(adev); + + /* 4 - write cmd to set CGLS */ + fiji_send_serdes_cmd(adev, BPM_REG_CGLS_EN, SET_BPM_SERDES_CMD); + + /* 5 - enable cgcg */ + data |= RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK; + + /* enable cgls*/ + data |= RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK; + + temp1 = data1 = RREG32(mmRLC_CGTT_MGCG_OVERRIDE); + data1 &= ~RLC_CGTT_MGCG_OVERRIDE__CGLS_MASK; + + if (temp1 != data1) + WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1); + + if (temp != data) + WREG32(mmRLC_CGCG_CGLS_CTRL, data); + } else { + /* disable cntx_empty_int_enable & GFX Idle interrupt */ + gfx_v8_0_enable_gui_idle_interrupt(adev, false); + + /* TEST CGCG */ + temp1 = data1 = RREG32(mmRLC_CGTT_MGCG_OVERRIDE); + data1 |= (RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK | + RLC_CGTT_MGCG_OVERRIDE__CGLS_MASK); + if (temp1 != data1) + WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1); + + /* read gfx register to wake up cgcg */ + RREG32(mmCB_CGTT_SCLK_CTRL); + RREG32(mmCB_CGTT_SCLK_CTRL); + RREG32(mmCB_CGTT_SCLK_CTRL); + RREG32(mmCB_CGTT_SCLK_CTRL); + + /* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ + gfx_v8_0_wait_for_rlc_serdes(adev); + + /* write cmd to Set CGCG Overrride */ + fiji_send_serdes_cmd(adev, BPM_REG_CGCG_OVERRIDE, SET_BPM_SERDES_CMD); + + /* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ + gfx_v8_0_wait_for_rlc_serdes(adev); + + /* write cmd to Clear CGLS */ + fiji_send_serdes_cmd(adev, BPM_REG_CGLS_EN, CLE_BPM_SERDES_CMD); + + /* disable cgcg, cgls should be disabled too. */ + data &= ~(RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK | + RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK); + if (temp != data) + WREG32(mmRLC_CGCG_CGLS_CTRL, data); + } +} +static int fiji_update_gfx_clock_gating(struct amdgpu_device *adev, + bool enable) +{ + if (enable) { + /* CGCG/CGLS should be enabled after MGCG/MGLS/TS(CG/LS) + * === MGCG + MGLS + TS(CG/LS) === + */ + fiji_update_medium_grain_clock_gating(adev, enable); + fiji_update_coarse_grain_clock_gating(adev, enable); + } else { + /* CGCG/CGLS should be disabled before MGCG/MGLS/TS(CG/LS) + * === CGCG + CGLS === + */ + fiji_update_coarse_grain_clock_gating(adev, enable); + fiji_update_medium_grain_clock_gating(adev, enable); + } + return 0; +} + static int gfx_v8_0_set_clockgating_state(void *handle, enum amd_clockgating_state state) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + switch (adev->asic_type) { + case CHIP_FIJI: + fiji_update_gfx_clock_gating(adev, + state == AMD_CG_STATE_GATE ? true : false); + break; + default: + break; + } return 0; } @@ -4339,7 +4718,7 @@ static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5))); amdgpu_ring_write(ring, addr & 0xfffffffc); - amdgpu_ring_write(ring, (upper_32_bits(addr) & 0xffff) | + amdgpu_ring_write(ring, (upper_32_bits(addr) & 0xffff) | DATA_SEL(write64bit ? 2 : 1) | INT_SEL(int_sel ? 2 : 0)); amdgpu_ring_write(ring, lower_32_bits(seq)); amdgpu_ring_write(ring, upper_32_bits(seq)); @@ -4707,7 +5086,7 @@ static int gfx_v8_0_priv_inst_irq(struct amdgpu_device *adev, const struct amd_ip_funcs gfx_v8_0_ip_funcs = { .early_init = gfx_v8_0_early_init, - .late_init = NULL, + .late_init = gfx_v8_0_late_init, .sw_init = gfx_v8_0_sw_init, .sw_fini = gfx_v8_0_sw_fini, .hw_init = gfx_v8_0_hw_init, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 85bbcdc73fff..3f956065d069 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -40,7 +40,7 @@ static void gmc_v7_0_set_gart_funcs(struct amdgpu_device *adev); static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev); -MODULE_FIRMWARE("radeon/boniare_mc.bin"); +MODULE_FIRMWARE("radeon/bonaire_mc.bin"); MODULE_FIRMWARE("radeon/hawaii_mc.bin"); /** @@ -370,6 +370,10 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev) adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; adev->mc.visible_vram_size = adev->mc.aper_size; + /* In case the PCI BAR is larger than the actual amount of vram */ + if (adev->mc.visible_vram_size > adev->mc.real_vram_size) + adev->mc.visible_vram_size = adev->mc.real_vram_size; + /* unless the user had overridden it, set the gart * size equal to the 1024 or vram, whichever is larger. */ @@ -501,6 +505,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE, 1); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, EFFECTIVE_L2_QUEUE_SIZE, 7); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1); + tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1); WREG32(mmVM_L2_CNTL, tmp); tmp = REG_SET_FIELD(0, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1); @@ -512,7 +517,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) WREG32(mmVM_L2_CNTL3, tmp); /* setup context0 */ WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); - WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, (adev->mc.gtt_end >> 12) - 1); + WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12); WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, (u32)(adev->dummy_page.addr >> 12)); @@ -960,12 +965,10 @@ static int gmc_v7_0_sw_init(void *handle) static int gmc_v7_0_sw_fini(void *handle) { - int i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (adev->vm_manager.enabled) { - for (i = 0; i < AMDGPU_NUM_VM; ++i) - fence_put(adev->vm_manager.active[i]); + amdgpu_vm_manager_fini(adev); gmc_v7_0_vm_fini(adev); adev->vm_manager.enabled = false; } @@ -1010,12 +1013,9 @@ static int gmc_v7_0_hw_fini(void *handle) static int gmc_v7_0_suspend(void *handle) { - int i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (adev->vm_manager.enabled) { - for (i = 0; i < AMDGPU_NUM_VM; ++i) - fence_put(adev->vm_manager.active[i]); gmc_v7_0_vm_fini(adev); adev->vm_manager.enabled = false; } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 1bcc4e74e3b4..c0c9a0101eb4 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -476,6 +476,10 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; adev->mc.visible_vram_size = adev->mc.aper_size; + /* In case the PCI BAR is larger than the actual amount of vram */ + if (adev->mc.visible_vram_size > adev->mc.real_vram_size) + adev->mc.visible_vram_size = adev->mc.real_vram_size; + /* unless the user had overridden it, set the gart * size equal to the 1024 or vram, whichever is larger. */ @@ -629,6 +633,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE, 1); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, EFFECTIVE_L2_QUEUE_SIZE, 7); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1); + tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1); WREG32(mmVM_L2_CNTL, tmp); tmp = RREG32(mmVM_L2_CNTL2); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); @@ -656,7 +661,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) WREG32(mmVM_L2_CNTL4, tmp); /* setup context0 */ WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); - WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, (adev->mc.gtt_end >> 12) - 1); + WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12); WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, (u32)(adev->dummy_page.addr >> 12)); @@ -979,12 +984,10 @@ static int gmc_v8_0_sw_init(void *handle) static int gmc_v8_0_sw_fini(void *handle) { - int i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (adev->vm_manager.enabled) { - for (i = 0; i < AMDGPU_NUM_VM; ++i) - fence_put(adev->vm_manager.active[i]); + amdgpu_vm_manager_fini(adev); gmc_v8_0_vm_fini(adev); adev->vm_manager.enabled = false; } @@ -1031,12 +1034,9 @@ static int gmc_v8_0_hw_fini(void *handle) static int gmc_v8_0_suspend(void *handle) { - int i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (adev->vm_manager.enabled) { - for (i = 0; i < AMDGPU_NUM_VM; ++i) - fence_put(adev->vm_manager.active[i]); gmc_v8_0_vm_fini(adev); adev->vm_manager.enabled = false; } @@ -1327,9 +1327,181 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev, return 0; } +static void fiji_update_mc_medium_grain_clock_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t data; + + if (enable) { + data = RREG32(mmMC_HUB_MISC_HUB_CG); + data |= MC_HUB_MISC_HUB_CG__ENABLE_MASK; + WREG32(mmMC_HUB_MISC_HUB_CG, data); + + data = RREG32(mmMC_HUB_MISC_SIP_CG); + data |= MC_HUB_MISC_SIP_CG__ENABLE_MASK; + WREG32(mmMC_HUB_MISC_SIP_CG, data); + + data = RREG32(mmMC_HUB_MISC_VM_CG); + data |= MC_HUB_MISC_VM_CG__ENABLE_MASK; + WREG32(mmMC_HUB_MISC_VM_CG, data); + + data = RREG32(mmMC_XPB_CLK_GAT); + data |= MC_XPB_CLK_GAT__ENABLE_MASK; + WREG32(mmMC_XPB_CLK_GAT, data); + + data = RREG32(mmATC_MISC_CG); + data |= ATC_MISC_CG__ENABLE_MASK; + WREG32(mmATC_MISC_CG, data); + + data = RREG32(mmMC_CITF_MISC_WR_CG); + data |= MC_CITF_MISC_WR_CG__ENABLE_MASK; + WREG32(mmMC_CITF_MISC_WR_CG, data); + + data = RREG32(mmMC_CITF_MISC_RD_CG); + data |= MC_CITF_MISC_RD_CG__ENABLE_MASK; + WREG32(mmMC_CITF_MISC_RD_CG, data); + + data = RREG32(mmMC_CITF_MISC_VM_CG); + data |= MC_CITF_MISC_VM_CG__ENABLE_MASK; + WREG32(mmMC_CITF_MISC_VM_CG, data); + + data = RREG32(mmVM_L2_CG); + data |= VM_L2_CG__ENABLE_MASK; + WREG32(mmVM_L2_CG, data); + } else { + data = RREG32(mmMC_HUB_MISC_HUB_CG); + data &= ~MC_HUB_MISC_HUB_CG__ENABLE_MASK; + WREG32(mmMC_HUB_MISC_HUB_CG, data); + + data = RREG32(mmMC_HUB_MISC_SIP_CG); + data &= ~MC_HUB_MISC_SIP_CG__ENABLE_MASK; + WREG32(mmMC_HUB_MISC_SIP_CG, data); + + data = RREG32(mmMC_HUB_MISC_VM_CG); + data &= ~MC_HUB_MISC_VM_CG__ENABLE_MASK; + WREG32(mmMC_HUB_MISC_VM_CG, data); + + data = RREG32(mmMC_XPB_CLK_GAT); + data &= ~MC_XPB_CLK_GAT__ENABLE_MASK; + WREG32(mmMC_XPB_CLK_GAT, data); + + data = RREG32(mmATC_MISC_CG); + data &= ~ATC_MISC_CG__ENABLE_MASK; + WREG32(mmATC_MISC_CG, data); + + data = RREG32(mmMC_CITF_MISC_WR_CG); + data &= ~MC_CITF_MISC_WR_CG__ENABLE_MASK; + WREG32(mmMC_CITF_MISC_WR_CG, data); + + data = RREG32(mmMC_CITF_MISC_RD_CG); + data &= ~MC_CITF_MISC_RD_CG__ENABLE_MASK; + WREG32(mmMC_CITF_MISC_RD_CG, data); + + data = RREG32(mmMC_CITF_MISC_VM_CG); + data &= ~MC_CITF_MISC_VM_CG__ENABLE_MASK; + WREG32(mmMC_CITF_MISC_VM_CG, data); + + data = RREG32(mmVM_L2_CG); + data &= ~VM_L2_CG__ENABLE_MASK; + WREG32(mmVM_L2_CG, data); + } +} + +static void fiji_update_mc_light_sleep(struct amdgpu_device *adev, + bool enable) +{ + uint32_t data; + + if (enable) { + data = RREG32(mmMC_HUB_MISC_HUB_CG); + data |= MC_HUB_MISC_HUB_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_HUB_MISC_HUB_CG, data); + + data = RREG32(mmMC_HUB_MISC_SIP_CG); + data |= MC_HUB_MISC_SIP_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_HUB_MISC_SIP_CG, data); + + data = RREG32(mmMC_HUB_MISC_VM_CG); + data |= MC_HUB_MISC_VM_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_HUB_MISC_VM_CG, data); + + data = RREG32(mmMC_XPB_CLK_GAT); + data |= MC_XPB_CLK_GAT__MEM_LS_ENABLE_MASK; + WREG32(mmMC_XPB_CLK_GAT, data); + + data = RREG32(mmATC_MISC_CG); + data |= ATC_MISC_CG__MEM_LS_ENABLE_MASK; + WREG32(mmATC_MISC_CG, data); + + data = RREG32(mmMC_CITF_MISC_WR_CG); + data |= MC_CITF_MISC_WR_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_CITF_MISC_WR_CG, data); + + data = RREG32(mmMC_CITF_MISC_RD_CG); + data |= MC_CITF_MISC_RD_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_CITF_MISC_RD_CG, data); + + data = RREG32(mmMC_CITF_MISC_VM_CG); + data |= MC_CITF_MISC_VM_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_CITF_MISC_VM_CG, data); + + data = RREG32(mmVM_L2_CG); + data |= VM_L2_CG__MEM_LS_ENABLE_MASK; + WREG32(mmVM_L2_CG, data); + } else { + data = RREG32(mmMC_HUB_MISC_HUB_CG); + data &= ~MC_HUB_MISC_HUB_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_HUB_MISC_HUB_CG, data); + + data = RREG32(mmMC_HUB_MISC_SIP_CG); + data &= ~MC_HUB_MISC_SIP_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_HUB_MISC_SIP_CG, data); + + data = RREG32(mmMC_HUB_MISC_VM_CG); + data &= ~MC_HUB_MISC_VM_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_HUB_MISC_VM_CG, data); + + data = RREG32(mmMC_XPB_CLK_GAT); + data &= ~MC_XPB_CLK_GAT__MEM_LS_ENABLE_MASK; + WREG32(mmMC_XPB_CLK_GAT, data); + + data = RREG32(mmATC_MISC_CG); + data &= ~ATC_MISC_CG__MEM_LS_ENABLE_MASK; + WREG32(mmATC_MISC_CG, data); + + data = RREG32(mmMC_CITF_MISC_WR_CG); + data &= ~MC_CITF_MISC_WR_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_CITF_MISC_WR_CG, data); + + data = RREG32(mmMC_CITF_MISC_RD_CG); + data &= ~MC_CITF_MISC_RD_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_CITF_MISC_RD_CG, data); + + data = RREG32(mmMC_CITF_MISC_VM_CG); + data &= ~MC_CITF_MISC_VM_CG__MEM_LS_ENABLE_MASK; + WREG32(mmMC_CITF_MISC_VM_CG, data); + + data = RREG32(mmVM_L2_CG); + data &= ~VM_L2_CG__MEM_LS_ENABLE_MASK; + WREG32(mmVM_L2_CG, data); + } +} + static int gmc_v8_0_set_clockgating_state(void *handle, enum amd_clockgating_state state) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + switch (adev->asic_type) { + case CHIP_FIJI: + fiji_update_mc_medium_grain_clock_gating(adev, + state == AMD_CG_STATE_GATE ? true : false); + fiji_update_mc_light_sleep(adev, + state == AMD_CG_STATE_GATE ? true : false); + break; + default: + break; + } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c index 779532d350ff..679e7394a495 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c @@ -253,8 +253,14 @@ static void iceland_ih_set_rptr(struct amdgpu_device *adev) static int iceland_ih_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int ret; + + ret = amdgpu_irq_add_domain(adev); + if (ret) + return ret; iceland_ih_set_interrupt_funcs(adev); + return 0; } @@ -278,6 +284,7 @@ static int iceland_ih_sw_fini(void *handle) amdgpu_irq_fini(adev); amdgpu_ih_ring_fini(adev); + amdgpu_irq_remove_domain(adev); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 7253132f04b8..ad54c46751b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -727,18 +727,20 @@ static int sdma_v3_0_start(struct amdgpu_device *adev) { int r, i; - if (!adev->firmware.smu_load) { - r = sdma_v3_0_load_microcode(adev); - if (r) - return r; - } else { - for (i = 0; i < adev->sdma.num_instances; i++) { - r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, - (i == 0) ? - AMDGPU_UCODE_ID_SDMA0 : - AMDGPU_UCODE_ID_SDMA1); + if (!adev->pp_enabled) { + if (!adev->firmware.smu_load) { + r = sdma_v3_0_load_microcode(adev); if (r) - return -EINVAL; + return r; + } else { + for (i = 0; i < adev->sdma.num_instances; i++) { + r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, + (i == 0) ? + AMDGPU_UCODE_ID_SDMA0 : + AMDGPU_UCODE_ID_SDMA1); + if (r) + return -EINVAL; + } } } @@ -1427,9 +1429,114 @@ static int sdma_v3_0_process_illegal_inst_irq(struct amdgpu_device *adev, return 0; } +static void fiji_update_sdma_medium_grain_clock_gating( + struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + if (enable) { + temp = data = RREG32(mmSDMA0_CLK_CTRL); + data &= ~(SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK); + if (data != temp) + WREG32(mmSDMA0_CLK_CTRL, data); + + temp = data = RREG32(mmSDMA1_CLK_CTRL); + data &= ~(SDMA1_CLK_CTRL__SOFT_OVERRIDE7_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE6_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE5_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE4_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE3_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE2_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE1_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE0_MASK); + + if (data != temp) + WREG32(mmSDMA1_CLK_CTRL, data); + } else { + temp = data = RREG32(mmSDMA0_CLK_CTRL); + data |= SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK | + SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK; + + if (data != temp) + WREG32(mmSDMA0_CLK_CTRL, data); + + temp = data = RREG32(mmSDMA1_CLK_CTRL); + data |= SDMA1_CLK_CTRL__SOFT_OVERRIDE7_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE6_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE5_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE4_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE3_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE2_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE1_MASK | + SDMA1_CLK_CTRL__SOFT_OVERRIDE0_MASK; + + if (data != temp) + WREG32(mmSDMA1_CLK_CTRL, data); + } +} + +static void fiji_update_sdma_medium_grain_light_sleep( + struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + if (enable) { + temp = data = RREG32(mmSDMA0_POWER_CNTL); + data |= SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK; + + if (temp != data) + WREG32(mmSDMA0_POWER_CNTL, data); + + temp = data = RREG32(mmSDMA1_POWER_CNTL); + data |= SDMA1_POWER_CNTL__MEM_POWER_OVERRIDE_MASK; + + if (temp != data) + WREG32(mmSDMA1_POWER_CNTL, data); + } else { + temp = data = RREG32(mmSDMA0_POWER_CNTL); + data &= ~SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK; + + if (temp != data) + WREG32(mmSDMA0_POWER_CNTL, data); + + temp = data = RREG32(mmSDMA1_POWER_CNTL); + data &= ~SDMA1_POWER_CNTL__MEM_POWER_OVERRIDE_MASK; + + if (temp != data) + WREG32(mmSDMA1_POWER_CNTL, data); + } +} + static int sdma_v3_0_set_clockgating_state(void *handle, enum amd_clockgating_state state) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + switch (adev->asic_type) { + case CHIP_FIJI: + fiji_update_sdma_medium_grain_clock_gating(adev, + state == AMD_CG_STATE_GATE ? true : false); + fiji_update_sdma_medium_grain_light_sleep(adev, + state == AMD_CG_STATE_GATE ? true : false); + break; + default: + break; + } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/smu7.h b/drivers/gpu/drm/amd/amdgpu/smu7.h deleted file mode 100644 index 75a380a15292..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/smu7.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2013 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef SMU7_H -#define SMU7_H - -#pragma pack(push, 1) - -#define SMU7_CONTEXT_ID_SMC 1 -#define SMU7_CONTEXT_ID_VBIOS 2 - - -#define SMU7_CONTEXT_ID_SMC 1 -#define SMU7_CONTEXT_ID_VBIOS 2 - -#define SMU7_MAX_LEVELS_VDDC 8 -#define SMU7_MAX_LEVELS_VDDCI 4 -#define SMU7_MAX_LEVELS_MVDD 4 -#define SMU7_MAX_LEVELS_VDDNB 8 - -#define SMU7_MAX_LEVELS_GRAPHICS SMU__NUM_SCLK_DPM_STATE // SCLK + SQ DPM + ULV -#define SMU7_MAX_LEVELS_MEMORY SMU__NUM_MCLK_DPM_LEVELS // MCLK Levels DPM -#define SMU7_MAX_LEVELS_GIO SMU__NUM_LCLK_DPM_LEVELS // LCLK Levels -#define SMU7_MAX_LEVELS_LINK SMU__NUM_PCIE_DPM_LEVELS // PCIe speed and number of lanes. -#define SMU7_MAX_LEVELS_UVD 8 // VCLK/DCLK levels for UVD. -#define SMU7_MAX_LEVELS_VCE 8 // ECLK levels for VCE. -#define SMU7_MAX_LEVELS_ACP 8 // ACLK levels for ACP. -#define SMU7_MAX_LEVELS_SAMU 8 // SAMCLK levels for SAMU. -#define SMU7_MAX_ENTRIES_SMIO 32 // Number of entries in SMIO table. - -#define DPM_NO_LIMIT 0 -#define DPM_NO_UP 1 -#define DPM_GO_DOWN 2 -#define DPM_GO_UP 3 - -#define SMU7_FIRST_DPM_GRAPHICS_LEVEL 0 -#define SMU7_FIRST_DPM_MEMORY_LEVEL 0 - -#define GPIO_CLAMP_MODE_VRHOT 1 -#define GPIO_CLAMP_MODE_THERM 2 -#define GPIO_CLAMP_MODE_DC 4 - -#define SCRATCH_B_TARG_PCIE_INDEX_SHIFT 0 -#define SCRATCH_B_TARG_PCIE_INDEX_MASK (0x7<<SCRATCH_B_TARG_PCIE_INDEX_SHIFT) -#define SCRATCH_B_CURR_PCIE_INDEX_SHIFT 3 -#define SCRATCH_B_CURR_PCIE_INDEX_MASK (0x7<<SCRATCH_B_CURR_PCIE_INDEX_SHIFT) -#define SCRATCH_B_TARG_UVD_INDEX_SHIFT 6 -#define SCRATCH_B_TARG_UVD_INDEX_MASK (0x7<<SCRATCH_B_TARG_UVD_INDEX_SHIFT) -#define SCRATCH_B_CURR_UVD_INDEX_SHIFT 9 -#define SCRATCH_B_CURR_UVD_INDEX_MASK (0x7<<SCRATCH_B_CURR_UVD_INDEX_SHIFT) -#define SCRATCH_B_TARG_VCE_INDEX_SHIFT 12 -#define SCRATCH_B_TARG_VCE_INDEX_MASK (0x7<<SCRATCH_B_TARG_VCE_INDEX_SHIFT) -#define SCRATCH_B_CURR_VCE_INDEX_SHIFT 15 -#define SCRATCH_B_CURR_VCE_INDEX_MASK (0x7<<SCRATCH_B_CURR_VCE_INDEX_SHIFT) -#define SCRATCH_B_TARG_ACP_INDEX_SHIFT 18 -#define SCRATCH_B_TARG_ACP_INDEX_MASK (0x7<<SCRATCH_B_TARG_ACP_INDEX_SHIFT) -#define SCRATCH_B_CURR_ACP_INDEX_SHIFT 21 -#define SCRATCH_B_CURR_ACP_INDEX_MASK (0x7<<SCRATCH_B_CURR_ACP_INDEX_SHIFT) -#define SCRATCH_B_TARG_SAMU_INDEX_SHIFT 24 -#define SCRATCH_B_TARG_SAMU_INDEX_MASK (0x7<<SCRATCH_B_TARG_SAMU_INDEX_SHIFT) -#define SCRATCH_B_CURR_SAMU_INDEX_SHIFT 27 -#define SCRATCH_B_CURR_SAMU_INDEX_MASK (0x7<<SCRATCH_B_CURR_SAMU_INDEX_SHIFT) - - -struct SMU7_PIDController -{ - uint32_t Ki; - int32_t LFWindupUL; - int32_t LFWindupLL; - uint32_t StatePrecision; - uint32_t LfPrecision; - uint32_t LfOffset; - uint32_t MaxState; - uint32_t MaxLfFraction; - uint32_t StateShift; -}; - -typedef struct SMU7_PIDController SMU7_PIDController; - -// ------------------------------------------------------------------------------------------------------------------------- -#define SMU7_MAX_PCIE_LINK_SPEEDS 3 /* 0:Gen1 1:Gen2 2:Gen3 */ - -#define SMU7_SCLK_DPM_CONFIG_MASK 0x01 -#define SMU7_VOLTAGE_CONTROLLER_CONFIG_MASK 0x02 -#define SMU7_THERMAL_CONTROLLER_CONFIG_MASK 0x04 -#define SMU7_MCLK_DPM_CONFIG_MASK 0x08 -#define SMU7_UVD_DPM_CONFIG_MASK 0x10 -#define SMU7_VCE_DPM_CONFIG_MASK 0x20 -#define SMU7_ACP_DPM_CONFIG_MASK 0x40 -#define SMU7_SAMU_DPM_CONFIG_MASK 0x80 -#define SMU7_PCIEGEN_DPM_CONFIG_MASK 0x100 - -#define SMU7_ACP_MCLK_HANDSHAKE_DISABLE 0x00000001 -#define SMU7_ACP_SCLK_HANDSHAKE_DISABLE 0x00000002 -#define SMU7_UVD_MCLK_HANDSHAKE_DISABLE 0x00000100 -#define SMU7_UVD_SCLK_HANDSHAKE_DISABLE 0x00000200 -#define SMU7_VCE_MCLK_HANDSHAKE_DISABLE 0x00010000 -#define SMU7_VCE_SCLK_HANDSHAKE_DISABLE 0x00020000 - -struct SMU7_Firmware_Header -{ - uint32_t Digest[5]; - uint32_t Version; - uint32_t HeaderSize; - uint32_t Flags; - uint32_t EntryPoint; - uint32_t CodeSize; - uint32_t ImageSize; - - uint32_t Rtos; - uint32_t SoftRegisters; - uint32_t DpmTable; - uint32_t FanTable; - uint32_t CacConfigTable; - uint32_t CacStatusTable; - - uint32_t mcRegisterTable; - - uint32_t mcArbDramTimingTable; - - uint32_t PmFuseTable; - uint32_t Globals; - uint32_t Reserved[42]; - uint32_t Signature; -}; - -typedef struct SMU7_Firmware_Header SMU7_Firmware_Header; - -#define SMU7_FIRMWARE_HEADER_LOCATION 0x20000 - -enum DisplayConfig { - PowerDown = 1, - DP54x4, - DP54x2, - DP54x1, - DP27x4, - DP27x2, - DP27x1, - HDMI297, - HDMI162, - LVDS, - DP324x4, - DP324x2, - DP324x1 -}; - -#pragma pack(pop) - -#endif - diff --git a/drivers/gpu/drm/amd/amdgpu/smu7_discrete.h b/drivers/gpu/drm/amd/amdgpu/smu7_discrete.h deleted file mode 100644 index 0b0b404ff091..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/smu7_discrete.h +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Copyright 2013 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef SMU7_DISCRETE_H -#define SMU7_DISCRETE_H - -#include "smu7.h" - -#pragma pack(push, 1) - -#define SMU7_DTE_ITERATIONS 5 -#define SMU7_DTE_SOURCES 3 -#define SMU7_DTE_SINKS 1 -#define SMU7_NUM_CPU_TES 0 -#define SMU7_NUM_GPU_TES 1 -#define SMU7_NUM_NON_TES 2 - -struct SMU7_SoftRegisters -{ - uint32_t RefClockFrequency; - uint32_t PmTimerP; - uint32_t FeatureEnables; - uint32_t PreVBlankGap; - uint32_t VBlankTimeout; - uint32_t TrainTimeGap; - - uint32_t MvddSwitchTime; - uint32_t LongestAcpiTrainTime; - uint32_t AcpiDelay; - uint32_t G5TrainTime; - uint32_t DelayMpllPwron; - uint32_t VoltageChangeTimeout; - uint32_t HandshakeDisables; - - uint8_t DisplayPhy1Config; - uint8_t DisplayPhy2Config; - uint8_t DisplayPhy3Config; - uint8_t DisplayPhy4Config; - - uint8_t DisplayPhy5Config; - uint8_t DisplayPhy6Config; - uint8_t DisplayPhy7Config; - uint8_t DisplayPhy8Config; - - uint32_t AverageGraphicsA; - uint32_t AverageMemoryA; - uint32_t AverageGioA; - - uint8_t SClkDpmEnabledLevels; - uint8_t MClkDpmEnabledLevels; - uint8_t LClkDpmEnabledLevels; - uint8_t PCIeDpmEnabledLevels; - - uint8_t UVDDpmEnabledLevels; - uint8_t SAMUDpmEnabledLevels; - uint8_t ACPDpmEnabledLevels; - uint8_t VCEDpmEnabledLevels; - - uint32_t DRAM_LOG_ADDR_H; - uint32_t DRAM_LOG_ADDR_L; - uint32_t DRAM_LOG_PHY_ADDR_H; - uint32_t DRAM_LOG_PHY_ADDR_L; - uint32_t DRAM_LOG_BUFF_SIZE; - uint32_t UlvEnterC; - uint32_t UlvTime; - uint32_t Reserved[3]; - -}; - -typedef struct SMU7_SoftRegisters SMU7_SoftRegisters; - -struct SMU7_Discrete_VoltageLevel -{ - uint16_t Voltage; - uint16_t StdVoltageHiSidd; - uint16_t StdVoltageLoSidd; - uint8_t Smio; - uint8_t padding; -}; - -typedef struct SMU7_Discrete_VoltageLevel SMU7_Discrete_VoltageLevel; - -struct SMU7_Discrete_GraphicsLevel -{ - uint32_t Flags; - uint32_t MinVddc; - uint32_t MinVddcPhases; - - uint32_t SclkFrequency; - - uint8_t padding1[2]; - uint16_t ActivityLevel; - - uint32_t CgSpllFuncCntl3; - uint32_t CgSpllFuncCntl4; - uint32_t SpllSpreadSpectrum; - uint32_t SpllSpreadSpectrum2; - uint32_t CcPwrDynRm; - uint32_t CcPwrDynRm1; - uint8_t SclkDid; - uint8_t DisplayWatermark; - uint8_t EnabledForActivity; - uint8_t EnabledForThrottle; - uint8_t UpH; - uint8_t DownH; - uint8_t VoltageDownH; - uint8_t PowerThrottle; - uint8_t DeepSleepDivId; - uint8_t padding[3]; -}; - -typedef struct SMU7_Discrete_GraphicsLevel SMU7_Discrete_GraphicsLevel; - -struct SMU7_Discrete_ACPILevel -{ - uint32_t Flags; - uint32_t MinVddc; - uint32_t MinVddcPhases; - uint32_t SclkFrequency; - uint8_t SclkDid; - uint8_t DisplayWatermark; - uint8_t DeepSleepDivId; - uint8_t padding; - uint32_t CgSpllFuncCntl; - uint32_t CgSpllFuncCntl2; - uint32_t CgSpllFuncCntl3; - uint32_t CgSpllFuncCntl4; - uint32_t SpllSpreadSpectrum; - uint32_t SpllSpreadSpectrum2; - uint32_t CcPwrDynRm; - uint32_t CcPwrDynRm1; -}; - -typedef struct SMU7_Discrete_ACPILevel SMU7_Discrete_ACPILevel; - -struct SMU7_Discrete_Ulv -{ - uint32_t CcPwrDynRm; - uint32_t CcPwrDynRm1; - uint16_t VddcOffset; - uint8_t VddcOffsetVid; - uint8_t VddcPhase; - uint32_t Reserved; -}; - -typedef struct SMU7_Discrete_Ulv SMU7_Discrete_Ulv; - -struct SMU7_Discrete_MemoryLevel -{ - uint32_t MinVddc; - uint32_t MinVddcPhases; - uint32_t MinVddci; - uint32_t MinMvdd; - - uint32_t MclkFrequency; - - uint8_t EdcReadEnable; - uint8_t EdcWriteEnable; - uint8_t RttEnable; - uint8_t StutterEnable; - - uint8_t StrobeEnable; - uint8_t StrobeRatio; - uint8_t EnabledForThrottle; - uint8_t EnabledForActivity; - - uint8_t UpH; - uint8_t DownH; - uint8_t VoltageDownH; - uint8_t padding; - - uint16_t ActivityLevel; - uint8_t DisplayWatermark; - uint8_t padding1; - - uint32_t MpllFuncCntl; - uint32_t MpllFuncCntl_1; - uint32_t MpllFuncCntl_2; - uint32_t MpllAdFuncCntl; - uint32_t MpllDqFuncCntl; - uint32_t MclkPwrmgtCntl; - uint32_t DllCntl; - uint32_t MpllSs1; - uint32_t MpllSs2; -}; - -typedef struct SMU7_Discrete_MemoryLevel SMU7_Discrete_MemoryLevel; - -struct SMU7_Discrete_LinkLevel -{ - uint8_t PcieGenSpeed; - uint8_t PcieLaneCount; - uint8_t EnabledForActivity; - uint8_t Padding; - uint32_t DownT; - uint32_t UpT; - uint32_t Reserved; -}; - -typedef struct SMU7_Discrete_LinkLevel SMU7_Discrete_LinkLevel; - - -struct SMU7_Discrete_MCArbDramTimingTableEntry -{ - uint32_t McArbDramTiming; - uint32_t McArbDramTiming2; - uint8_t McArbBurstTime; - uint8_t padding[3]; -}; - -typedef struct SMU7_Discrete_MCArbDramTimingTableEntry SMU7_Discrete_MCArbDramTimingTableEntry; - -struct SMU7_Discrete_MCArbDramTimingTable -{ - SMU7_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS]; -}; - -typedef struct SMU7_Discrete_MCArbDramTimingTable SMU7_Discrete_MCArbDramTimingTable; - -struct SMU7_Discrete_UvdLevel -{ - uint32_t VclkFrequency; - uint32_t DclkFrequency; - uint16_t MinVddc; - uint8_t MinVddcPhases; - uint8_t VclkDivider; - uint8_t DclkDivider; - uint8_t padding[3]; -}; - -typedef struct SMU7_Discrete_UvdLevel SMU7_Discrete_UvdLevel; - -struct SMU7_Discrete_ExtClkLevel -{ - uint32_t Frequency; - uint16_t MinVoltage; - uint8_t MinPhases; - uint8_t Divider; -}; - -typedef struct SMU7_Discrete_ExtClkLevel SMU7_Discrete_ExtClkLevel; - -struct SMU7_Discrete_StateInfo -{ - uint32_t SclkFrequency; - uint32_t MclkFrequency; - uint32_t VclkFrequency; - uint32_t DclkFrequency; - uint32_t SamclkFrequency; - uint32_t AclkFrequency; - uint32_t EclkFrequency; - uint16_t MvddVoltage; - uint16_t padding16; - uint8_t DisplayWatermark; - uint8_t McArbIndex; - uint8_t McRegIndex; - uint8_t SeqIndex; - uint8_t SclkDid; - int8_t SclkIndex; - int8_t MclkIndex; - uint8_t PCIeGen; - -}; - -typedef struct SMU7_Discrete_StateInfo SMU7_Discrete_StateInfo; - - -struct SMU7_Discrete_DpmTable -{ - SMU7_PIDController GraphicsPIDController; - SMU7_PIDController MemoryPIDController; - SMU7_PIDController LinkPIDController; - - uint32_t SystemFlags; - - - uint32_t SmioMaskVddcVid; - uint32_t SmioMaskVddcPhase; - uint32_t SmioMaskVddciVid; - uint32_t SmioMaskMvddVid; - - uint32_t VddcLevelCount; - uint32_t VddciLevelCount; - uint32_t MvddLevelCount; - - SMU7_Discrete_VoltageLevel VddcLevel [SMU7_MAX_LEVELS_VDDC]; -// SMU7_Discrete_VoltageLevel VddcStandardReference [SMU7_MAX_LEVELS_VDDC]; - SMU7_Discrete_VoltageLevel VddciLevel [SMU7_MAX_LEVELS_VDDCI]; - SMU7_Discrete_VoltageLevel MvddLevel [SMU7_MAX_LEVELS_MVDD]; - - uint8_t GraphicsDpmLevelCount; - uint8_t MemoryDpmLevelCount; - uint8_t LinkLevelCount; - uint8_t UvdLevelCount; - uint8_t VceLevelCount; - uint8_t AcpLevelCount; - uint8_t SamuLevelCount; - uint8_t MasterDeepSleepControl; - uint32_t Reserved[5]; -// uint32_t SamuDefaultLevel; - - SMU7_Discrete_GraphicsLevel GraphicsLevel [SMU7_MAX_LEVELS_GRAPHICS]; - SMU7_Discrete_MemoryLevel MemoryACPILevel; - SMU7_Discrete_MemoryLevel MemoryLevel [SMU7_MAX_LEVELS_MEMORY]; - SMU7_Discrete_LinkLevel LinkLevel [SMU7_MAX_LEVELS_LINK]; - SMU7_Discrete_ACPILevel ACPILevel; - SMU7_Discrete_UvdLevel UvdLevel [SMU7_MAX_LEVELS_UVD]; - SMU7_Discrete_ExtClkLevel VceLevel [SMU7_MAX_LEVELS_VCE]; - SMU7_Discrete_ExtClkLevel AcpLevel [SMU7_MAX_LEVELS_ACP]; - SMU7_Discrete_ExtClkLevel SamuLevel [SMU7_MAX_LEVELS_SAMU]; - SMU7_Discrete_Ulv Ulv; - - uint32_t SclkStepSize; - uint32_t Smio [SMU7_MAX_ENTRIES_SMIO]; - - uint8_t UvdBootLevel; - uint8_t VceBootLevel; - uint8_t AcpBootLevel; - uint8_t SamuBootLevel; - - uint8_t UVDInterval; - uint8_t VCEInterval; - uint8_t ACPInterval; - uint8_t SAMUInterval; - - uint8_t GraphicsBootLevel; - uint8_t GraphicsVoltageChangeEnable; - uint8_t GraphicsThermThrottleEnable; - uint8_t GraphicsInterval; - - uint8_t VoltageInterval; - uint8_t ThermalInterval; - uint16_t TemperatureLimitHigh; - - uint16_t TemperatureLimitLow; - uint8_t MemoryBootLevel; - uint8_t MemoryVoltageChangeEnable; - - uint8_t MemoryInterval; - uint8_t MemoryThermThrottleEnable; - uint16_t VddcVddciDelta; - - uint16_t VoltageResponseTime; - uint16_t PhaseResponseTime; - - uint8_t PCIeBootLinkLevel; - uint8_t PCIeGenInterval; - uint8_t DTEInterval; - uint8_t DTEMode; - - uint8_t SVI2Enable; - uint8_t VRHotGpio; - uint8_t AcDcGpio; - uint8_t ThermGpio; - - uint16_t PPM_PkgPwrLimit; - uint16_t PPM_TemperatureLimit; - - uint16_t DefaultTdp; - uint16_t TargetTdp; - - uint16_t FpsHighT; - uint16_t FpsLowT; - - uint16_t BAPMTI_R [SMU7_DTE_ITERATIONS][SMU7_DTE_SOURCES][SMU7_DTE_SINKS]; - uint16_t BAPMTI_RC [SMU7_DTE_ITERATIONS][SMU7_DTE_SOURCES][SMU7_DTE_SINKS]; - - uint8_t DTEAmbientTempBase; - uint8_t DTETjOffset; - uint8_t GpuTjMax; - uint8_t GpuTjHyst; - - uint16_t BootVddc; - uint16_t BootVddci; - - uint16_t BootMVdd; - uint16_t padding; - - uint32_t BAPM_TEMP_GRADIENT; - - uint32_t LowSclkInterruptT; -}; - -typedef struct SMU7_Discrete_DpmTable SMU7_Discrete_DpmTable; - -#define SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE 16 -#define SMU7_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT SMU7_MAX_LEVELS_MEMORY - -struct SMU7_Discrete_MCRegisterAddress -{ - uint16_t s0; - uint16_t s1; -}; - -typedef struct SMU7_Discrete_MCRegisterAddress SMU7_Discrete_MCRegisterAddress; - -struct SMU7_Discrete_MCRegisterSet -{ - uint32_t value[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE]; -}; - -typedef struct SMU7_Discrete_MCRegisterSet SMU7_Discrete_MCRegisterSet; - -struct SMU7_Discrete_MCRegisters -{ - uint8_t last; - uint8_t reserved[3]; - SMU7_Discrete_MCRegisterAddress address[SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE]; - SMU7_Discrete_MCRegisterSet data[SMU7_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT]; -}; - -typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters; - -struct SMU7_Discrete_FanTable -{ - uint16_t FdoMode; - int16_t TempMin; - int16_t TempMed; - int16_t TempMax; - int16_t Slope1; - int16_t Slope2; - int16_t FdoMin; - int16_t HystUp; - int16_t HystDown; - int16_t HystSlope; - int16_t TempRespLim; - int16_t TempCurr; - int16_t SlopeCurr; - int16_t PwmCurr; - uint32_t RefreshPeriod; - int16_t FdoMax; - uint8_t TempSrc; - int8_t Padding; -}; - -typedef struct SMU7_Discrete_FanTable SMU7_Discrete_FanTable; - - -struct SMU7_Discrete_PmFuses { - // dw0-dw1 - uint8_t BapmVddCVidHiSidd[8]; - - // dw2-dw3 - uint8_t BapmVddCVidLoSidd[8]; - - // dw4-dw5 - uint8_t VddCVid[8]; - - // dw6 - uint8_t SviLoadLineEn; - uint8_t SviLoadLineVddC; - uint8_t SviLoadLineTrimVddC; - uint8_t SviLoadLineOffsetVddC; - - // dw7 - uint16_t TDC_VDDC_PkgLimit; - uint8_t TDC_VDDC_ThrottleReleaseLimitPerc; - uint8_t TDC_MAWt; - - // dw8 - uint8_t TdcWaterfallCtl; - uint8_t LPMLTemperatureMin; - uint8_t LPMLTemperatureMax; - uint8_t Reserved; - - // dw9-dw10 - uint8_t BapmVddCVidHiSidd2[8]; - - // dw11-dw12 - int16_t FuzzyFan_ErrorSetDelta; - int16_t FuzzyFan_ErrorRateSetDelta; - int16_t FuzzyFan_PwmSetDelta; - uint16_t CalcMeasPowerBlend; - - // dw13-dw16 - uint8_t GnbLPML[16]; - - // dw17 - uint8_t GnbLPMLMaxVid; - uint8_t GnbLPMLMinVid; - uint8_t Reserved1[2]; - - // dw18 - uint16_t BapmVddCBaseLeakageHiSidd; - uint16_t BapmVddCBaseLeakageLoSidd; -}; - -typedef struct SMU7_Discrete_PmFuses SMU7_Discrete_PmFuses; - - -#pragma pack(pop) - -#endif - diff --git a/drivers/gpu/drm/amd/amdgpu/smu7_fusion.h b/drivers/gpu/drm/amd/amdgpu/smu7_fusion.h deleted file mode 100644 index 78ada9ffd508..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/smu7_fusion.h +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright 2013 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef SMU7_FUSION_H -#define SMU7_FUSION_H - -#include "smu7.h" - -#pragma pack(push, 1) - -#define SMU7_DTE_ITERATIONS 5 -#define SMU7_DTE_SOURCES 5 -#define SMU7_DTE_SINKS 3 -#define SMU7_NUM_CPU_TES 2 -#define SMU7_NUM_GPU_TES 1 -#define SMU7_NUM_NON_TES 2 - -// All 'soft registers' should be uint32_t. -struct SMU7_SoftRegisters -{ - uint32_t RefClockFrequency; - uint32_t PmTimerP; - uint32_t FeatureEnables; - uint32_t HandshakeDisables; - - uint8_t DisplayPhy1Config; - uint8_t DisplayPhy2Config; - uint8_t DisplayPhy3Config; - uint8_t DisplayPhy4Config; - - uint8_t DisplayPhy5Config; - uint8_t DisplayPhy6Config; - uint8_t DisplayPhy7Config; - uint8_t DisplayPhy8Config; - - uint32_t AverageGraphicsA; - uint32_t AverageMemoryA; - uint32_t AverageGioA; - - uint8_t SClkDpmEnabledLevels; - uint8_t MClkDpmEnabledLevels; - uint8_t LClkDpmEnabledLevels; - uint8_t PCIeDpmEnabledLevels; - - uint8_t UVDDpmEnabledLevels; - uint8_t SAMUDpmEnabledLevels; - uint8_t ACPDpmEnabledLevels; - uint8_t VCEDpmEnabledLevels; - - uint32_t DRAM_LOG_ADDR_H; - uint32_t DRAM_LOG_ADDR_L; - uint32_t DRAM_LOG_PHY_ADDR_H; - uint32_t DRAM_LOG_PHY_ADDR_L; - uint32_t DRAM_LOG_BUFF_SIZE; - uint32_t UlvEnterC; - uint32_t UlvTime; - uint32_t Reserved[3]; - -}; - -typedef struct SMU7_SoftRegisters SMU7_SoftRegisters; - -struct SMU7_Fusion_GraphicsLevel -{ - uint32_t MinVddNb; - - uint32_t SclkFrequency; - - uint8_t Vid; - uint8_t VidOffset; - uint16_t AT; - - uint8_t PowerThrottle; - uint8_t GnbSlow; - uint8_t ForceNbPs1; - uint8_t SclkDid; - - uint8_t DisplayWatermark; - uint8_t EnabledForActivity; - uint8_t EnabledForThrottle; - uint8_t UpH; - - uint8_t DownH; - uint8_t VoltageDownH; - uint8_t DeepSleepDivId; - - uint8_t ClkBypassCntl; - - uint32_t reserved; -}; - -typedef struct SMU7_Fusion_GraphicsLevel SMU7_Fusion_GraphicsLevel; - -struct SMU7_Fusion_GIOLevel -{ - uint8_t EnabledForActivity; - uint8_t LclkDid; - uint8_t Vid; - uint8_t VoltageDownH; - - uint32_t MinVddNb; - - uint16_t ResidencyCounter; - uint8_t UpH; - uint8_t DownH; - - uint32_t LclkFrequency; - - uint8_t ActivityLevel; - uint8_t EnabledForThrottle; - - uint8_t ClkBypassCntl; - - uint8_t padding; -}; - -typedef struct SMU7_Fusion_GIOLevel SMU7_Fusion_GIOLevel; - -// UVD VCLK/DCLK state (level) definition. -struct SMU7_Fusion_UvdLevel -{ - uint32_t VclkFrequency; - uint32_t DclkFrequency; - uint16_t MinVddNb; - uint8_t VclkDivider; - uint8_t DclkDivider; - - uint8_t VClkBypassCntl; - uint8_t DClkBypassCntl; - - uint8_t padding[2]; - -}; - -typedef struct SMU7_Fusion_UvdLevel SMU7_Fusion_UvdLevel; - -// Clocks for other external blocks (VCE, ACP, SAMU). -struct SMU7_Fusion_ExtClkLevel -{ - uint32_t Frequency; - uint16_t MinVoltage; - uint8_t Divider; - uint8_t ClkBypassCntl; - - uint32_t Reserved; -}; -typedef struct SMU7_Fusion_ExtClkLevel SMU7_Fusion_ExtClkLevel; - -struct SMU7_Fusion_ACPILevel -{ - uint32_t Flags; - uint32_t MinVddNb; - uint32_t SclkFrequency; - uint8_t SclkDid; - uint8_t GnbSlow; - uint8_t ForceNbPs1; - uint8_t DisplayWatermark; - uint8_t DeepSleepDivId; - uint8_t padding[3]; -}; - -typedef struct SMU7_Fusion_ACPILevel SMU7_Fusion_ACPILevel; - -struct SMU7_Fusion_NbDpm -{ - uint8_t DpmXNbPsHi; - uint8_t DpmXNbPsLo; - uint8_t Dpm0PgNbPsHi; - uint8_t Dpm0PgNbPsLo; - uint8_t EnablePsi1; - uint8_t SkipDPM0; - uint8_t SkipPG; - uint8_t Hysteresis; - uint8_t EnableDpmPstatePoll; - uint8_t padding[3]; -}; - -typedef struct SMU7_Fusion_NbDpm SMU7_Fusion_NbDpm; - -struct SMU7_Fusion_StateInfo -{ - uint32_t SclkFrequency; - uint32_t LclkFrequency; - uint32_t VclkFrequency; - uint32_t DclkFrequency; - uint32_t SamclkFrequency; - uint32_t AclkFrequency; - uint32_t EclkFrequency; - uint8_t DisplayWatermark; - uint8_t McArbIndex; - int8_t SclkIndex; - int8_t MclkIndex; -}; - -typedef struct SMU7_Fusion_StateInfo SMU7_Fusion_StateInfo; - -struct SMU7_Fusion_DpmTable -{ - uint32_t SystemFlags; - - SMU7_PIDController GraphicsPIDController; - SMU7_PIDController GioPIDController; - - uint8_t GraphicsDpmLevelCount; - uint8_t GIOLevelCount; - uint8_t UvdLevelCount; - uint8_t VceLevelCount; - - uint8_t AcpLevelCount; - uint8_t SamuLevelCount; - uint16_t FpsHighT; - - SMU7_Fusion_GraphicsLevel GraphicsLevel [SMU__NUM_SCLK_DPM_STATE]; - SMU7_Fusion_ACPILevel ACPILevel; - SMU7_Fusion_UvdLevel UvdLevel [SMU7_MAX_LEVELS_UVD]; - SMU7_Fusion_ExtClkLevel VceLevel [SMU7_MAX_LEVELS_VCE]; - SMU7_Fusion_ExtClkLevel AcpLevel [SMU7_MAX_LEVELS_ACP]; - SMU7_Fusion_ExtClkLevel SamuLevel [SMU7_MAX_LEVELS_SAMU]; - - uint8_t UvdBootLevel; - uint8_t VceBootLevel; - uint8_t AcpBootLevel; - uint8_t SamuBootLevel; - uint8_t UVDInterval; - uint8_t VCEInterval; - uint8_t ACPInterval; - uint8_t SAMUInterval; - - uint8_t GraphicsBootLevel; - uint8_t GraphicsInterval; - uint8_t GraphicsThermThrottleEnable; - uint8_t GraphicsVoltageChangeEnable; - - uint8_t GraphicsClkSlowEnable; - uint8_t GraphicsClkSlowDivider; - uint16_t FpsLowT; - - uint32_t DisplayCac; - uint32_t LowSclkInterruptT; - - uint32_t DRAM_LOG_ADDR_H; - uint32_t DRAM_LOG_ADDR_L; - uint32_t DRAM_LOG_PHY_ADDR_H; - uint32_t DRAM_LOG_PHY_ADDR_L; - uint32_t DRAM_LOG_BUFF_SIZE; - -}; - -struct SMU7_Fusion_GIODpmTable -{ - - SMU7_Fusion_GIOLevel GIOLevel [SMU7_MAX_LEVELS_GIO]; - - SMU7_PIDController GioPIDController; - - uint32_t GIOLevelCount; - - uint8_t Enable; - uint8_t GIOVoltageChangeEnable; - uint8_t GIOBootLevel; - uint8_t padding; - uint8_t padding1[2]; - uint8_t TargetState; - uint8_t CurrenttState; - uint8_t ThrottleOnHtc; - uint8_t ThermThrottleStatus; - uint8_t ThermThrottleTempSelect; - uint8_t ThermThrottleEnable; - uint16_t TemperatureLimitHigh; - uint16_t TemperatureLimitLow; - -}; - -typedef struct SMU7_Fusion_DpmTable SMU7_Fusion_DpmTable; -typedef struct SMU7_Fusion_GIODpmTable SMU7_Fusion_GIODpmTable; - -#pragma pack(pop) - -#endif - diff --git a/drivers/gpu/drm/amd/amdgpu/smu8_fusion.h b/drivers/gpu/drm/amd/amdgpu/smu8_fusion.h deleted file mode 100644 index 5c9cc3c0bbfa..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/smu8_fusion.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2014 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef SMU8_FUSION_H -#define SMU8_FUSION_H - -#include "smu8.h" - -#pragma pack(push, 1) - -#define SMU8_MAX_CUS 2 -#define SMU8_PSMS_PER_CU 4 -#define SMU8_CACS_PER_CU 4 - -struct SMU8_GfxCuPgScoreboard { - uint8_t Enabled; - uint8_t spare[3]; -}; - -struct SMU8_Port80MonitorTable { - uint32_t MmioAddress; - uint32_t MemoryBaseHi; - uint32_t MemoryBaseLo; - uint16_t MemoryBufferSize; - uint16_t MemoryPosition; - uint16_t PollingInterval; - uint8_t EnableCsrShadow; - uint8_t EnableDramShadow; -}; - -/* Clock Table Definitions */ -#define NUM_SCLK_LEVELS 8 -#define NUM_LCLK_LEVELS 8 -#define NUM_UVD_LEVELS 8 -#define NUM_ECLK_LEVELS 8 -#define NUM_ACLK_LEVELS 8 - -struct SMU8_Fusion_ClkLevel { - uint8_t GnbVid; - uint8_t GfxVid; - uint8_t DfsDid; - uint8_t DeepSleepDid; - uint32_t DfsBypass; - uint32_t Frequency; -}; - -struct SMU8_Fusion_SclkBreakdownTable { - struct SMU8_Fusion_ClkLevel ClkLevel[NUM_SCLK_LEVELS]; - struct SMU8_Fusion_ClkLevel DpmOffLevel; - /* SMU8_Fusion_ClkLevel PwrOffLevel; */ - uint32_t SclkValidMask; - uint32_t MaxSclkIndex; -}; - -struct SMU8_Fusion_LclkBreakdownTable { - struct SMU8_Fusion_ClkLevel ClkLevel[NUM_LCLK_LEVELS]; - struct SMU8_Fusion_ClkLevel DpmOffLevel; - /* SMU8_Fusion_ClkLevel PwrOffLevel; */ - uint32_t LclkValidMask; - uint32_t MaxLclkIndex; -}; - -struct SMU8_Fusion_EclkBreakdownTable { - struct SMU8_Fusion_ClkLevel ClkLevel[NUM_ECLK_LEVELS]; - struct SMU8_Fusion_ClkLevel DpmOffLevel; - struct SMU8_Fusion_ClkLevel PwrOffLevel; - uint32_t EclkValidMask; - uint32_t MaxEclkIndex; -}; - -struct SMU8_Fusion_VclkBreakdownTable { - struct SMU8_Fusion_ClkLevel ClkLevel[NUM_UVD_LEVELS]; - struct SMU8_Fusion_ClkLevel DpmOffLevel; - struct SMU8_Fusion_ClkLevel PwrOffLevel; - uint32_t VclkValidMask; - uint32_t MaxVclkIndex; -}; - -struct SMU8_Fusion_DclkBreakdownTable { - struct SMU8_Fusion_ClkLevel ClkLevel[NUM_UVD_LEVELS]; - struct SMU8_Fusion_ClkLevel DpmOffLevel; - struct SMU8_Fusion_ClkLevel PwrOffLevel; - uint32_t DclkValidMask; - uint32_t MaxDclkIndex; -}; - -struct SMU8_Fusion_AclkBreakdownTable { - struct SMU8_Fusion_ClkLevel ClkLevel[NUM_ACLK_LEVELS]; - struct SMU8_Fusion_ClkLevel DpmOffLevel; - struct SMU8_Fusion_ClkLevel PwrOffLevel; - uint32_t AclkValidMask; - uint32_t MaxAclkIndex; -}; - - -struct SMU8_Fusion_ClkTable { - struct SMU8_Fusion_SclkBreakdownTable SclkBreakdownTable; - struct SMU8_Fusion_LclkBreakdownTable LclkBreakdownTable; - struct SMU8_Fusion_EclkBreakdownTable EclkBreakdownTable; - struct SMU8_Fusion_VclkBreakdownTable VclkBreakdownTable; - struct SMU8_Fusion_DclkBreakdownTable DclkBreakdownTable; - struct SMU8_Fusion_AclkBreakdownTable AclkBreakdownTable; -}; - -#pragma pack(pop) - -#endif diff --git a/drivers/gpu/drm/amd/amdgpu/smu_ucode_xfer_cz.h b/drivers/gpu/drm/amd/amdgpu/smu_ucode_xfer_cz.h deleted file mode 100644 index f8ba071f39c8..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/smu_ucode_xfer_cz.h +++ /dev/null @@ -1,147 +0,0 @@ -// CZ Ucode Loading Definitions -#ifndef SMU_UCODE_XFER_CZ_H -#define SMU_UCODE_XFER_CZ_H - -#define NUM_JOBLIST_ENTRIES 32 - -#define TASK_TYPE_NO_ACTION 0 -#define TASK_TYPE_UCODE_LOAD 1 -#define TASK_TYPE_UCODE_SAVE 2 -#define TASK_TYPE_REG_LOAD 3 -#define TASK_TYPE_REG_SAVE 4 -#define TASK_TYPE_INITIALIZE 5 - -#define TASK_ARG_REG_SMCIND 0 -#define TASK_ARG_REG_MMIO 1 -#define TASK_ARG_REG_FCH 2 -#define TASK_ARG_REG_UNB 3 - -#define TASK_ARG_INIT_MM_PWR_LOG 0 -#define TASK_ARG_INIT_CLK_TABLE 1 - -#define JOB_GFX_SAVE 0 -#define JOB_GFX_RESTORE 1 -#define JOB_FCH_SAVE 2 -#define JOB_FCH_RESTORE 3 -#define JOB_UNB_SAVE 4 -#define JOB_UNB_RESTORE 5 -#define JOB_GMC_SAVE 6 -#define JOB_GMC_RESTORE 7 -#define JOB_GNB_SAVE 8 -#define JOB_GNB_RESTORE 9 - -#define IGNORE_JOB 0xff -#define END_OF_TASK_LIST (uint16_t)0xffff - -// Size of DRAM regions (in bytes) requested by SMU: -#define SMU_DRAM_REQ_MM_PWR_LOG 48 - -#define UCODE_ID_SDMA0 0 -#define UCODE_ID_SDMA1 1 -#define UCODE_ID_CP_CE 2 -#define UCODE_ID_CP_PFP 3 -#define UCODE_ID_CP_ME 4 -#define UCODE_ID_CP_MEC_JT1 5 -#define UCODE_ID_CP_MEC_JT2 6 -#define UCODE_ID_GMCON_RENG 7 -#define UCODE_ID_RLC_G 8 -#define UCODE_ID_RLC_SCRATCH 9 -#define UCODE_ID_RLC_SRM_ARAM 10 -#define UCODE_ID_RLC_SRM_DRAM 11 -#define UCODE_ID_DMCU_ERAM 12 -#define UCODE_ID_DMCU_IRAM 13 - -#define UCODE_ID_SDMA0_MASK 0x00000001 -#define UCODE_ID_SDMA1_MASK 0x00000002 -#define UCODE_ID_CP_CE_MASK 0x00000004 -#define UCODE_ID_CP_PFP_MASK 0x00000008 -#define UCODE_ID_CP_ME_MASK 0x00000010 -#define UCODE_ID_CP_MEC_JT1_MASK 0x00000020 -#define UCODE_ID_CP_MEC_JT2_MASK 0x00000040 -#define UCODE_ID_GMCON_RENG_MASK 0x00000080 -#define UCODE_ID_RLC_G_MASK 0x00000100 -#define UCODE_ID_RLC_SCRATCH_MASK 0x00000200 -#define UCODE_ID_RLC_SRM_ARAM_MASK 0x00000400 -#define UCODE_ID_RLC_SRM_DRAM_MASK 0x00000800 -#define UCODE_ID_DMCU_ERAM_MASK 0x00001000 -#define UCODE_ID_DMCU_IRAM_MASK 0x00002000 - -#define UCODE_ID_SDMA0_SIZE_BYTE 10368 -#define UCODE_ID_SDMA1_SIZE_BYTE 10368 -#define UCODE_ID_CP_CE_SIZE_BYTE 8576 -#define UCODE_ID_CP_PFP_SIZE_BYTE 16768 -#define UCODE_ID_CP_ME_SIZE_BYTE 16768 -#define UCODE_ID_CP_MEC_JT1_SIZE_BYTE 384 -#define UCODE_ID_CP_MEC_JT2_SIZE_BYTE 384 -#define UCODE_ID_GMCON_RENG_SIZE_BYTE 4096 -#define UCODE_ID_RLC_G_SIZE_BYTE 2048 -#define UCODE_ID_RLC_SCRATCH_SIZE_BYTE 132 -#define UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE 8192 -#define UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE 4096 -#define UCODE_ID_DMCU_ERAM_SIZE_BYTE 24576 -#define UCODE_ID_DMCU_IRAM_SIZE_BYTE 1024 - -#define NUM_UCODES 14 - -typedef struct { - uint32_t high; - uint32_t low; -} data_64_t; - -struct SMU_Task { - uint8_t type; - uint8_t arg; - uint16_t next; - data_64_t addr; - uint32_t size_bytes; -}; -typedef struct SMU_Task SMU_Task; - -struct TOC { - uint8_t JobList[NUM_JOBLIST_ENTRIES]; - SMU_Task tasks[1]; -}; - -// META DATA COMMAND Definitions -#define METADATA_CMD_MODE0 0x00000103 -#define METADATA_CMD_MODE1 0x00000113 -#define METADATA_CMD_MODE2 0x00000123 -#define METADATA_CMD_MODE3 0x00000133 -#define METADATA_CMD_DELAY 0x00000203 -#define METADATA_CMD_CHNG_REGSPACE 0x00000303 -#define METADATA_PERFORM_ON_SAVE 0x00001000 -#define METADATA_PERFORM_ON_LOAD 0x00002000 -#define METADATA_CMD_ARG_MASK 0xFFFF0000 -#define METADATA_CMD_ARG_SHIFT 16 - -// Simple register addr/data fields -struct SMU_MetaData_Mode0 { - uint32_t register_address; - uint32_t register_data; -}; -typedef struct SMU_MetaData_Mode0 SMU_MetaData_Mode0; - -// Register addr/data with mask -struct SMU_MetaData_Mode1 { - uint32_t register_address; - uint32_t register_mask; - uint32_t register_data; -}; -typedef struct SMU_MetaData_Mode1 SMU_MetaData_Mode1; - -struct SMU_MetaData_Mode2 { - uint32_t register_address; - uint32_t register_mask; - uint32_t target_value; -}; -typedef struct SMU_MetaData_Mode2 SMU_MetaData_Mode2; - -// Always write data (even on a save operation) -struct SMU_MetaData_Mode3 { - uint32_t register_address; - uint32_t register_mask; - uint32_t register_data; -}; -typedef struct SMU_MetaData_Mode3 SMU_MetaData_Mode3; - -#endif diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c index 204903897b4f..f4a1346525fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c @@ -24,7 +24,7 @@ #include <linux/firmware.h> #include "drmP.h" #include "amdgpu.h" -#include "tonga_smumgr.h" +#include "tonga_smum.h" MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index 743c372837aa..b6f7d7bff929 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -273,8 +273,14 @@ static void tonga_ih_set_rptr(struct amdgpu_device *adev) static int tonga_ih_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int ret; + + ret = amdgpu_irq_add_domain(adev); + if (ret) + return ret; tonga_ih_set_interrupt_funcs(adev); + return 0; } @@ -301,6 +307,7 @@ static int tonga_ih_sw_fini(void *handle) amdgpu_irq_fini(adev); amdgpu_ih_ring_fini(adev); + amdgpu_irq_add_domain(adev); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ppsmc.h b/drivers/gpu/drm/amd/amdgpu/tonga_ppsmc.h deleted file mode 100644 index 811781f69482..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ppsmc.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2014 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef TONGA_PP_SMC_H -#define TONGA_PP_SMC_H - -#pragma pack(push, 1) - -#define PPSMC_SWSTATE_FLAG_DC 0x01 -#define PPSMC_SWSTATE_FLAG_UVD 0x02 -#define PPSMC_SWSTATE_FLAG_VCE 0x04 -#define PPSMC_SWSTATE_FLAG_PCIE_X1 0x08 - -#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL 0x00 -#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL 0x01 -#define PPSMC_THERMAL_PROTECT_TYPE_NONE 0xff - -#define PPSMC_SYSTEMFLAG_GPIO_DC 0x01 -#define PPSMC_SYSTEMFLAG_STEPVDDC 0x02 -#define PPSMC_SYSTEMFLAG_GDDR5 0x04 - -#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP 0x08 - -#define PPSMC_SYSTEMFLAG_REGULATOR_HOT 0x10 -#define PPSMC_SYSTEMFLAG_REGULATOR_HOT_ANALOG 0x20 -#define PPSMC_SYSTEMFLAG_12CHANNEL 0x40 - -#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK 0x07 -#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK 0x08 - -#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE 0x00 -#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE 0x01 - -#define PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH 0x10 -#define PPSMC_EXTRAFLAGS_DRIVER_TO_GPIO17 0x20 -#define PPSMC_EXTRAFLAGS_PCC_TO_GPIO17 0x40 - -#define PPSMC_DPM2FLAGS_TDPCLMP 0x01 -#define PPSMC_DPM2FLAGS_PWRSHFT 0x02 -#define PPSMC_DPM2FLAGS_OCP 0x04 - -#define PPSMC_DISPLAY_WATERMARK_LOW 0 -#define PPSMC_DISPLAY_WATERMARK_HIGH 1 - -#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP 0x01 -#define PPSMC_STATEFLAG_POWERBOOST 0x02 -#define PPSMC_STATEFLAG_PSKIP_ON_TDP_FAULT 0x04 -#define PPSMC_STATEFLAG_POWERSHIFT 0x08 -#define PPSMC_STATEFLAG_SLOW_READ_MARGIN 0x10 -#define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 0x20 -#define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS 0x40 - -#define FDO_MODE_HARDWARE 0 -#define FDO_MODE_PIECE_WISE_LINEAR 1 - -enum FAN_CONTROL { - FAN_CONTROL_FUZZY, - FAN_CONTROL_TABLE -}; - -#define PPSMC_Result_OK ((uint16_t)0x01) -#define PPSMC_Result_NoMore ((uint16_t)0x02) -#define PPSMC_Result_NotNow ((uint16_t)0x03) -#define PPSMC_Result_Failed ((uint16_t)0xFF) -#define PPSMC_Result_UnknownCmd ((uint16_t)0xFE) -#define PPSMC_Result_UnknownVT ((uint16_t)0xFD) - -typedef uint16_t PPSMC_Result; - -#define PPSMC_isERROR(x) ((uint16_t)0x80 & (x)) - -#define PPSMC_MSG_Halt ((uint16_t)0x10) -#define PPSMC_MSG_Resume ((uint16_t)0x11) -#define PPSMC_MSG_EnableDPMLevel ((uint16_t)0x12) -#define PPSMC_MSG_ZeroLevelsDisabled ((uint16_t)0x13) -#define PPSMC_MSG_OneLevelsDisabled ((uint16_t)0x14) -#define PPSMC_MSG_TwoLevelsDisabled ((uint16_t)0x15) -#define PPSMC_MSG_EnableThermalInterrupt ((uint16_t)0x16) -#define PPSMC_MSG_RunningOnAC ((uint16_t)0x17) -#define PPSMC_MSG_LevelUp ((uint16_t)0x18) -#define PPSMC_MSG_LevelDown ((uint16_t)0x19) -#define PPSMC_MSG_ResetDPMCounters ((uint16_t)0x1a) -#define PPSMC_MSG_SwitchToSwState ((uint16_t)0x20) -#define PPSMC_MSG_SwitchToSwStateLast ((uint16_t)0x3f) -#define PPSMC_MSG_SwitchToInitialState ((uint16_t)0x40) -#define PPSMC_MSG_NoForcedLevel ((uint16_t)0x41) -#define PPSMC_MSG_ForceHigh ((uint16_t)0x42) -#define PPSMC_MSG_ForceMediumOrHigh ((uint16_t)0x43) -#define PPSMC_MSG_SwitchToMinimumPower ((uint16_t)0x51) -#define PPSMC_MSG_ResumeFromMinimumPower ((uint16_t)0x52) -#define PPSMC_MSG_EnableCac ((uint16_t)0x53) -#define PPSMC_MSG_DisableCac ((uint16_t)0x54) -#define PPSMC_DPMStateHistoryStart ((uint16_t)0x55) -#define PPSMC_DPMStateHistoryStop ((uint16_t)0x56) -#define PPSMC_CACHistoryStart ((uint16_t)0x57) -#define PPSMC_CACHistoryStop ((uint16_t)0x58) -#define PPSMC_TDPClampingActive ((uint16_t)0x59) -#define PPSMC_TDPClampingInactive ((uint16_t)0x5A) -#define PPSMC_StartFanControl ((uint16_t)0x5B) -#define PPSMC_StopFanControl ((uint16_t)0x5C) -#define PPSMC_NoDisplay ((uint16_t)0x5D) -#define PPSMC_HasDisplay ((uint16_t)0x5E) -#define PPSMC_MSG_UVDPowerOFF ((uint16_t)0x60) -#define PPSMC_MSG_UVDPowerON ((uint16_t)0x61) -#define PPSMC_MSG_EnableULV ((uint16_t)0x62) -#define PPSMC_MSG_DisableULV ((uint16_t)0x63) -#define PPSMC_MSG_EnterULV ((uint16_t)0x64) -#define PPSMC_MSG_ExitULV ((uint16_t)0x65) -#define PPSMC_PowerShiftActive ((uint16_t)0x6A) -#define PPSMC_PowerShiftInactive ((uint16_t)0x6B) -#define PPSMC_OCPActive ((uint16_t)0x6C) -#define PPSMC_OCPInactive ((uint16_t)0x6D) -#define PPSMC_CACLongTermAvgEnable ((uint16_t)0x6E) -#define PPSMC_CACLongTermAvgDisable ((uint16_t)0x6F) -#define PPSMC_MSG_InferredStateSweep_Start ((uint16_t)0x70) -#define PPSMC_MSG_InferredStateSweep_Stop ((uint16_t)0x71) -#define PPSMC_MSG_SwitchToLowestInfState ((uint16_t)0x72) -#define PPSMC_MSG_SwitchToNonInfState ((uint16_t)0x73) -#define PPSMC_MSG_AllStateSweep_Start ((uint16_t)0x74) -#define PPSMC_MSG_AllStateSweep_Stop ((uint16_t)0x75) -#define PPSMC_MSG_SwitchNextLowerInfState ((uint16_t)0x76) -#define PPSMC_MSG_SwitchNextHigherInfState ((uint16_t)0x77) -#define PPSMC_MSG_MclkRetrainingTest ((uint16_t)0x78) -#define PPSMC_MSG_ForceTDPClamping ((uint16_t)0x79) -#define PPSMC_MSG_CollectCAC_PowerCorreln ((uint16_t)0x7A) -#define PPSMC_MSG_CollectCAC_WeightCalib ((uint16_t)0x7B) -#define PPSMC_MSG_CollectCAC_SQonly ((uint16_t)0x7C) -#define PPSMC_MSG_CollectCAC_TemperaturePwr ((uint16_t)0x7D) -#define PPSMC_MSG_ExtremitiesTest_Start ((uint16_t)0x7E) -#define PPSMC_MSG_ExtremitiesTest_Stop ((uint16_t)0x7F) -#define PPSMC_FlushDataCache ((uint16_t)0x80) -#define PPSMC_FlushInstrCache ((uint16_t)0x81) -#define PPSMC_MSG_SetEnabledLevels ((uint16_t)0x82) -#define PPSMC_MSG_SetForcedLevels ((uint16_t)0x83) -#define PPSMC_MSG_ResetToDefaults ((uint16_t)0x84) -#define PPSMC_MSG_SetForcedLevelsAndJump ((uint16_t)0x85) -#define PPSMC_MSG_SetCACHistoryMode ((uint16_t)0x86) -#define PPSMC_MSG_EnableDTE ((uint16_t)0x87) -#define PPSMC_MSG_DisableDTE ((uint16_t)0x88) -#define PPSMC_MSG_SmcSpaceSetAddress ((uint16_t)0x89) -#define PPSMC_MSG_SmcSpaceWriteDWordInc ((uint16_t)0x8A) -#define PPSMC_MSG_SmcSpaceWriteWordInc ((uint16_t)0x8B) -#define PPSMC_MSG_SmcSpaceWriteByteInc ((uint16_t)0x8C) -#define PPSMC_MSG_ChangeNearTDPLimit ((uint16_t)0x90) -#define PPSMC_MSG_ChangeSafePowerLimit ((uint16_t)0x91) -#define PPSMC_MSG_DPMStateSweepStart ((uint16_t)0x92) -#define PPSMC_MSG_DPMStateSweepStop ((uint16_t)0x93) -#define PPSMC_MSG_OVRDDisableSCLKDS ((uint16_t)0x94) -#define PPSMC_MSG_CancelDisableOVRDSCLKDS ((uint16_t)0x95) -#define PPSMC_MSG_ThrottleOVRDSCLKDS ((uint16_t)0x96) -#define PPSMC_MSG_CancelThrottleOVRDSCLKDS ((uint16_t)0x97) -#define PPSMC_MSG_GPIO17 ((uint16_t)0x98) -#define PPSMC_MSG_API_SetSvi2Volt_Vddc ((uint16_t)0x99) -#define PPSMC_MSG_API_SetSvi2Volt_Vddci ((uint16_t)0x9A) -#define PPSMC_MSG_API_SetSvi2Volt_Mvdd ((uint16_t)0x9B) -#define PPSMC_MSG_API_GetSvi2Volt_Vddc ((uint16_t)0x9C) -#define PPSMC_MSG_API_GetSvi2Volt_Vddci ((uint16_t)0x9D) -#define PPSMC_MSG_API_GetSvi2Volt_Mvdd ((uint16_t)0x9E) - -#define PPSMC_MSG_BREAK ((uint16_t)0xF8) - -#define PPSMC_MSG_Test ((uint16_t)0x100) -#define PPSMC_MSG_DRV_DRAM_ADDR_HI ((uint16_t)0x250) -#define PPSMC_MSG_DRV_DRAM_ADDR_LO ((uint16_t)0x251) -#define PPSMC_MSG_SMU_DRAM_ADDR_HI ((uint16_t)0x252) -#define PPSMC_MSG_SMU_DRAM_ADDR_LO ((uint16_t)0x253) -#define PPSMC_MSG_LoadUcodes ((uint16_t)0x254) - -typedef uint16_t PPSMC_Msg; - -#define PPSMC_EVENT_STATUS_THERMAL 0x00000001 -#define PPSMC_EVENT_STATUS_REGULATORHOT 0x00000002 -#define PPSMC_EVENT_STATUS_DC 0x00000004 -#define PPSMC_EVENT_STATUS_GPIO17 0x00000008 - -#pragma pack(pop) - -#endif diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c index 5421309c1862..361c49a82323 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c @@ -25,7 +25,7 @@ #include "drmP.h" #include "amdgpu.h" #include "tonga_ppsmc.h" -#include "tonga_smumgr.h" +#include "tonga_smum.h" #include "smu_ucode_xfer_vi.h" #include "amdgpu_ucode.h" diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smumgr.h b/drivers/gpu/drm/amd/amdgpu/tonga_smum.h index c031ff99fe3e..c031ff99fe3e 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_smumgr.h +++ b/drivers/gpu/drm/amd/amdgpu/tonga_smum.h diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 121915bbc3b6..3d5913926436 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -279,6 +279,234 @@ static void uvd_v6_0_mc_resume(struct amdgpu_device *adev) WREG32(mmUVD_VCPU_CACHE_SIZE2, size); } +static void cz_set_uvd_clock_gating_branches(struct amdgpu_device *adev, + bool enable) +{ + u32 data, data1; + + data = RREG32(mmUVD_CGC_GATE); + data1 = RREG32(mmUVD_SUVD_CGC_GATE); + if (enable) { + data |= UVD_CGC_GATE__SYS_MASK | + UVD_CGC_GATE__UDEC_MASK | + UVD_CGC_GATE__MPEG2_MASK | + UVD_CGC_GATE__RBC_MASK | + UVD_CGC_GATE__LMI_MC_MASK | + UVD_CGC_GATE__IDCT_MASK | + UVD_CGC_GATE__MPRD_MASK | + UVD_CGC_GATE__MPC_MASK | + UVD_CGC_GATE__LBSI_MASK | + UVD_CGC_GATE__LRBBM_MASK | + UVD_CGC_GATE__UDEC_RE_MASK | + UVD_CGC_GATE__UDEC_CM_MASK | + UVD_CGC_GATE__UDEC_IT_MASK | + UVD_CGC_GATE__UDEC_DB_MASK | + UVD_CGC_GATE__UDEC_MP_MASK | + UVD_CGC_GATE__WCB_MASK | + UVD_CGC_GATE__VCPU_MASK | + UVD_CGC_GATE__SCPU_MASK; + data1 |= UVD_SUVD_CGC_GATE__SRE_MASK | + UVD_SUVD_CGC_GATE__SIT_MASK | + UVD_SUVD_CGC_GATE__SMP_MASK | + UVD_SUVD_CGC_GATE__SCM_MASK | + UVD_SUVD_CGC_GATE__SDB_MASK | + UVD_SUVD_CGC_GATE__SRE_H264_MASK | + UVD_SUVD_CGC_GATE__SRE_HEVC_MASK | + UVD_SUVD_CGC_GATE__SIT_H264_MASK | + UVD_SUVD_CGC_GATE__SIT_HEVC_MASK | + UVD_SUVD_CGC_GATE__SCM_H264_MASK | + UVD_SUVD_CGC_GATE__SCM_HEVC_MASK | + UVD_SUVD_CGC_GATE__SDB_H264_MASK | + UVD_SUVD_CGC_GATE__SDB_HEVC_MASK; + } else { + data &= ~(UVD_CGC_GATE__SYS_MASK | + UVD_CGC_GATE__UDEC_MASK | + UVD_CGC_GATE__MPEG2_MASK | + UVD_CGC_GATE__RBC_MASK | + UVD_CGC_GATE__LMI_MC_MASK | + UVD_CGC_GATE__LMI_UMC_MASK | + UVD_CGC_GATE__IDCT_MASK | + UVD_CGC_GATE__MPRD_MASK | + UVD_CGC_GATE__MPC_MASK | + UVD_CGC_GATE__LBSI_MASK | + UVD_CGC_GATE__LRBBM_MASK | + UVD_CGC_GATE__UDEC_RE_MASK | + UVD_CGC_GATE__UDEC_CM_MASK | + UVD_CGC_GATE__UDEC_IT_MASK | + UVD_CGC_GATE__UDEC_DB_MASK | + UVD_CGC_GATE__UDEC_MP_MASK | + UVD_CGC_GATE__WCB_MASK | + UVD_CGC_GATE__VCPU_MASK | + UVD_CGC_GATE__SCPU_MASK); + data1 &= ~(UVD_SUVD_CGC_GATE__SRE_MASK | + UVD_SUVD_CGC_GATE__SIT_MASK | + UVD_SUVD_CGC_GATE__SMP_MASK | + UVD_SUVD_CGC_GATE__SCM_MASK | + UVD_SUVD_CGC_GATE__SDB_MASK | + UVD_SUVD_CGC_GATE__SRE_H264_MASK | + UVD_SUVD_CGC_GATE__SRE_HEVC_MASK | + UVD_SUVD_CGC_GATE__SIT_H264_MASK | + UVD_SUVD_CGC_GATE__SIT_HEVC_MASK | + UVD_SUVD_CGC_GATE__SCM_H264_MASK | + UVD_SUVD_CGC_GATE__SCM_HEVC_MASK | + UVD_SUVD_CGC_GATE__SDB_H264_MASK | + UVD_SUVD_CGC_GATE__SDB_HEVC_MASK); + } + WREG32(mmUVD_CGC_GATE, data); + WREG32(mmUVD_SUVD_CGC_GATE, data1); +} + +static void tonga_set_uvd_clock_gating_branches(struct amdgpu_device *adev, + bool enable) +{ + u32 data, data1; + + data = RREG32(mmUVD_CGC_GATE); + data1 = RREG32(mmUVD_SUVD_CGC_GATE); + if (enable) { + data |= UVD_CGC_GATE__SYS_MASK | + UVD_CGC_GATE__UDEC_MASK | + UVD_CGC_GATE__MPEG2_MASK | + UVD_CGC_GATE__RBC_MASK | + UVD_CGC_GATE__LMI_MC_MASK | + UVD_CGC_GATE__IDCT_MASK | + UVD_CGC_GATE__MPRD_MASK | + UVD_CGC_GATE__MPC_MASK | + UVD_CGC_GATE__LBSI_MASK | + UVD_CGC_GATE__LRBBM_MASK | + UVD_CGC_GATE__UDEC_RE_MASK | + UVD_CGC_GATE__UDEC_CM_MASK | + UVD_CGC_GATE__UDEC_IT_MASK | + UVD_CGC_GATE__UDEC_DB_MASK | + UVD_CGC_GATE__UDEC_MP_MASK | + UVD_CGC_GATE__WCB_MASK | + UVD_CGC_GATE__VCPU_MASK | + UVD_CGC_GATE__SCPU_MASK; + data1 |= UVD_SUVD_CGC_GATE__SRE_MASK | + UVD_SUVD_CGC_GATE__SIT_MASK | + UVD_SUVD_CGC_GATE__SMP_MASK | + UVD_SUVD_CGC_GATE__SCM_MASK | + UVD_SUVD_CGC_GATE__SDB_MASK; + } else { + data &= ~(UVD_CGC_GATE__SYS_MASK | + UVD_CGC_GATE__UDEC_MASK | + UVD_CGC_GATE__MPEG2_MASK | + UVD_CGC_GATE__RBC_MASK | + UVD_CGC_GATE__LMI_MC_MASK | + UVD_CGC_GATE__LMI_UMC_MASK | + UVD_CGC_GATE__IDCT_MASK | + UVD_CGC_GATE__MPRD_MASK | + UVD_CGC_GATE__MPC_MASK | + UVD_CGC_GATE__LBSI_MASK | + UVD_CGC_GATE__LRBBM_MASK | + UVD_CGC_GATE__UDEC_RE_MASK | + UVD_CGC_GATE__UDEC_CM_MASK | + UVD_CGC_GATE__UDEC_IT_MASK | + UVD_CGC_GATE__UDEC_DB_MASK | + UVD_CGC_GATE__UDEC_MP_MASK | + UVD_CGC_GATE__WCB_MASK | + UVD_CGC_GATE__VCPU_MASK | + UVD_CGC_GATE__SCPU_MASK); + data1 &= ~(UVD_SUVD_CGC_GATE__SRE_MASK | + UVD_SUVD_CGC_GATE__SIT_MASK | + UVD_SUVD_CGC_GATE__SMP_MASK | + UVD_SUVD_CGC_GATE__SCM_MASK | + UVD_SUVD_CGC_GATE__SDB_MASK); + } + WREG32(mmUVD_CGC_GATE, data); + WREG32(mmUVD_SUVD_CGC_GATE, data1); +} + +static void uvd_v6_0_set_uvd_dynamic_clock_mode(struct amdgpu_device *adev, + bool swmode) +{ + u32 data, data1 = 0, data2; + + /* Always un-gate UVD REGS bit */ + data = RREG32(mmUVD_CGC_GATE); + data &= ~(UVD_CGC_GATE__REGS_MASK); + WREG32(mmUVD_CGC_GATE, data); + + data = RREG32(mmUVD_CGC_CTRL); + data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | + UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK); + data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK | + 1 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_GATE_DLY_TIMER) | + 4 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_OFF_DELAY); + + data2 = RREG32(mmUVD_SUVD_CGC_CTRL); + if (swmode) { + data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK | + UVD_CGC_CTRL__UDEC_CM_MODE_MASK | + UVD_CGC_CTRL__UDEC_IT_MODE_MASK | + UVD_CGC_CTRL__UDEC_DB_MODE_MASK | + UVD_CGC_CTRL__UDEC_MP_MODE_MASK | + UVD_CGC_CTRL__SYS_MODE_MASK | + UVD_CGC_CTRL__UDEC_MODE_MASK | + UVD_CGC_CTRL__MPEG2_MODE_MASK | + UVD_CGC_CTRL__REGS_MODE_MASK | + UVD_CGC_CTRL__RBC_MODE_MASK | + UVD_CGC_CTRL__LMI_MC_MODE_MASK | + UVD_CGC_CTRL__LMI_UMC_MODE_MASK | + UVD_CGC_CTRL__IDCT_MODE_MASK | + UVD_CGC_CTRL__MPRD_MODE_MASK | + UVD_CGC_CTRL__MPC_MODE_MASK | + UVD_CGC_CTRL__LBSI_MODE_MASK | + UVD_CGC_CTRL__LRBBM_MODE_MASK | + UVD_CGC_CTRL__WCB_MODE_MASK | + UVD_CGC_CTRL__VCPU_MODE_MASK | + UVD_CGC_CTRL__JPEG_MODE_MASK | + UVD_CGC_CTRL__SCPU_MODE_MASK); + data1 |= UVD_CGC_CTRL2__DYN_OCLK_RAMP_EN_MASK | + UVD_CGC_CTRL2__DYN_RCLK_RAMP_EN_MASK; + data1 &= ~UVD_CGC_CTRL2__GATER_DIV_ID_MASK; + data1 |= 7 << REG_FIELD_SHIFT(UVD_CGC_CTRL2, GATER_DIV_ID); + data2 &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK | + UVD_SUVD_CGC_CTRL__SIT_MODE_MASK | + UVD_SUVD_CGC_CTRL__SMP_MODE_MASK | + UVD_SUVD_CGC_CTRL__SCM_MODE_MASK | + UVD_SUVD_CGC_CTRL__SDB_MODE_MASK); + } else { + data |= UVD_CGC_CTRL__UDEC_RE_MODE_MASK | + UVD_CGC_CTRL__UDEC_CM_MODE_MASK | + UVD_CGC_CTRL__UDEC_IT_MODE_MASK | + UVD_CGC_CTRL__UDEC_DB_MODE_MASK | + UVD_CGC_CTRL__UDEC_MP_MODE_MASK | + UVD_CGC_CTRL__SYS_MODE_MASK | + UVD_CGC_CTRL__UDEC_MODE_MASK | + UVD_CGC_CTRL__MPEG2_MODE_MASK | + UVD_CGC_CTRL__REGS_MODE_MASK | + UVD_CGC_CTRL__RBC_MODE_MASK | + UVD_CGC_CTRL__LMI_MC_MODE_MASK | + UVD_CGC_CTRL__LMI_UMC_MODE_MASK | + UVD_CGC_CTRL__IDCT_MODE_MASK | + UVD_CGC_CTRL__MPRD_MODE_MASK | + UVD_CGC_CTRL__MPC_MODE_MASK | + UVD_CGC_CTRL__LBSI_MODE_MASK | + UVD_CGC_CTRL__LRBBM_MODE_MASK | + UVD_CGC_CTRL__WCB_MODE_MASK | + UVD_CGC_CTRL__VCPU_MODE_MASK | + UVD_CGC_CTRL__SCPU_MODE_MASK; + data2 |= UVD_SUVD_CGC_CTRL__SRE_MODE_MASK | + UVD_SUVD_CGC_CTRL__SIT_MODE_MASK | + UVD_SUVD_CGC_CTRL__SMP_MODE_MASK | + UVD_SUVD_CGC_CTRL__SCM_MODE_MASK | + UVD_SUVD_CGC_CTRL__SDB_MODE_MASK; + } + WREG32(mmUVD_CGC_CTRL, data); + WREG32(mmUVD_SUVD_CGC_CTRL, data2); + + data = RREG32_UVD_CTX(ixUVD_CGC_CTRL2); + data &= ~(REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_OCLK_RAMP_EN) | + REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_RCLK_RAMP_EN) | + REG_FIELD_MASK(UVD_CGC_CTRL2, GATER_DIV_ID)); + data1 &= (REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_OCLK_RAMP_EN) | + REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_RCLK_RAMP_EN) | + REG_FIELD_MASK(UVD_CGC_CTRL2, GATER_DIV_ID)); + data |= data1; + WREG32_UVD_CTX(ixUVD_CGC_CTRL2, data); +} + /** * uvd_v6_0_start - start UVD block * @@ -303,8 +531,19 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) uvd_v6_0_mc_resume(adev); - /* disable clock gating */ - WREG32(mmUVD_CGC_GATE, 0); + /* Set dynamic clock gating in S/W control mode */ + if (adev->cg_flags & AMDGPU_CG_SUPPORT_UVD_MGCG) { + if (adev->flags & AMD_IS_APU) + cz_set_uvd_clock_gating_branches(adev, false); + else + tonga_set_uvd_clock_gating_branches(adev, false); + uvd_v6_0_set_uvd_dynamic_clock_mode(adev, true); + } else { + /* disable clock gating */ + uint32_t data = RREG32(mmUVD_CGC_CTRL); + data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; + WREG32(mmUVD_CGC_CTRL, data); + } /* disable interupt */ WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1)); @@ -758,6 +997,24 @@ static int uvd_v6_0_process_interrupt(struct amdgpu_device *adev, static int uvd_v6_0_set_clockgating_state(void *handle, enum amd_clockgating_state state) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + bool enable = (state == AMD_CG_STATE_GATE) ? true : false; + + if (!(adev->cg_flags & AMDGPU_CG_SUPPORT_UVD_MGCG)) + return 0; + + if (enable) { + if (adev->flags & AMD_IS_APU) + cz_set_uvd_clock_gating_branches(adev, enable); + else + tonga_set_uvd_clock_gating_branches(adev, enable); + uvd_v6_0_set_uvd_dynamic_clock_mode(adev, true); + } else { + uint32_t data = RREG32(mmUVD_CGC_CTRL); + data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; + WREG32(mmUVD_CGC_CTRL, data); + } + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 6a52db6ad8d7..e99af81e4aec 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -40,6 +40,9 @@ #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 +#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0 0x8616 +#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1 0x8617 +#define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2 0x8618 #define VCE_V3_0_FW_SIZE (384 * 1024) #define VCE_V3_0_STACK_SIZE (64 * 1024) @@ -100,6 +103,108 @@ static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring) WREG32(mmVCE_RB_WPTR2, ring->wptr); } +static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override) +{ + u32 tmp, data; + + tmp = data = RREG32(mmVCE_RB_ARB_CTRL); + if (override) + data |= VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK; + else + data &= ~VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK; + + if (tmp != data) + WREG32(mmVCE_RB_ARB_CTRL, data); +} + +static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev, + bool gated) +{ + u32 tmp, data; + /* Set Override to disable Clock Gating */ + vce_v3_0_override_vce_clock_gating(adev, true); + + if (!gated) { + /* Force CLOCK ON for VCE_CLOCK_GATING_B, + * {*_FORCE_ON, *_FORCE_OFF} = {1, 0} + * VREG can be FORCE ON or set to Dynamic, but can't be OFF + */ + tmp = data = RREG32(mmVCE_CLOCK_GATING_B); + data |= 0x1ff; + data &= ~0xef0000; + if (tmp != data) + WREG32(mmVCE_CLOCK_GATING_B, data); + + /* Force CLOCK ON for VCE_UENC_CLOCK_GATING, + * {*_FORCE_ON, *_FORCE_OFF} = {1, 0} + */ + tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING); + data |= 0x3ff000; + data &= ~0xffc00000; + if (tmp != data) + WREG32(mmVCE_UENC_CLOCK_GATING, data); + + /* set VCE_UENC_CLOCK_GATING_2 */ + tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2); + data |= 0x2; + data &= ~0x2; + if (tmp != data) + WREG32(mmVCE_UENC_CLOCK_GATING_2, data); + + /* Force CLOCK ON for VCE_UENC_REG_CLOCK_GATING */ + tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING); + data |= 0x37f; + if (tmp != data) + WREG32(mmVCE_UENC_REG_CLOCK_GATING, data); + + /* Force VCE_UENC_DMA_DCLK_CTRL Clock ON */ + tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL); + data |= VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK | + VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK | + VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK | + 0x8; + if (tmp != data) + WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data); + } else { + /* Force CLOCK OFF for VCE_CLOCK_GATING_B, + * {*, *_FORCE_OFF} = {*, 1} + * set VREG to Dynamic, as it can't be OFF + */ + tmp = data = RREG32(mmVCE_CLOCK_GATING_B); + data &= ~0x80010; + data |= 0xe70008; + if (tmp != data) + WREG32(mmVCE_CLOCK_GATING_B, data); + /* Force CLOCK OFF for VCE_UENC_CLOCK_GATING, + * Force ClOCK OFF takes precedent over Force CLOCK ON setting. + * {*_FORCE_ON, *_FORCE_OFF} = {*, 1} + */ + tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING); + data |= 0xffc00000; + if (tmp != data) + WREG32(mmVCE_UENC_CLOCK_GATING, data); + /* Set VCE_UENC_CLOCK_GATING_2 */ + tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2); + data |= 0x10000; + if (tmp != data) + WREG32(mmVCE_UENC_CLOCK_GATING_2, data); + /* Set VCE_UENC_REG_CLOCK_GATING to dynamic */ + tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING); + data &= ~0xffc00000; + if (tmp != data) + WREG32(mmVCE_UENC_REG_CLOCK_GATING, data); + /* Set VCE_UENC_DMA_DCLK_CTRL CG always in dynamic mode */ + tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL); + data &= ~(VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK | + VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK | + VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK | + 0x8); + if (tmp != data) + WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data); + } + vce_v3_0_override_vce_clock_gating(adev, false); +} + /** * vce_v3_0_start - start VCE block * @@ -118,7 +223,7 @@ static int vce_v3_0_start(struct amdgpu_device *adev) if (adev->vce.harvest_config & (1 << idx)) continue; - if(idx == 0) + if (idx == 0) WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); else @@ -130,9 +235,11 @@ static int vce_v3_0_start(struct amdgpu_device *adev) /* set BUSY flag */ WREG32_P(mmVCE_STATUS, 1, ~1); - - WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, - ~VCE_VCPU_CNTL__CLK_EN_MASK); + if (adev->asic_type >= CHIP_STONEY) + WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001); + else + WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, + ~VCE_VCPU_CNTL__CLK_EN_MASK); WREG32_P(mmVCE_SOFT_RESET, VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, @@ -169,6 +276,10 @@ static int vce_v3_0_start(struct amdgpu_device *adev) /* clear BUSY flag */ WREG32_P(mmVCE_STATUS, 0, ~1); + /* Set Clock-Gating off */ + if (adev->cg_flags & AMDGPU_CG_SUPPORT_VCE_MGCG) + vce_v3_0_set_vce_sw_clock_gating(adev, false); + if (r) { DRM_ERROR("VCE not responding, giving up!!!\n"); mutex_unlock(&adev->grbm_idx_mutex); @@ -203,14 +314,11 @@ static int vce_v3_0_start(struct amdgpu_device *adev) static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev) { u32 tmp; - unsigned ret; /* Fiji, Stoney are single pipe */ if ((adev->asic_type == CHIP_FIJI) || - (adev->asic_type == CHIP_STONEY)){ - ret = AMDGPU_VCE_HARVEST_VCE1; - return ret; - } + (adev->asic_type == CHIP_STONEY)) + return AMDGPU_VCE_HARVEST_VCE1; /* Tonga and CZ are dual or single pipe */ if (adev->flags & AMD_IS_APU) @@ -224,19 +332,14 @@ static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev) switch (tmp) { case 1: - ret = AMDGPU_VCE_HARVEST_VCE0; - break; + return AMDGPU_VCE_HARVEST_VCE0; case 2: - ret = AMDGPU_VCE_HARVEST_VCE1; - break; + return AMDGPU_VCE_HARVEST_VCE1; case 3: - ret = AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1; - break; + return AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1; default: - ret = 0; + return 0; } - - return ret; } static int vce_v3_0_early_init(void *handle) @@ -311,28 +414,22 @@ static int vce_v3_0_sw_fini(void *handle) static int vce_v3_0_hw_init(void *handle) { - struct amdgpu_ring *ring; - int r; + int r, i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; r = vce_v3_0_start(adev); if (r) return r; - ring = &adev->vce.ring[0]; - ring->ready = true; - r = amdgpu_ring_test_ring(ring); - if (r) { - ring->ready = false; - return r; - } + adev->vce.ring[0].ready = false; + adev->vce.ring[1].ready = false; - ring = &adev->vce.ring[1]; - ring->ready = true; - r = amdgpu_ring_test_ring(ring); - if (r) { - ring->ready = false; - return r; + for (i = 0; i < 2; i++) { + r = amdgpu_ring_test_ring(&adev->vce.ring[i]); + if (r) + return r; + else + adev->vce.ring[i].ready = true; } DRM_INFO("VCE initialized successfully.\n"); @@ -391,8 +488,12 @@ static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx) WREG32(mmVCE_LMI_SWAP_CNTL, 0); WREG32(mmVCE_LMI_SWAP_CNTL1, 0); WREG32(mmVCE_LMI_VM_CTRL, 0); - - WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); + if (adev->asic_type >= CHIP_STONEY) { + WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8)); + WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8)); + WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8)); + } else + WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); offset = AMDGPU_VCE_FIRMWARE_OFFSET; size = VCE_V3_0_FW_SIZE; WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); @@ -428,17 +529,9 @@ static bool vce_v3_0_is_idle(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; u32 mask = 0; - int idx; - for (idx = 0; idx < 2; ++idx) { - if (adev->vce.harvest_config & (1 << idx)) - continue; - - if (idx == 0) - mask |= SRBM_STATUS2__VCE0_BUSY_MASK; - else - mask |= SRBM_STATUS2__VCE1_BUSY_MASK; - } + mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK; + mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_STATUS2__VCE1_BUSY_MASK; return !(RREG32(mmSRBM_STATUS2) & mask); } @@ -447,23 +540,11 @@ static int vce_v3_0_wait_for_idle(void *handle) { unsigned i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - u32 mask = 0; - int idx; - - for (idx = 0; idx < 2; ++idx) { - if (adev->vce.harvest_config & (1 << idx)) - continue; - if (idx == 0) - mask |= SRBM_STATUS2__VCE0_BUSY_MASK; - else - mask |= SRBM_STATUS2__VCE1_BUSY_MASK; - } - - for (i = 0; i < adev->usec_timeout; i++) { - if (!(RREG32(mmSRBM_STATUS2) & mask)) + for (i = 0; i < adev->usec_timeout; i++) + if (vce_v3_0_is_idle(handle)) return 0; - } + return -ETIMEDOUT; } @@ -471,17 +552,10 @@ static int vce_v3_0_soft_reset(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; u32 mask = 0; - int idx; - for (idx = 0; idx < 2; ++idx) { - if (adev->vce.harvest_config & (1 << idx)) - continue; + mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK; + mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK; - if (idx == 0) - mask |= SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK; - else - mask |= SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK; - } WREG32_P(mmSRBM_SOFT_RESET, mask, ~(SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK | SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK)); @@ -576,12 +650,15 @@ static int vce_v3_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_iv_entry *entry) { DRM_DEBUG("IH: VCE\n"); + + WREG32_P(mmVCE_SYS_INT_STATUS, + VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK, + ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK); + switch (entry->src_data) { case 0: - amdgpu_fence_process(&adev->vce.ring[0]); - break; case 1: - amdgpu_fence_process(&adev->vce.ring[1]); + amdgpu_fence_process(&adev->vce.ring[entry->src_data]); break; default: DRM_ERROR("Unhandled interrupt: %d %d\n", @@ -595,6 +672,47 @@ static int vce_v3_0_process_interrupt(struct amdgpu_device *adev, static int vce_v3_0_set_clockgating_state(void *handle, enum amd_clockgating_state state) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + bool enable = (state == AMD_CG_STATE_GATE) ? true : false; + int i; + + if (!(adev->cg_flags & AMDGPU_CG_SUPPORT_VCE_MGCG)) + return 0; + + mutex_lock(&adev->grbm_idx_mutex); + for (i = 0; i < 2; i++) { + /* Program VCE Instance 0 or 1 if not harvested */ + if (adev->vce.harvest_config & (1 << i)) + continue; + + if (i == 0) + WREG32_P(mmGRBM_GFX_INDEX, 0, + ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); + else + WREG32_P(mmGRBM_GFX_INDEX, + GRBM_GFX_INDEX__VCE_INSTANCE_MASK, + ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); + + if (enable) { + /* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */ + uint32_t data = RREG32(mmVCE_CLOCK_GATING_A); + data &= ~(0xf | 0xff0); + data |= ((0x0 << 0) | (0x04 << 4)); + WREG32(mmVCE_CLOCK_GATING_A, data); + + /* initialize VCE_UENC_CLOCK_GATING: Clock ON/OFF delay */ + data = RREG32(mmVCE_UENC_CLOCK_GATING); + data &= ~(0xf | 0xff0); + data |= ((0x0 << 0) | (0x04 << 4)); + WREG32(mmVCE_UENC_CLOCK_GATING, data); + } + + vce_v3_0_set_vce_sw_clock_gating(adev, enable); + } + + WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); + mutex_unlock(&adev->grbm_idx_mutex); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 2adc1c855e85..652e76644c31 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -31,6 +31,7 @@ #include "amdgpu_vce.h" #include "amdgpu_ucode.h" #include "atom.h" +#include "amd_pcie.h" #include "gmc/gmc_8_1_d.h" #include "gmc/gmc_8_1_sh_mask.h" @@ -71,6 +72,7 @@ #include "uvd_v5_0.h" #include "uvd_v6_0.h" #include "vce_v3_0.h" +#include "amdgpu_powerplay.h" /* * Indirect registers accessor @@ -376,6 +378,38 @@ static bool vi_read_disabled_bios(struct amdgpu_device *adev) WREG32_SMC(ixROM_CNTL, rom_cntl); return r; } + +static bool vi_read_bios_from_rom(struct amdgpu_device *adev, + u8 *bios, u32 length_bytes) +{ + u32 *dw_ptr; + unsigned long flags; + u32 i, length_dw; + + if (bios == NULL) + return false; + if (length_bytes == 0) + return false; + /* APU vbios image is part of sbios image */ + if (adev->flags & AMD_IS_APU) + return false; + + dw_ptr = (u32 *)bios; + length_dw = ALIGN(length_bytes, 4) / 4; + /* take the smc lock since we are using the smc index */ + spin_lock_irqsave(&adev->smc_idx_lock, flags); + /* set rom index to 0 */ + WREG32(mmSMC_IND_INDEX_0, ixROM_INDEX); + WREG32(mmSMC_IND_DATA_0, 0); + /* set index to data for continous read */ + WREG32(mmSMC_IND_INDEX_0, ixROM_DATA); + for (i = 0; i < length_dw; i++) + dw_ptr[i] = RREG32(mmSMC_IND_DATA_0); + spin_unlock_irqrestore(&adev->smc_idx_lock, flags); + + return true; +} + static struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { {mmGB_MACROTILE_MODE7, true}, }; @@ -1019,9 +1053,6 @@ static int vi_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk) static void vi_pcie_gen3_enable(struct amdgpu_device *adev) { - u32 mask; - int ret; - if (pci_is_root_bus(adev->pdev->bus)) return; @@ -1031,11 +1062,8 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev) if (adev->flags & AMD_IS_APU) return; - ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); - if (ret != 0) - return; - - if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80))) + if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) return; /* todo */ @@ -1098,7 +1126,7 @@ static const struct amdgpu_ip_block_version topaz_ip_blocks[] = .major = 7, .minor = 1, .rev = 0, - .funcs = &iceland_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_GFX, @@ -1145,7 +1173,7 @@ static const struct amdgpu_ip_block_version tonga_ip_blocks[] = .major = 7, .minor = 1, .rev = 0, - .funcs = &tonga_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -1213,7 +1241,7 @@ static const struct amdgpu_ip_block_version fiji_ip_blocks[] = .major = 7, .minor = 1, .rev = 0, - .funcs = &fiji_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -1281,7 +1309,7 @@ static const struct amdgpu_ip_block_version cz_ip_blocks[] = .major = 8, .minor = 0, .rev = 0, - .funcs = &cz_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -1354,20 +1382,18 @@ int vi_set_ip_blocks(struct amdgpu_device *adev) static uint32_t vi_get_rev_id(struct amdgpu_device *adev) { - if (adev->asic_type == CHIP_TOPAZ) - return (RREG32(mmPCIE_EFUSE4) & PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID_MASK) - >> PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID__SHIFT; - else if (adev->flags & AMD_IS_APU) + if (adev->flags & AMD_IS_APU) return (RREG32_SMC(ATI_REV_ID_FUSE_MACRO__ADDRESS) & ATI_REV_ID_FUSE_MACRO__MASK) >> ATI_REV_ID_FUSE_MACRO__SHIFT; else - return (RREG32(mmCC_DRM_ID_STRAPS) & CC_DRM_ID_STRAPS__ATI_REV_ID_MASK) - >> CC_DRM_ID_STRAPS__ATI_REV_ID__SHIFT; + return (RREG32(mmPCIE_EFUSE4) & PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID_MASK) + >> PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID__SHIFT; } static const struct amdgpu_asic_funcs vi_asic_funcs = { .read_disabled_bios = &vi_read_disabled_bios, + .read_bios_from_rom = &vi_read_bios_from_rom, .read_register = &vi_read_register, .reset = &vi_asic_reset, .set_vga_state = &vi_vga_set_state, @@ -1416,7 +1442,8 @@ static int vi_common_early_init(void *handle) break; case CHIP_FIJI: adev->has_uvd = true; - adev->cg_flags = 0; + adev->cg_flags = AMDGPU_CG_SUPPORT_UVD_MGCG | + AMDGPU_CG_SUPPORT_VCE_MGCG; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x3c; break; @@ -1442,6 +1469,8 @@ static int vi_common_early_init(void *handle) if (amdgpu_smc_load_fw && smc_enabled) adev->firmware.smu_load = true; + amdgpu_get_pcie_info(adev); + return 0; } @@ -1515,9 +1544,95 @@ static int vi_common_soft_reset(void *handle) return 0; } +static void fiji_update_bif_medium_grain_light_sleep(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + temp = data = RREG32_PCIE(ixPCIE_CNTL2); + + if (enable) + data |= PCIE_CNTL2__SLV_MEM_LS_EN_MASK | + PCIE_CNTL2__MST_MEM_LS_EN_MASK | + PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK; + else + data &= ~(PCIE_CNTL2__SLV_MEM_LS_EN_MASK | + PCIE_CNTL2__MST_MEM_LS_EN_MASK | + PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK); + + if (temp != data) + WREG32_PCIE(ixPCIE_CNTL2, data); +} + +static void fiji_update_hdp_medium_grain_clock_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + temp = data = RREG32(mmHDP_HOST_PATH_CNTL); + + if (enable) + data &= ~HDP_HOST_PATH_CNTL__CLOCK_GATING_DIS_MASK; + else + data |= HDP_HOST_PATH_CNTL__CLOCK_GATING_DIS_MASK; + + if (temp != data) + WREG32(mmHDP_HOST_PATH_CNTL, data); +} + +static void fiji_update_hdp_light_sleep(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + temp = data = RREG32(mmHDP_MEM_POWER_LS); + + if (enable) + data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK; + else + data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK; + + if (temp != data) + WREG32(mmHDP_MEM_POWER_LS, data); +} + +static void fiji_update_rom_medium_grain_clock_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + temp = data = RREG32_SMC(ixCGTT_ROM_CLK_CTRL0); + + if (enable) + data &= ~(CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK | + CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK); + else + data |= CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK | + CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK; + + if (temp != data) + WREG32_SMC(ixCGTT_ROM_CLK_CTRL0, data); +} + static int vi_common_set_clockgating_state(void *handle, enum amd_clockgating_state state) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + switch (adev->asic_type) { + case CHIP_FIJI: + fiji_update_bif_medium_grain_light_sleep(adev, + state == AMD_CG_STATE_GATE ? true : false); + fiji_update_hdp_medium_grain_clock_gating(adev, + state == AMD_CG_STATE_GATE ? true : false); + fiji_update_hdp_light_sleep(adev, + state == AMD_CG_STATE_GATE ? true : false); + fiji_update_rom_medium_grain_clock_gating(adev, + state == AMD_CG_STATE_GATE ? true : false); + break; + default: + break; + } return 0; } |