Merge tag 'amd-drm-next-5.17-2021-12-02' of https://gitlab.freedesktop.org/agd5f...
authorDave Airlie <airlied@redhat.com>
Fri, 10 Dec 2021 03:52:51 +0000 (13:52 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 10 Dec 2021 03:52:51 +0000 (13:52 +1000)
amd-drm-next-5.17-2021-12-02:

amdgpu:
- Use generic drm fb helpers
- PSR fixes
- Rework DCN3.1 clkmgr
- DPCD 1.3 fixes
- Misc display fixes can cleanups
- Clock query fixes for APUs
- LTTPR fixes
- DSC fixes
- Misc PM fixes
- RAS fixes
- OLED backlight fix
- SRIOV fixes
- Add STB (Smart Trace Buffer) for supported dGPUs
- IH rework
- Enable seamless boot for DCN3.01

amdkfd:
- Rework more stuff around IP discovery enumeration
- Further clean up of interfaces with amdgpu
- SVM fixes

radeon:
- Indentation fixes

UAPI:
- Add a new KFD header that defines some of the sysfs bitfields and enums that userspace has been using for a while
  The corresponding bit-fields and enums in user mode are defined in
  https://github.com/RadeonOpenCompute/ROCT-Thunk-Interface/blob/master/include/hsakmttypes.h

Signed-off-by: Dave Airlie <airlied@redhat.com>
# Conflicts:
# drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211202191643.5970-1-alexander.deucher@amd.com
156 files changed:
MAINTAINERS
drivers/gpu/drm/amd/amdgpu/Makefile
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c [deleted file]
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/navi10_ih.c
drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
drivers/gpu/drm/amd/amdgpu/nv.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/amdgpu/umc_v6_7.c
drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_crat.c
drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c
drivers/gpu/drm/amd/amdkfd/kfd_events.c
drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/amd/amdkfd/kfd_topology.c
drivers/gpu/drm/amd/amdkfd/kfd_topology.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/core/dc_sink.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/dml_wrapper_translation.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h
drivers/gpu/drm/amd/display/dc/inc/dml_wrapper.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h
drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
drivers/gpu/drm/amd/display/include/ddc_service_types.h
drivers/gpu/drm/amd/display/include/logger_types.h
drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_offset.h
drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_sh_mask.h
drivers/gpu/drm/amd/include/kgd_kfd_interface.h
drivers/gpu/drm/amd/pm/amdgpu_pm.c
drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/inc/smu13_driver_if_aldebaran.h
drivers/gpu/drm/amd/pm/inc/smu_v13_0.h
drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
drivers/gpu/drm/radeon/radeon_kms.c
include/uapi/linux/kfd_sysfs.h [new file with mode: 0644]

index 53b859d10de692944ce4f2c11b62217ca929b079..ae021c31158dbaeb73aa9921238485a646a1cfd2 100644 (file)
@@ -966,6 +966,7 @@ F:  drivers/gpu/drm/amd/include/kgd_kfd_interface.h
 F:     drivers/gpu/drm/amd/include/v9_structs.h
 F:     drivers/gpu/drm/amd/include/vi_structs.h
 F:     include/uapi/linux/kfd_ioctl.h
+F:     include/uapi/linux/kfd_sysfs.h
 
 AMD SPI DRIVER
 M:     Sanjay R Mehta <sanju.mehta@amd.com>
index 653726588956ef4b1f155fd489ca1bbdc5fce34f..7fedbb725e179e700513c35aea6dacf949bf964f 100644 (file)
@@ -45,7 +45,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
        amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
        atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
        amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
-       amdgpu_fb.o amdgpu_gem.o amdgpu_ring.o \
+       amdgpu_gem.o amdgpu_ring.o \
        amdgpu_cs.o amdgpu_bios.o amdgpu_benchmark.o amdgpu_test.o \
        atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \
        atombios_encoders.o amdgpu_sa.o atombios_i2c.o \
index 7077f21f002123f26e9bc7af314ef8ad9b41f8fb..46cf48b3904ac11297f95e9f3890886e2113f453 100644 (file)
@@ -72,7 +72,7 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
        if (!kfd_initialized)
                return;
 
-       adev->kfd.dev = kgd2kfd_probe((struct kgd_dev *)adev, vf);
+       adev->kfd.dev = kgd2kfd_probe(adev, vf);
 
        if (adev->kfd.dev)
                amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
@@ -233,19 +233,16 @@ int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev)
        return r;
 }
 
-void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd)
+void amdgpu_amdkfd_gpu_reset(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        if (amdgpu_device_should_recover_gpu(adev))
                amdgpu_device_gpu_recover(adev, NULL);
 }
 
-int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
+int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size,
                                void **mem_obj, uint64_t *gpu_addr,
                                void **cpu_ptr, bool cp_mqd_gfx9)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct amdgpu_bo *bo = NULL;
        struct amdgpu_bo_param bp;
        int r;
@@ -314,7 +311,7 @@ allocate_mem_reserve_bo_failed:
        return r;
 }
 
-void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj)
+void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj)
 {
        struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj;
 
@@ -325,10 +322,9 @@ void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj)
        amdgpu_bo_unref(&(bo));
 }
 
-int amdgpu_amdkfd_alloc_gws(struct kgd_dev *kgd, size_t size,
+int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size,
                                void **mem_obj)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct amdgpu_bo *bo = NULL;
        struct amdgpu_bo_user *ubo;
        struct amdgpu_bo_param bp;
@@ -355,18 +351,16 @@ int amdgpu_amdkfd_alloc_gws(struct kgd_dev *kgd, size_t size,
        return 0;
 }
 
-void amdgpu_amdkfd_free_gws(struct kgd_dev *kgd, void *mem_obj)
+void amdgpu_amdkfd_free_gws(struct amdgpu_device *adev, void *mem_obj)
 {
        struct amdgpu_bo *bo = (struct amdgpu_bo *)mem_obj;
 
        amdgpu_bo_unref(&bo);
 }
 
-uint32_t amdgpu_amdkfd_get_fw_version(struct kgd_dev *kgd,
+uint32_t amdgpu_amdkfd_get_fw_version(struct amdgpu_device *adev,
                                      enum kgd_engine_type type)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        switch (type) {
        case KGD_ENGINE_PFP:
                return adev->gfx.pfp_fw_version;
@@ -399,11 +393,9 @@ uint32_t amdgpu_amdkfd_get_fw_version(struct kgd_dev *kgd,
        return 0;
 }
 
-void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd,
+void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev,
                                      struct kfd_local_mem_info *mem_info)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        memset(mem_info, 0, sizeof(*mem_info));
 
        mem_info->local_mem_size_public = adev->gmc.visible_vram_size;
@@ -428,19 +420,15 @@ void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd,
                mem_info->mem_clk_max = 100;
 }
 
-uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd)
+uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        if (adev->gfx.funcs->get_gpu_clock_counter)
                return adev->gfx.funcs->get_gpu_clock_counter(adev);
        return 0;
 }
 
-uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd)
+uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        /* the sclk is in quantas of 10kHz */
        if (amdgpu_sriov_vf(adev))
                return adev->clock.default_sclk / 100;
@@ -450,9 +438,8 @@ uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd)
                return 100;
 }
 
-void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info)
+void amdgpu_amdkfd_get_cu_info(struct amdgpu_device *adev, struct kfd_cu_info *cu_info)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct amdgpu_cu_info acu_info = adev->gfx.cu_info;
 
        memset(cu_info, 0, sizeof(*cu_info));
@@ -473,13 +460,12 @@ void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info)
        cu_info->lds_size = acu_info.lds_size;
 }
 
-int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd,
-                                 struct kgd_dev **dma_buf_kgd,
+int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
+                                 struct amdgpu_device **dmabuf_adev,
                                  uint64_t *bo_size, void *metadata_buffer,
                                  size_t buffer_size, uint32_t *metadata_size,
                                  uint32_t *flags)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct dma_buf *dma_buf;
        struct drm_gem_object *obj;
        struct amdgpu_bo *bo;
@@ -507,8 +493,8 @@ int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd,
                goto out_put;
 
        r = 0;
-       if (dma_buf_kgd)
-               *dma_buf_kgd = (struct kgd_dev *)adev;
+       if (dmabuf_adev)
+               *dmabuf_adev = adev;
        if (bo_size)
                *bo_size = amdgpu_bo_size(bo);
        if (metadata_buffer)
@@ -528,32 +514,18 @@ out_put:
        return r;
 }
 
-uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd)
+uint64_t amdgpu_amdkfd_get_vram_usage(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct ttm_resource_manager *vram_man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
 
        return amdgpu_vram_mgr_usage(vram_man);
 }
 
-uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd)
-{
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
-       return adev->gmc.xgmi.hive_id;
-}
-
-uint64_t amdgpu_amdkfd_get_unique_id(struct kgd_dev *kgd)
-{
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
-       return adev->unique_id;
-}
-
-uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct kgd_dev *dst, struct kgd_dev *src)
+uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct amdgpu_device *dst,
+                                         struct amdgpu_device *src)
 {
-       struct amdgpu_device *peer_adev = (struct amdgpu_device *)src;
-       struct amdgpu_device *adev = (struct amdgpu_device *)dst;
+       struct amdgpu_device *peer_adev = src;
+       struct amdgpu_device *adev = dst;
        int ret = amdgpu_xgmi_get_hops_count(adev, peer_adev);
 
        if (ret < 0) {
@@ -565,16 +537,18 @@ uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct kgd_dev *dst, struct kgd_dev *s
        return  (uint8_t)ret;
 }
 
-int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct kgd_dev *dst, struct kgd_dev *src, bool is_min)
+int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct amdgpu_device *dst,
+                                           struct amdgpu_device *src,
+                                           bool is_min)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)dst, *peer_adev;
+       struct amdgpu_device *adev = dst, *peer_adev;
        int num_links;
 
        if (adev->asic_type != CHIP_ALDEBARAN)
                return 0;
 
        if (src)
-               peer_adev = (struct amdgpu_device *)src;
+               peer_adev = src;
 
        /* num links returns 0 for indirect peers since indirect route is unknown. */
        num_links = is_min ? 1 : amdgpu_xgmi_get_num_links(adev, peer_adev);
@@ -589,9 +563,8 @@ int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct kgd_dev *dst, struct kgd_dev
        return (num_links * 16 * 25000)/BITS_PER_BYTE;
 }
 
-int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct kgd_dev *dev, bool is_min)
+int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_min)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)dev;
        int num_lanes_shift = (is_min ? ffs(adev->pm.pcie_mlw_mask) :
                                                        fls(adev->pm.pcie_mlw_mask)) - 1;
        int gen_speed_shift = (is_min ? ffs(adev->pm.pcie_gen_mask &
@@ -647,39 +620,11 @@ int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct kgd_dev *dev, bool is_min)
        return (num_lanes_factor * gen_speed_mbits_factor)/BITS_PER_BYTE;
 }
 
-uint64_t amdgpu_amdkfd_get_mmio_remap_phys_addr(struct kgd_dev *kgd)
-{
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
-       return adev->rmmio_remap.bus_addr;
-}
-
-uint32_t amdgpu_amdkfd_get_num_gws(struct kgd_dev *kgd)
-{
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
-       return adev->gds.gws_size;
-}
-
-uint32_t amdgpu_amdkfd_get_asic_rev_id(struct kgd_dev *kgd)
-{
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
-       return adev->rev_id;
-}
-
-int amdgpu_amdkfd_get_noretry(struct kgd_dev *kgd)
-{
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
-       return adev->gmc.noretry;
-}
-
-int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
+int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
+                               enum kgd_engine_type engine,
                                uint32_t vmid, uint64_t gpu_addr,
                                uint32_t *ib_cmd, uint32_t ib_len)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct amdgpu_job *job;
        struct amdgpu_ib *ib;
        struct amdgpu_ring *ring;
@@ -730,10 +675,8 @@ err:
        return ret;
 }
 
-void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)
+void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        amdgpu_dpm_switch_power_profile(adev,
                                        PP_SMC_POWER_PROFILE_COMPUTE,
                                        !idle);
@@ -747,10 +690,9 @@ bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
        return false;
 }
 
-int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct kgd_dev *kgd, uint16_t vmid)
+int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev,
+                                    uint16_t vmid)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        if (adev->family == AMDGPU_FAMILY_AI) {
                int i;
 
@@ -763,10 +705,9 @@ int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct kgd_dev *kgd, uint16_t vmid)
        return 0;
 }
 
-int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct kgd_dev *kgd, uint16_t pasid,
-                                     enum TLB_FLUSH_TYPE flush_type)
+int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
+                                     uint16_t pasid, enum TLB_FLUSH_TYPE flush_type)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        bool all_hub = false;
 
        if (adev->family == AMDGPU_FAMILY_AI)
@@ -775,21 +716,18 @@ int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct kgd_dev *kgd, uint16_t pasid,
        return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub);
 }
 
-bool amdgpu_amdkfd_have_atomics_support(struct kgd_dev *kgd)
+bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        return adev->have_atomics_support;
 }
 
-void amdgpu_amdkfd_ras_poison_consumption_handler(struct kgd_dev *kgd)
+void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct ras_err_data err_data = {0, 0, 0, NULL};
 
        /* CPU MCA will handle page retirement if connected_to_cpu is 1 */
        if (!adev->gmc.xgmi.connected_to_cpu)
                amdgpu_umc_process_ras_data_cb(adev, &err_data, NULL);
        else
-               amdgpu_amdkfd_gpu_reset(kgd);
+               amdgpu_amdkfd_gpu_reset(adev);
 }
index a15a4787c7ee7990d797bc1014ba851a4a1bb666..fcbc8a9c9e06d7161a24d3ff03012792976a0fb8 100644 (file)
@@ -144,14 +144,16 @@ void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
 void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev);
 void amdgpu_amdkfd_device_init(struct amdgpu_device *adev);
 void amdgpu_amdkfd_device_fini_sw(struct amdgpu_device *adev);
-int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
+int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
+                               enum kgd_engine_type engine,
                                uint32_t vmid, uint64_t gpu_addr,
                                uint32_t *ib_cmd, uint32_t ib_len);
-void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle);
-bool amdgpu_amdkfd_have_atomics_support(struct kgd_dev *kgd);
-int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct kgd_dev *kgd, uint16_t vmid);
-int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct kgd_dev *kgd, uint16_t pasid,
-                                     enum TLB_FLUSH_TYPE flush_type);
+void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle);
+bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev);
+int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev,
+                               uint16_t vmid);
+int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
+                               uint16_t pasid, enum TLB_FLUSH_TYPE flush_type);
 
 bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid);
 
@@ -159,7 +161,7 @@ int amdgpu_amdkfd_pre_reset(struct amdgpu_device *adev);
 
 int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev);
 
-void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd);
+void amdgpu_amdkfd_gpu_reset(struct amdgpu_device *adev);
 
 int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev,
                                        int queue_bit);
@@ -198,37 +200,36 @@ int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem, struct mm_struct *mm)
 }
 #endif
 /* Shared API */
-int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
+int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size,
                                void **mem_obj, uint64_t *gpu_addr,
                                void **cpu_ptr, bool mqd_gfx9);
-void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj);
-int amdgpu_amdkfd_alloc_gws(struct kgd_dev *kgd, size_t size, void **mem_obj);
-void amdgpu_amdkfd_free_gws(struct kgd_dev *kgd, void *mem_obj);
+void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj);
+int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size,
+                               void **mem_obj);
+void amdgpu_amdkfd_free_gws(struct amdgpu_device *adev, void *mem_obj);
 int amdgpu_amdkfd_add_gws_to_process(void *info, void *gws, struct kgd_mem **mem);
 int amdgpu_amdkfd_remove_gws_from_process(void *info, void *mem);
-uint32_t amdgpu_amdkfd_get_fw_version(struct kgd_dev *kgd,
+uint32_t amdgpu_amdkfd_get_fw_version(struct amdgpu_device *adev,
                                      enum kgd_engine_type type);
-void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd,
+void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev,
                                      struct kfd_local_mem_info *mem_info);
-uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd);
+uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct amdgpu_device *adev);
 
-uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd);
-void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info);
-int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd,
-                                 struct kgd_dev **dmabuf_kgd,
+uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev);
+void amdgpu_amdkfd_get_cu_info(struct amdgpu_device *adev,
+                              struct kfd_cu_info *cu_info);
+int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
+                                 struct amdgpu_device **dmabuf_adev,
                                  uint64_t *bo_size, void *metadata_buffer,
                                  size_t buffer_size, uint32_t *metadata_size,
                                  uint32_t *flags);
-uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd);
-uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd);
-uint64_t amdgpu_amdkfd_get_unique_id(struct kgd_dev *kgd);
-uint64_t amdgpu_amdkfd_get_mmio_remap_phys_addr(struct kgd_dev *kgd);
-uint32_t amdgpu_amdkfd_get_num_gws(struct kgd_dev *kgd);
-uint32_t amdgpu_amdkfd_get_asic_rev_id(struct kgd_dev *kgd);
-int amdgpu_amdkfd_get_noretry(struct kgd_dev *kgd);
-uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct kgd_dev *dst, struct kgd_dev *src);
-int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct kgd_dev *dst, struct kgd_dev *src, bool is_min);
-int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct kgd_dev *dev, bool is_min);
+uint64_t amdgpu_amdkfd_get_vram_usage(struct amdgpu_device *adev);
+uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct amdgpu_device *dst,
+                                         struct amdgpu_device *src);
+int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct amdgpu_device *dst,
+                                           struct amdgpu_device *src,
+                                           bool is_min);
+int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_min);
 
 /* Read user wptr from a specified user address space with page fault
  * disabled. The memory must be pinned and mapped to the hardware when
@@ -258,45 +259,54 @@ int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct kgd_dev *dev, bool is_min);
        (&((struct amdgpu_fpriv *)                                      \
                ((struct drm_file *)(drm_priv))->driver_priv)->vm)
 
-int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd,
+int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
                                        struct file *filp, u32 pasid,
                                        void **process_info,
                                        struct dma_fence **ef);
-void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *drm_priv);
+void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
+                                       void *drm_priv);
 uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv);
 int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
-               struct kgd_dev *kgd, uint64_t va, uint64_t size,
+               struct amdgpu_device *adev, uint64_t va, uint64_t size,
                void *drm_priv, struct kgd_mem **mem,
                uint64_t *offset, uint32_t flags);
 int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
-               struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv,
+               struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv,
                uint64_t *size);
 int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
-               struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv, bool *table_freed);
+               struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv,
+               bool *table_freed);
 int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
-               struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv);
+               struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv);
 int amdgpu_amdkfd_gpuvm_sync_memory(
-               struct kgd_dev *kgd, struct kgd_mem *mem, bool intr);
-int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd,
+               struct amdgpu_device *adev, struct kgd_mem *mem, bool intr);
+int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev,
                struct kgd_mem *mem, void **kptr, uint64_t *size);
-void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_dev *kgd, struct kgd_mem *mem);
+void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct amdgpu_device *adev,
+               struct kgd_mem *mem);
 
 int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
                                            struct dma_fence **ef);
-int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
+int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,
                                              struct kfd_vm_fault_info *info);
-int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd,
+int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
                                      struct dma_buf *dmabuf,
                                      uint64_t va, void *drm_priv,
                                      struct kgd_mem **mem, uint64_t *size,
                                      uint64_t *mmap_offset);
-int amdgpu_amdkfd_get_tile_config(struct kgd_dev *kgd,
+int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
                                struct tile_config *config);
-void amdgpu_amdkfd_ras_poison_consumption_handler(struct kgd_dev *kgd);
+void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev);
 #if IS_ENABLED(CONFIG_HSA_AMD)
 void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
 void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
                                struct amdgpu_vm *vm);
+
+/**
+ * @amdgpu_amdkfd_release_notify() - Notify KFD when GEM object is released
+ *
+ * Allows KFD to release its resources associated with the GEM object.
+ */
 void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo);
 void amdgpu_amdkfd_reserve_system_mem(uint64_t size);
 #else
@@ -324,7 +334,7 @@ int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm,
 #if IS_ENABLED(CONFIG_HSA_AMD)
 int kgd2kfd_init(void);
 void kgd2kfd_exit(void);
-struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, bool vf);
+struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf);
 bool kgd2kfd_device_init(struct kfd_dev *kfd,
                         struct drm_device *ddev,
                         const struct kgd2kfd_shared_resources *gpu_resources);
@@ -348,7 +358,7 @@ static inline void kgd2kfd_exit(void)
 }
 
 static inline
-struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, bool vf)
+struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
 {
        return NULL;
 }
index 5a7f680bcb3f13d8666e3c8911d1a46817b2e4f6..abe93b3ff765cb024449b008a49f58b110abd7fe 100644 (file)
                (*dump)[i++][1] = RREG32(addr);         \
        } while (0)
 
-static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
-{
-       return (struct amdgpu_device *)kgd;
-}
-
 static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd)
 {
        return (struct v9_sdma_mqd *)mqd;
@@ -123,10 +118,9 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev,
        return sdma_rlc_reg_offset;
 }
 
-int kgd_arcturus_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+int kgd_arcturus_hqd_sdma_load(struct amdgpu_device *adev, void *mqd,
                             uint32_t __user *wptr, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v9_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        unsigned long end_jiffies;
@@ -193,11 +187,10 @@ int kgd_arcturus_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-int kgd_arcturus_hqd_sdma_dump(struct kgd_dev *kgd,
+int kgd_arcturus_hqd_sdma_dump(struct amdgpu_device *adev,
                             uint32_t engine_id, uint32_t queue_id,
                             uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev,
                        engine_id, queue_id);
        uint32_t i = 0, reg;
@@ -225,9 +218,9 @@ int kgd_arcturus_hqd_sdma_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-bool kgd_arcturus_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
+bool kgd_arcturus_hqd_sdma_is_occupied(struct amdgpu_device *adev,
+                               void *mqd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v9_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t sdma_rlc_rb_cntl;
@@ -244,10 +237,9 @@ bool kgd_arcturus_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
        return false;
 }
 
-int kgd_arcturus_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+int kgd_arcturus_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
                                unsigned int utimeout)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v9_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t temp;
index ce08131b7b5fde418712692ffdd6dc7a5184d9b3..756c1a5679c08cc3b6732fbf6e5198db691ffa0b 100644 (file)
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
-int kgd_arcturus_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+int kgd_arcturus_hqd_sdma_load(struct amdgpu_device *adev, void *mqd,
                             uint32_t __user *wptr, struct mm_struct *mm);
-int kgd_arcturus_hqd_sdma_dump(struct kgd_dev *kgd,
+int kgd_arcturus_hqd_sdma_dump(struct amdgpu_device *adev,
                             uint32_t engine_id, uint32_t queue_id,
                             uint32_t (**dump)[2], uint32_t *n_regs);
-bool kgd_arcturus_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
-int kgd_arcturus_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+bool kgd_arcturus_hqd_sdma_is_occupied(struct amdgpu_device *adev,
+                               void *mqd);
+int kgd_arcturus_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
                                unsigned int utimeout);
index 960acf68150a4d527f45cca61fe3d0469116c8d4..7b7f4b2764c1aeb69f349156a35e55f4f5723ac9 100644 (file)
@@ -39,37 +39,26 @@ enum hqd_dequeue_request_type {
        SAVE_WAVES
 };
 
-static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
-{
-       return (struct amdgpu_device *)kgd;
-}
-
-static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe,
+static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
                        uint32_t queue, uint32_t vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        mutex_lock(&adev->srbm_mutex);
        nv_grbm_select(adev, mec, pipe, queue, vmid);
 }
 
-static void unlock_srbm(struct kgd_dev *kgd)
+static void unlock_srbm(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        nv_grbm_select(adev, 0, 0, 0, 0);
        mutex_unlock(&adev->srbm_mutex);
 }
 
-static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
+static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, queue_id, 0);
+       lock_srbm(adev, mec, pipe, queue_id, 0);
 }
 
 static uint64_t get_queue_mask(struct amdgpu_device *adev,
@@ -81,33 +70,29 @@ static uint64_t get_queue_mask(struct amdgpu_device *adev,
        return 1ull << bit;
 }
 
-static void release_queue(struct kgd_dev *kgd)
+static void release_queue(struct amdgpu_device *adev)
 {
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
+static void kgd_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid,
                                        uint32_t sh_mem_config,
                                        uint32_t sh_mem_ape1_base,
                                        uint32_t sh_mem_ape1_limit,
                                        uint32_t sh_mem_bases)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
 
        WREG32_SOC15(GC, 0, mmSH_MEM_CONFIG, sh_mem_config);
        WREG32_SOC15(GC, 0, mmSH_MEM_BASES, sh_mem_bases);
        /* APE1 no longer exists on GFX9 */
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
+static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid,
                                        unsigned int vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        /*
         * We have to assume that there is no outstanding mapping.
         * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because
@@ -150,22 +135,21 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
  * but still works
  */
 
-static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
+static int kgd_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t mec;
        uint32_t pipe;
 
        mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, 0, 0);
+       lock_srbm(adev, mec, pipe, 0, 0);
 
        WREG32_SOC15(GC, 0, mmCPC_INT_CNTL,
                CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
                CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 
        return 0;
 }
@@ -218,12 +202,11 @@ static inline struct v10_sdma_mqd *get_sdma_mqd(void *mqd)
        return (struct v10_sdma_mqd *)mqd;
 }
 
-static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
-                       uint32_t queue_id, uint32_t __user *wptr,
-                       uint32_t wptr_shift, uint32_t wptr_mask,
-                       struct mm_struct *mm)
+static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd,
+                       uint32_t pipe_id, uint32_t queue_id,
+                       uint32_t __user *wptr, uint32_t wptr_shift,
+                       uint32_t wptr_mask, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v10_compute_mqd *m;
        uint32_t *mqd_hqd;
        uint32_t reg, hqd_base, data;
@@ -231,7 +214,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
        m = get_mqd(mqd);
 
        pr_debug("Load hqd of pipe %d queue %d\n", pipe_id, queue_id);
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */
        mqd_hqd = &m->cp_mqd_base_addr_lo;
@@ -296,16 +279,15 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
        data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
        WREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE, data);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        return 0;
 }
 
-static int kgd_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
+static int kgd_hiq_mqd_load(struct amdgpu_device *adev, void *mqd,
                            uint32_t pipe_id, uint32_t queue_id,
                            uint32_t doorbell_off)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
        struct v10_compute_mqd *m;
        uint32_t mec, pipe;
@@ -313,7 +295,7 @@ static int kgd_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
 
        m = get_mqd(mqd);
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
@@ -349,16 +331,15 @@ static int kgd_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
 
 out_unlock:
        spin_unlock(&adev->gfx.kiq.ring_lock);
-       release_queue(kgd);
+       release_queue(adev);
 
        return r;
 }
 
-static int kgd_hqd_dump(struct kgd_dev *kgd,
+static int kgd_hqd_dump(struct amdgpu_device *adev,
                        uint32_t pipe_id, uint32_t queue_id,
                        uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t i = 0, reg;
 #define HQD_N_REGS 56
 #define DUMP_REG(addr) do {                            \
@@ -372,13 +353,13 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,
        if (*dump == NULL)
                return -ENOMEM;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        for (reg = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR);
             reg <= SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI); reg++)
                DUMP_REG(reg);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        WARN_ON_ONCE(i != HQD_N_REGS);
        *n_regs = i;
@@ -386,10 +367,9 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd,
                             uint32_t __user *wptr, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v10_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        unsigned long end_jiffies;
@@ -456,11 +436,10 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
+static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,
                             uint32_t engine_id, uint32_t queue_id,
                             uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev,
                        engine_id, queue_id);
        uint32_t i = 0, reg;
@@ -488,15 +467,15 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
-                               uint32_t pipe_id, uint32_t queue_id)
+static bool kgd_hqd_is_occupied(struct amdgpu_device *adev,
+                               uint64_t queue_address, uint32_t pipe_id,
+                               uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t act;
        bool retval = false;
        uint32_t low, high;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
        act = RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE);
        if (act) {
                low = lower_32_bits(queue_address >> 8);
@@ -506,13 +485,12 @@ static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
                   high == RREG32_SOC15(GC, 0, mmCP_HQD_PQ_BASE_HI))
                        retval = true;
        }
-       release_queue(kgd);
+       release_queue(adev);
        return retval;
 }
 
-static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
+static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v10_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t sdma_rlc_rb_cntl;
@@ -529,12 +507,11 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
        return false;
 }
 
-static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd,
                                enum kfd_preempt_type reset_type,
                                unsigned int utimeout, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        enum hqd_dequeue_request_type type;
        unsigned long end_jiffies;
        uint32_t temp;
@@ -548,7 +525,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
        int retry;
 #endif
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        if (m->cp_hqd_vmid == 0)
                WREG32_FIELD15(GC, 0, RLC_CP_SCHEDULERS, scheduler1, 0);
@@ -633,20 +610,19 @@ loop:
                        break;
                if (time_after(jiffies, end_jiffies)) {
                        pr_err("cp queue preemption time out.\n");
-                       release_queue(kgd);
+                       release_queue(adev);
                        return -ETIME;
                }
                usleep_range(500, 1000);
        }
 
-       release_queue(kgd);
+       release_queue(adev);
        return 0;
 }
 
-static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
                                unsigned int utimeout)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v10_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t temp;
@@ -683,11 +659,10 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
+static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
                                        uint8_t vmid, uint16_t *p_pasid)
 {
        uint32_t value;
-       struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
 
        value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
                     + vmid);
@@ -696,12 +671,12 @@ static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
        return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
 }
 
-static int kgd_address_watch_disable(struct kgd_dev *kgd)
+static int kgd_address_watch_disable(struct amdgpu_device *adev)
 {
        return 0;
 }
 
-static int kgd_address_watch_execute(struct kgd_dev *kgd,
+static int kgd_address_watch_execute(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        uint32_t cntl_val,
                                        uint32_t addr_hi,
@@ -710,11 +685,10 @@ static int kgd_address_watch_execute(struct kgd_dev *kgd,
        return 0;
 }
 
-static int kgd_wave_control_execute(struct kgd_dev *kgd,
+static int kgd_wave_control_execute(struct amdgpu_device *adev,
                                        uint32_t gfx_index_val,
                                        uint32_t sq_cmd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t data = 0;
 
        mutex_lock(&adev->grbm_idx_mutex);
@@ -735,18 +709,16 @@ static int kgd_wave_control_execute(struct kgd_dev *kgd,
        return 0;
 }
 
-static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
+static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset)
 {
        return 0;
 }
 
-static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
-               uint64_t page_table_base)
+static void set_vm_context_page_table_base(struct amdgpu_device *adev,
+               uint32_t vmid, uint64_t page_table_base)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
                pr_err("trying to set page table base for wrong VMID %u\n",
                       vmid);
@@ -757,12 +729,10 @@ static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
        adev->gfxhub.funcs->setup_vm_pt_regs(adev, vmid, page_table_base);
 }
 
-static void program_trap_handler_settings(struct kgd_dev *kgd,
+static void program_trap_handler_settings(struct amdgpu_device *adev,
                uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
 
        /*
         * Program TBA registers
@@ -781,7 +751,7 @@ static void program_trap_handler_settings(struct kgd_dev *kgd,
        WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TMA_HI),
                        upper_32_bits(tma_addr >> 8));
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
 const struct kfd2kgd_calls gfx_v10_kfd2kgd = {
index dac0d751d5af73a8f594d04a0e621f2ed6c34fce..1f37d35740015923f85e69dee9ceaeb154cd5762 100644 (file)
@@ -38,37 +38,26 @@ enum hqd_dequeue_request_type {
        SAVE_WAVES
 };
 
-static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
-{
-       return (struct amdgpu_device *)kgd;
-}
-
-static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe,
+static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
                        uint32_t queue, uint32_t vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        mutex_lock(&adev->srbm_mutex);
        nv_grbm_select(adev, mec, pipe, queue, vmid);
 }
 
-static void unlock_srbm(struct kgd_dev *kgd)
+static void unlock_srbm(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        nv_grbm_select(adev, 0, 0, 0, 0);
        mutex_unlock(&adev->srbm_mutex);
 }
 
-static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
+static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, queue_id, 0);
+       lock_srbm(adev, mec, pipe, queue_id, 0);
 }
 
 static uint64_t get_queue_mask(struct amdgpu_device *adev,
@@ -80,34 +69,30 @@ static uint64_t get_queue_mask(struct amdgpu_device *adev,
        return 1ull << bit;
 }
 
-static void release_queue(struct kgd_dev *kgd)
+static void release_queue(struct amdgpu_device *adev)
 {
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static void program_sh_mem_settings_v10_3(struct kgd_dev *kgd, uint32_t vmid,
+static void program_sh_mem_settings_v10_3(struct amdgpu_device *adev, uint32_t vmid,
                                        uint32_t sh_mem_config,
                                        uint32_t sh_mem_ape1_base,
                                        uint32_t sh_mem_ape1_limit,
                                        uint32_t sh_mem_bases)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
 
        WREG32_SOC15(GC, 0, mmSH_MEM_CONFIG, sh_mem_config);
        WREG32_SOC15(GC, 0, mmSH_MEM_BASES, sh_mem_bases);
        /* APE1 no longer exists on GFX9 */
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
 /* ATC is defeatured on Sienna_Cichlid */
-static int set_pasid_vmid_mapping_v10_3(struct kgd_dev *kgd, unsigned int pasid,
+static int set_pasid_vmid_mapping_v10_3(struct amdgpu_device *adev, unsigned int pasid,
                                        unsigned int vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        uint32_t value = pasid << IH_VMID_0_LUT__PASID__SHIFT;
 
        /* Mapping vmid to pasid also for IH block */
@@ -118,22 +103,21 @@ static int set_pasid_vmid_mapping_v10_3(struct kgd_dev *kgd, unsigned int pasid,
        return 0;
 }
 
-static int init_interrupts_v10_3(struct kgd_dev *kgd, uint32_t pipe_id)
+static int init_interrupts_v10_3(struct amdgpu_device *adev, uint32_t pipe_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t mec;
        uint32_t pipe;
 
        mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, 0, 0);
+       lock_srbm(adev, mec, pipe, 0, 0);
 
        WREG32_SOC15(GC, 0, mmCPC_INT_CNTL,
                CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
                CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 
        return 0;
 }
@@ -188,12 +172,11 @@ static inline struct v10_sdma_mqd *get_sdma_mqd(void *mqd)
        return (struct v10_sdma_mqd *)mqd;
 }
 
-static int hqd_load_v10_3(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
-                       uint32_t queue_id, uint32_t __user *wptr,
-                       uint32_t wptr_shift, uint32_t wptr_mask,
-                       struct mm_struct *mm)
+static int hqd_load_v10_3(struct amdgpu_device *adev, void *mqd,
+                       uint32_t pipe_id, uint32_t queue_id,
+                       uint32_t __user *wptr, uint32_t wptr_shift,
+                       uint32_t wptr_mask, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v10_compute_mqd *m;
        uint32_t *mqd_hqd;
        uint32_t reg, hqd_base, data;
@@ -201,7 +184,7 @@ static int hqd_load_v10_3(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
        m = get_mqd(mqd);
 
        pr_debug("Load hqd of pipe %d queue %d\n", pipe_id, queue_id);
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        /* HIQ is set during driver init period with vmid set to 0*/
        if (m->cp_hqd_vmid == 0) {
@@ -281,16 +264,15 @@ static int hqd_load_v10_3(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
        data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
        WREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE, data);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        return 0;
 }
 
-static int hiq_mqd_load_v10_3(struct kgd_dev *kgd, void *mqd,
+static int hiq_mqd_load_v10_3(struct amdgpu_device *adev, void *mqd,
                            uint32_t pipe_id, uint32_t queue_id,
                            uint32_t doorbell_off)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
        struct v10_compute_mqd *m;
        uint32_t mec, pipe;
@@ -298,7 +280,7 @@ static int hiq_mqd_load_v10_3(struct kgd_dev *kgd, void *mqd,
 
        m = get_mqd(mqd);
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
@@ -334,16 +316,15 @@ static int hiq_mqd_load_v10_3(struct kgd_dev *kgd, void *mqd,
 
 out_unlock:
        spin_unlock(&adev->gfx.kiq.ring_lock);
-       release_queue(kgd);
+       release_queue(adev);
 
        return r;
 }
 
-static int hqd_dump_v10_3(struct kgd_dev *kgd,
+static int hqd_dump_v10_3(struct amdgpu_device *adev,
                        uint32_t pipe_id, uint32_t queue_id,
                        uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t i = 0, reg;
 #define HQD_N_REGS 56
 #define DUMP_REG(addr) do {                            \
@@ -357,13 +338,13 @@ static int hqd_dump_v10_3(struct kgd_dev *kgd,
        if (*dump == NULL)
                return -ENOMEM;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        for (reg = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR);
             reg <= SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI); reg++)
                DUMP_REG(reg);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        WARN_ON_ONCE(i != HQD_N_REGS);
        *n_regs = i;
@@ -371,10 +352,9 @@ static int hqd_dump_v10_3(struct kgd_dev *kgd,
        return 0;
 }
 
-static int hqd_sdma_load_v10_3(struct kgd_dev *kgd, void *mqd,
+static int hqd_sdma_load_v10_3(struct amdgpu_device *adev, void *mqd,
                             uint32_t __user *wptr, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v10_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        unsigned long end_jiffies;
@@ -441,11 +421,10 @@ static int hqd_sdma_load_v10_3(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-static int hqd_sdma_dump_v10_3(struct kgd_dev *kgd,
+static int hqd_sdma_dump_v10_3(struct amdgpu_device *adev,
                             uint32_t engine_id, uint32_t queue_id,
                             uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev,
                        engine_id, queue_id);
        uint32_t i = 0, reg;
@@ -473,15 +452,15 @@ static int hqd_sdma_dump_v10_3(struct kgd_dev *kgd,
        return 0;
 }
 
-static bool hqd_is_occupied_v10_3(struct kgd_dev *kgd, uint64_t queue_address,
-                               uint32_t pipe_id, uint32_t queue_id)
+static bool hqd_is_occupied_v10_3(struct amdgpu_device *adev,
+                               uint64_t queue_address, uint32_t pipe_id,
+                               uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t act;
        bool retval = false;
        uint32_t low, high;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
        act = RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE);
        if (act) {
                low = lower_32_bits(queue_address >> 8);
@@ -491,13 +470,13 @@ static bool hqd_is_occupied_v10_3(struct kgd_dev *kgd, uint64_t queue_address,
                   high == RREG32_SOC15(GC, 0, mmCP_HQD_PQ_BASE_HI))
                        retval = true;
        }
-       release_queue(kgd);
+       release_queue(adev);
        return retval;
 }
 
-static bool hqd_sdma_is_occupied_v10_3(struct kgd_dev *kgd, void *mqd)
+static bool hqd_sdma_is_occupied_v10_3(struct amdgpu_device *adev,
+                               void *mqd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v10_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t sdma_rlc_rb_cntl;
@@ -514,18 +493,17 @@ static bool hqd_sdma_is_occupied_v10_3(struct kgd_dev *kgd, void *mqd)
        return false;
 }
 
-static int hqd_destroy_v10_3(struct kgd_dev *kgd, void *mqd,
+static int hqd_destroy_v10_3(struct amdgpu_device *adev, void *mqd,
                                enum kfd_preempt_type reset_type,
                                unsigned int utimeout, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        enum hqd_dequeue_request_type type;
        unsigned long end_jiffies;
        uint32_t temp;
        struct v10_compute_mqd *m = get_mqd(mqd);
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        if (m->cp_hqd_vmid == 0)
                WREG32_FIELD15(GC, 0, RLC_CP_SCHEDULERS, scheduler1, 0);
@@ -555,20 +533,19 @@ static int hqd_destroy_v10_3(struct kgd_dev *kgd, void *mqd,
                if (time_after(jiffies, end_jiffies)) {
                        pr_err("cp queue pipe %d queue %d preemption failed\n",
                                        pipe_id, queue_id);
-                       release_queue(kgd);
+                       release_queue(adev);
                        return -ETIME;
                }
                usleep_range(500, 1000);
        }
 
-       release_queue(kgd);
+       release_queue(adev);
        return 0;
 }
 
-static int hqd_sdma_destroy_v10_3(struct kgd_dev *kgd, void *mqd,
+static int hqd_sdma_destroy_v10_3(struct amdgpu_device *adev, void *mqd,
                                unsigned int utimeout)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v10_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t temp;
@@ -606,12 +583,12 @@ static int hqd_sdma_destroy_v10_3(struct kgd_dev *kgd, void *mqd,
 }
 
 
-static int address_watch_disable_v10_3(struct kgd_dev *kgd)
+static int address_watch_disable_v10_3(struct amdgpu_device *adev)
 {
        return 0;
 }
 
-static int address_watch_execute_v10_3(struct kgd_dev *kgd,
+static int address_watch_execute_v10_3(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        uint32_t cntl_val,
                                        uint32_t addr_hi,
@@ -620,11 +597,10 @@ static int address_watch_execute_v10_3(struct kgd_dev *kgd,
        return 0;
 }
 
-static int wave_control_execute_v10_3(struct kgd_dev *kgd,
+static int wave_control_execute_v10_3(struct amdgpu_device *adev,
                                        uint32_t gfx_index_val,
                                        uint32_t sq_cmd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t data = 0;
 
        mutex_lock(&adev->grbm_idx_mutex);
@@ -645,28 +621,24 @@ static int wave_control_execute_v10_3(struct kgd_dev *kgd,
        return 0;
 }
 
-static uint32_t address_watch_get_offset_v10_3(struct kgd_dev *kgd,
+static uint32_t address_watch_get_offset_v10_3(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset)
 {
        return 0;
 }
 
-static void set_vm_context_page_table_base_v10_3(struct kgd_dev *kgd, uint32_t vmid,
-               uint64_t page_table_base)
+static void set_vm_context_page_table_base_v10_3(struct amdgpu_device *adev,
+               uint32_t vmid, uint64_t page_table_base)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        /* SDMA is on gfxhub as well for Navi1* series */
        adev->gfxhub.funcs->setup_vm_pt_regs(adev, vmid, page_table_base);
 }
 
-static void program_trap_handler_settings_v10_3(struct kgd_dev *kgd,
+static void program_trap_handler_settings_v10_3(struct amdgpu_device *adev,
                        uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
 
        /*
         * Program TBA registers
@@ -685,15 +657,14 @@ static void program_trap_handler_settings_v10_3(struct kgd_dev *kgd,
        WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TMA_HI),
                         upper_32_bits(tma_addr >> 8));
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
 #if 0
-uint32_t enable_debug_trap_v10_3(struct kgd_dev *kgd,
+uint32_t enable_debug_trap_v10_3(struct amdgpu_device *adev,
                                uint32_t trap_debug_wave_launch_mode,
                                uint32_t vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t data = 0;
        uint32_t orig_wave_cntl_value;
        uint32_t orig_stall_vmid;
@@ -720,10 +691,8 @@ uint32_t enable_debug_trap_v10_3(struct kgd_dev *kgd,
        return 0;
 }
 
-uint32_t disable_debug_trap_v10_3(struct kgd_dev *kgd)
+uint32_t disable_debug_trap_v10_3(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        mutex_lock(&adev->grbm_idx_mutex);
 
        WREG32(SOC15_REG_OFFSET(GC, 0, mmSPI_GDBG_TRAP_MASK), 0);
@@ -733,11 +702,10 @@ uint32_t disable_debug_trap_v10_3(struct kgd_dev *kgd)
        return 0;
 }
 
-uint32_t set_wave_launch_trap_override_v10_3(struct kgd_dev *kgd,
+uint32_t set_wave_launch_trap_override_v10_3(struct amdgpu_device *adev,
                                                uint32_t trap_override,
                                                uint32_t trap_mask)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t data = 0;
 
        mutex_lock(&adev->grbm_idx_mutex);
@@ -762,11 +730,10 @@ uint32_t set_wave_launch_trap_override_v10_3(struct kgd_dev *kgd,
        return 0;
 }
 
-uint32_t set_wave_launch_mode_v10_3(struct kgd_dev *kgd,
+uint32_t set_wave_launch_mode_v10_3(struct amdgpu_device *adev,
                                        uint8_t wave_launch_mode,
                                        uint32_t vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t data = 0;
        bool is_stall_mode;
        bool is_mode_set;
@@ -805,16 +772,14 @@ uint32_t set_wave_launch_mode_v10_3(struct kgd_dev *kgd,
  *     sem_rearm_wait_time      -- Wait Count for Semaphore re-arm.
  *     deq_retry_wait_time      -- Wait Count for Global Wave Syncs.
  */
-void get_iq_wait_times_v10_3(struct kgd_dev *kgd,
+void get_iq_wait_times_v10_3(struct amdgpu_device *adev,
                                        uint32_t *wait_times)
 
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        *wait_times = RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_IQ_WAIT_TIME2));
 }
 
-void build_grace_period_packet_info_v10_3(struct kgd_dev *kgd,
+void build_grace_period_packet_info_v10_3(struct amdgpu_device *adev,
                                                uint32_t wait_times,
                                                uint32_t grace_period,
                                                uint32_t *reg_offset,
index b91d27e39bad9bd7cfca52a627c67343e43d8968..36528dad7684a47b5120ea84619cf5694b0c3ea4 100644 (file)
@@ -82,68 +82,54 @@ union TCP_WATCH_CNTL_BITS {
        float f32All;
 };
 
-static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
-{
-       return (struct amdgpu_device *)kgd;
-}
-
-static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe,
+static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
                        uint32_t queue, uint32_t vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t value = PIPEID(pipe) | MEID(mec) | VMID(vmid) | QUEUEID(queue);
 
        mutex_lock(&adev->srbm_mutex);
        WREG32(mmSRBM_GFX_CNTL, value);
 }
 
-static void unlock_srbm(struct kgd_dev *kgd)
+static void unlock_srbm(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        WREG32(mmSRBM_GFX_CNTL, 0);
        mutex_unlock(&adev->srbm_mutex);
 }
 
-static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
+static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, queue_id, 0);
+       lock_srbm(adev, mec, pipe, queue_id, 0);
 }
 
-static void release_queue(struct kgd_dev *kgd)
+static void release_queue(struct amdgpu_device *adev)
 {
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
+static void kgd_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid,
                                        uint32_t sh_mem_config,
                                        uint32_t sh_mem_ape1_base,
                                        uint32_t sh_mem_ape1_limit,
                                        uint32_t sh_mem_bases)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
 
        WREG32(mmSH_MEM_CONFIG, sh_mem_config);
        WREG32(mmSH_MEM_APE1_BASE, sh_mem_ape1_base);
        WREG32(mmSH_MEM_APE1_LIMIT, sh_mem_ape1_limit);
        WREG32(mmSH_MEM_BASES, sh_mem_bases);
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
+static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid,
                                        unsigned int vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        /*
         * We have to assume that there is no outstanding mapping.
         * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because
@@ -165,21 +151,20 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
        return 0;
 }
 
-static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
+static int kgd_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t mec;
        uint32_t pipe;
 
        mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, 0, 0);
+       lock_srbm(adev, mec, pipe, 0, 0);
 
        WREG32(mmCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
                        CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 
        return 0;
 }
@@ -207,12 +192,11 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
        return (struct cik_sdma_rlc_registers *)mqd;
 }
 
-static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
-                       uint32_t queue_id, uint32_t __user *wptr,
-                       uint32_t wptr_shift, uint32_t wptr_mask,
-                       struct mm_struct *mm)
+static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd,
+                       uint32_t pipe_id, uint32_t queue_id,
+                       uint32_t __user *wptr, uint32_t wptr_shift,
+                       uint32_t wptr_mask, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct cik_mqd *m;
        uint32_t *mqd_hqd;
        uint32_t reg, wptr_val, data;
@@ -220,7 +204,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 
        m = get_mqd(mqd);
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        /* HQD registers extend from CP_MQD_BASE_ADDR to CP_MQD_CONTROL. */
        mqd_hqd = &m->cp_mqd_base_addr_lo;
@@ -239,25 +223,24 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
         * release srbm_mutex to avoid circular dependency between
         * srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex.
         */
-       release_queue(kgd);
+       release_queue(adev);
        valid_wptr = read_user_wptr(mm, wptr, wptr_val);
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
        if (valid_wptr)
                WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask);
 
        data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
        WREG32(mmCP_HQD_ACTIVE, data);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        return 0;
 }
 
-static int kgd_hqd_dump(struct kgd_dev *kgd,
+static int kgd_hqd_dump(struct amdgpu_device *adev,
                        uint32_t pipe_id, uint32_t queue_id,
                        uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t i = 0, reg;
 #define HQD_N_REGS (35+4)
 #define DUMP_REG(addr) do {                            \
@@ -271,7 +254,7 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,
        if (*dump == NULL)
                return -ENOMEM;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE0);
        DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE1);
@@ -281,7 +264,7 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,
        for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_MQD_CONTROL; reg++)
                DUMP_REG(reg);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        WARN_ON_ONCE(i != HQD_N_REGS);
        *n_regs = i;
@@ -289,10 +272,9 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd,
                             uint32_t __user *wptr, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct cik_sdma_rlc_registers *m;
        unsigned long end_jiffies;
        uint32_t sdma_rlc_reg_offset;
@@ -345,11 +327,10 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
+static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,
                             uint32_t engine_id, uint32_t queue_id,
                             uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t sdma_offset = engine_id * SDMA1_REGISTER_OFFSET +
                queue_id * KFD_CIK_SDMA_QUEUE_OFFSET;
        uint32_t i = 0, reg;
@@ -372,15 +353,15 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
-                               uint32_t pipe_id, uint32_t queue_id)
+static bool kgd_hqd_is_occupied(struct amdgpu_device *adev,
+                               uint64_t queue_address, uint32_t pipe_id,
+                               uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t act;
        bool retval = false;
        uint32_t low, high;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
        act = RREG32(mmCP_HQD_ACTIVE);
        if (act) {
                low = lower_32_bits(queue_address >> 8);
@@ -390,13 +371,12 @@ static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
                                high == RREG32(mmCP_HQD_PQ_BASE_HI))
                        retval = true;
        }
-       release_queue(kgd);
+       release_queue(adev);
        return retval;
 }
 
-static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
+static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct cik_sdma_rlc_registers *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t sdma_rlc_rb_cntl;
@@ -412,12 +392,11 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
        return false;
 }
 
-static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd,
                                enum kfd_preempt_type reset_type,
                                unsigned int utimeout, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t temp;
        enum hqd_dequeue_request_type type;
        unsigned long flags, end_jiffies;
@@ -426,7 +405,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
        if (amdgpu_in_reset(adev))
                return -EIO;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
        WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, 0);
 
        switch (reset_type) {
@@ -504,20 +483,19 @@ loop:
                        break;
                if (time_after(jiffies, end_jiffies)) {
                        pr_err("cp queue preemption time out\n");
-                       release_queue(kgd);
+                       release_queue(adev);
                        return -ETIME;
                }
                usleep_range(500, 1000);
        }
 
-       release_queue(kgd);
+       release_queue(adev);
        return 0;
 }
 
-static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
                                unsigned int utimeout)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct cik_sdma_rlc_registers *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t temp;
@@ -551,9 +529,8 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-static int kgd_address_watch_disable(struct kgd_dev *kgd)
+static int kgd_address_watch_disable(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        union TCP_WATCH_CNTL_BITS cntl;
        unsigned int i;
 
@@ -571,13 +548,12 @@ static int kgd_address_watch_disable(struct kgd_dev *kgd)
        return 0;
 }
 
-static int kgd_address_watch_execute(struct kgd_dev *kgd,
+static int kgd_address_watch_execute(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        uint32_t cntl_val,
                                        uint32_t addr_hi,
                                        uint32_t addr_lo)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        union TCP_WATCH_CNTL_BITS cntl;
 
        cntl.u32All = cntl_val;
@@ -602,11 +578,10 @@ static int kgd_address_watch_execute(struct kgd_dev *kgd,
        return 0;
 }
 
-static int kgd_wave_control_execute(struct kgd_dev *kgd,
+static int kgd_wave_control_execute(struct amdgpu_device *adev,
                                        uint32_t gfx_index_val,
                                        uint32_t sq_cmd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t data;
 
        mutex_lock(&adev->grbm_idx_mutex);
@@ -627,18 +602,17 @@ static int kgd_wave_control_execute(struct kgd_dev *kgd,
        return 0;
 }
 
-static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
+static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset)
 {
        return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset];
 }
 
-static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
+static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
                                        uint8_t vmid, uint16_t *p_pasid)
 {
        uint32_t value;
-       struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
 
        value = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
        *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
@@ -646,21 +620,17 @@ static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
        return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
 }
 
-static void set_scratch_backing_va(struct kgd_dev *kgd,
+static void set_scratch_backing_va(struct amdgpu_device *adev,
                                        uint64_t va, uint32_t vmid)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
        WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va);
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
-                       uint64_t page_table_base)
+static void set_vm_context_page_table_base(struct amdgpu_device *adev,
+                       uint32_t vmid, uint64_t page_table_base)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
                pr_err("trying to set page table base for wrong VMID\n");
                return;
@@ -676,10 +646,8 @@ static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
   * @vmid: vmid pointer
   * read vmid from register (CIK).
   */
-static uint32_t read_vmid_from_vmfault_reg(struct kgd_dev *kgd)
+static uint32_t read_vmid_from_vmfault_reg(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        uint32_t status = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS);
 
        return REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS, VMID);
index 5ce0ce704a217dd25e78aff2b2dbf2ab51a24e1e..52832cd69a93311e8ed61697602470a944d28c14 100644 (file)
@@ -39,68 +39,54 @@ enum hqd_dequeue_request_type {
        RESET_WAVES
 };
 
-static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
-{
-       return (struct amdgpu_device *)kgd;
-}
-
-static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe,
+static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
                        uint32_t queue, uint32_t vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t value = PIPEID(pipe) | MEID(mec) | VMID(vmid) | QUEUEID(queue);
 
        mutex_lock(&adev->srbm_mutex);
        WREG32(mmSRBM_GFX_CNTL, value);
 }
 
-static void unlock_srbm(struct kgd_dev *kgd)
+static void unlock_srbm(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        WREG32(mmSRBM_GFX_CNTL, 0);
        mutex_unlock(&adev->srbm_mutex);
 }
 
-static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
+static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, queue_id, 0);
+       lock_srbm(adev, mec, pipe, queue_id, 0);
 }
 
-static void release_queue(struct kgd_dev *kgd)
+static void release_queue(struct amdgpu_device *adev)
 {
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
+static void kgd_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid,
                                        uint32_t sh_mem_config,
                                        uint32_t sh_mem_ape1_base,
                                        uint32_t sh_mem_ape1_limit,
                                        uint32_t sh_mem_bases)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
 
        WREG32(mmSH_MEM_CONFIG, sh_mem_config);
        WREG32(mmSH_MEM_APE1_BASE, sh_mem_ape1_base);
        WREG32(mmSH_MEM_APE1_LIMIT, sh_mem_ape1_limit);
        WREG32(mmSH_MEM_BASES, sh_mem_bases);
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
+static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid,
                                        unsigned int vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        /*
         * We have to assume that there is no outstanding mapping.
         * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because
@@ -123,21 +109,20 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
        return 0;
 }
 
-static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
+static int kgd_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t mec;
        uint32_t pipe;
 
        mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, 0, 0);
+       lock_srbm(adev, mec, pipe, 0, 0);
 
        WREG32(mmCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
                        CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 
        return 0;
 }
@@ -165,12 +150,11 @@ static inline struct vi_sdma_mqd *get_sdma_mqd(void *mqd)
        return (struct vi_sdma_mqd *)mqd;
 }
 
-static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
-                       uint32_t queue_id, uint32_t __user *wptr,
-                       uint32_t wptr_shift, uint32_t wptr_mask,
-                       struct mm_struct *mm)
+static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd,
+                       uint32_t pipe_id, uint32_t queue_id,
+                       uint32_t __user *wptr, uint32_t wptr_shift,
+                       uint32_t wptr_mask, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct vi_mqd *m;
        uint32_t *mqd_hqd;
        uint32_t reg, wptr_val, data;
@@ -178,7 +162,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 
        m = get_mqd(mqd);
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        /* HIQ is set during driver init period with vmid set to 0*/
        if (m->cp_hqd_vmid == 0) {
@@ -206,7 +190,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
         * on ASICs that do not support context-save.
         * EOP writes/reads can start anywhere in the ring.
         */
-       if (get_amdgpu_device(kgd)->asic_type != CHIP_TONGA) {
+       if (adev->asic_type != CHIP_TONGA) {
                WREG32(mmCP_HQD_EOP_RPTR, m->cp_hqd_eop_rptr);
                WREG32(mmCP_HQD_EOP_WPTR, m->cp_hqd_eop_wptr);
                WREG32(mmCP_HQD_EOP_WPTR_MEM, m->cp_hqd_eop_wptr_mem);
@@ -226,25 +210,24 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
         * release srbm_mutex to avoid circular dependency between
         * srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex.
         */
-       release_queue(kgd);
+       release_queue(adev);
        valid_wptr = read_user_wptr(mm, wptr, wptr_val);
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
        if (valid_wptr)
                WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask);
 
        data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
        WREG32(mmCP_HQD_ACTIVE, data);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        return 0;
 }
 
-static int kgd_hqd_dump(struct kgd_dev *kgd,
+static int kgd_hqd_dump(struct amdgpu_device *adev,
                        uint32_t pipe_id, uint32_t queue_id,
                        uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t i = 0, reg;
 #define HQD_N_REGS (54+4)
 #define DUMP_REG(addr) do {                            \
@@ -258,7 +241,7 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,
        if (*dump == NULL)
                return -ENOMEM;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE0);
        DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE1);
@@ -268,7 +251,7 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,
        for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_HQD_EOP_DONES; reg++)
                DUMP_REG(reg);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        WARN_ON_ONCE(i != HQD_N_REGS);
        *n_regs = i;
@@ -276,10 +259,9 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd,
                             uint32_t __user *wptr, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct vi_sdma_mqd *m;
        unsigned long end_jiffies;
        uint32_t sdma_rlc_reg_offset;
@@ -331,11 +313,10 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
+static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,
                             uint32_t engine_id, uint32_t queue_id,
                             uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t sdma_offset = engine_id * SDMA1_REGISTER_OFFSET +
                queue_id * KFD_VI_SDMA_QUEUE_OFFSET;
        uint32_t i = 0, reg;
@@ -367,15 +348,15 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
-                               uint32_t pipe_id, uint32_t queue_id)
+static bool kgd_hqd_is_occupied(struct amdgpu_device *adev,
+                               uint64_t queue_address, uint32_t pipe_id,
+                               uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t act;
        bool retval = false;
        uint32_t low, high;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
        act = RREG32(mmCP_HQD_ACTIVE);
        if (act) {
                low = lower_32_bits(queue_address >> 8);
@@ -385,13 +366,12 @@ static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
                                high == RREG32(mmCP_HQD_PQ_BASE_HI))
                        retval = true;
        }
-       release_queue(kgd);
+       release_queue(adev);
        return retval;
 }
 
-static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
+static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct vi_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t sdma_rlc_rb_cntl;
@@ -407,12 +387,11 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
        return false;
 }
 
-static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd,
                                enum kfd_preempt_type reset_type,
                                unsigned int utimeout, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t temp;
        enum hqd_dequeue_request_type type;
        unsigned long flags, end_jiffies;
@@ -422,7 +401,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
        if (amdgpu_in_reset(adev))
                return -EIO;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        if (m->cp_hqd_vmid == 0)
                WREG32_FIELD(RLC_CP_SCHEDULERS, scheduler1, 0);
@@ -502,20 +481,19 @@ loop:
                        break;
                if (time_after(jiffies, end_jiffies)) {
                        pr_err("cp queue preemption time out.\n");
-                       release_queue(kgd);
+                       release_queue(adev);
                        return -ETIME;
                }
                usleep_range(500, 1000);
        }
 
-       release_queue(kgd);
+       release_queue(adev);
        return 0;
 }
 
-static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
                                unsigned int utimeout)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct vi_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t temp;
@@ -549,11 +527,10 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
+static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
                                        uint8_t vmid, uint16_t *p_pasid)
 {
        uint32_t value;
-       struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
 
        value = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
        *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
@@ -561,12 +538,12 @@ static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
        return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
 }
 
-static int kgd_address_watch_disable(struct kgd_dev *kgd)
+static int kgd_address_watch_disable(struct amdgpu_device *adev)
 {
        return 0;
 }
 
-static int kgd_address_watch_execute(struct kgd_dev *kgd,
+static int kgd_address_watch_execute(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        uint32_t cntl_val,
                                        uint32_t addr_hi,
@@ -575,11 +552,10 @@ static int kgd_address_watch_execute(struct kgd_dev *kgd,
        return 0;
 }
 
-static int kgd_wave_control_execute(struct kgd_dev *kgd,
+static int kgd_wave_control_execute(struct amdgpu_device *adev,
                                        uint32_t gfx_index_val,
                                        uint32_t sq_cmd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t data = 0;
 
        mutex_lock(&adev->grbm_idx_mutex);
@@ -600,28 +576,24 @@ static int kgd_wave_control_execute(struct kgd_dev *kgd,
        return 0;
 }
 
-static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
+static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset)
 {
        return 0;
 }
 
-static void set_scratch_backing_va(struct kgd_dev *kgd,
+static void set_scratch_backing_va(struct amdgpu_device *adev,
                                        uint64_t va, uint32_t vmid)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
        WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va);
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
-               uint64_t page_table_base)
+static void set_vm_context_page_table_base(struct amdgpu_device *adev,
+               uint32_t vmid, uint64_t page_table_base)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
                pr_err("trying to set page table base for wrong VMID\n");
                return;
index bcc1cbeb8799713512e57da7671a9f1b795c10f7..ddfe7aff919d89678d23b7966cd82e8e7bcef35d 100644 (file)
@@ -46,37 +46,26 @@ enum hqd_dequeue_request_type {
        SAVE_WAVES
 };
 
-static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
-{
-       return (struct amdgpu_device *)kgd;
-}
-
-static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe,
+static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
                        uint32_t queue, uint32_t vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        mutex_lock(&adev->srbm_mutex);
        soc15_grbm_select(adev, mec, pipe, queue, vmid);
 }
 
-static void unlock_srbm(struct kgd_dev *kgd)
+static void unlock_srbm(struct amdgpu_device *adev)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        soc15_grbm_select(adev, 0, 0, 0, 0);
        mutex_unlock(&adev->srbm_mutex);
 }
 
-static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
+static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, queue_id, 0);
+       lock_srbm(adev, mec, pipe, queue_id, 0);
 }
 
 static uint64_t get_queue_mask(struct amdgpu_device *adev,
@@ -88,33 +77,29 @@ static uint64_t get_queue_mask(struct amdgpu_device *adev,
        return 1ull << bit;
 }
 
-static void release_queue(struct kgd_dev *kgd)
+static void release_queue(struct amdgpu_device *adev)
 {
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-void kgd_gfx_v9_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
+void kgd_gfx_v9_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid,
                                        uint32_t sh_mem_config,
                                        uint32_t sh_mem_ape1_base,
                                        uint32_t sh_mem_ape1_limit,
                                        uint32_t sh_mem_bases)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
 
        WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG), sh_mem_config);
        WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmSH_MEM_BASES), sh_mem_bases);
        /* APE1 no longer exists on GFX9 */
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
-int kgd_gfx_v9_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
+int kgd_gfx_v9_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid,
                                        unsigned int vmid)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        /*
         * We have to assume that there is no outstanding mapping.
         * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because
@@ -171,22 +156,21 @@ int kgd_gfx_v9_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
  * but still works
  */
 
-int kgd_gfx_v9_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
+int kgd_gfx_v9_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t mec;
        uint32_t pipe;
 
        mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
 
-       lock_srbm(kgd, mec, pipe, 0, 0);
+       lock_srbm(adev, mec, pipe, 0, 0);
 
        WREG32(SOC15_REG_OFFSET(GC, 0, mmCPC_INT_CNTL),
                CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
                CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 
        return 0;
 }
@@ -233,19 +217,18 @@ static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd)
        return (struct v9_sdma_mqd *)mqd;
 }
 
-int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
-                       uint32_t queue_id, uint32_t __user *wptr,
-                       uint32_t wptr_shift, uint32_t wptr_mask,
-                       struct mm_struct *mm)
+int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd,
+                       uint32_t pipe_id, uint32_t queue_id,
+                       uint32_t __user *wptr, uint32_t wptr_shift,
+                       uint32_t wptr_mask, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v9_mqd *m;
        uint32_t *mqd_hqd;
        uint32_t reg, hqd_base, data;
 
        m = get_mqd(mqd);
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */
        mqd_hqd = &m->cp_mqd_base_addr_lo;
@@ -308,16 +291,15 @@ int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
        data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
        WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE), data);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        return 0;
 }
 
-int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
+int kgd_gfx_v9_hiq_mqd_load(struct amdgpu_device *adev, void *mqd,
                            uint32_t pipe_id, uint32_t queue_id,
                            uint32_t doorbell_off)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
        struct v9_mqd *m;
        uint32_t mec, pipe;
@@ -325,7 +307,7 @@ int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
 
        m = get_mqd(mqd);
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
        pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
@@ -361,16 +343,15 @@ int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
 
 out_unlock:
        spin_unlock(&adev->gfx.kiq.ring_lock);
-       release_queue(kgd);
+       release_queue(adev);
 
        return r;
 }
 
-int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd,
+int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev,
                        uint32_t pipe_id, uint32_t queue_id,
                        uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t i = 0, reg;
 #define HQD_N_REGS 56
 #define DUMP_REG(addr) do {                            \
@@ -384,13 +365,13 @@ int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd,
        if (*dump == NULL)
                return -ENOMEM;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        for (reg = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR);
             reg <= SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI); reg++)
                DUMP_REG(reg);
 
-       release_queue(kgd);
+       release_queue(adev);
 
        WARN_ON_ONCE(i != HQD_N_REGS);
        *n_regs = i;
@@ -398,10 +379,9 @@ int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd,
                             uint32_t __user *wptr, struct mm_struct *mm)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v9_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        unsigned long end_jiffies;
@@ -468,11 +448,10 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
+static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,
                             uint32_t engine_id, uint32_t queue_id,
                             uint32_t (**dump)[2], uint32_t *n_regs)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev,
                        engine_id, queue_id);
        uint32_t i = 0, reg;
@@ -500,15 +479,15 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
        return 0;
 }
 
-bool kgd_gfx_v9_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
-                               uint32_t pipe_id, uint32_t queue_id)
+bool kgd_gfx_v9_hqd_is_occupied(struct amdgpu_device *adev,
+                               uint64_t queue_address, uint32_t pipe_id,
+                               uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t act;
        bool retval = false;
        uint32_t low, high;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
        act = RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE));
        if (act) {
                low = lower_32_bits(queue_address >> 8);
@@ -518,13 +497,12 @@ bool kgd_gfx_v9_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
                   high == RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_BASE_HI)))
                        retval = true;
        }
-       release_queue(kgd);
+       release_queue(adev);
        return retval;
 }
 
-static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
+static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v9_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t sdma_rlc_rb_cntl;
@@ -541,12 +519,11 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
        return false;
 }
 
-int kgd_gfx_v9_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd,
                                enum kfd_preempt_type reset_type,
                                unsigned int utimeout, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        enum hqd_dequeue_request_type type;
        unsigned long end_jiffies;
        uint32_t temp;
@@ -555,7 +532,7 @@ int kgd_gfx_v9_hqd_destroy(struct kgd_dev *kgd, void *mqd,
        if (amdgpu_in_reset(adev))
                return -EIO;
 
-       acquire_queue(kgd, pipe_id, queue_id);
+       acquire_queue(adev, pipe_id, queue_id);
 
        if (m->cp_hqd_vmid == 0)
                WREG32_FIELD15_RLC(GC, 0, RLC_CP_SCHEDULERS, scheduler1, 0);
@@ -584,20 +561,19 @@ int kgd_gfx_v9_hqd_destroy(struct kgd_dev *kgd, void *mqd,
                        break;
                if (time_after(jiffies, end_jiffies)) {
                        pr_err("cp queue preemption time out.\n");
-                       release_queue(kgd);
+                       release_queue(adev);
                        return -ETIME;
                }
                usleep_range(500, 1000);
        }
 
-       release_queue(kgd);
+       release_queue(adev);
        return 0;
 }
 
-static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
                                unsigned int utimeout)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct v9_sdma_mqd *m;
        uint32_t sdma_rlc_reg_offset;
        uint32_t temp;
@@ -634,11 +610,10 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
        return 0;
 }
 
-bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
+bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
                                        uint8_t vmid, uint16_t *p_pasid)
 {
        uint32_t value;
-       struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
 
        value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
                     + vmid);
@@ -647,12 +622,12 @@ bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
        return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
 }
 
-int kgd_gfx_v9_address_watch_disable(struct kgd_dev *kgd)
+int kgd_gfx_v9_address_watch_disable(struct amdgpu_device *adev)
 {
        return 0;
 }
 
-int kgd_gfx_v9_address_watch_execute(struct kgd_dev *kgd,
+int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        uint32_t cntl_val,
                                        uint32_t addr_hi,
@@ -661,11 +636,10 @@ int kgd_gfx_v9_address_watch_execute(struct kgd_dev *kgd,
        return 0;
 }
 
-int kgd_gfx_v9_wave_control_execute(struct kgd_dev *kgd,
+int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev,
                                        uint32_t gfx_index_val,
                                        uint32_t sq_cmd)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        uint32_t data = 0;
 
        mutex_lock(&adev->grbm_idx_mutex);
@@ -686,18 +660,16 @@ int kgd_gfx_v9_wave_control_execute(struct kgd_dev *kgd,
        return 0;
 }
 
-uint32_t kgd_gfx_v9_address_watch_get_offset(struct kgd_dev *kgd,
+uint32_t kgd_gfx_v9_address_watch_get_offset(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset)
 {
        return 0;
 }
 
-void kgd_gfx_v9_set_vm_context_page_table_base(struct kgd_dev *kgd,
+void kgd_gfx_v9_set_vm_context_page_table_base(struct amdgpu_device *adev,
                        uint32_t vmid, uint64_t page_table_base)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
        if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
                pr_err("trying to set page table base for wrong VMID %u\n",
                       vmid);
@@ -804,7 +776,7 @@ static void get_wave_count(struct amdgpu_device *adev, int queue_idx,
  *
  *  Reading registers referenced above involves programming GRBM appropriately
  */
-void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid,
+void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid,
                int *pasid_wave_cnt, int *max_waves_per_cu)
 {
        int qidx;
@@ -818,10 +790,8 @@ void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid,
        int pasid_tmp;
        int max_queue_cnt;
        int vmid_wave_cnt = 0;
-       struct amdgpu_device *adev;
        DECLARE_BITMAP(cp_queue_bitmap, KGD_MAX_QUEUES);
 
-       adev = get_amdgpu_device(kgd);
        lock_spi_csq_mutexes(adev);
        soc15_grbm_select(adev, 1, 0, 0, 0);
 
@@ -882,12 +852,10 @@ void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid,
                                adev->gfx.cu_info.max_waves_per_simd;
 }
 
-void kgd_gfx_v9_program_trap_handler_settings(struct kgd_dev *kgd,
+void kgd_gfx_v9_program_trap_handler_settings(struct amdgpu_device *adev,
                         uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
-
-       lock_srbm(kgd, 0, 0, 0, vmid);
+       lock_srbm(adev, 0, 0, 0, vmid);
 
        /*
         * Program TBA registers
@@ -905,7 +873,7 @@ void kgd_gfx_v9_program_trap_handler_settings(struct kgd_dev *kgd,
        WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TMA_HI),
                        upper_32_bits(tma_addr >> 8));
 
-       unlock_srbm(kgd);
+       unlock_srbm(adev);
 }
 
 const struct kfd2kgd_calls gfx_v9_kfd2kgd = {
index c635911068798b54bf9666d1cb50e401029b7943..24be49df26fdd88e7a7197771f7de22620296b10 100644 (file)
 
 
 
-void kgd_gfx_v9_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
+void kgd_gfx_v9_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid,
                uint32_t sh_mem_config,
                uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit,
                uint32_t sh_mem_bases);
-int kgd_gfx_v9_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid,
+int kgd_gfx_v9_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid,
                unsigned int vmid);
-int kgd_gfx_v9_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
-int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
+int kgd_gfx_v9_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id);
+int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd, uint32_t pipe_id,
                        uint32_t queue_id, uint32_t __user *wptr,
                        uint32_t wptr_shift, uint32_t wptr_mask,
                        struct mm_struct *mm);
-int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
+int kgd_gfx_v9_hiq_mqd_load(struct amdgpu_device *adev, void *mqd,
                            uint32_t pipe_id, uint32_t queue_id,
                            uint32_t doorbell_off);
-int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd,
+int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev,
                        uint32_t pipe_id, uint32_t queue_id,
                        uint32_t (**dump)[2], uint32_t *n_regs);
-bool kgd_gfx_v9_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
-               uint32_t pipe_id, uint32_t queue_id);
-int kgd_gfx_v9_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+bool kgd_gfx_v9_hqd_is_occupied(struct amdgpu_device *adev,
+                       uint64_t queue_address, uint32_t pipe_id,
+                       uint32_t queue_id);
+int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd,
                                enum kfd_preempt_type reset_type,
                                unsigned int utimeout, uint32_t pipe_id,
                                uint32_t queue_id);
-int kgd_gfx_v9_address_watch_disable(struct kgd_dev *kgd);
-int kgd_gfx_v9_address_watch_execute(struct kgd_dev *kgd,
+int kgd_gfx_v9_address_watch_disable(struct amdgpu_device *adev);
+int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        uint32_t cntl_val,
                                        uint32_t addr_hi,
                                        uint32_t addr_lo);
-int kgd_gfx_v9_wave_control_execute(struct kgd_dev *kgd,
+int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev,
                                        uint32_t gfx_index_val,
                                        uint32_t sq_cmd);
-uint32_t kgd_gfx_v9_address_watch_get_offset(struct kgd_dev *kgd,
+uint32_t kgd_gfx_v9_address_watch_get_offset(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset);
 
-bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
+bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
                                        uint8_t vmid, uint16_t *p_pasid);
 
-void kgd_gfx_v9_set_vm_context_page_table_base(struct kgd_dev *kgd,
+void kgd_gfx_v9_set_vm_context_page_table_base(struct amdgpu_device *adev,
                        uint32_t vmid, uint64_t page_table_base);
-void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid,
+void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid,
                int *pasid_wave_cnt, int *max_waves_per_cu);
-void kgd_gfx_v9_program_trap_handler_settings(struct kgd_dev *kgd,
+void kgd_gfx_v9_program_trap_handler_settings(struct amdgpu_device *adev,
                uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr);
index 71acd577803ec3a6f9899883c2e25f9ab745c47f..c5362c23e6875b3456852a6709f5f02537bbf22c 100644 (file)
@@ -60,12 +60,6 @@ static const char * const domain_bit_to_string[] = {
 
 static void amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work);
 
-
-static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
-{
-       return (struct amdgpu_device *)kgd;
-}
-
 static bool kfd_mem_is_attached(struct amdgpu_vm *avm,
                struct kgd_mem *mem)
 {
@@ -126,8 +120,19 @@ static size_t amdgpu_amdkfd_acc_size(uint64_t size)
                PAGE_ALIGN(size);
 }
 
+/**
+ * @amdgpu_amdkfd_reserve_mem_limit() - Decrease available memory by size
+ * of buffer including any reserved for control structures
+ *
+ * @adev: Device to which allocated BO belongs to
+ * @size: Size of buffer, in bytes, encapsulated by B0. This should be
+ * equivalent to amdgpu_bo_size(BO)
+ * @alloc_flag: Flag used in allocating a BO as noted above
+ *
+ * Return: returns -ENOMEM in case of error, ZERO otherwise
+ */
 static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
-               uint64_t size, u32 domain, bool sg)
+               uint64_t size, u32 alloc_flag)
 {
        uint64_t reserved_for_pt =
                ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
@@ -137,20 +142,24 @@ static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
        acc_size = amdgpu_amdkfd_acc_size(size);
 
        vram_needed = 0;
-       if (domain == AMDGPU_GEM_DOMAIN_GTT) {
-               /* TTM GTT memory */
+       if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_GTT) {
                system_mem_needed = acc_size + size;
                ttm_mem_needed = acc_size + size;
-       } else if (domain == AMDGPU_GEM_DOMAIN_CPU && !sg) {
-               /* Userptr */
+       } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
+               system_mem_needed = acc_size;
+               ttm_mem_needed = acc_size;
+               vram_needed = size;
+       } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
                system_mem_needed = acc_size + size;
                ttm_mem_needed = acc_size;
-       } else {
-               /* VRAM and SG */
+       } else if (alloc_flag &
+                  (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
+                   KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
                system_mem_needed = acc_size;
                ttm_mem_needed = acc_size;
-               if (domain == AMDGPU_GEM_DOMAIN_VRAM)
-                       vram_needed = size;
+       } else {
+               pr_err("%s: Invalid BO type %#x\n", __func__, alloc_flag);
+               return -ENOMEM;
        }
 
        spin_lock(&kfd_mem_limit.mem_limit_lock);
@@ -166,64 +175,72 @@ static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
            (adev->kfd.vram_used + vram_needed >
             adev->gmc.real_vram_size - reserved_for_pt)) {
                ret = -ENOMEM;
-       } else {
-               kfd_mem_limit.system_mem_used += system_mem_needed;
-               kfd_mem_limit.ttm_mem_used += ttm_mem_needed;
-               adev->kfd.vram_used += vram_needed;
+               goto release;
        }
 
+       /* Update memory accounting by decreasing available system
+        * memory, TTM memory and GPU memory as computed above
+        */
+       adev->kfd.vram_used += vram_needed;
+       kfd_mem_limit.system_mem_used += system_mem_needed;
+       kfd_mem_limit.ttm_mem_used += ttm_mem_needed;
+
+release:
        spin_unlock(&kfd_mem_limit.mem_limit_lock);
        return ret;
 }
 
 static void unreserve_mem_limit(struct amdgpu_device *adev,
-               uint64_t size, u32 domain, bool sg)
+               uint64_t size, u32 alloc_flag)
 {
        size_t acc_size;
 
        acc_size = amdgpu_amdkfd_acc_size(size);
 
        spin_lock(&kfd_mem_limit.mem_limit_lock);
-       if (domain == AMDGPU_GEM_DOMAIN_GTT) {
+
+       if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_GTT) {
                kfd_mem_limit.system_mem_used -= (acc_size + size);
                kfd_mem_limit.ttm_mem_used -= (acc_size + size);
-       } else if (domain == AMDGPU_GEM_DOMAIN_CPU && !sg) {
+       } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
+               kfd_mem_limit.system_mem_used -= acc_size;
+               kfd_mem_limit.ttm_mem_used -= acc_size;
+               adev->kfd.vram_used -= size;
+       } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
                kfd_mem_limit.system_mem_used -= (acc_size + size);
                kfd_mem_limit.ttm_mem_used -= acc_size;
-       } else {
+       } else if (alloc_flag &
+                  (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
+                   KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
                kfd_mem_limit.system_mem_used -= acc_size;
                kfd_mem_limit.ttm_mem_used -= acc_size;
-               if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
-                       adev->kfd.vram_used -= size;
-                       WARN_ONCE(adev->kfd.vram_used < 0,
-                                 "kfd VRAM memory accounting unbalanced");
-               }
+       } else {
+               pr_err("%s: Invalid BO type %#x\n", __func__, alloc_flag);
+               goto release;
        }
-       WARN_ONCE(kfd_mem_limit.system_mem_used < 0,
-                 "kfd system memory accounting unbalanced");
+
+       WARN_ONCE(adev->kfd.vram_used < 0,
+                 "KFD VRAM memory accounting unbalanced");
        WARN_ONCE(kfd_mem_limit.ttm_mem_used < 0,
-                 "kfd TTM memory accounting unbalanced");
+                 "KFD TTM memory accounting unbalanced");
+       WARN_ONCE(kfd_mem_limit.system_mem_used < 0,
+                 "KFD system memory accounting unbalanced");
 
+release:
        spin_unlock(&kfd_mem_limit.mem_limit_lock);
 }
 
 void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-       u32 domain = bo->preferred_domains;
-       bool sg = (bo->preferred_domains == AMDGPU_GEM_DOMAIN_CPU);
-
-       if (bo->flags & AMDGPU_AMDKFD_CREATE_USERPTR_BO) {
-               domain = AMDGPU_GEM_DOMAIN_CPU;
-               sg = false;
-       }
+       u32 alloc_flags = bo->kfd_bo->alloc_flags;
+       u64 size = amdgpu_bo_size(bo);
 
-       unreserve_mem_limit(adev, amdgpu_bo_size(bo), domain, sg);
+       unreserve_mem_limit(adev, size, alloc_flags);
 
        kfree(bo->kfd_bo);
 }
 
-
 /* amdgpu_amdkfd_remove_eviction_fence - Removes eviction fence from BO's
  *  reservation object.
  *
@@ -646,12 +663,6 @@ kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem,
        if (IS_ERR(gobj))
                return PTR_ERR(gobj);
 
-       /* Import takes an extra reference on the dmabuf. Drop it now to
-        * avoid leaking it. We only need the one reference in
-        * kgd_mem->dmabuf.
-        */
-       dma_buf_put(mem->dmabuf);
-
        *bo = gem_to_amdgpu_bo(gobj);
        (*bo)->flags |= AMDGPU_GEM_CREATE_PREEMPTIBLE;
        (*bo)->parent = amdgpu_bo_ref(mem->bo);
@@ -1278,12 +1289,60 @@ create_evict_fence_fail:
        return ret;
 }
 
-int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd,
+/**
+ * amdgpu_amdkfd_gpuvm_pin_bo() - Pins a BO using following criteria
+ * @bo: Handle of buffer object being pinned
+ * @domain: Domain into which BO should be pinned
+ *
+ *   - USERPTR BOs are UNPINNABLE and will return error
+ *   - All other BO types (GTT, VRAM, MMIO and DOORBELL) will have their
+ *     PIN count incremented. It is valid to PIN a BO multiple times
+ *
+ * Return: ZERO if successful in pinning, Non-Zero in case of error.
+ */
+static int amdgpu_amdkfd_gpuvm_pin_bo(struct amdgpu_bo *bo, u32 domain)
+{
+       int ret = 0;
+
+       ret = amdgpu_bo_reserve(bo, false);
+       if (unlikely(ret))
+               return ret;
+
+       ret = amdgpu_bo_pin_restricted(bo, domain, 0, 0);
+       if (ret)
+               pr_err("Error in Pinning BO to domain: %d\n", domain);
+
+       amdgpu_bo_sync_wait(bo, AMDGPU_FENCE_OWNER_KFD, false);
+       amdgpu_bo_unreserve(bo);
+
+       return ret;
+}
+
+/**
+ * amdgpu_amdkfd_gpuvm_unpin_bo() - Unpins BO using following criteria
+ * @bo: Handle of buffer object being unpinned
+ *
+ *   - Is a illegal request for USERPTR BOs and is ignored
+ *   - All other BO types (GTT, VRAM, MMIO and DOORBELL) will have their
+ *     PIN count decremented. Calls to UNPIN must balance calls to PIN
+ */
+static void amdgpu_amdkfd_gpuvm_unpin_bo(struct amdgpu_bo *bo)
+{
+       int ret = 0;
+
+       ret = amdgpu_bo_reserve(bo, false);
+       if (unlikely(ret))
+               return;
+
+       amdgpu_bo_unpin(bo);
+       amdgpu_bo_unreserve(bo);
+}
+
+int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
                                           struct file *filp, u32 pasid,
                                           void **process_info,
                                           struct dma_fence **ef)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct amdgpu_fpriv *drv_priv;
        struct amdgpu_vm *avm;
        int ret;
@@ -1359,12 +1418,12 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
        }
 }
 
-void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *drm_priv)
+void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
+                                           void *drm_priv)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct amdgpu_vm *avm;
 
-       if (WARN_ON(!kgd || !drm_priv))
+       if (WARN_ON(!adev || !drm_priv))
                return;
 
        avm = drm_priv_to_vm(drm_priv);
@@ -1392,11 +1451,10 @@ uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv)
 }
 
 int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
-               struct kgd_dev *kgd, uint64_t va, uint64_t size,
+               struct amdgpu_device *adev, uint64_t va, uint64_t size,
                void *drm_priv, struct kgd_mem **mem,
                uint64_t *offset, uint32_t flags)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
        enum ttm_bo_type bo_type = ttm_bo_type_device;
        struct sg_table *sg = NULL;
@@ -1460,7 +1518,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
 
        amdgpu_sync_create(&(*mem)->sync);
 
-       ret = amdgpu_amdkfd_reserve_mem_limit(adev, size, alloc_domain, !!sg);
+       ret = amdgpu_amdkfd_reserve_mem_limit(adev, size, flags);
        if (ret) {
                pr_debug("Insufficient memory\n");
                goto err_reserve_limit;
@@ -1506,17 +1564,29 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
        if (offset)
                *offset = amdgpu_bo_mmap_offset(bo);
 
+       if (flags & (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
+                       KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
+               ret = amdgpu_amdkfd_gpuvm_pin_bo(bo, AMDGPU_GEM_DOMAIN_GTT);
+               if (ret) {
+                       pr_err("Pinning MMIO/DOORBELL BO during ALLOC FAILED\n");
+                       goto err_pin_bo;
+               }
+               bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
+               bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
+       }
+
        return 0;
 
 allocate_init_user_pages_failed:
        remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
+err_pin_bo:
        drm_vma_node_revoke(&gobj->vma_node, drm_priv);
 err_node_allow:
        drm_gem_object_put(gobj);
        /* Don't unreserve system mem limit twice */
        goto err_reserve_limit;
 err_bo_create:
-       unreserve_mem_limit(adev, size, alloc_domain, !!sg);
+       unreserve_mem_limit(adev, size, flags);
 err_reserve_limit:
        mutex_destroy(&(*mem)->lock);
        kfree(*mem);
@@ -1529,7 +1599,7 @@ err:
 }
 
 int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
-               struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv,
+               struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv,
                uint64_t *size)
 {
        struct amdkfd_process_info *process_info = mem->process_info;
@@ -1542,6 +1612,14 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
        bool is_imported = false;
 
        mutex_lock(&mem->lock);
+
+       /* Unpin MMIO/DOORBELL BO's that were pinnned during allocation */
+       if (mem->alloc_flags &
+           (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
+            KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
+               amdgpu_amdkfd_gpuvm_unpin_bo(mem->bo);
+       }
+
        mapped_to_gpu_memory = mem->mapped_to_gpu_memory;
        is_imported = mem->is_imported;
        mutex_unlock(&mem->lock);
@@ -1621,10 +1699,9 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
 }
 
 int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
-               struct kgd_dev *kgd, struct kgd_mem *mem,
+               struct amdgpu_device *adev, struct kgd_mem *mem,
                void *drm_priv, bool *table_freed)
 {
-       struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
        int ret;
        struct amdgpu_bo *bo;
@@ -1751,7 +1828,7 @@ out:
 }
 
 int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
-               struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv)
+               struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv)
 {
        struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
        struct amdkfd_process_info *process_info = avm->process_info;
@@ -1812,7 +1889,7 @@ out:
 }
 
 int amdgpu_amdkfd_gpuvm_sync_memory(
-               struct kgd_dev *kgd, struct kgd_mem *mem, bool intr)
+               struct amdgpu_device *adev, struct kgd_mem *mem, bool intr)
 {
        struct amdgpu_sync sync;
        int ret;
@@ -1828,7 +1905,7 @@ int amdgpu_amdkfd_gpuvm_sync_memory(
        return ret;
 }
 
-int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd,
+int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev,
                struct kgd_mem *mem, void **kptr, uint64_t *size)
 {
        int ret;
@@ -1884,7 +1961,8 @@ bo_reserve_failed:
        return ret;
 }
 
-void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_dev *kgd, struct kgd_mem *mem)
+void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct amdgpu_device *adev,
+                                                 struct kgd_mem *mem)
 {
        struct amdgpu_bo *bo = mem->bo;
 
@@ -1894,12 +1972,9 @@ void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_dev *kgd, struct kg
        amdgpu_bo_unreserve(bo);
 }
 
-int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
-                                             struct kfd_vm_fault_info *mem)
+int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,
+                                         struct kfd_vm_fault_info *mem)
 {
-       struct amdgpu_device *adev;
-
-       adev = (struct amdgpu_device *)kgd;
        if (atomic_read(&adev->gmc.vm_fault_info_updated) == 1) {
                *mem = *adev->gmc.vm_fault_info;
                mb();
@@ -1908,13 +1983,12 @@ int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
        return 0;
 }
 
-int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd,
+int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
                                      struct dma_buf *dma_buf,
                                      uint64_t va, void *drm_priv,
                                      struct kgd_mem **mem, uint64_t *size,
                                      uint64_t *mmap_offset)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
        struct drm_gem_object *obj;
        struct amdgpu_bo *bo;
@@ -2541,11 +2615,9 @@ int amdgpu_amdkfd_remove_gws_from_process(void *info, void *mem)
 }
 
 /* Returns GPU-specific tiling mode information */
-int amdgpu_amdkfd_get_tile_config(struct kgd_dev *kgd,
+int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
                                struct tile_config *config)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
-
        config->gb_addr_config = adev->gfx.config.gb_addr_config;
        config->tile_config_ptr = adev->gfx.config.tile_mode_array;
        config->num_tile_configs =
index 96b7bb13a2dd95f424925194d55ac33786b0924e..12a6b1c99c93e9d25f3146456af1f24e5807e50c 100644 (file)
@@ -1569,6 +1569,18 @@ void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
        WREG32(adev->bios_scratch_reg_offset + 3, tmp);
 }
 
+void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev,
+                                                     u32 backlight_level)
+{
+       u32 tmp = RREG32(adev->bios_scratch_reg_offset + 2);
+
+       tmp &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
+       tmp |= (backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) &
+               ATOM_S2_CURRENT_BL_LEVEL_MASK;
+
+       WREG32(adev->bios_scratch_reg_offset + 2, tmp);
+}
+
 bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev)
 {
        u32 tmp = RREG32(adev->bios_scratch_reg_offset + 7);
index 8cc0222dba1910e1569a88d4e8d4313c3420b76c..27e74b1fc260a3b27e97e1fb576bad29457908c3 100644 (file)
@@ -185,6 +185,8 @@ bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev);
 void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock);
 void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
                                              bool hung);
+void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev,
+                                                     u32 backlight_level);
 bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev);
 
 void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
index 188accb7124937aa2ba2cf9dda99432143b5baf3..6acdf7cfe0a4ca271321040fdcd1d3c9be78b0d8 100644 (file)
@@ -3687,8 +3687,6 @@ fence_driver_init:
        /* Get a log2 for easy divisions. */
        adev->mm_stats.log2_max_MBps = ilog2(max(1u, max_MBps));
 
-       amdgpu_fbdev_init(adev);
-
        r = amdgpu_pm_sysfs_init(adev);
        if (r) {
                adev->pm_sysfs_en = false;
@@ -3846,8 +3844,6 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
                amdgpu_ucode_sysfs_fini(adev);
        sysfs_remove_files(&adev->dev->kobj, amdgpu_dev_attributes);
 
-       amdgpu_fbdev_fini(adev);
-
        amdgpu_device_ip_fini_early(adev);
 
        amdgpu_irq_fini_hw(adev);
@@ -3942,7 +3938,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
        drm_kms_helper_poll_disable(dev);
 
        if (fbcon)
-               amdgpu_fbdev_set_suspend(adev, 1);
+               drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true);
 
        cancel_delayed_work_sync(&adev->delayed_init_work);
 
@@ -4019,7 +4015,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
        flush_delayed_work(&adev->delayed_init_work);
 
        if (fbcon)
-               amdgpu_fbdev_set_suspend(adev, 0);
+               drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
 
        drm_kms_helper_poll_enable(dev);
 
@@ -4316,7 +4312,6 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
 
        amdgpu_irq_gpu_reset_resume_helper(adev);
        r = amdgpu_ib_ring_tests(adev);
-       amdgpu_amdkfd_post_reset(adev);
 
 error:
        if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
@@ -4649,7 +4644,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
                                if (r)
                                        goto out;
 
-                               amdgpu_fbdev_set_suspend(tmp_adev, 0);
+                               drm_fb_helper_set_suspend_unlocked(adev_to_drm(tmp_adev)->fb_helper, false);
 
                                /*
                                 * The GPU enters bad state once faulty pages
@@ -5039,7 +5034,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
                 */
                amdgpu_unregister_gpu_instance(tmp_adev);
 
-               amdgpu_fbdev_set_suspend(tmp_adev, 1);
+               drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true);
 
                /* disable ras on ALL IPs */
                if (!need_emergency_restart &&
@@ -5089,7 +5084,7 @@ retry:    /* Rest of adevs pre asic reset from XGMI hive. */
 
        tmp_vram_lost_counter = atomic_read(&((adev)->vram_lost_counter));
        /* Actual ASIC resets if needed.*/
-       /* TODO Implement XGMI hive reset logic for SRIOV */
+       /* Host driver will handle XGMI hive reset for SRIOV */
        if (amdgpu_sriov_vf(adev)) {
                r = amdgpu_device_reset_sriov(adev, job ? false : true);
                if (r)
@@ -5149,8 +5144,8 @@ skip_hw_reset:
 
 skip_sched_resume:
        list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
-               /* unlock kfd: SRIOV would do it separately */
-               if (!need_emergency_restart && !amdgpu_sriov_vf(tmp_adev))
+               /* unlock kfd */
+               if (!need_emergency_restart)
                        amdgpu_amdkfd_post_reset(tmp_adev);
 
                /* kfd_post_reset will do nothing if kfd device is not initialized,
index 4e3669407518f9213d32f08252bb9689543167fb..503995c7ff6c1e6acd85eef8f3d298918e70c490 100644 (file)
@@ -248,8 +248,8 @@ get_from_vram:
 
        offset = offsetof(struct binary_header, binary_checksum) +
                sizeof(bhdr->binary_checksum);
-       size = bhdr->binary_size - offset;
-       checksum = bhdr->binary_checksum;
+       size = le16_to_cpu(bhdr->binary_size) - offset;
+       checksum = le16_to_cpu(bhdr->binary_checksum);
 
        if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
                                              size, checksum)) {
@@ -270,7 +270,7 @@ get_from_vram:
        }
 
        if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
-                                             ihdr->size, checksum)) {
+                                             le16_to_cpu(ihdr->size), checksum)) {
                DRM_ERROR("invalid ip discovery data table checksum\n");
                r = -EINVAL;
                goto out;
@@ -282,7 +282,7 @@ get_from_vram:
        ghdr = (struct gpu_info_header *)(adev->mman.discovery_bin + offset);
 
        if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
-                                             ghdr->size, checksum)) {
+                                             le32_to_cpu(ghdr->size), checksum)) {
                DRM_ERROR("invalid gc data table checksum\n");
                r = -EINVAL;
                goto out;
@@ -489,10 +489,10 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)
                        le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset));
 
        for (i = 0; i < 32; i++) {
-               if (le32_to_cpu(harvest_info->list[i].hw_id) == 0)
+               if (le16_to_cpu(harvest_info->list[i].hw_id) == 0)
                        break;
 
-               switch (le32_to_cpu(harvest_info->list[i].hw_id)) {
+               switch (le16_to_cpu(harvest_info->list[i].hw_id)) {
                case VCN_HWID:
                        vcn_harvest_count++;
                        if (harvest_info->list[i].number_instance == 0)
index 68108f151dadfbb6cc5f54739e437aee7d01794f..18cc7155e6674a5e78881ba094e3d0ec04a54627 100644 (file)
@@ -1599,13 +1599,10 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
                        continue;
                }
                robj = gem_to_amdgpu_bo(fb->obj[0]);
-               /* don't unpin kernel fb objects */
-               if (!amdgpu_fbdev_robj_is_fb(adev, robj)) {
-                       r = amdgpu_bo_reserve(robj, true);
-                       if (r == 0) {
-                               amdgpu_bo_unpin(robj);
-                               amdgpu_bo_unreserve(robj);
-                       }
+               r = amdgpu_bo_reserve(robj, true);
+               if (r == 0) {
+                       amdgpu_bo_unpin(robj);
+                       amdgpu_bo_unreserve(robj);
                }
        }
        return 0;
index 438468b82eb63aee7ac3acb2bd6607cec977ff96..3a6f125c6dc948968309676b9dc408a07be4eaea 100644 (file)
@@ -2001,6 +2001,19 @@ retry_init:
                goto err_pci;
        }
 
+       /*
+        * 1. don't init fbdev on hw without DCE
+        * 2. don't init fbdev if there are no connectors
+        */
+       if (adev->mode_info.mode_config_initialized &&
+           !list_empty(&adev_to_drm(adev)->mode_config.connector_list)) {
+               /* select 8 bpp console on low vram cards */
+               if (adev->gmc.real_vram_size <= (32*1024*1024))
+                       drm_fbdev_generic_setup(adev_to_drm(adev), 8);
+               else
+                       drm_fbdev_generic_setup(adev_to_drm(adev), 32);
+       }
+
        ret = amdgpu_debugfs_init(adev);
        if (ret)
                DRM_ERROR("Creating debugfs files failed (%d).\n", ret);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
deleted file mode 100644 (file)
index cd0acbe..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright Â© 2007 David Airlie
- *
- * 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 (including the next
- * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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:
- *     David Airlie
- */
-
-#include <linux/module.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/vga_switcheroo.h>
-
-#include <drm/amdgpu_drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_fourcc.h>
-
-#include "amdgpu.h"
-#include "cikd.h"
-#include "amdgpu_gem.h"
-
-#include "amdgpu_display.h"
-
-/* object hierarchy -
-   this contains a helper + a amdgpu fb
-   the helper contains a pointer to amdgpu framebuffer baseclass.
-*/
-
-static int
-amdgpufb_open(struct fb_info *info, int user)
-{
-       struct drm_fb_helper *fb_helper = info->par;
-       int ret = pm_runtime_get_sync(fb_helper->dev->dev);
-       if (ret < 0 && ret != -EACCES) {
-               pm_runtime_mark_last_busy(fb_helper->dev->dev);
-               pm_runtime_put_autosuspend(fb_helper->dev->dev);
-               return ret;
-       }
-       return 0;
-}
-
-static int
-amdgpufb_release(struct fb_info *info, int user)
-{
-       struct drm_fb_helper *fb_helper = info->par;
-
-       pm_runtime_mark_last_busy(fb_helper->dev->dev);
-       pm_runtime_put_autosuspend(fb_helper->dev->dev);
-       return 0;
-}
-
-static const struct fb_ops amdgpufb_ops = {
-       .owner = THIS_MODULE,
-       DRM_FB_HELPER_DEFAULT_OPS,
-       .fb_open = amdgpufb_open,
-       .fb_release = amdgpufb_release,
-       .fb_fillrect = drm_fb_helper_cfb_fillrect,
-       .fb_copyarea = drm_fb_helper_cfb_copyarea,
-       .fb_imageblit = drm_fb_helper_cfb_imageblit,
-};
-
-
-int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int cpp, bool tiled)
-{
-       int aligned = width;
-       int pitch_mask = 0;
-
-       switch (cpp) {
-       case 1:
-               pitch_mask = 255;
-               break;
-       case 2:
-               pitch_mask = 127;
-               break;
-       case 3:
-       case 4:
-               pitch_mask = 63;
-               break;
-       }
-
-       aligned += pitch_mask;
-       aligned &= ~pitch_mask;
-       return aligned * cpp;
-}
-
-static void amdgpufb_destroy_pinned_object(struct drm_gem_object *gobj)
-{
-       struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj);
-       int ret;
-
-       ret = amdgpu_bo_reserve(abo, true);
-       if (likely(ret == 0)) {
-               amdgpu_bo_kunmap(abo);
-               amdgpu_bo_unpin(abo);
-               amdgpu_bo_unreserve(abo);
-       }
-       drm_gem_object_put(gobj);
-}
-
-static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
-                                        struct drm_mode_fb_cmd2 *mode_cmd,
-                                        struct drm_gem_object **gobj_p)
-{
-       const struct drm_format_info *info;
-       struct amdgpu_device *adev = rfbdev->adev;
-       struct drm_gem_object *gobj = NULL;
-       struct amdgpu_bo *abo = NULL;
-       bool fb_tiled = false; /* useful for testing */
-       u32 tiling_flags = 0, domain;
-       int ret;
-       int aligned_size, size;
-       int height = mode_cmd->height;
-       u32 cpp;
-       u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
-                              AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS     |
-                              AMDGPU_GEM_CREATE_VRAM_CLEARED;
-
-       info = drm_get_format_info(adev_to_drm(adev), mode_cmd);
-       cpp = info->cpp[0];
-
-       /* need to align pitch with crtc limits */
-       mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp,
-                                                 fb_tiled);
-       domain = amdgpu_display_supported_domains(adev, flags);
-       height = ALIGN(mode_cmd->height, 8);
-       size = mode_cmd->pitches[0] * height;
-       aligned_size = ALIGN(size, PAGE_SIZE);
-       ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain, flags,
-                                      ttm_bo_type_device, NULL, &gobj);
-       if (ret) {
-               pr_err("failed to allocate framebuffer (%d)\n", aligned_size);
-               return -ENOMEM;
-       }
-       abo = gem_to_amdgpu_bo(gobj);
-
-       if (fb_tiled)
-               tiling_flags = AMDGPU_TILING_SET(ARRAY_MODE, GRPH_ARRAY_2D_TILED_THIN1);
-
-       ret = amdgpu_bo_reserve(abo, false);
-       if (unlikely(ret != 0))
-               goto out_unref;
-
-       if (tiling_flags) {
-               ret = amdgpu_bo_set_tiling_flags(abo,
-                                                tiling_flags);
-               if (ret)
-                       dev_err(adev->dev, "FB failed to set tiling flags\n");
-       }
-
-       ret = amdgpu_bo_pin(abo, domain);
-       if (ret) {
-               amdgpu_bo_unreserve(abo);
-               goto out_unref;
-       }
-
-       ret = amdgpu_ttm_alloc_gart(&abo->tbo);
-       if (ret) {
-               amdgpu_bo_unreserve(abo);
-               dev_err(adev->dev, "%p bind failed\n", abo);
-               goto out_unref;
-       }
-
-       ret = amdgpu_bo_kmap(abo, NULL);
-       amdgpu_bo_unreserve(abo);
-       if (ret) {
-               goto out_unref;
-       }
-
-       *gobj_p = gobj;
-       return 0;
-out_unref:
-       amdgpufb_destroy_pinned_object(gobj);
-       *gobj_p = NULL;
-       return ret;
-}
-
-static int amdgpufb_create(struct drm_fb_helper *helper,
-                          struct drm_fb_helper_surface_size *sizes)
-{
-       struct amdgpu_fbdev *rfbdev = (struct amdgpu_fbdev *)helper;
-       struct amdgpu_device *adev = rfbdev->adev;
-       struct fb_info *info;
-       struct drm_framebuffer *fb = NULL;
-       struct drm_mode_fb_cmd2 mode_cmd;
-       struct drm_gem_object *gobj = NULL;
-       struct amdgpu_bo *abo = NULL;
-       int ret;
-
-       memset(&mode_cmd, 0, sizeof(mode_cmd));
-       mode_cmd.width = sizes->surface_width;
-       mode_cmd.height = sizes->surface_height;
-
-       if (sizes->surface_bpp == 24)
-               sizes->surface_bpp = 32;
-
-       mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
-                                                         sizes->surface_depth);
-
-       ret = amdgpufb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
-       if (ret) {
-               DRM_ERROR("failed to create fbcon object %d\n", ret);
-               return ret;
-       }
-
-       abo = gem_to_amdgpu_bo(gobj);
-
-       /* okay we have an object now allocate the framebuffer */
-       info = drm_fb_helper_alloc_fbi(helper);
-       if (IS_ERR(info)) {
-               ret = PTR_ERR(info);
-               goto out;
-       }
-
-       ret = amdgpu_display_gem_fb_init(adev_to_drm(adev), &rfbdev->rfb,
-                                        &mode_cmd, gobj);
-       if (ret) {
-               DRM_ERROR("failed to initialize framebuffer %d\n", ret);
-               goto out;
-       }
-
-       fb = &rfbdev->rfb.base;
-
-       /* setup helper */
-       rfbdev->helper.fb = fb;
-
-       info->fbops = &amdgpufb_ops;
-
-       info->fix.smem_start = amdgpu_gmc_vram_cpu_pa(adev, abo);
-       info->fix.smem_len = amdgpu_bo_size(abo);
-       info->screen_base = amdgpu_bo_kptr(abo);
-       info->screen_size = amdgpu_bo_size(abo);
-
-       drm_fb_helper_fill_info(info, &rfbdev->helper, sizes);
-
-       /* setup aperture base/size for vesafb takeover */
-       info->apertures->ranges[0].base = adev_to_drm(adev)->mode_config.fb_base;
-       info->apertures->ranges[0].size = adev->gmc.aper_size;
-
-       /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
-
-       if (info->screen_base == NULL) {
-               ret = -ENOSPC;
-               goto out;
-       }
-
-       DRM_INFO("fb mappable at 0x%lX\n",  info->fix.smem_start);
-       DRM_INFO("vram apper at 0x%lX\n",  (unsigned long)adev->gmc.aper_base);
-       DRM_INFO("size %lu\n", (unsigned long)amdgpu_bo_size(abo));
-       DRM_INFO("fb depth is %d\n", fb->format->depth);
-       DRM_INFO("   pitch is %d\n", fb->pitches[0]);
-
-       vga_switcheroo_client_fb_set(adev->pdev, info);
-       return 0;
-
-out:
-       if (fb && ret) {
-               drm_gem_object_put(gobj);
-               drm_framebuffer_unregister_private(fb);
-               drm_framebuffer_cleanup(fb);
-               kfree(fb);
-       }
-       return ret;
-}
-
-static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfbdev)
-{
-       struct amdgpu_framebuffer *rfb = &rfbdev->rfb;
-       int i;
-
-       drm_fb_helper_unregister_fbi(&rfbdev->helper);
-
-       if (rfb->base.obj[0]) {
-               for (i = 0; i < rfb->base.format->num_planes; i++)
-                       drm_gem_object_put(rfb->base.obj[0]);
-               amdgpufb_destroy_pinned_object(rfb->base.obj[0]);
-               rfb->base.obj[0] = NULL;
-               drm_framebuffer_unregister_private(&rfb->base);
-               drm_framebuffer_cleanup(&rfb->base);
-       }
-       drm_fb_helper_fini(&rfbdev->helper);
-
-       return 0;
-}
-
-static const struct drm_fb_helper_funcs amdgpu_fb_helper_funcs = {
-       .fb_probe = amdgpufb_create,
-};
-
-int amdgpu_fbdev_init(struct amdgpu_device *adev)
-{
-       struct amdgpu_fbdev *rfbdev;
-       int bpp_sel = 32;
-       int ret;
-
-       /* don't init fbdev on hw without DCE */
-       if (!adev->mode_info.mode_config_initialized)
-               return 0;
-
-       /* don't init fbdev if there are no connectors */
-       if (list_empty(&adev_to_drm(adev)->mode_config.connector_list))
-               return 0;
-
-       /* select 8 bpp console on low vram cards */
-       if (adev->gmc.real_vram_size <= (32*1024*1024))
-               bpp_sel = 8;
-
-       rfbdev = kzalloc(sizeof(struct amdgpu_fbdev), GFP_KERNEL);
-       if (!rfbdev)
-               return -ENOMEM;
-
-       rfbdev->adev = adev;
-       adev->mode_info.rfbdev = rfbdev;
-
-       drm_fb_helper_prepare(adev_to_drm(adev), &rfbdev->helper,
-                             &amdgpu_fb_helper_funcs);
-
-       ret = drm_fb_helper_init(adev_to_drm(adev), &rfbdev->helper);
-       if (ret) {
-               kfree(rfbdev);
-               return ret;
-       }
-
-       /* disable all the possible outputs/crtcs before entering KMS mode */
-       if (!amdgpu_device_has_dc_support(adev) && !amdgpu_virtual_display)
-               drm_helper_disable_unused_functions(adev_to_drm(adev));
-
-       drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
-       return 0;
-}
-
-void amdgpu_fbdev_fini(struct amdgpu_device *adev)
-{
-       if (!adev->mode_info.rfbdev)
-               return;
-
-       amdgpu_fbdev_destroy(adev_to_drm(adev), adev->mode_info.rfbdev);
-       kfree(adev->mode_info.rfbdev);
-       adev->mode_info.rfbdev = NULL;
-}
-
-void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state)
-{
-       if (adev->mode_info.rfbdev)
-               drm_fb_helper_set_suspend_unlocked(&adev->mode_info.rfbdev->helper,
-                                                  state);
-}
-
-int amdgpu_fbdev_total_size(struct amdgpu_device *adev)
-{
-       struct amdgpu_bo *robj;
-       int size = 0;
-
-       if (!adev->mode_info.rfbdev)
-               return 0;
-
-       robj = gem_to_amdgpu_bo(adev->mode_info.rfbdev->rfb.base.obj[0]);
-       size += amdgpu_bo_size(robj);
-       return size;
-}
-
-bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
-{
-       if (!adev->mode_info.rfbdev)
-               return false;
-       if (robj == gem_to_amdgpu_bo(adev->mode_info.rfbdev->rfb.base.obj[0]))
-               return true;
-       return false;
-}
index a1e63ba4c54a590672db95ef58cda699201845b1..c0d8f40a5b45cb861c27bd226ee2f4293a74d00c 100644 (file)
@@ -877,6 +877,32 @@ out:
        return r;
 }
 
+static int amdgpu_gem_align_pitch(struct amdgpu_device *adev,
+                                 int width,
+                                 int cpp,
+                                 bool tiled)
+{
+       int aligned = width;
+       int pitch_mask = 0;
+
+       switch (cpp) {
+       case 1:
+               pitch_mask = 255;
+               break;
+       case 2:
+               pitch_mask = 127;
+               break;
+       case 3:
+       case 4:
+               pitch_mask = 63;
+               break;
+       }
+
+       aligned += pitch_mask;
+       aligned &= ~pitch_mask;
+       return aligned * cpp;
+}
+
 int amdgpu_mode_dumb_create(struct drm_file *file_priv,
                            struct drm_device *dev,
                            struct drm_mode_create_dumb *args)
@@ -885,7 +911,8 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
        struct drm_gem_object *gobj;
        uint32_t handle;
        u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
-                   AMDGPU_GEM_CREATE_CPU_GTT_USWC;
+                   AMDGPU_GEM_CREATE_CPU_GTT_USWC |
+                   AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
        u32 domain;
        int r;
 
@@ -897,8 +924,8 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
        if (adev->mman.buffer_funcs_enabled)
                flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED;
 
-       args->pitch = amdgpu_align_pitch(adev, args->width,
-                                        DIV_ROUND_UP(args->bpp, 8), 0);
+       args->pitch = amdgpu_gem_align_pitch(adev, args->width,
+                                            DIV_ROUND_UP(args->bpp, 8), 0);
        args->size = (u64)args->pitch * args->height;
        args->size = ALIGN(args->size, PAGE_SIZE);
        domain = amdgpu_bo_get_preferred_domain(adev,
index f3d62e196901a85fe77d3221e80dd91b8d64dcd4..0c7963dfacad1e4ce458ae6993b3d5fdeafe0091 100644 (file)
@@ -223,7 +223,7 @@ int amdgpu_ih_wait_on_checkpoint_process(struct amdgpu_device *adev,
  */
 int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
 {
-       unsigned int count = AMDGPU_IH_MAX_NUM_IVS;
+       unsigned int count;
        u32 wptr;
 
        if (!ih->enabled || adev->shutdown)
@@ -232,6 +232,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
        wptr = amdgpu_ih_get_wptr(adev, ih);
 
 restart_ih:
+       count  = AMDGPU_IH_MAX_NUM_IVS;
        DRM_DEBUG("%s: rptr %d, wptr %d\n", __func__, ih->rptr, wptr);
 
        /* Order reading of wptr vs. reading of IH ring data */
index cc2e0c9cfe0a132f68f3d93c785517e25bd6537d..4f3c62adccbdef85d46b979e2db56ec3cf116dd0 100644 (file)
@@ -333,7 +333,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
        if (!amdgpu_device_has_dc_support(adev)) {
                if (!adev->enable_virtual_display)
                        /* Disable vblank IRQs aggressively for power-saving */
-                       /* XXX: can this be enabled for DC? */
                        adev_to_drm(adev)->vblank_disable_immediate = true;
 
                r = drm_vblank_init(adev_to_drm(adev), adev->mode_info.num_crtc);
index 89fb372ed49c9e6fc50be66caa394c5d0881bb97..6043bf6fd414d2b512abaf31240a0fd6db4e4586 100644 (file)
@@ -232,8 +232,6 @@ struct amdgpu_i2c_chan {
        struct mutex mutex;
 };
 
-struct amdgpu_fbdev;
-
 struct amdgpu_afmt {
        bool enabled;
        int offset;
@@ -309,13 +307,6 @@ struct amdgpu_framebuffer {
        uint64_t address;
 };
 
-struct amdgpu_fbdev {
-       struct drm_fb_helper helper;
-       struct amdgpu_framebuffer rfb;
-       struct list_head fbdev_list;
-       struct amdgpu_device *adev;
-};
-
 struct amdgpu_mode_info {
        struct atom_context *atom_context;
        struct card_info *atom_card_info;
@@ -341,8 +332,6 @@ struct amdgpu_mode_info {
        struct edid *bios_hardcoded_edid;
        int bios_hardcoded_edid_size;
 
-       /* pointer to fbdev info structure */
-       struct amdgpu_fbdev *rfbdev;
        /* firmware flags */
        u32 firmware_flags;
        /* pointer to backlight encoder */
@@ -631,15 +620,6 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc,
                        int *hpos, ktime_t *stime, ktime_t *etime,
                        const struct drm_display_mode *mode);
 
-/* fbdev layer */
-int amdgpu_fbdev_init(struct amdgpu_device *adev);
-void amdgpu_fbdev_fini(struct amdgpu_device *adev);
-void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state);
-int amdgpu_fbdev_total_size(struct amdgpu_device *adev);
-bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj);
-
-int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tiled);
-
 /* amdgpu_display.c */
 void amdgpu_display_print_display_setup(struct drm_device *dev);
 int amdgpu_display_modeset_create_props(struct amdgpu_device *adev);
index 4fcfc2313b8ce122063652779cbee442b027942b..3a7b56e57cec114afee1c117c2ecef79a0543f2a 100644 (file)
@@ -1032,9 +1032,14 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
        /* On A+A platform, VRAM can be mapped as WB */
        if (!adev->gmc.xgmi.connected_to_cpu) {
                /* reserve PAT memory space to WC for VRAM */
-               arch_io_reserve_memtype_wc(adev->gmc.aper_base,
+               int r = arch_io_reserve_memtype_wc(adev->gmc.aper_base,
                                adev->gmc.aper_size);
 
+               if (r) {
+                       DRM_ERROR("Unable to set WC memtype for the aperture base\n");
+                       return r;
+               }
+
                /* Add an MTRR for the VRAM */
                adev->gmc.vram_mtrr = arch_phys_wc_add(adev->gmc.aper_base,
                                adev->gmc.aper_size);
index 08133de21fdd635015e0dae2a4baf46b34a5d539..46910e7b292777ce11b48bbfb9dd7186edffb2f5 100644 (file)
@@ -892,6 +892,38 @@ void amdgpu_ras_mca_query_error_status(struct amdgpu_device *adev,
        }
 }
 
+static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_data *err_data)
+{
+       struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+       int ret = 0;
+
+       /*
+        * choosing right query method according to
+        * whether smu support query error information
+        */
+       ret = smu_get_ecc_info(&adev->smu, (void *)&(ras->umc_ecc));
+       if (ret == -EOPNOTSUPP) {
+               if (adev->umc.ras_funcs &&
+                       adev->umc.ras_funcs->query_ras_error_count)
+                       adev->umc.ras_funcs->query_ras_error_count(adev, err_data);
+
+               /* umc query_ras_error_address is also responsible for clearing
+                * error status
+                */
+               if (adev->umc.ras_funcs &&
+                   adev->umc.ras_funcs->query_ras_error_address)
+                       adev->umc.ras_funcs->query_ras_error_address(adev, err_data);
+       } else if (!ret) {
+               if (adev->umc.ras_funcs &&
+                       adev->umc.ras_funcs->ecc_info_query_ras_error_count)
+                       adev->umc.ras_funcs->ecc_info_query_ras_error_count(adev, err_data);
+
+               if (adev->umc.ras_funcs &&
+                       adev->umc.ras_funcs->ecc_info_query_ras_error_address)
+                       adev->umc.ras_funcs->ecc_info_query_ras_error_address(adev, err_data);
+       }
+}
+
 /* query/inject/cure begin */
 int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
                                  struct ras_query_if *info)
@@ -905,15 +937,7 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
 
        switch (info->head.block) {
        case AMDGPU_RAS_BLOCK__UMC:
-               if (adev->umc.ras_funcs &&
-                   adev->umc.ras_funcs->query_ras_error_count)
-                       adev->umc.ras_funcs->query_ras_error_count(adev, &err_data);
-               /* umc query_ras_error_address is also responsible for clearing
-                * error status
-                */
-               if (adev->umc.ras_funcs &&
-                   adev->umc.ras_funcs->query_ras_error_address)
-                       adev->umc.ras_funcs->query_ras_error_address(adev, &err_data);
+               amdgpu_ras_get_ecc_info(adev, &err_data);
                break;
        case AMDGPU_RAS_BLOCK__SDMA:
                if (adev->sdma.funcs->query_ras_error_count) {
@@ -1935,9 +1959,11 @@ int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev)
        if (!con || !con->eh_data)
                return 0;
 
+       mutex_lock(&con->recovery_lock);
        control = &con->eeprom_control;
        data = con->eh_data;
        save_count = data->count - control->ras_num_recs;
+       mutex_unlock(&con->recovery_lock);
        /* only new entries are saved */
        if (save_count > 0) {
                if (amdgpu_ras_eeprom_append(control,
index e36f4de9fa55c95a285b8f4cead683b7bf529a78..1c708122d4922979fcb511b852857c70cea3cf6c 100644 (file)
@@ -319,6 +319,19 @@ struct ras_common_if {
        char name[32];
 };
 
+#define MAX_UMC_CHANNEL_NUM 32
+
+struct ecc_info_per_ch {
+       uint16_t ce_count_lo_chip;
+       uint16_t ce_count_hi_chip;
+       uint64_t mca_umc_status;
+       uint64_t mca_umc_addr;
+};
+
+struct umc_ecc_info {
+       struct ecc_info_per_ch ecc[MAX_UMC_CHANNEL_NUM];
+};
+
 struct amdgpu_ras {
        /* ras infrastructure */
        /* for ras itself. */
@@ -358,6 +371,9 @@ struct amdgpu_ras {
        struct delayed_work ras_counte_delay_work;
        atomic_t ras_ue_count;
        atomic_t ras_ce_count;
+
+       /* record umc error info queried from smu */
+       struct umc_ecc_info umc_ecc;
 };
 
 struct ras_fs_data {
index c15687ce67c4b2953a0acaabbfdbf30bdc31d0e6..fb0d8bffdce23c5eced53bbdc18ea857cd857f41 100644 (file)
@@ -913,11 +913,6 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
                     ttm->num_pages, bo_mem, ttm);
        }
 
-       if (bo_mem->mem_type == AMDGPU_PL_GDS ||
-           bo_mem->mem_type == AMDGPU_PL_GWS ||
-           bo_mem->mem_type == AMDGPU_PL_OA)
-               return -EINVAL;
-
        if (bo_mem->mem_type != TTM_PL_TT ||
            !amdgpu_gtt_mgr_has_gart_addr(bo_mem)) {
                gtt->offset = AMDGPU_BO_INVALID_OFFSET;
index a90029ee9733e9b83e97db3ed739871a12682f7e..6e4bea012ea4f097c8d0dffc0fd9b2ff91ca3007 100644 (file)
@@ -94,30 +94,58 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
 {
        struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
        struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
+       int ret = 0;
 
        kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
-       if (adev->umc.ras_funcs &&
-           adev->umc.ras_funcs->query_ras_error_count)
-           adev->umc.ras_funcs->query_ras_error_count(adev, ras_error_status);
-
-       if (adev->umc.ras_funcs &&
-           adev->umc.ras_funcs->query_ras_error_address &&
-           adev->umc.max_ras_err_cnt_per_query) {
-               err_data->err_addr =
-                       kcalloc(adev->umc.max_ras_err_cnt_per_query,
-                               sizeof(struct eeprom_table_record), GFP_KERNEL);
-
-               /* still call query_ras_error_address to clear error status
-                * even NOMEM error is encountered
-                */
-               if(!err_data->err_addr)
-                       dev_warn(adev->dev, "Failed to alloc memory for "
-                                       "umc error address record!\n");
-
-               /* umc query_ras_error_address is also responsible for clearing
-                * error status
-                */
-               adev->umc.ras_funcs->query_ras_error_address(adev, ras_error_status);
+       ret = smu_get_ecc_info(&adev->smu, (void *)&(con->umc_ecc));
+       if (ret == -EOPNOTSUPP) {
+               if (adev->umc.ras_funcs &&
+                   adev->umc.ras_funcs->query_ras_error_count)
+                   adev->umc.ras_funcs->query_ras_error_count(adev, ras_error_status);
+
+               if (adev->umc.ras_funcs &&
+                   adev->umc.ras_funcs->query_ras_error_address &&
+                   adev->umc.max_ras_err_cnt_per_query) {
+                       err_data->err_addr =
+                               kcalloc(adev->umc.max_ras_err_cnt_per_query,
+                                       sizeof(struct eeprom_table_record), GFP_KERNEL);
+
+                       /* still call query_ras_error_address to clear error status
+                        * even NOMEM error is encountered
+                        */
+                       if(!err_data->err_addr)
+                               dev_warn(adev->dev, "Failed to alloc memory for "
+                                               "umc error address record!\n");
+
+                       /* umc query_ras_error_address is also responsible for clearing
+                        * error status
+                        */
+                       adev->umc.ras_funcs->query_ras_error_address(adev, ras_error_status);
+               }
+       } else if (!ret) {
+               if (adev->umc.ras_funcs &&
+                   adev->umc.ras_funcs->ecc_info_query_ras_error_count)
+                   adev->umc.ras_funcs->ecc_info_query_ras_error_count(adev, ras_error_status);
+
+               if (adev->umc.ras_funcs &&
+                   adev->umc.ras_funcs->ecc_info_query_ras_error_address &&
+                   adev->umc.max_ras_err_cnt_per_query) {
+                       err_data->err_addr =
+                               kcalloc(adev->umc.max_ras_err_cnt_per_query,
+                                       sizeof(struct eeprom_table_record), GFP_KERNEL);
+
+                       /* still call query_ras_error_address to clear error status
+                        * even NOMEM error is encountered
+                        */
+                       if(!err_data->err_addr)
+                               dev_warn(adev->dev, "Failed to alloc memory for "
+                                               "umc error address record!\n");
+
+                       /* umc query_ras_error_address is also responsible for clearing
+                        * error status
+                        */
+                       adev->umc.ras_funcs->ecc_info_query_ras_error_address(adev, ras_error_status);
+               }
        }
 
        /* only uncorrectable error needs gpu reset */
index 1f5fe2315236d86a486bc340697a4b89796ef79d..9e40bade0a687609baa7bf1514574d2c8a80e4b5 100644 (file)
@@ -49,6 +49,10 @@ struct amdgpu_umc_ras_funcs {
        void (*query_ras_error_address)(struct amdgpu_device *adev,
                                        void *ras_error_status);
        bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
+       void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev,
+                                     void *ras_error_status);
+       void (*ecc_info_query_ras_error_address)(struct amdgpu_device *adev,
+                                       void *ras_error_status);
 };
 
 struct amdgpu_umc_funcs {
index 04cf9b207e628cd9bb93a75e68fa4f69ba17beb7..3fc49823f52766bc49dd455ac4d3a75a9595c9a6 100644 (file)
@@ -283,17 +283,15 @@ static int amdgpu_virt_init_ras_err_handler_data(struct amdgpu_device *adev)
 
        *data = kmalloc(sizeof(struct amdgpu_virt_ras_err_handler_data), GFP_KERNEL);
        if (!*data)
-               return -ENOMEM;
+               goto data_failure;
 
        bps = kmalloc_array(align_space, sizeof((*data)->bps), GFP_KERNEL);
-       bps_bo = kmalloc_array(align_space, sizeof((*data)->bps_bo), GFP_KERNEL);
+       if (!bps)
+               goto bps_failure;
 
-       if (!bps || !bps_bo) {
-               kfree(bps);
-               kfree(bps_bo);
-               kfree(*data);
-               return -ENOMEM;
-       }
+       bps_bo = kmalloc_array(align_space, sizeof((*data)->bps_bo), GFP_KERNEL);
+       if (!bps_bo)
+               goto bps_bo_failure;
 
        (*data)->bps = bps;
        (*data)->bps_bo = bps_bo;
@@ -303,6 +301,13 @@ static int amdgpu_virt_init_ras_err_handler_data(struct amdgpu_device *adev)
        virt->ras_init_done = true;
 
        return 0;
+
+bps_bo_failure:
+       kfree(bps);
+bps_failure:
+       kfree(*data);
+data_failure:
+       return -ENOMEM;
 }
 
 static void amdgpu_virt_ras_release_bp(struct amdgpu_device *adev)
index b200b9e722d97887bb20472fdb635e3289af2433..8318ee8339f1b9af4165b5f7c5a09590be608585 100644 (file)
@@ -2092,22 +2092,18 @@ static int dce_v8_0_pick_dig_encoder(struct drm_encoder *encoder)
                        return 1;
                else
                        return 0;
-               break;
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
                if (dig->linkb)
                        return 3;
                else
                        return 2;
-               break;
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
                if (dig->linkb)
                        return 5;
                else
                        return 4;
-               break;
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
                return 6;
-               break;
        default:
                DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id);
                return 0;
index e7dfeb466a0e4dd41b14e39ed2bb3ff5a3756ad8..dbe7442fb25cc4968e4237f7dbef1fbd3eab1c03 100644 (file)
@@ -7707,8 +7707,19 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev)
        switch (adev->ip_versions[GC_HWIP][0]) {
        case IP_VERSION(10, 3, 1):
        case IP_VERSION(10, 3, 3):
-               clock = (uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh) |
-                       ((uint64_t)RREG32_SOC15(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh) << 32ULL);
+               preempt_disable();
+               clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh);
+               clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh);
+               hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh);
+               /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over
+                * roughly every 42 seconds.
+                */
+               if (hi_check != clock_hi) {
+                       clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh);
+                       clock_hi = hi_check;
+               }
+               preempt_enable();
+               clock = clock_lo | (clock_hi << 32ULL);
                break;
        default:
                preempt_disable();
index b4b80f27b894098f822068b2ba3ccc656f28ef6b..34478bcc4d095cd94bd6e23d1e5fbab14cb799dd 100644 (file)
@@ -140,6 +140,11 @@ MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
 #define mmTCP_CHAN_STEER_5_ARCT                                                                0x0b0c
 #define mmTCP_CHAN_STEER_5_ARCT_BASE_IDX                                                       0
 
+#define mmGOLDEN_TSC_COUNT_UPPER_Renoir                0x0025
+#define mmGOLDEN_TSC_COUNT_UPPER_Renoir_BASE_IDX       1
+#define mmGOLDEN_TSC_COUNT_LOWER_Renoir                0x0026
+#define mmGOLDEN_TSC_COUNT_LOWER_Renoir_BASE_IDX       1
+
 enum ta_ras_gfx_subblock {
        /*CPC*/
        TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0,
@@ -4238,19 +4243,38 @@ failed_kiq_read:
 
 static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev)
 {
-       uint64_t clock;
+       uint64_t clock, clock_lo, clock_hi, hi_check;
 
-       amdgpu_gfx_off_ctrl(adev, false);
-       mutex_lock(&adev->gfx.gpu_clock_mutex);
-       if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 0, 1) && amdgpu_sriov_runtime(adev)) {
-               clock = gfx_v9_0_kiq_read_clock(adev);
-       } else {
-               WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1);
-               clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) |
-                       ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+       switch (adev->ip_versions[GC_HWIP][0]) {
+       case IP_VERSION(9, 3, 0):
+               preempt_disable();
+               clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir);
+               clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir);
+               hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir);
+               /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over
+                * roughly every 42 seconds.
+                */
+               if (hi_check != clock_hi) {
+                       clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir);
+                       clock_hi = hi_check;
+               }
+               preempt_enable();
+               clock = clock_lo | (clock_hi << 32ULL);
+               break;
+       default:
+               amdgpu_gfx_off_ctrl(adev, false);
+               mutex_lock(&adev->gfx.gpu_clock_mutex);
+               if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 0, 1) && amdgpu_sriov_runtime(adev)) {
+                       clock = gfx_v9_0_kiq_read_clock(adev);
+               } else {
+                       WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+                       clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) |
+                               ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+               }
+               mutex_unlock(&adev->gfx.gpu_clock_mutex);
+               amdgpu_gfx_off_ctrl(adev, true);
+               break;
        }
-       mutex_unlock(&adev->gfx.gpu_clock_mutex);
-       amdgpu_gfx_off_ctrl(adev, true);
        return clock;
 }
 
index 1d8414c3fadb6d5edd6ba924e0ec6ae5631f5180..38241cf0e1f1639f5d1e5ac97c5f6d0d7d716706 100644 (file)
@@ -160,6 +160,7 @@ static int navi10_ih_toggle_ring_interrupts(struct amdgpu_device *adev,
 
        tmp = RREG32(ih_regs->ih_rb_cntl);
        tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
+       tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1);
        /* enable_intr field is only valid in ring0 */
        if (ih == &adev->irq.ih)
                tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
@@ -275,10 +276,8 @@ static int navi10_ih_enable_ring(struct amdgpu_device *adev,
        tmp = navi10_ih_rb_cntl(ih, tmp);
        if (ih == &adev->irq.ih)
                tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled);
-       if (ih == &adev->irq.ih1) {
-               tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
+       if (ih == &adev->irq.ih1)
                tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
-       }
 
        if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
                if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
@@ -319,7 +318,6 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
 {
        struct amdgpu_ih_ring *ih[] = {&adev->irq.ih, &adev->irq.ih1, &adev->irq.ih2};
        u32 ih_chicken;
-       u32 tmp;
        int ret;
        int i;
 
@@ -363,15 +361,6 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
        adev->nbio.funcs->ih_doorbell_range(adev, ih[0]->use_doorbell,
                                            ih[0]->doorbell_index);
 
-       tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
-       tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
-                           CLIENT18_IS_STORM_CLIENT, 1);
-       WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
-
-       tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
-       tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
-       WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
-
        pci_set_master(adev->pdev);
 
        /* enable interrupts */
@@ -420,12 +409,19 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
        u32 wptr, tmp;
        struct amdgpu_ih_regs *ih_regs;
 
-       wptr = le32_to_cpu(*ih->wptr_cpu);
-       ih_regs = &ih->ih_regs;
+       if (ih == &adev->irq.ih) {
+               /* Only ring0 supports writeback. On other rings fall back
+                * to register-based code with overflow checking below.
+                */
+               wptr = le32_to_cpu(*ih->wptr_cpu);
 
-       if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
-               goto out;
+               if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
+                       goto out;
+       }
 
+       ih_regs = &ih->ih_regs;
+
+       /* Double check that the overflow wasn't already cleared. */
        wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr);
        if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
                goto out;
@@ -513,15 +509,11 @@ static int navi10_ih_self_irq(struct amdgpu_device *adev,
                              struct amdgpu_irq_src *source,
                              struct amdgpu_iv_entry *entry)
 {
-       uint32_t wptr = cpu_to_le32(entry->src_data[0]);
-
        switch (entry->ring_id) {
        case 1:
-               *adev->irq.ih1.wptr_cpu = wptr;
                schedule_work(&adev->irq.ih1_work);
                break;
        case 2:
-               *adev->irq.ih2.wptr_cpu = wptr;
                schedule_work(&adev->irq.ih2_work);
                break;
        default: break;
index 4ecd2b5808cee083349b869df527a42d25fcdfeb..ee7cab37dfd58a0a76ec658c8bf1e0d06dca37b1 100644 (file)
@@ -359,6 +359,10 @@ static void nbio_v2_3_init_registers(struct amdgpu_device *adev)
 
        if (def != data)
                WREG32_PCIE(smnPCIE_CONFIG_CNTL, data);
+
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
+                       mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 #define NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT         0x00000000 // off by default, no gains over L1
index 0d2d629e2d6a2223c5fdb7e7461288e90332136f..4bbacf1be25a413b9ae1af0c064421333c7e2acb 100644 (file)
@@ -276,6 +276,10 @@ static void nbio_v6_1_init_registers(struct amdgpu_device *adev)
 
        if (def != data)
                WREG32_PCIE(smnPCIE_CI_CNTL, data);
+
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
+                       mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 static void nbio_v6_1_program_ltr(struct amdgpu_device *adev)
index 3c00666a13e16b45213a98da1aa8151628640d5c..37a4039fdfc53da3b85a4a18bc05e2891bee4671 100644 (file)
@@ -273,7 +273,9 @@ const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = {
 
 static void nbio_v7_0_init_registers(struct amdgpu_device *adev)
 {
-
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset =
+                       SOC15_REG_OFFSET(NBIO, 0, mmHDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 const struct amdgpu_nbio_funcs nbio_v7_0_funcs = {
index 8f2a315e7c73ce8d874dd31238be23bf547bedb8..3444332ea1104e5334a0c96438c9f0f409b26f60 100644 (file)
@@ -371,6 +371,10 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
                if (def != data)
                        WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL), data);
        }
+
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
+                       regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 const struct amdgpu_nbio_funcs nbio_v7_2_funcs = {
index b8bd03d16dbaf13ec5634a92b60e6babf08b9885..dc5e93756fea4fd8d7a193dd75774604b49cd570 100644 (file)
@@ -362,7 +362,9 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald = {
 
 static void nbio_v7_4_init_registers(struct amdgpu_device *adev)
 {
-
+       if (amdgpu_sriov_vf(adev))
+               adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
+                       mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
 }
 
 static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device *adev)
@@ -692,6 +694,9 @@ static void nbio_v7_4_program_aspm(struct amdgpu_device *adev)
 {
        uint32_t def, data;
 
+       if (adev->ip_versions[NBIO_HWIP][0] == IP_VERSION(7, 4, 4))
+               return;
+
        def = data = RREG32_PCIE(smnPCIE_LC_CNTL);
        data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK;
        data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK;
index 59eafa31c626ac6fdafbe84ad68fc0da0e035260..a6659d9ecdd220a212ebb80ee7203c214cf28548 100644 (file)
@@ -731,8 +731,10 @@ static int nv_common_early_init(void *handle)
 #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
-       adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
+       if (!amdgpu_sriov_vf(adev)) {
+               adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
+               adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
+       }
        adev->smc_rreg = NULL;
        adev->smc_wreg = NULL;
        adev->pcie_rreg = &nv_pcie_rreg;
@@ -1032,7 +1034,7 @@ static int nv_common_hw_init(void *handle)
         * for the purpose of expose those registers
         * to process space
         */
-       if (adev->nbio.funcs->remap_hdp_registers)
+       if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev))
                adev->nbio.funcs->remap_hdp_registers(adev);
        /* enable the doorbell aperture */
        nv_enable_doorbell_aperture(adev, true);
index 0c316a2d42ed2431f64e3c7b0833b1b91f83c50b..de9b55383e9f8088cb8dc8425fe47f86a7686208 100644 (file)
@@ -971,8 +971,10 @@ static int soc15_common_early_init(void *handle)
 #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
-       adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
+       if (!amdgpu_sriov_vf(adev)) {
+               adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
+               adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
+       }
        adev->smc_rreg = NULL;
        adev->smc_wreg = NULL;
        adev->pcie_rreg = &soc15_pcie_rreg;
@@ -1285,7 +1287,7 @@ static int soc15_common_hw_init(void *handle)
         * for the purpose of expose those registers
         * to process space
         */
-       if (adev->nbio.funcs->remap_hdp_registers)
+       if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev))
                adev->nbio.funcs->remap_hdp_registers(adev);
 
        /* enable the doorbell aperture */
index f7ec3fe134e52fd6c685b90b9c971da24378a28d..6dd1e19e8d43234231bfefc0b9bac7f600be6a86 100644 (file)
@@ -50,6 +50,165 @@ static inline uint32_t get_umc_v6_7_reg_offset(struct amdgpu_device *adev,
        return adev->umc.channel_offs * ch_inst + UMC_V6_7_INST_DIST * umc_inst;
 }
 
+static inline uint32_t get_umc_v6_7_channel_index(struct amdgpu_device *adev,
+                                             uint32_t umc_inst,
+                                             uint32_t ch_inst)
+{
+       return adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
+}
+
+static void umc_v6_7_ecc_info_query_correctable_error_count(struct amdgpu_device *adev,
+                                                  uint32_t channel_index,
+                                                  unsigned long *error_count)
+{
+       uint32_t ecc_err_cnt;
+       uint64_t mc_umc_status;
+       struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+       /*
+        * select the lower chip and check the error count
+        * skip add error count, calc error counter only from mca_umc_status
+        */
+       ecc_err_cnt = ras->umc_ecc.ecc[channel_index].ce_count_lo_chip;
+
+       /*
+        * select the higher chip and check the err counter
+        * skip add error count, calc error counter only from mca_umc_status
+        */
+       ecc_err_cnt = ras->umc_ecc.ecc[channel_index].ce_count_hi_chip;
+
+       /* check for SRAM correctable error
+         MCUMC_STATUS is a 64 bit register */
+       mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status;
+       if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
+           REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)
+               *error_count += 1;
+}
+
+static void umc_v6_7_ecc_info_querry_uncorrectable_error_count(struct amdgpu_device *adev,
+                                                     uint32_t channel_index,
+                                                     unsigned long *error_count)
+{
+       uint64_t mc_umc_status;
+       struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+       /* check the MCUMC_STATUS */
+       mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status;
+       if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
+           (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 ||
+           REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
+           REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
+           REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 ||
+           REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1))
+               *error_count += 1;
+}
+
+static void umc_v6_7_ecc_info_query_ras_error_count(struct amdgpu_device *adev,
+                                          void *ras_error_status)
+{
+       struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
+
+       uint32_t umc_inst        = 0;
+       uint32_t ch_inst         = 0;
+       uint32_t umc_reg_offset  = 0;
+       uint32_t channel_index   = 0;
+
+       /*TODO: driver needs to toggle DF Cstate to ensure
+        * safe access of UMC registers. Will add the protection */
+       LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
+               umc_reg_offset = get_umc_v6_7_reg_offset(adev,
+                                                        umc_inst,
+                                                        ch_inst);
+               channel_index = get_umc_v6_7_channel_index(adev,
+                                                        umc_inst,
+                                                        ch_inst);
+               umc_v6_7_ecc_info_query_correctable_error_count(adev,
+                                                     channel_index,
+                                                     &(err_data->ce_count));
+               umc_v6_7_ecc_info_querry_uncorrectable_error_count(adev,
+                                                         channel_index,
+                                                         &(err_data->ue_count));
+       }
+}
+
+static void umc_v6_7_ecc_info_query_error_address(struct amdgpu_device *adev,
+                                        struct ras_err_data *err_data,
+                                        uint32_t umc_reg_offset,
+                                        uint32_t ch_inst,
+                                        uint32_t umc_inst)
+{
+       uint64_t mc_umc_status, err_addr, retired_page;
+       struct eeprom_table_record *err_rec;
+       uint32_t channel_index;
+       struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+       channel_index =
+               adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
+
+       mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status;
+
+       if (mc_umc_status == 0)
+               return;
+
+       if (!err_data->err_addr)
+               return;
+
+       err_rec = &err_data->err_addr[err_data->err_addr_cnt];
+
+       /* calculate error address if ue/ce error is detected */
+       if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
+           (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
+           REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
+
+               err_addr = ras->umc_ecc.ecc[channel_index].mca_umc_addr;
+               err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
+
+               /* translate umc channel address to soc pa, 3 parts are included */
+               retired_page = ADDR_OF_8KB_BLOCK(err_addr) |
+                               ADDR_OF_256B_BLOCK(channel_index) |
+                               OFFSET_IN_256B_BLOCK(err_addr);
+
+               /* we only save ue error information currently, ce is skipped */
+               if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
+                               == 1) {
+                       err_rec->address = err_addr;
+                       /* page frame address is saved */
+                       err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
+                       err_rec->ts = (uint64_t)ktime_get_real_seconds();
+                       err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
+                       err_rec->cu = 0;
+                       err_rec->mem_channel = channel_index;
+                       err_rec->mcumc_id = umc_inst;
+
+                       err_data->err_addr_cnt++;
+               }
+       }
+}
+
+static void umc_v6_7_ecc_info_query_ras_error_address(struct amdgpu_device *adev,
+                                            void *ras_error_status)
+{
+       struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
+
+       uint32_t umc_inst        = 0;
+       uint32_t ch_inst         = 0;
+       uint32_t umc_reg_offset  = 0;
+
+       /*TODO: driver needs to toggle DF Cstate to ensure
+        * safe access of UMC resgisters. Will add the protection
+        * when firmware interface is ready */
+       LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
+               umc_reg_offset = get_umc_v6_7_reg_offset(adev,
+                                                        umc_inst,
+                                                        ch_inst);
+               umc_v6_7_ecc_info_query_error_address(adev,
+                                            err_data,
+                                            umc_reg_offset,
+                                            ch_inst,
+                                            umc_inst);
+       }
+}
+
 static void umc_v6_7_query_correctable_error_count(struct amdgpu_device *adev,
                                                   uint32_t umc_reg_offset,
                                                   unsigned long *error_count)
@@ -327,4 +486,6 @@ const struct amdgpu_umc_ras_funcs umc_v6_7_ras_funcs = {
        .query_ras_error_count = umc_v6_7_query_ras_error_count,
        .query_ras_error_address = umc_v6_7_query_ras_error_address,
        .query_ras_poison_mode = umc_v6_7_query_ras_poison_mode,
+       .ecc_info_query_ras_error_count = umc_v6_7_ecc_info_query_ras_error_count,
+       .ecc_info_query_ras_error_address = umc_v6_7_ecc_info_query_ras_error_address,
 };
index f6233019f042036db620d1187114be7fa3890e07..d60576ce10cdfb6ecaa149f74d9c7589272f06ec 100644 (file)
@@ -43,15 +43,15 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev,
         */
        if ((ihre->source_id == CIK_INTSRC_GFX_PAGE_INV_FAULT ||
                ihre->source_id == CIK_INTSRC_GFX_MEM_PROT_FAULT) &&
-               dev->device_info->asic_family == CHIP_HAWAII) {
+               dev->adev->asic_type == CHIP_HAWAII) {
                struct cik_ih_ring_entry *tmp_ihre =
                        (struct cik_ih_ring_entry *)patched_ihre;
 
                *patched_flag = true;
                *tmp_ihre = *ihre;
 
-               vmid = f2g->read_vmid_from_vmfault_reg(dev->kgd);
-               ret = f2g->get_atc_vmid_pasid_mapping_info(dev->kgd, vmid, &pasid);
+               vmid = f2g->read_vmid_from_vmfault_reg(dev->adev);
+               ret = f2g->get_atc_vmid_pasid_mapping_info(dev->adev, vmid, &pasid);
 
                tmp_ihre->ring_id &= 0x000000ff;
                tmp_ihre->ring_id |= vmid << 8;
@@ -113,7 +113,7 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev,
                kfd_process_vm_fault(dev->dqm, pasid);
 
                memset(&info, 0, sizeof(info));
-               amdgpu_amdkfd_gpuvm_get_vm_fault_info(dev->kgd, &info);
+               amdgpu_amdkfd_gpuvm_get_vm_fault_info(dev->adev, &info);
                if (!info.page_addr && !info.status)
                        return;
 
index 24ebd61395d84742ed2113b90637f22005a17c4f..4bfc0c8ab764be48fe14f6cb6b44b651a1b22723 100644 (file)
@@ -321,7 +321,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
        /* Return gpu_id as doorbell offset for mmap usage */
        args->doorbell_offset = KFD_MMAP_TYPE_DOORBELL;
        args->doorbell_offset |= KFD_MMAP_GPU_ID(args->gpu_id);
-       if (KFD_IS_SOC15(dev->device_info->asic_family))
+       if (KFD_IS_SOC15(dev))
                /* On SOC15 ASICs, include the doorbell offset within the
                 * process doorbell frame, which is 2 pages.
                 */
@@ -580,7 +580,7 @@ static int kfd_ioctl_dbg_register(struct file *filep,
        if (!dev)
                return -EINVAL;
 
-       if (dev->device_info->asic_family == CHIP_CARRIZO) {
+       if (dev->adev->asic_type == CHIP_CARRIZO) {
                pr_debug("kfd_ioctl_dbg_register not supported on CZ\n");
                return -EINVAL;
        }
@@ -631,7 +631,7 @@ static int kfd_ioctl_dbg_unregister(struct file *filep,
        if (!dev || !dev->dbgmgr)
                return -EINVAL;
 
-       if (dev->device_info->asic_family == CHIP_CARRIZO) {
+       if (dev->adev->asic_type == CHIP_CARRIZO) {
                pr_debug("kfd_ioctl_dbg_unregister not supported on CZ\n");
                return -EINVAL;
        }
@@ -676,7 +676,7 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
        if (!dev)
                return -EINVAL;
 
-       if (dev->device_info->asic_family == CHIP_CARRIZO) {
+       if (dev->adev->asic_type == CHIP_CARRIZO) {
                pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n");
                return -EINVAL;
        }
@@ -784,7 +784,7 @@ static int kfd_ioctl_dbg_wave_control(struct file *filep,
        if (!dev)
                return -EINVAL;
 
-       if (dev->device_info->asic_family == CHIP_CARRIZO) {
+       if (dev->adev->asic_type == CHIP_CARRIZO) {
                pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n");
                return -EINVAL;
        }
@@ -851,7 +851,7 @@ static int kfd_ioctl_get_clock_counters(struct file *filep,
        dev = kfd_device_by_id(args->gpu_id);
        if (dev)
                /* Reading GPU clock counter from KGD */
-               args->gpu_clock_counter = amdgpu_amdkfd_get_gpu_clock_counter(dev->kgd);
+               args->gpu_clock_counter = amdgpu_amdkfd_get_gpu_clock_counter(dev->adev);
        else
                /* Node without GPU resource */
                args->gpu_clock_counter = 0;
@@ -1041,7 +1041,7 @@ static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p,
                        goto out_unlock;
                }
 
-               err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kfd->kgd,
+               err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kfd->adev,
                                                mem, &kern_addr, &size);
                if (err) {
                        pr_err("Failed to map event page to kernel\n");
@@ -1051,7 +1051,7 @@ static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p,
                err = kfd_event_page_set(p, kern_addr, size);
                if (err) {
                        pr_err("Failed to set event page\n");
-                       amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kfd->kgd, mem);
+                       amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kfd->adev, mem);
                        goto out_unlock;
                }
 
@@ -1137,7 +1137,7 @@ static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
        if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS &&
            pdd->qpd.vmid != 0 && dev->kfd2kgd->set_scratch_backing_va)
                dev->kfd2kgd->set_scratch_backing_va(
-                       dev->kgd, args->va_addr, pdd->qpd.vmid);
+                       dev->adev, args->va_addr, pdd->qpd.vmid);
 
        return 0;
 
@@ -1158,7 +1158,7 @@ static int kfd_ioctl_get_tile_config(struct file *filep,
        if (!dev)
                return -EINVAL;
 
-       amdgpu_amdkfd_get_tile_config(dev->kgd, &config);
+       amdgpu_amdkfd_get_tile_config(dev->adev, &config);
 
        args->gb_addr_config = config.gb_addr_config;
        args->num_banks = config.num_banks;
@@ -1244,7 +1244,7 @@ bool kfd_dev_is_large_bar(struct kfd_dev *dev)
        if (dev->use_iommu_v2)
                return false;
 
-       amdgpu_amdkfd_get_local_mem_info(dev->kgd, &mem_info);
+       amdgpu_amdkfd_get_local_mem_info(dev->adev, &mem_info);
        if (mem_info.local_mem_size_private == 0 &&
                        mem_info.local_mem_size_public > 0)
                return true;
@@ -1313,7 +1313,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
                        err = -EINVAL;
                        goto err_unlock;
                }
-               offset = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd);
+               offset = dev->adev->rmmio_remap.bus_addr;
                if (!offset) {
                        err = -ENOMEM;
                        goto err_unlock;
@@ -1321,7 +1321,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
        }
 
        err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
-               dev->kgd, args->va_addr, args->size,
+               dev->adev, args->va_addr, args->size,
                pdd->drm_priv, (struct kgd_mem **) &mem, &offset,
                flags);
 
@@ -1353,7 +1353,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
        return 0;
 
 err_free:
-       amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem,
+       amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, (struct kgd_mem *)mem,
                                               pdd->drm_priv, NULL);
 err_unlock:
        mutex_unlock(&p->mutex);
@@ -1399,7 +1399,7 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
                goto err_unlock;
        }
 
-       ret = amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd,
+       ret = amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev,
                                (struct kgd_mem *)mem, pdd->drm_priv, &size);
 
        /* If freeing the buffer failed, leave the handle in place for
@@ -1484,7 +1484,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
                        goto get_mem_obj_from_handle_failed;
                }
                err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
-                       peer->kgd, (struct kgd_mem *)mem,
+                       peer->adev, (struct kgd_mem *)mem,
                        peer_pdd->drm_priv, &table_freed);
                if (err) {
                        pr_err("Failed to map to gpu %d/%d\n",
@@ -1496,7 +1496,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
 
        mutex_unlock(&p->mutex);
 
-       err = amdgpu_amdkfd_gpuvm_sync_memory(dev->kgd, (struct kgd_mem *) mem, true);
+       err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev, (struct kgd_mem *) mem, true);
        if (err) {
                pr_debug("Sync memory failed, wait interrupted by user signal\n");
                goto sync_memory_failed;
@@ -1593,7 +1593,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
                        goto get_mem_obj_from_handle_failed;
                }
                err = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
-                       peer->kgd, (struct kgd_mem *)mem, peer_pdd->drm_priv);
+                       peer->adev, (struct kgd_mem *)mem, peer_pdd->drm_priv);
                if (err) {
                        pr_err("Failed to unmap from gpu %d/%d\n",
                               i, args->n_devices);
@@ -1603,8 +1603,8 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
        }
        mutex_unlock(&p->mutex);
 
-       if (dev->device_info->asic_family == CHIP_ALDEBARAN) {
-               err = amdgpu_amdkfd_gpuvm_sync_memory(dev->kgd,
+       if (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2)) {
+               err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev,
                                (struct kgd_mem *) mem, true);
                if (err) {
                        pr_debug("Sync memory failed, wait interrupted by user signal\n");
@@ -1680,7 +1680,7 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep,
 {
        struct kfd_ioctl_get_dmabuf_info_args *args = data;
        struct kfd_dev *dev = NULL;
-       struct kgd_dev *dma_buf_kgd;
+       struct amdgpu_device *dmabuf_adev;
        void *metadata_buffer = NULL;
        uint32_t flags;
        unsigned int i;
@@ -1700,15 +1700,15 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep,
        }
 
        /* Get dmabuf info from KGD */
-       r = amdgpu_amdkfd_get_dmabuf_info(dev->kgd, args->dmabuf_fd,
-                                         &dma_buf_kgd, &args->size,
+       r = amdgpu_amdkfd_get_dmabuf_info(dev->adev, args->dmabuf_fd,
+                                         &dmabuf_adev, &args->size,
                                          metadata_buffer, args->metadata_size,
                                          &args->metadata_size, &flags);
        if (r)
                goto exit;
 
        /* Reverse-lookup gpu_id from kgd pointer */
-       dev = kfd_device_by_kgd(dma_buf_kgd);
+       dev = kfd_device_by_adev(dmabuf_adev);
        if (!dev) {
                r = -EINVAL;
                goto exit;
@@ -1758,7 +1758,7 @@ static int kfd_ioctl_import_dmabuf(struct file *filep,
                goto err_unlock;
        }
 
-       r = amdgpu_amdkfd_gpuvm_import_dmabuf(dev->kgd, dmabuf,
+       r = amdgpu_amdkfd_gpuvm_import_dmabuf(dev->adev, dmabuf,
                                              args->va_addr, pdd->drm_priv,
                                              (struct kgd_mem **)&mem, &size,
                                              NULL);
@@ -1779,7 +1779,7 @@ static int kfd_ioctl_import_dmabuf(struct file *filep,
        return 0;
 
 err_free:
-       amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem,
+       amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, (struct kgd_mem *)mem,
                                               pdd->drm_priv, NULL);
 err_unlock:
        mutex_unlock(&p->mutex);
@@ -2066,7 +2066,7 @@ static int kfd_mmio_mmap(struct kfd_dev *dev, struct kfd_process *process,
        if (vma->vm_end - vma->vm_start != PAGE_SIZE)
                return -EINVAL;
 
-       address = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd);
+       address = dev->adev->rmmio_remap.bus_addr;
 
        vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
                                VM_DONTDUMP | VM_PFNMAP;
index cfedfb1e8596c3346c9bf3019a18a52a846c9045..f187596faf666197bca53083999e632edf609a2f 100644 (file)
@@ -1340,7 +1340,7 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
        int ret;
        unsigned int num_cu_shared;
 
-       switch (kdev->device_info->asic_family) {
+       switch (kdev->adev->asic_type) {
        case CHIP_KAVERI:
                pcache_info = kaveri_cache_info;
                num_of_cache_types = ARRAY_SIZE(kaveri_cache_info);
@@ -1377,67 +1377,71 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
                pcache_info = vegam_cache_info;
                num_of_cache_types = ARRAY_SIZE(vegam_cache_info);
                break;
-       case CHIP_VEGA10:
-               pcache_info = vega10_cache_info;
-               num_of_cache_types = ARRAY_SIZE(vega10_cache_info);
-               break;
-       case CHIP_VEGA12:
-               pcache_info = vega12_cache_info;
-               num_of_cache_types = ARRAY_SIZE(vega12_cache_info);
-               break;
-       case CHIP_VEGA20:
-       case CHIP_ARCTURUS:
-               pcache_info = vega20_cache_info;
-               num_of_cache_types = ARRAY_SIZE(vega20_cache_info);
-               break;
-       case CHIP_ALDEBARAN:
-               pcache_info = aldebaran_cache_info;
-               num_of_cache_types = ARRAY_SIZE(aldebaran_cache_info);
-               break;
-       case CHIP_RAVEN:
-               pcache_info = raven_cache_info;
-               num_of_cache_types = ARRAY_SIZE(raven_cache_info);
-               break;
-       case CHIP_RENOIR:
-               pcache_info = renoir_cache_info;
-               num_of_cache_types = ARRAY_SIZE(renoir_cache_info);
-               break;
-       case CHIP_NAVI10:
-       case CHIP_NAVI12:
-       case CHIP_CYAN_SKILLFISH:
-               pcache_info = navi10_cache_info;
-               num_of_cache_types = ARRAY_SIZE(navi10_cache_info);
-               break;
-       case CHIP_NAVI14:
-               pcache_info = navi14_cache_info;
-               num_of_cache_types = ARRAY_SIZE(navi14_cache_info);
-               break;
-       case CHIP_SIENNA_CICHLID:
-               pcache_info = sienna_cichlid_cache_info;
-               num_of_cache_types = ARRAY_SIZE(sienna_cichlid_cache_info);
-               break;
-       case CHIP_NAVY_FLOUNDER:
-               pcache_info = navy_flounder_cache_info;
-               num_of_cache_types = ARRAY_SIZE(navy_flounder_cache_info);
-               break;
-       case CHIP_DIMGREY_CAVEFISH:
-               pcache_info = dimgrey_cavefish_cache_info;
-               num_of_cache_types = ARRAY_SIZE(dimgrey_cavefish_cache_info);
-               break;
-       case CHIP_VANGOGH:
-               pcache_info = vangogh_cache_info;
-               num_of_cache_types = ARRAY_SIZE(vangogh_cache_info);
-               break;
-       case CHIP_BEIGE_GOBY:
-               pcache_info = beige_goby_cache_info;
-               num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info);
-               break;
-       case CHIP_YELLOW_CARP:
-               pcache_info = yellow_carp_cache_info;
-               num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info);
-               break;
        default:
-               return -EINVAL;
+               switch(KFD_GC_VERSION(kdev)) {
+               case IP_VERSION(9, 0, 1):
+                       pcache_info = vega10_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(vega10_cache_info);
+                       break;
+               case IP_VERSION(9, 2, 1):
+                       pcache_info = vega12_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(vega12_cache_info);
+                       break;
+               case IP_VERSION(9, 4, 0):
+               case IP_VERSION(9, 4, 1):
+                       pcache_info = vega20_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(vega20_cache_info);
+                       break;
+               case IP_VERSION(9, 4, 2):
+                       pcache_info = aldebaran_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(aldebaran_cache_info);
+                       break;
+               case IP_VERSION(9, 1, 0):
+               case IP_VERSION(9, 2, 2):
+                       pcache_info = raven_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(raven_cache_info);
+                       break;
+               case IP_VERSION(9, 3, 0):
+                       pcache_info = renoir_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(renoir_cache_info);
+                       break;
+               case IP_VERSION(10, 1, 10):
+               case IP_VERSION(10, 1, 2):
+               case IP_VERSION(10, 1, 3):
+                       pcache_info = navi10_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(navi10_cache_info);
+                       break;
+               case IP_VERSION(10, 1, 1):
+                       pcache_info = navi14_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(navi14_cache_info);
+                       break;
+               case IP_VERSION(10, 3, 0):
+                       pcache_info = sienna_cichlid_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(sienna_cichlid_cache_info);
+                       break;
+               case IP_VERSION(10, 3, 2):
+                       pcache_info = navy_flounder_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(navy_flounder_cache_info);
+                       break;
+               case IP_VERSION(10, 3, 4):
+                       pcache_info = dimgrey_cavefish_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(dimgrey_cavefish_cache_info);
+                       break;
+               case IP_VERSION(10, 3, 1):
+                       pcache_info = vangogh_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(vangogh_cache_info);
+                       break;
+               case IP_VERSION(10, 3, 5):
+                       pcache_info = beige_goby_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info);
+                       break;
+               case IP_VERSION(10, 3, 3):
+                       pcache_info = yellow_carp_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info);
+                       break;
+               default:
+                       return -EINVAL;
+               }
        }
 
        *size_filled = 0;
@@ -1963,8 +1967,6 @@ static int kfd_fill_gpu_direct_io_link_to_cpu(int *avail_size,
                        struct crat_subtype_iolink *sub_type_hdr,
                        uint32_t proximity_domain)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)kdev->kgd;
-
        *avail_size -= sizeof(struct crat_subtype_iolink);
        if (*avail_size < 0)
                return -ENOMEM;
@@ -1981,7 +1983,7 @@ static int kfd_fill_gpu_direct_io_link_to_cpu(int *avail_size,
        /* Fill in IOLINK subtype.
         * TODO: Fill-in other fields of iolink subtype
         */
-       if (adev->gmc.xgmi.connected_to_cpu) {
+       if (kdev->adev->gmc.xgmi.connected_to_cpu) {
                /*
                 * with host gpu xgmi link, host can access gpu memory whether
                 * or not pcie bar type is large, so always create bidirectional
@@ -1990,19 +1992,19 @@ static int kfd_fill_gpu_direct_io_link_to_cpu(int *avail_size,
                sub_type_hdr->flags |= CRAT_IOLINK_FLAGS_BI_DIRECTIONAL;
                sub_type_hdr->io_interface_type = CRAT_IOLINK_TYPE_XGMI;
                sub_type_hdr->num_hops_xgmi = 1;
-               if (adev->asic_type == CHIP_ALDEBARAN) {
+               if (KFD_GC_VERSION(kdev) == IP_VERSION(9, 4, 2)) {
                        sub_type_hdr->minimum_bandwidth_mbs =
                                        amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(
-                                                       kdev->kgd, NULL, true);
+                                                       kdev->adev, NULL, true);
                        sub_type_hdr->maximum_bandwidth_mbs =
                                        sub_type_hdr->minimum_bandwidth_mbs;
                }
        } else {
                sub_type_hdr->io_interface_type = CRAT_IOLINK_TYPE_PCIEXPRESS;
                sub_type_hdr->minimum_bandwidth_mbs =
-                               amdgpu_amdkfd_get_pcie_bandwidth_mbytes(kdev->kgd, true);
+                               amdgpu_amdkfd_get_pcie_bandwidth_mbytes(kdev->adev, true);
                sub_type_hdr->maximum_bandwidth_mbs =
-                               amdgpu_amdkfd_get_pcie_bandwidth_mbytes(kdev->kgd, false);
+                               amdgpu_amdkfd_get_pcie_bandwidth_mbytes(kdev->adev, false);
        }
 
        sub_type_hdr->proximity_domain_from = proximity_domain;
@@ -2044,11 +2046,11 @@ static int kfd_fill_gpu_xgmi_link_to_gpu(int *avail_size,
        sub_type_hdr->proximity_domain_from = proximity_domain_from;
        sub_type_hdr->proximity_domain_to = proximity_domain_to;
        sub_type_hdr->num_hops_xgmi =
-               amdgpu_amdkfd_get_xgmi_hops_count(kdev->kgd, peer_kdev->kgd);
+               amdgpu_amdkfd_get_xgmi_hops_count(kdev->adev, peer_kdev->adev);
        sub_type_hdr->maximum_bandwidth_mbs =
-               amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(kdev->kgd, peer_kdev->kgd, false);
+               amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(kdev->adev, peer_kdev->adev, false);
        sub_type_hdr->minimum_bandwidth_mbs = sub_type_hdr->maximum_bandwidth_mbs ?
-               amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(kdev->kgd, NULL, true) : 0;
+               amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(kdev->adev, NULL, true) : 0;
 
        return 0;
 }
@@ -2114,7 +2116,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image,
        cu->flags |= CRAT_CU_FLAGS_GPU_PRESENT;
        cu->proximity_domain = proximity_domain;
 
-       amdgpu_amdkfd_get_cu_info(kdev->kgd, &cu_info);
+       amdgpu_amdkfd_get_cu_info(kdev->adev, &cu_info);
        cu->num_simd_per_cu = cu_info.simd_per_cu;
        cu->num_simd_cores = cu_info.simd_per_cu * cu_info.cu_active_number;
        cu->max_waves_simd = cu_info.max_waves_per_simd;
@@ -2145,7 +2147,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image,
         * report the total FB size (public+private) as a single
         * private heap.
         */
-       amdgpu_amdkfd_get_local_mem_info(kdev->kgd, &local_mem_info);
+       amdgpu_amdkfd_get_local_mem_info(kdev->adev, &local_mem_info);
        sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr +
                        sub_type_hdr->length);
 
index 159add0f5aaae26fe0a7c8824d93f0a1127a5808..1e30717b5253f4e83ef0214c4678dbbc902fd0d3 100644 (file)
@@ -41,7 +41,7 @@
 
 static void dbgdev_address_watch_disable_nodiq(struct kfd_dev *dev)
 {
-       dev->kfd2kgd->address_watch_disable(dev->kgd);
+       dev->kfd2kgd->address_watch_disable(dev->adev);
 }
 
 static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
@@ -322,7 +322,7 @@ static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
                pr_debug("\t\t%30s\n", "* * * * * * * * * * * * * * * * * *");
 
                pdd->dev->kfd2kgd->address_watch_execute(
-                                               dbgdev->dev->kgd,
+                                               dbgdev->dev->adev,
                                                i,
                                                cntl.u32All,
                                                addrHi.u32All,
@@ -420,7 +420,7 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
 
                aw_reg_add_dword =
                                dbgdev->dev->kfd2kgd->address_watch_get_offset(
-                                       dbgdev->dev->kgd,
+                                       dbgdev->dev->adev,
                                        i,
                                        ADDRESS_WATCH_REG_CNTL);
 
@@ -431,7 +431,7 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
 
                aw_reg_add_dword =
                                dbgdev->dev->kfd2kgd->address_watch_get_offset(
-                                       dbgdev->dev->kgd,
+                                       dbgdev->dev->adev,
                                        i,
                                        ADDRESS_WATCH_REG_ADDR_HI);
 
@@ -441,7 +441,7 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
 
                aw_reg_add_dword =
                                dbgdev->dev->kfd2kgd->address_watch_get_offset(
-                                       dbgdev->dev->kgd,
+                                       dbgdev->dev->adev,
                                        i,
                                        ADDRESS_WATCH_REG_ADDR_LO);
 
@@ -457,7 +457,7 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
 
                aw_reg_add_dword =
                                dbgdev->dev->kfd2kgd->address_watch_get_offset(
-                                       dbgdev->dev->kgd,
+                                       dbgdev->dev->adev,
                                        i,
                                        ADDRESS_WATCH_REG_CNTL);
 
@@ -752,7 +752,7 @@ static int dbgdev_wave_control_nodiq(struct kfd_dbgdev *dbgdev,
 
        pr_debug("\t\t %30s\n", "* * * * * * * * * * * * * * * * * *");
 
-       return dbgdev->dev->kfd2kgd->wave_control_execute(dbgdev->dev->kgd,
+       return dbgdev->dev->kfd2kgd->wave_control_execute(dbgdev->dev->adev,
                                                        reg_gfx_index.u32All,
                                                        reg_sq_cmd.u32All);
 }
@@ -784,7 +784,7 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
 
        for (vmid = first_vmid_to_scan; vmid <= last_vmid_to_scan; vmid++) {
                status = dev->kfd2kgd->get_atc_vmid_pasid_mapping_info
-                               (dev->kgd, vmid, &queried_pasid);
+                               (dev->adev, vmid, &queried_pasid);
 
                if (status && queried_pasid == p->pasid) {
                        pr_debug("Killing wave fronts of vmid %d and pasid 0x%x\n",
@@ -811,7 +811,7 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
        /* for non DIQ we need to patch the VMID: */
        reg_sq_cmd.bits.vm_id = vmid;
 
-       dev->kfd2kgd->wave_control_execute(dev->kgd,
+       dev->kfd2kgd->wave_control_execute(dev->adev,
                                        reg_gfx_index.u32All,
                                        reg_sq_cmd.u32All);
 
index 3b119db16003ed9b3c7afdf48ae32d69f9b691fd..e1294fba0c265917fbbd189d5a6fa4b6996e64cb 100644 (file)
@@ -55,7 +55,6 @@ extern const struct kfd2kgd_calls gfx_v10_3_kfd2kgd;
 
 #ifdef KFD_SUPPORT_IOMMU_V2
 static const struct kfd_device_info kaveri_device_info = {
-       .asic_family = CHIP_KAVERI,
        .asic_name = "kaveri",
        .gfx_target_version = 70000,
        .max_pasid_bits = 16,
@@ -69,13 +68,10 @@ static const struct kfd_device_info kaveri_device_info = {
        .supports_cwsr = false,
        .needs_iommu_device = true,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info carrizo_device_info = {
-       .asic_family = CHIP_CARRIZO,
        .asic_name = "carrizo",
        .gfx_target_version = 80001,
        .max_pasid_bits = 16,
@@ -89,13 +85,10 @@ static const struct kfd_device_info carrizo_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = true,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info raven_device_info = {
-       .asic_family = CHIP_RAVEN,
        .asic_name = "raven",
        .gfx_target_version = 90002,
        .max_pasid_bits = 16,
@@ -108,15 +101,12 @@ static const struct kfd_device_info raven_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = true,
        .needs_pci_atomics = true,
-       .num_sdma_engines = 1,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 #endif
 
 #ifdef CONFIG_DRM_AMDGPU_CIK
 static const struct kfd_device_info hawaii_device_info = {
-       .asic_family = CHIP_HAWAII,
        .asic_name = "hawaii",
        .gfx_target_version = 70001,
        .max_pasid_bits = 16,
@@ -130,14 +120,11 @@ static const struct kfd_device_info hawaii_device_info = {
        .supports_cwsr = false,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 #endif
 
 static const struct kfd_device_info tonga_device_info = {
-       .asic_family = CHIP_TONGA,
        .asic_name = "tonga",
        .gfx_target_version = 80002,
        .max_pasid_bits = 16,
@@ -150,13 +137,10 @@ static const struct kfd_device_info tonga_device_info = {
        .supports_cwsr = false,
        .needs_iommu_device = false,
        .needs_pci_atomics = true,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info fiji_device_info = {
-       .asic_family = CHIP_FIJI,
        .asic_name = "fiji",
        .gfx_target_version = 80003,
        .max_pasid_bits = 16,
@@ -169,13 +153,10 @@ static const struct kfd_device_info fiji_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = true,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info fiji_vf_device_info = {
-       .asic_family = CHIP_FIJI,
        .asic_name = "fiji",
        .gfx_target_version = 80003,
        .max_pasid_bits = 16,
@@ -188,14 +169,11 @@ static const struct kfd_device_info fiji_vf_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 
 static const struct kfd_device_info polaris10_device_info = {
-       .asic_family = CHIP_POLARIS10,
        .asic_name = "polaris10",
        .gfx_target_version = 80003,
        .max_pasid_bits = 16,
@@ -208,13 +186,10 @@ static const struct kfd_device_info polaris10_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = true,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info polaris10_vf_device_info = {
-       .asic_family = CHIP_POLARIS10,
        .asic_name = "polaris10",
        .gfx_target_version = 80003,
        .max_pasid_bits = 16,
@@ -227,13 +202,10 @@ static const struct kfd_device_info polaris10_vf_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info polaris11_device_info = {
-       .asic_family = CHIP_POLARIS11,
        .asic_name = "polaris11",
        .gfx_target_version = 80003,
        .max_pasid_bits = 16,
@@ -246,13 +218,10 @@ static const struct kfd_device_info polaris11_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = true,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info polaris12_device_info = {
-       .asic_family = CHIP_POLARIS12,
        .asic_name = "polaris12",
        .gfx_target_version = 80003,
        .max_pasid_bits = 16,
@@ -265,13 +234,10 @@ static const struct kfd_device_info polaris12_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = true,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info vegam_device_info = {
-       .asic_family = CHIP_VEGAM,
        .asic_name = "vegam",
        .gfx_target_version = 80003,
        .max_pasid_bits = 16,
@@ -284,13 +250,10 @@ static const struct kfd_device_info vegam_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = true,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info vega10_device_info = {
-       .asic_family = CHIP_VEGA10,
        .asic_name = "vega10",
        .gfx_target_version = 90000,
        .max_pasid_bits = 16,
@@ -303,13 +266,10 @@ static const struct kfd_device_info vega10_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info vega10_vf_device_info = {
-       .asic_family = CHIP_VEGA10,
        .asic_name = "vega10",
        .gfx_target_version = 90000,
        .max_pasid_bits = 16,
@@ -322,13 +282,10 @@ static const struct kfd_device_info vega10_vf_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info vega12_device_info = {
-       .asic_family = CHIP_VEGA12,
        .asic_name = "vega12",
        .gfx_target_version = 90004,
        .max_pasid_bits = 16,
@@ -341,13 +298,10 @@ static const struct kfd_device_info vega12_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info vega20_device_info = {
-       .asic_family = CHIP_VEGA20,
        .asic_name = "vega20",
        .gfx_target_version = 90006,
        .max_pasid_bits = 16,
@@ -360,13 +314,10 @@ static const struct kfd_device_info vega20_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info arcturus_device_info = {
-       .asic_family = CHIP_ARCTURUS,
        .asic_name = "arcturus",
        .gfx_target_version = 90008,
        .max_pasid_bits = 16,
@@ -379,13 +330,10 @@ static const struct kfd_device_info arcturus_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 6,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info aldebaran_device_info = {
-       .asic_family = CHIP_ALDEBARAN,
        .asic_name = "aldebaran",
        .gfx_target_version = 90010,
        .max_pasid_bits = 16,
@@ -398,13 +346,10 @@ static const struct kfd_device_info aldebaran_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 3,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info renoir_device_info = {
-       .asic_family = CHIP_RENOIR,
        .asic_name = "renoir",
        .gfx_target_version = 90012,
        .max_pasid_bits = 16,
@@ -417,13 +362,10 @@ static const struct kfd_device_info renoir_device_info = {
        .supports_cwsr = true,
        .needs_iommu_device = false,
        .needs_pci_atomics = false,
-       .num_sdma_engines = 1,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info navi10_device_info = {
-       .asic_family = CHIP_NAVI10,
        .asic_name = "navi10",
        .gfx_target_version = 100100,
        .max_pasid_bits = 16,
@@ -437,13 +379,10 @@ static const struct kfd_device_info navi10_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 145,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info navi12_device_info = {
-       .asic_family = CHIP_NAVI12,
        .asic_name = "navi12",
        .gfx_target_version = 100101,
        .max_pasid_bits = 16,
@@ -457,13 +396,10 @@ static const struct kfd_device_info navi12_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 145,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info navi14_device_info = {
-       .asic_family = CHIP_NAVI14,
        .asic_name = "navi14",
        .gfx_target_version = 100102,
        .max_pasid_bits = 16,
@@ -477,13 +413,10 @@ static const struct kfd_device_info navi14_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 145,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info sienna_cichlid_device_info = {
-       .asic_family = CHIP_SIENNA_CICHLID,
        .asic_name = "sienna_cichlid",
        .gfx_target_version = 100300,
        .max_pasid_bits = 16,
@@ -497,13 +430,10 @@ static const struct kfd_device_info sienna_cichlid_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 92,
-       .num_sdma_engines = 4,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info navy_flounder_device_info = {
-       .asic_family = CHIP_NAVY_FLOUNDER,
        .asic_name = "navy_flounder",
        .gfx_target_version = 100301,
        .max_pasid_bits = 16,
@@ -517,13 +447,10 @@ static const struct kfd_device_info navy_flounder_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 92,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info vangogh_device_info = {
-       .asic_family = CHIP_VANGOGH,
        .asic_name = "vangogh",
        .gfx_target_version = 100303,
        .max_pasid_bits = 16,
@@ -537,13 +464,10 @@ static const struct kfd_device_info vangogh_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 92,
-       .num_sdma_engines = 1,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info dimgrey_cavefish_device_info = {
-       .asic_family = CHIP_DIMGREY_CAVEFISH,
        .asic_name = "dimgrey_cavefish",
        .gfx_target_version = 100302,
        .max_pasid_bits = 16,
@@ -557,13 +481,10 @@ static const struct kfd_device_info dimgrey_cavefish_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 92,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info beige_goby_device_info = {
-       .asic_family = CHIP_BEIGE_GOBY,
        .asic_name = "beige_goby",
        .gfx_target_version = 100304,
        .max_pasid_bits = 16,
@@ -577,13 +498,10 @@ static const struct kfd_device_info beige_goby_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 92,
-       .num_sdma_engines = 1,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
 static const struct kfd_device_info yellow_carp_device_info = {
-       .asic_family = CHIP_YELLOW_CARP,
        .asic_name = "yellow_carp",
        .gfx_target_version = 100305,
        .max_pasid_bits = 16,
@@ -597,13 +515,10 @@ static const struct kfd_device_info yellow_carp_device_info = {
        .supports_cwsr = true,
        .needs_pci_atomics = true,
        .no_atomic_fw_version = 92,
-       .num_sdma_engines = 1,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 2,
 };
 
 static const struct kfd_device_info cyan_skillfish_device_info = {
-       .asic_family = CHIP_CYAN_SKILLFISH,
        .asic_name = "cyan_skillfish",
        .gfx_target_version = 100103,
        .max_pasid_bits = 16,
@@ -616,8 +531,6 @@ static const struct kfd_device_info cyan_skillfish_device_info = {
        .needs_iommu_device = false,
        .supports_cwsr = true,
        .needs_pci_atomics = true,
-       .num_sdma_engines = 2,
-       .num_xgmi_sdma_engines = 0,
        .num_sdma_queues_per_engine = 8,
 };
 
@@ -627,12 +540,11 @@ static void kfd_gtt_sa_fini(struct kfd_dev *kfd);
 
 static int kfd_resume(struct kfd_dev *kfd);
 
-struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, bool vf)
+struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
 {
        struct kfd_dev *kfd;
        const struct kfd_device_info *device_info;
        const struct kfd2kgd_calls *f2g;
-       struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
        struct pci_dev *pdev = adev->pdev;
 
        switch (adev->asic_type) {
@@ -815,8 +727,12 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, bool vf)
        }
 
        if (!device_info || !f2g) {
-               dev_err(kfd_device, "%s %s not supported in kfd\n",
-                       amdgpu_asic_name[adev->asic_type], vf ? "VF" : "");
+               if (adev->ip_versions[GC_HWIP][0])
+                       dev_err(kfd_device, "GC IP %06x %s not supported in kfd\n",
+                               adev->ip_versions[GC_HWIP][0], vf ? "VF" : "");
+               else
+                       dev_err(kfd_device, "%s %s not supported in kfd\n",
+                               amdgpu_asic_name[adev->asic_type], vf ? "VF" : "");
                return NULL;
        }
 
@@ -824,7 +740,7 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, bool vf)
        if (!kfd)
                return NULL;
 
-       kfd->kgd = kgd;
+       kfd->adev = adev;
        kfd->device_info = device_info;
        kfd->pdev = pdev;
        kfd->init_complete = false;
@@ -845,23 +761,23 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, bool vf)
 static void kfd_cwsr_init(struct kfd_dev *kfd)
 {
        if (cwsr_enable && kfd->device_info->supports_cwsr) {
-               if (kfd->device_info->asic_family < CHIP_VEGA10) {
+               if (KFD_GC_VERSION(kfd) < IP_VERSION(9, 0, 1)) {
                        BUILD_BUG_ON(sizeof(cwsr_trap_gfx8_hex) > PAGE_SIZE);
                        kfd->cwsr_isa = cwsr_trap_gfx8_hex;
                        kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx8_hex);
-               } else if (kfd->device_info->asic_family == CHIP_ARCTURUS) {
+               } else if (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 1)) {
                        BUILD_BUG_ON(sizeof(cwsr_trap_arcturus_hex) > PAGE_SIZE);
                        kfd->cwsr_isa = cwsr_trap_arcturus_hex;
                        kfd->cwsr_isa_size = sizeof(cwsr_trap_arcturus_hex);
-               } else if (kfd->device_info->asic_family == CHIP_ALDEBARAN) {
+               } else if (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 2)) {
                        BUILD_BUG_ON(sizeof(cwsr_trap_aldebaran_hex) > PAGE_SIZE);
                        kfd->cwsr_isa = cwsr_trap_aldebaran_hex;
                        kfd->cwsr_isa_size = sizeof(cwsr_trap_aldebaran_hex);
-               } else if (kfd->device_info->asic_family < CHIP_NAVI10) {
+               } else if (KFD_GC_VERSION(kfd) < IP_VERSION(10, 1, 1)) {
                        BUILD_BUG_ON(sizeof(cwsr_trap_gfx9_hex) > PAGE_SIZE);
                        kfd->cwsr_isa = cwsr_trap_gfx9_hex;
                        kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx9_hex);
-               } else if (kfd->device_info->asic_family < CHIP_SIENNA_CICHLID) {
+               } else if (KFD_GC_VERSION(kfd) < IP_VERSION(10, 3, 0)) {
                        BUILD_BUG_ON(sizeof(cwsr_trap_nv1x_hex) > PAGE_SIZE);
                        kfd->cwsr_isa = cwsr_trap_nv1x_hex;
                        kfd->cwsr_isa_size = sizeof(cwsr_trap_nv1x_hex);
@@ -882,18 +798,17 @@ static int kfd_gws_init(struct kfd_dev *kfd)
        if (kfd->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS)
                return 0;
 
-       if (hws_gws_support
-               || (kfd->device_info->asic_family == CHIP_VEGA10
-                       && kfd->mec2_fw_version >= 0x81b3)
-               || (kfd->device_info->asic_family >= CHIP_VEGA12
-                       && kfd->device_info->asic_family <= CHIP_RAVEN
-                       && kfd->mec2_fw_version >= 0x1b3)
-               || (kfd->device_info->asic_family == CHIP_ARCTURUS
-                       && kfd->mec2_fw_version >= 0x30)
-               || (kfd->device_info->asic_family == CHIP_ALDEBARAN
-                       && kfd->mec2_fw_version >= 0x28))
-               ret = amdgpu_amdkfd_alloc_gws(kfd->kgd,
-                               amdgpu_amdkfd_get_num_gws(kfd->kgd), &kfd->gws);
+       if (hws_gws_support || (KFD_IS_SOC15(kfd) &&
+               ((KFD_GC_VERSION(kfd) == IP_VERSION(9, 0, 1)
+                       && kfd->mec2_fw_version >= 0x81b3) ||
+               (KFD_GC_VERSION(kfd) <= IP_VERSION(9, 4, 0)
+                       && kfd->mec2_fw_version >= 0x1b3)  ||
+               (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 1)
+                       && kfd->mec2_fw_version >= 0x30)   ||
+               (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 2)
+                       && kfd->mec2_fw_version >= 0x28))))
+               ret = amdgpu_amdkfd_alloc_gws(kfd->adev,
+                               kfd->adev->gds.gws_size, &kfd->gws);
 
        return ret;
 }
@@ -910,11 +825,11 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
        unsigned int size, map_process_packet_size;
 
        kfd->ddev = ddev;
-       kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
+       kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->adev,
                        KGD_ENGINE_MEC1);
-       kfd->mec2_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
+       kfd->mec2_fw_version = amdgpu_amdkfd_get_fw_version(kfd->adev,
                        KGD_ENGINE_MEC2);
-       kfd->sdma_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
+       kfd->sdma_fw_version = amdgpu_amdkfd_get_fw_version(kfd->adev,
                        KGD_ENGINE_SDMA1);
        kfd->shared_resources = *gpu_resources;
 
@@ -927,7 +842,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
         * 32 and 64-bit requests are possible and must be
         * supported.
         */
-       kfd->pci_atomic_requested = amdgpu_amdkfd_have_atomics_support(kfd->kgd);
+       kfd->pci_atomic_requested = amdgpu_amdkfd_have_atomics_support(kfd->adev);
        if (!kfd->pci_atomic_requested &&
            kfd->device_info->needs_pci_atomics &&
            (!kfd->device_info->no_atomic_fw_version ||
@@ -959,10 +874,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
         * calculate max size of runlist packet.
         * There can be only 2 packets at once
         */
-       map_process_packet_size =
-                       kfd->device_info->asic_family == CHIP_ALDEBARAN ?
+       map_process_packet_size = KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 2) ?
                                sizeof(struct pm4_mes_map_process_aldebaran) :
-                                       sizeof(struct pm4_mes_map_process);
+                               sizeof(struct pm4_mes_map_process);
        size += (KFD_MAX_NUM_OF_PROCESSES * map_process_packet_size +
                max_num_of_queues_per_device * sizeof(struct pm4_mes_map_queues)
                + sizeof(struct pm4_mes_runlist)) * 2;
@@ -974,7 +888,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
        size += 512 * 1024;
 
        if (amdgpu_amdkfd_alloc_gtt_mem(
-                       kfd->kgd, size, &kfd->gtt_mem,
+                       kfd->adev, size, &kfd->gtt_mem,
                        &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr,
                        false)) {
                dev_err(kfd_device, "Could not allocate %d bytes\n", size);
@@ -995,9 +909,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
                goto kfd_doorbell_error;
        }
 
-       kfd->hive_id = amdgpu_amdkfd_get_hive_id(kfd->kgd);
+       kfd->hive_id = kfd->adev->gmc.xgmi.hive_id;
 
-       kfd->noretry = amdgpu_amdkfd_get_noretry(kfd->kgd);
+       kfd->noretry = kfd->adev->gmc.noretry;
 
        if (kfd_interrupt_init(kfd)) {
                dev_err(kfd_device, "Error initializing interrupts\n");
@@ -1015,7 +929,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
         */
        if (kfd_gws_init(kfd)) {
                dev_err(kfd_device, "Could not allocate %d gws\n",
-                       amdgpu_amdkfd_get_num_gws(kfd->kgd));
+                       kfd->adev->gds.gws_size);
                goto gws_error;
        }
 
@@ -1030,7 +944,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
 
        kfd_cwsr_init(kfd);
 
-       svm_migrate_init((struct amdgpu_device *)kfd->kgd);
+       svm_migrate_init(kfd->adev);
 
        if(kgd2kfd_resume_iommu(kfd))
                goto device_iommu_error;
@@ -1068,10 +982,10 @@ kfd_interrupt_error:
 kfd_doorbell_error:
        kfd_gtt_sa_fini(kfd);
 kfd_gtt_sa_init_error:
-       amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem);
+       amdgpu_amdkfd_free_gtt_mem(kfd->adev, kfd->gtt_mem);
 alloc_gtt_mem_failure:
        if (kfd->gws)
-               amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws);
+               amdgpu_amdkfd_free_gws(kfd->adev, kfd->gws);
        dev_err(kfd_device,
                "device %x:%x NOT added due to errors\n",
                kfd->pdev->vendor, kfd->pdev->device);
@@ -1088,9 +1002,9 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
                kfd_doorbell_fini(kfd);
                ida_destroy(&kfd->doorbell_ida);
                kfd_gtt_sa_fini(kfd);
-               amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem);
+               amdgpu_amdkfd_free_gtt_mem(kfd->adev, kfd->gtt_mem);
                if (kfd->gws)
-                       amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws);
+                       amdgpu_amdkfd_free_gws(kfd->adev, kfd->gws);
        }
 
        kfree(kfd);
@@ -1526,7 +1440,7 @@ void kgd2kfd_set_sram_ecc_flag(struct kfd_dev *kfd)
 void kfd_inc_compute_active(struct kfd_dev *kfd)
 {
        if (atomic_inc_return(&kfd->compute_profile) == 1)
-               amdgpu_amdkfd_set_compute_idle(kfd->kgd, false);
+               amdgpu_amdkfd_set_compute_idle(kfd->adev, false);
 }
 
 void kfd_dec_compute_active(struct kfd_dev *kfd)
@@ -1534,7 +1448,7 @@ void kfd_dec_compute_active(struct kfd_dev *kfd)
        int count = atomic_dec_return(&kfd->compute_profile);
 
        if (count == 0)
-               amdgpu_amdkfd_set_compute_idle(kfd->kgd, true);
+               amdgpu_amdkfd_set_compute_idle(kfd->adev, true);
        WARN_ONCE(count < 0, "Compute profile ref. count error");
 }
 
@@ -1544,6 +1458,26 @@ void kgd2kfd_smi_event_throttle(struct kfd_dev *kfd, uint64_t throttle_bitmask)
                kfd_smi_event_update_thermal_throttling(kfd, throttle_bitmask);
 }
 
+/* kfd_get_num_sdma_engines returns the number of PCIe optimized SDMA and
+ * kfd_get_num_xgmi_sdma_engines returns the number of XGMI SDMA.
+ * When the device has more than two engines, we reserve two for PCIe to enable
+ * full-duplex and the rest are used as XGMI.
+ */
+unsigned int kfd_get_num_sdma_engines(struct kfd_dev *kdev)
+{
+       /* If XGMI is not supported, all SDMA engines are PCIe */
+       if (!kdev->adev->gmc.xgmi.supported)
+               return kdev->adev->sdma.num_instances;
+
+       return min(kdev->adev->sdma.num_instances, 2);
+}
+
+unsigned int kfd_get_num_xgmi_sdma_engines(struct kfd_dev *kdev)
+{
+       /* After reserved for PCIe, the rest of engines are XGMI */
+       return kdev->adev->sdma.num_instances - kfd_get_num_sdma_engines(kdev);
+}
+
 #if defined(CONFIG_DEBUG_FS)
 
 /* This function will send a package to HIQ to hang the HWS
index 93e33dd84dd41cf37a84c815718d95ba5de2cae4..2af2b3268171362617c0e3c4bc60c6116ea8803d 100644 (file)
@@ -99,38 +99,29 @@ unsigned int get_pipes_per_mec(struct device_queue_manager *dqm)
        return dqm->dev->shared_resources.num_pipe_per_mec;
 }
 
-static unsigned int get_num_sdma_engines(struct device_queue_manager *dqm)
-{
-       return dqm->dev->device_info->num_sdma_engines;
-}
-
-static unsigned int get_num_xgmi_sdma_engines(struct device_queue_manager *dqm)
-{
-       return dqm->dev->device_info->num_xgmi_sdma_engines;
-}
-
 static unsigned int get_num_all_sdma_engines(struct device_queue_manager *dqm)
 {
-       return get_num_sdma_engines(dqm) + get_num_xgmi_sdma_engines(dqm);
+       return kfd_get_num_sdma_engines(dqm->dev) +
+               kfd_get_num_xgmi_sdma_engines(dqm->dev);
 }
 
 unsigned int get_num_sdma_queues(struct device_queue_manager *dqm)
 {
-       return dqm->dev->device_info->num_sdma_engines
-                       * dqm->dev->device_info->num_sdma_queues_per_engine;
+       return kfd_get_num_sdma_engines(dqm->dev) *
+               dqm->dev->device_info->num_sdma_queues_per_engine;
 }
 
 unsigned int get_num_xgmi_sdma_queues(struct device_queue_manager *dqm)
 {
-       return dqm->dev->device_info->num_xgmi_sdma_engines
-                       * dqm->dev->device_info->num_sdma_queues_per_engine;
+       return kfd_get_num_xgmi_sdma_engines(dqm->dev) *
+               dqm->dev->device_info->num_sdma_queues_per_engine;
 }
 
 void program_sh_mem_settings(struct device_queue_manager *dqm,
                                        struct qcm_process_device *qpd)
 {
        return dqm->dev->kfd2kgd->program_sh_mem_settings(
-                                               dqm->dev->kgd, qpd->vmid,
+                                               dqm->dev->adev, qpd->vmid,
                                                qpd->sh_mem_config,
                                                qpd->sh_mem_ape1_base,
                                                qpd->sh_mem_ape1_limit,
@@ -157,7 +148,7 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
 {
        struct kfd_dev *dev = qpd->dqm->dev;
 
-       if (!KFD_IS_SOC15(dev->device_info->asic_family)) {
+       if (!KFD_IS_SOC15(dev)) {
                /* On pre-SOC15 chips we need to use the queue ID to
                 * preserve the user mode ABI.
                 */
@@ -202,7 +193,7 @@ static void deallocate_doorbell(struct qcm_process_device *qpd,
        unsigned int old;
        struct kfd_dev *dev = qpd->dqm->dev;
 
-       if (!KFD_IS_SOC15(dev->device_info->asic_family) ||
+       if (!KFD_IS_SOC15(dev) ||
            q->properties.type == KFD_QUEUE_TYPE_SDMA ||
            q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
                return;
@@ -216,7 +207,7 @@ static void program_trap_handler_settings(struct device_queue_manager *dqm,
 {
        if (dqm->dev->kfd2kgd->program_trap_handler_settings)
                dqm->dev->kfd2kgd->program_trap_handler_settings(
-                                               dqm->dev->kgd, qpd->vmid,
+                                               dqm->dev->adev, qpd->vmid,
                                                qpd->tba_addr, qpd->tma_addr);
 }
 
@@ -250,21 +241,20 @@ static int allocate_vmid(struct device_queue_manager *dqm,
 
        program_sh_mem_settings(dqm, qpd);
 
-       if (dqm->dev->device_info->asic_family >= CHIP_VEGA10 &&
-           dqm->dev->cwsr_enabled)
+       if (KFD_IS_SOC15(dqm->dev) && dqm->dev->cwsr_enabled)
                program_trap_handler_settings(dqm, qpd);
 
        /* qpd->page_table_base is set earlier when register_process()
         * is called, i.e. when the first queue is created.
         */
-       dqm->dev->kfd2kgd->set_vm_context_page_table_base(dqm->dev->kgd,
+       dqm->dev->kfd2kgd->set_vm_context_page_table_base(dqm->dev->adev,
                        qpd->vmid,
                        qpd->page_table_base);
        /* invalidate the VM context after pasid and vmid mapping is set up */
        kfd_flush_tlb(qpd_to_pdd(qpd), TLB_FLUSH_LEGACY);
 
        if (dqm->dev->kfd2kgd->set_scratch_backing_va)
-               dqm->dev->kfd2kgd->set_scratch_backing_va(dqm->dev->kgd,
+               dqm->dev->kfd2kgd->set_scratch_backing_va(dqm->dev->adev,
                                qpd->sh_hidden_private_base, qpd->vmid);
 
        return 0;
@@ -283,7 +273,7 @@ static int flush_texture_cache_nocpsch(struct kfd_dev *kdev,
        if (ret)
                return ret;
 
-       return amdgpu_amdkfd_submit_ib(kdev->kgd, KGD_ENGINE_MEC1, qpd->vmid,
+       return amdgpu_amdkfd_submit_ib(kdev->adev, KGD_ENGINE_MEC1, qpd->vmid,
                                qpd->ib_base, (uint32_t *)qpd->ib_kaddr,
                                pmf->release_mem_size / sizeof(uint32_t));
 }
@@ -293,7 +283,7 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
                                struct queue *q)
 {
        /* On GFX v7, CP doesn't flush TC at dequeue */
-       if (q->device->device_info->asic_family == CHIP_HAWAII)
+       if (q->device->adev->asic_type == CHIP_HAWAII)
                if (flush_texture_cache_nocpsch(q->device, qpd))
                        pr_err("Failed to flush TC\n");
 
@@ -776,7 +766,7 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm,
 
        if (!list_empty(&qpd->queues_list)) {
                dqm->dev->kfd2kgd->set_vm_context_page_table_base(
-                               dqm->dev->kgd,
+                               dqm->dev->adev,
                                qpd->vmid,
                                qpd->page_table_base);
                kfd_flush_tlb(pdd, TLB_FLUSH_LEGACY);
@@ -954,7 +944,7 @@ set_pasid_vmid_mapping(struct device_queue_manager *dqm, u32 pasid,
                        unsigned int vmid)
 {
        return dqm->dev->kfd2kgd->set_pasid_vmid_mapping(
-                                               dqm->dev->kgd, pasid, vmid);
+                                               dqm->dev->adev, pasid, vmid);
 }
 
 static void init_interrupts(struct device_queue_manager *dqm)
@@ -963,7 +953,7 @@ static void init_interrupts(struct device_queue_manager *dqm)
 
        for (i = 0 ; i < get_pipes_per_mec(dqm) ; i++)
                if (is_pipe_enabled(dqm, 0, i))
-                       dqm->dev->kfd2kgd->init_interrupts(dqm->dev->kgd, i);
+                       dqm->dev->kfd2kgd->init_interrupts(dqm->dev->adev, i);
 }
 
 static int initialize_nocpsch(struct device_queue_manager *dqm)
@@ -1017,7 +1007,7 @@ static int start_nocpsch(struct device_queue_manager *dqm)
        pr_info("SW scheduler is used");
        init_interrupts(dqm);
        
-       if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
+       if (dqm->dev->adev->asic_type == CHIP_HAWAII)
                return pm_init(&dqm->packet_mgr, dqm);
        dqm->sched_running = true;
 
@@ -1026,7 +1016,7 @@ static int start_nocpsch(struct device_queue_manager *dqm)
 
 static int stop_nocpsch(struct device_queue_manager *dqm)
 {
-       if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
+       if (dqm->dev->adev->asic_type == CHIP_HAWAII)
                pm_uninit(&dqm->packet_mgr, false);
        dqm->sched_running = false;
 
@@ -1055,9 +1045,9 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
                dqm->sdma_bitmap &= ~(1ULL << bit);
                q->sdma_id = bit;
                q->properties.sdma_engine_id = q->sdma_id %
-                               get_num_sdma_engines(dqm);
+                               kfd_get_num_sdma_engines(dqm->dev);
                q->properties.sdma_queue_id = q->sdma_id /
-                               get_num_sdma_engines(dqm);
+                               kfd_get_num_sdma_engines(dqm->dev);
        } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
                if (dqm->xgmi_sdma_bitmap == 0) {
                        pr_err("No more XGMI SDMA queue to allocate\n");
@@ -1072,10 +1062,11 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
                 * assumes the first N engines are always
                 * PCIe-optimized ones
                 */
-               q->properties.sdma_engine_id = get_num_sdma_engines(dqm) +
-                               q->sdma_id % get_num_xgmi_sdma_engines(dqm);
+               q->properties.sdma_engine_id =
+                       kfd_get_num_sdma_engines(dqm->dev) +
+                       q->sdma_id % kfd_get_num_xgmi_sdma_engines(dqm->dev);
                q->properties.sdma_queue_id = q->sdma_id /
-                               get_num_xgmi_sdma_engines(dqm);
+                       kfd_get_num_xgmi_sdma_engines(dqm->dev);
        }
 
        pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id);
@@ -1132,7 +1123,7 @@ static int set_sched_resources(struct device_queue_manager *dqm)
 
                res.queue_mask |= 1ull
                        << amdgpu_queue_mask_bit_to_set_resource_bit(
-                               (struct amdgpu_device *)dqm->dev->kgd, i);
+                               dqm->dev->adev, i);
        }
        res.gws_mask = ~0ull;
        res.oac_mask = res.gds_heap_base = res.gds_heap_size = 0;
@@ -1850,7 +1841,7 @@ static int allocate_hiq_sdma_mqd(struct device_queue_manager *dqm)
                dev->device_info->num_sdma_queues_per_engine +
                dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ]->mqd_size;
 
-       retval = amdgpu_amdkfd_alloc_gtt_mem(dev->kgd, size,
+       retval = amdgpu_amdkfd_alloc_gtt_mem(dev->adev, size,
                &(mem_obj->gtt_mem), &(mem_obj->gpu_addr),
                (void *)&(mem_obj->cpu_ptr), false);
 
@@ -1867,7 +1858,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
        if (!dqm)
                return NULL;
 
-       switch (dev->device_info->asic_family) {
+       switch (dev->adev->asic_type) {
        /* HWS is not available on Hawaii. */
        case CHIP_HAWAII:
        /* HWS depends on CWSR for timely dequeue. CWSR is not
@@ -1930,7 +1921,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
                goto out_free;
        }
 
-       switch (dev->device_info->asic_family) {
+       switch (dev->adev->asic_type) {
        case CHIP_CARRIZO:
                device_queue_manager_init_vi(&dqm->asic_ops);
                break;
@@ -1952,31 +1943,16 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
                device_queue_manager_init_vi_tonga(&dqm->asic_ops);
                break;
 
-       case CHIP_VEGA10:
-       case CHIP_VEGA12:
-       case CHIP_VEGA20:
-       case CHIP_RAVEN:
-       case CHIP_RENOIR:
-       case CHIP_ARCTURUS:
-       case CHIP_ALDEBARAN:
-               device_queue_manager_init_v9(&dqm->asic_ops);
-               break;
-       case CHIP_NAVI10:
-       case CHIP_NAVI12:
-       case CHIP_NAVI14:
-       case CHIP_SIENNA_CICHLID:
-       case CHIP_NAVY_FLOUNDER:
-       case CHIP_VANGOGH:
-       case CHIP_DIMGREY_CAVEFISH:
-       case CHIP_BEIGE_GOBY:
-       case CHIP_YELLOW_CARP:
-       case CHIP_CYAN_SKILLFISH:
-               device_queue_manager_init_v10_navi10(&dqm->asic_ops);
-               break;
        default:
-               WARN(1, "Unexpected ASIC family %u",
-                    dev->device_info->asic_family);
-               goto out_free;
+               if (KFD_GC_VERSION(dev) >= IP_VERSION(10, 1, 1))
+                       device_queue_manager_init_v10_navi10(&dqm->asic_ops);
+               else if (KFD_GC_VERSION(dev) >= IP_VERSION(9, 0, 1))
+                       device_queue_manager_init_v9(&dqm->asic_ops);
+               else {
+                       WARN(1, "Unexpected ASIC family %u",
+                            dev->adev->asic_type);
+                       goto out_free;
+               }
        }
 
        if (init_mqd_managers(dqm))
@@ -2000,7 +1976,7 @@ static void deallocate_hiq_sdma_mqd(struct kfd_dev *dev,
 {
        WARN(!mqd, "No hiq sdma mqd trunk to free");
 
-       amdgpu_amdkfd_free_gtt_mem(dev->kgd, mqd->gtt_mem);
+       amdgpu_amdkfd_free_gtt_mem(dev->adev, mqd->gtt_mem);
 }
 
 void device_queue_manager_uninit(struct device_queue_manager *dqm)
@@ -2031,7 +2007,7 @@ static void kfd_process_hw_exception(struct work_struct *work)
 {
        struct device_queue_manager *dqm = container_of(work,
                        struct device_queue_manager, hw_exception_work);
-       amdgpu_amdkfd_gpu_reset(dqm->dev->kgd);
+       amdgpu_amdkfd_gpu_reset(dqm->dev->adev);
 }
 
 #if defined(CONFIG_DEBUG_FS)
@@ -2070,7 +2046,7 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)
                return 0;
        }
 
-       r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd,
+       r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->adev,
                                        KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE,
                                        &dump, &n_regs);
        if (!r) {
@@ -2092,7 +2068,7 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)
                                continue;
 
                        r = dqm->dev->kfd2kgd->hqd_dump(
-                               dqm->dev->kgd, pipe, queue, &dump, &n_regs);
+                               dqm->dev->adev, pipe, queue, &dump, &n_regs);
                        if (r)
                                break;
 
@@ -2109,7 +2085,7 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)
                     queue < dqm->dev->device_info->num_sdma_queues_per_engine;
                     queue++) {
                        r = dqm->dev->kfd2kgd->hqd_sdma_dump(
-                               dqm->dev->kgd, pipe, queue, &dump, &n_regs);
+                               dqm->dev->adev, pipe, queue, &dump, &n_regs);
                        if (r)
                                break;
 
index b5c3d13643f135bef97cb3a490f9f2c74db406d4..f20434d9980e0cd8944acb95aa1c895269da9418 100644 (file)
@@ -62,7 +62,7 @@ static int update_qpd_v9(struct device_queue_manager *dqm,
                                SH_MEM_ALIGNMENT_MODE_UNALIGNED <<
                                        SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT;
 
-               if (dqm->dev->device_info->asic_family == CHIP_ALDEBARAN) {
+               if (KFD_GC_VERSION(dqm->dev) == IP_VERSION(9, 4, 2)) {
                        /* Aldebaran can safely support different XNACK modes
                         * per process
                         */
index 3eea4edee355da838cddbd8eb8a69a41320a73cb..afe72dd11325d79d468b50ddcc8a8692351b4817 100644 (file)
@@ -935,8 +935,10 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, u32 pasid,
        /* Workaround on Raven to not kill the process when memory is freed
         * before IOMMU is able to finish processing all the excessive PPRs
         */
-       if (dev->device_info->asic_family != CHIP_RAVEN &&
-           dev->device_info->asic_family != CHIP_RENOIR) {
+
+       if (KFD_GC_VERSION(dev) != IP_VERSION(9, 1, 0) &&
+           KFD_GC_VERSION(dev) != IP_VERSION(9, 2, 2) &&
+           KFD_GC_VERSION(dev) != IP_VERSION(9, 3, 0)) {
                mutex_lock(&p->event_mutex);
 
                /* Lookup events by type and signal them */
index d1388896f9c12187e12654c254327c8e85408dfd..2e2b7ceb71dbe667c952c4c1f91fafb45685a721 100644 (file)
@@ -394,7 +394,7 @@ int kfd_init_apertures(struct kfd_process *process)
                        pdd->gpuvm_base = pdd->gpuvm_limit = 0;
                        pdd->scratch_base = pdd->scratch_limit = 0;
                } else {
-                       switch (dev->device_info->asic_family) {
+                       switch (dev->adev->asic_type) {
                        case CHIP_KAVERI:
                        case CHIP_HAWAII:
                        case CHIP_CARRIZO:
@@ -406,29 +406,14 @@ int kfd_init_apertures(struct kfd_process *process)
                        case CHIP_VEGAM:
                                kfd_init_apertures_vi(pdd, id);
                                break;
-                       case CHIP_VEGA10:
-                       case CHIP_VEGA12:
-                       case CHIP_VEGA20:
-                       case CHIP_RAVEN:
-                       case CHIP_RENOIR:
-                       case CHIP_ARCTURUS:
-                       case CHIP_ALDEBARAN:
-                       case CHIP_NAVI10:
-                       case CHIP_NAVI12:
-                       case CHIP_NAVI14:
-                       case CHIP_SIENNA_CICHLID:
-                       case CHIP_NAVY_FLOUNDER:
-                       case CHIP_VANGOGH:
-                       case CHIP_DIMGREY_CAVEFISH:
-                       case CHIP_BEIGE_GOBY:
-                       case CHIP_YELLOW_CARP:
-                       case CHIP_CYAN_SKILLFISH:
-                               kfd_init_apertures_v9(pdd, id);
-                               break;
                        default:
-                               WARN(1, "Unexpected ASIC family %u",
-                                    dev->device_info->asic_family);
-                               return -EINVAL;
+                               if (KFD_GC_VERSION(dev) >= IP_VERSION(9, 0, 1))
+                                       kfd_init_apertures_v9(pdd, id);
+                               else {
+                                       WARN(1, "Unexpected ASIC family %u",
+                                            dev->adev->asic_type);
+                                       return -EINVAL;
+                               }
                        }
 
                        if (!dev->use_iommu_v2) {
index 543e7ea755936605b996e87d14648ebef63d3ed9..20512a4e9a91d7c904b58106c6f7dff0a6b5dff5 100644 (file)
@@ -231,7 +231,7 @@ static void event_interrupt_wq_v9(struct kfd_dev *dev,
                                if (sq_intr_err != SQ_INTERRUPT_ERROR_TYPE_ILLEGAL_INST &&
                                        sq_intr_err != SQ_INTERRUPT_ERROR_TYPE_MEMVIOL) {
                                        kfd_signal_poison_consumed_event(dev, pasid);
-                                       amdgpu_amdkfd_ras_poison_consumption_handler(dev->kgd);
+                                       amdgpu_amdkfd_ras_poison_consumption_handler(dev->adev);
                                        return;
                                }
                                break;
@@ -253,7 +253,7 @@ static void event_interrupt_wq_v9(struct kfd_dev *dev,
                        kfd_signal_event_interrupt(pasid, context_id0 & 0xfffffff, 28);
                } else if (source_id == SOC15_INTSRC_SDMA_ECC) {
                        kfd_signal_poison_consumed_event(dev, pasid);
-                       amdgpu_amdkfd_ras_poison_consumption_handler(dev->kgd);
+                       amdgpu_amdkfd_ras_poison_consumption_handler(dev->adev);
                        return;
                }
        } else if (client_id == SOC15_IH_CLIENTID_VMC ||
index 64b4ac339904f8039016396814c3048b1eaa4f2d..406479a369a991f3a9cae259ccd1af48b53eea35 100644 (file)
@@ -91,7 +91,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_dev *dev,
        kq->pq_gpu_addr = kq->pq->gpu_addr;
 
        /* For CIK family asics, kq->eop_mem is not needed */
-       if (dev->device_info->asic_family > CHIP_MULLINS) {
+       if (dev->adev->asic_type > CHIP_MULLINS) {
                retval = kfd_gtt_sa_allocate(dev, PAGE_SIZE, &kq->eop_mem);
                if (retval != 0)
                        goto err_eop_allocate_vidmem;
index 9b9c2b9bf2ef089a81775bece991f65a990dd5dc..d84cec0022b1b5816291aaf71b0af421143b61cb 100644 (file)
@@ -938,7 +938,7 @@ int svm_migrate_init(struct amdgpu_device *adev)
        void *r;
 
        /* Page migration works on Vega10 or newer */
-       if (kfddev->device_info->asic_family < CHIP_VEGA10)
+       if (!KFD_IS_SOC15(kfddev))
                return -EINVAL;
 
        pgmap = &kfddev->pgmap;
index c021519af810656605a1498664b4ae66ce1591ba..7b4118915bf633668995ac8292aecc07736ce2c6 100644 (file)
@@ -100,7 +100,7 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
        struct kfd_cu_info cu_info;
        uint32_t cu_per_sh[KFD_MAX_NUM_SE][KFD_MAX_NUM_SH_PER_SE] = {0};
        int i, se, sh, cu;
-       amdgpu_amdkfd_get_cu_info(mm->dev->kgd, &cu_info);
+       amdgpu_amdkfd_get_cu_info(mm->dev->adev, &cu_info);
 
        if (cu_mask_count > cu_info.cu_active_number)
                cu_mask_count = cu_info.cu_active_number;
index 8128f4d312f1e9c3e5a7d661d5f32072d15bced1..e9a8e21e144ed629bc97b85383e99bf02377518c 100644 (file)
@@ -171,7 +171,7 @@ static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
        uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
        uint32_t wptr_mask = (uint32_t)((p->queue_size / 4) - 1);
 
-       return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
+       return mm->dev->kfd2kgd->hqd_load(mm->dev->adev, mqd, pipe_id, queue_id,
                                          (uint32_t __user *)p->write_ptr,
                                          wptr_shift, wptr_mask, mms);
 }
@@ -180,7 +180,7 @@ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
                         uint32_t pipe_id, uint32_t queue_id,
                         struct queue_properties *p, struct mm_struct *mms)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd,
+       return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
                                               (uint32_t __user *)p->write_ptr,
                                               mms);
 }
@@ -276,7 +276,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
                        unsigned int timeout, uint32_t pipe_id,
                        uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, mqd, type, timeout,
+       return mm->dev->kfd2kgd->hqd_destroy(mm->dev->adev, mqd, type, timeout,
                                        pipe_id, queue_id);
 }
 
@@ -289,7 +289,7 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
                                unsigned int timeout, uint32_t pipe_id,
                                uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
+       return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
 }
 
 static bool is_occupied(struct mqd_manager *mm, void *mqd,
@@ -297,7 +297,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd,
                        uint32_t queue_id)
 {
 
-       return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
+       return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->adev, queue_address,
                                        pipe_id, queue_id);
 
 }
@@ -306,7 +306,7 @@ static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
                        uint64_t queue_address, uint32_t pipe_id,
                        uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
+       return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
 }
 
 /*
index 270160fc401b746a8b38004f6c010519be32f352..d74d8a6ac27ae0631a24db1b4d9108fb8d0c788f 100644 (file)
@@ -148,7 +148,7 @@ static int load_mqd(struct mqd_manager *mm, void *mqd,
        /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
        uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
 
-       r = mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
+       r = mm->dev->kfd2kgd->hqd_load(mm->dev->adev, mqd, pipe_id, queue_id,
                                          (uint32_t __user *)p->write_ptr,
                                          wptr_shift, 0, mms);
        return r;
@@ -158,7 +158,7 @@ static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
                            uint32_t pipe_id, uint32_t queue_id,
                            struct queue_properties *p, struct mm_struct *mms)
 {
-       return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->kgd, mqd, pipe_id,
+       return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->adev, mqd, pipe_id,
                                              queue_id, p->doorbell_off);
 }
 
@@ -239,7 +239,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
                       uint32_t queue_id)
 {
        return mm->dev->kfd2kgd->hqd_destroy
-               (mm->dev->kgd, mqd, type, timeout,
+               (mm->dev->adev, mqd, type, timeout,
                 pipe_id, queue_id);
 }
 
@@ -254,7 +254,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd,
                        uint32_t queue_id)
 {
        return mm->dev->kfd2kgd->hqd_is_occupied(
-               mm->dev->kgd, queue_address,
+               mm->dev->adev, queue_address,
                pipe_id, queue_id);
 }
 
@@ -320,7 +320,7 @@ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
                uint32_t pipe_id, uint32_t queue_id,
                struct queue_properties *p, struct mm_struct *mms)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd,
+       return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
                                               (uint32_t __user *)p->write_ptr,
                                               mms);
 }
@@ -363,14 +363,14 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
                unsigned int timeout, uint32_t pipe_id,
                uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
+       return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
 }
 
 static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
                uint64_t queue_address, uint32_t pipe_id,
                uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
+       return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
 }
 
 #if defined(CONFIG_DEBUG_FS)
index 4e5932f54b5ac4c4cf75a87736d6de5758fbb0e9..326eb2285029865b81de61d422393e6f64093587 100644 (file)
@@ -108,7 +108,7 @@ static struct kfd_mem_obj *allocate_mqd(struct kfd_dev *kfd,
                mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL);
                if (!mqd_mem_obj)
                        return NULL;
-               retval = amdgpu_amdkfd_alloc_gtt_mem(kfd->kgd,
+               retval = amdgpu_amdkfd_alloc_gtt_mem(kfd->adev,
                        ALIGN(q->ctl_stack_size, PAGE_SIZE) +
                                ALIGN(sizeof(struct v9_mqd), PAGE_SIZE),
                        &(mqd_mem_obj->gtt_mem),
@@ -199,7 +199,7 @@ static int load_mqd(struct mqd_manager *mm, void *mqd,
        /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
        uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
 
-       return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
+       return mm->dev->kfd2kgd->hqd_load(mm->dev->adev, mqd, pipe_id, queue_id,
                                          (uint32_t __user *)p->write_ptr,
                                          wptr_shift, 0, mms);
 }
@@ -208,7 +208,7 @@ static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
                            uint32_t pipe_id, uint32_t queue_id,
                            struct queue_properties *p, struct mm_struct *mms)
 {
-       return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->kgd, mqd, pipe_id,
+       return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->adev, mqd, pipe_id,
                                              queue_id, p->doorbell_off);
 }
 
@@ -291,7 +291,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
                        uint32_t queue_id)
 {
        return mm->dev->kfd2kgd->hqd_destroy
-               (mm->dev->kgd, mqd, type, timeout,
+               (mm->dev->adev, mqd, type, timeout,
                pipe_id, queue_id);
 }
 
@@ -301,7 +301,7 @@ static void free_mqd(struct mqd_manager *mm, void *mqd,
        struct kfd_dev *kfd = mm->dev;
 
        if (mqd_mem_obj->gtt_mem) {
-               amdgpu_amdkfd_free_gtt_mem(kfd->kgd, mqd_mem_obj->gtt_mem);
+               amdgpu_amdkfd_free_gtt_mem(kfd->adev, mqd_mem_obj->gtt_mem);
                kfree(mqd_mem_obj);
        } else {
                kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
@@ -313,7 +313,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd,
                        uint32_t queue_id)
 {
        return mm->dev->kfd2kgd->hqd_is_occupied(
-               mm->dev->kgd, queue_address,
+               mm->dev->adev, queue_address,
                pipe_id, queue_id);
 }
 
@@ -375,7 +375,7 @@ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
                uint32_t pipe_id, uint32_t queue_id,
                struct queue_properties *p, struct mm_struct *mms)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd,
+       return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
                                               (uint32_t __user *)p->write_ptr,
                                               mms);
 }
@@ -418,14 +418,14 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
                unsigned int timeout, uint32_t pipe_id,
                uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
+       return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
 }
 
 static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
                uint64_t queue_address, uint32_t pipe_id,
                uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
+       return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
 }
 
 #if defined(CONFIG_DEBUG_FS)
index cd9220eb8a7a3b05a6e34668c30497e9f4c0e257..d456e950ce1d9241b4426f1f7f74e3ed29ef0aa0 100644 (file)
@@ -162,7 +162,7 @@ static int load_mqd(struct mqd_manager *mm, void *mqd,
        uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
        uint32_t wptr_mask = (uint32_t)((p->queue_size / 4) - 1);
 
-       return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
+       return mm->dev->kfd2kgd->hqd_load(mm->dev->adev, mqd, pipe_id, queue_id,
                                          (uint32_t __user *)p->write_ptr,
                                          wptr_shift, wptr_mask, mms);
 }
@@ -265,7 +265,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
                        uint32_t queue_id)
 {
        return mm->dev->kfd2kgd->hqd_destroy
-               (mm->dev->kgd, mqd, type, timeout,
+               (mm->dev->adev, mqd, type, timeout,
                pipe_id, queue_id);
 }
 
@@ -280,7 +280,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd,
                        uint32_t queue_id)
 {
        return mm->dev->kfd2kgd->hqd_is_occupied(
-               mm->dev->kgd, queue_address,
+               mm->dev->adev, queue_address,
                pipe_id, queue_id);
 }
 
@@ -347,7 +347,7 @@ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
                uint32_t pipe_id, uint32_t queue_id,
                struct queue_properties *p, struct mm_struct *mms)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd,
+       return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
                                               (uint32_t __user *)p->write_ptr,
                                               mms);
 }
@@ -389,14 +389,14 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
                unsigned int timeout, uint32_t pipe_id,
                uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
+       return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
 }
 
 static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
                uint64_t queue_address, uint32_t pipe_id,
                uint32_t queue_id)
 {
-       return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
+       return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
 }
 
 #if defined(CONFIG_DEBUG_FS)
index e547f1f8c49f601bfbd1b2b56395c4d7d711a9ab..1439420925a053b253a3c0d694ef0272d131279e 100644 (file)
@@ -223,7 +223,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
 
 int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm)
 {
-       switch (dqm->dev->device_info->asic_family) {
+       switch (dqm->dev->adev->asic_type) {
        case CHIP_KAVERI:
        case CHIP_HAWAII:
                /* PM4 packet structures on CIK are the same as on VI */
@@ -236,31 +236,16 @@ int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm)
        case CHIP_VEGAM:
                pm->pmf = &kfd_vi_pm_funcs;
                break;
-       case CHIP_VEGA10:
-       case CHIP_VEGA12:
-       case CHIP_VEGA20:
-       case CHIP_RAVEN:
-       case CHIP_RENOIR:
-       case CHIP_ARCTURUS:
-       case CHIP_NAVI10:
-       case CHIP_NAVI12:
-       case CHIP_NAVI14:
-       case CHIP_SIENNA_CICHLID:
-       case CHIP_NAVY_FLOUNDER:
-       case CHIP_VANGOGH:
-       case CHIP_DIMGREY_CAVEFISH:
-       case CHIP_BEIGE_GOBY:
-       case CHIP_YELLOW_CARP:
-       case CHIP_CYAN_SKILLFISH:
-               pm->pmf = &kfd_v9_pm_funcs;
-               break;
-       case CHIP_ALDEBARAN:
-               pm->pmf = &kfd_aldebaran_pm_funcs;
-               break;
        default:
-               WARN(1, "Unexpected ASIC family %u",
-                    dqm->dev->device_info->asic_family);
-               return -EINVAL;
+               if (KFD_GC_VERSION(dqm->dev) == IP_VERSION(9, 4, 2))
+                       pm->pmf = &kfd_aldebaran_pm_funcs;
+               else if (KFD_GC_VERSION(dqm->dev) >= IP_VERSION(9, 0, 1))
+                       pm->pmf = &kfd_v9_pm_funcs;
+               else {
+                       WARN(1, "Unexpected ASIC family %u",
+                            dqm->dev->adev->asic_type);
+                       return -EINVAL;
+               }
        }
 
        pm->dqm = dqm;
index 94e92c0812db733535244a2d18133baf280903f2..7ea5289419510a16bcd01ae27d7ed161ce6535d1 100644 (file)
@@ -183,7 +183,8 @@ enum cache_policy {
        cache_policy_noncoherent
 };
 
-#define KFD_IS_SOC15(chip) ((chip) >= CHIP_VEGA10)
+#define KFD_GC_VERSION(dev) ((dev)->adev->ip_versions[GC_HWIP][0])
+#define KFD_IS_SOC15(dev)   ((KFD_GC_VERSION(dev)) >= (IP_VERSION(9, 0, 1)))
 
 struct kfd_event_interrupt_class {
        bool (*interrupt_isr)(struct kfd_dev *dev,
@@ -194,7 +195,6 @@ struct kfd_event_interrupt_class {
 };
 
 struct kfd_device_info {
-       enum amd_asic_type asic_family;
        const char *asic_name;
        uint32_t gfx_target_version;
        const struct kfd_event_interrupt_class *event_interrupt_class;
@@ -208,11 +208,12 @@ struct kfd_device_info {
        bool needs_iommu_device;
        bool needs_pci_atomics;
        uint32_t no_atomic_fw_version;
-       unsigned int num_sdma_engines;
-       unsigned int num_xgmi_sdma_engines;
        unsigned int num_sdma_queues_per_engine;
 };
 
+unsigned int kfd_get_num_sdma_engines(struct kfd_dev *kdev);
+unsigned int kfd_get_num_xgmi_sdma_engines(struct kfd_dev *kdev);
+
 struct kfd_mem_obj {
        uint32_t range_start;
        uint32_t range_end;
@@ -228,7 +229,7 @@ struct kfd_vmid_info {
 };
 
 struct kfd_dev {
-       struct kgd_dev *kgd;
+       struct amdgpu_device *adev;
 
        const struct kfd_device_info *device_info;
        struct pci_dev *pdev;
@@ -766,7 +767,7 @@ struct svm_range_list {
        struct list_head                deferred_range_list;
        spinlock_t                      deferred_list_lock;
        atomic_t                        evicted_ranges;
-       bool                            drain_pagefaults;
+       atomic_t                        drain_pagefaults;
        struct delayed_work             restore_work;
        DECLARE_BITMAP(bitmap_supported, MAX_GPU_INSTANCE);
        struct task_struct              *faulting_task;
@@ -891,7 +892,7 @@ struct kfd_process *kfd_lookup_process_by_pasid(u32 pasid);
 struct kfd_process *kfd_lookup_process_by_mm(const struct mm_struct *mm);
 
 int kfd_process_gpuidx_from_gpuid(struct kfd_process *p, uint32_t gpu_id);
-int kfd_process_gpuid_from_kgd(struct kfd_process *p,
+int kfd_process_gpuid_from_adev(struct kfd_process *p,
                               struct amdgpu_device *adev, uint32_t *gpuid,
                               uint32_t *gpuidx);
 static inline int kfd_process_gpuid_from_gpuidx(struct kfd_process *p,
@@ -984,7 +985,7 @@ struct kfd_topology_device *kfd_topology_device_by_proximity_domain(
 struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id);
 struct kfd_dev *kfd_device_by_id(uint32_t gpu_id);
 struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev);
-struct kfd_dev *kfd_device_by_kgd(const struct kgd_dev *kgd);
+struct kfd_dev *kfd_device_by_adev(const struct amdgpu_device *adev);
 int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_dev **kdev);
 int kfd_numa_node_to_apic_id(int numa_node_id);
 void kfd_double_confirm_iommu_support(struct kfd_dev *gpu);
index b993011cfa64a8ca18aac32df66480bcc5b2bc0b..d4c8a6948a9ff7f1b0c36a47616737f33c3d9d0a 100644 (file)
@@ -288,7 +288,7 @@ static int kfd_get_cu_occupancy(struct attribute *attr, char *buffer)
        /* Collect wave count from device if it supports */
        wave_cnt = 0;
        max_waves_per_cu = 0;
-       dev->kfd2kgd->get_cu_occupancy(dev->kgd, proc->pasid, &wave_cnt,
+       dev->kfd2kgd->get_cu_occupancy(dev->adev, proc->pasid, &wave_cnt,
                        &max_waves_per_cu);
 
        /* Translate wave count to number of compute units */
@@ -692,12 +692,12 @@ static void kfd_process_free_gpuvm(struct kgd_mem *mem,
        struct kfd_dev *dev = pdd->dev;
 
        if (kptr) {
-               amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(dev->kgd, mem);
+               amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(dev->adev, mem);
                kptr = NULL;
        }
 
-       amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->kgd, mem, pdd->drm_priv);
-       amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, mem, pdd->drm_priv,
+       amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->adev, mem, pdd->drm_priv);
+       amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, mem, pdd->drm_priv,
                                               NULL);
 }
 
@@ -714,24 +714,24 @@ static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd,
        struct kfd_dev *kdev = pdd->dev;
        int err;
 
-       err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(kdev->kgd, gpu_va, size,
+       err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(kdev->adev, gpu_va, size,
                                                 pdd->drm_priv, mem, NULL, flags);
        if (err)
                goto err_alloc_mem;
 
-       err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, *mem,
+       err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->adev, *mem,
                        pdd->drm_priv, NULL);
        if (err)
                goto err_map_mem;
 
-       err = amdgpu_amdkfd_gpuvm_sync_memory(kdev->kgd, *mem, true);
+       err = amdgpu_amdkfd_gpuvm_sync_memory(kdev->adev, *mem, true);
        if (err) {
                pr_debug("Sync memory failed, wait interrupted by user signal\n");
                goto sync_memory_failed;
        }
 
        if (kptr) {
-               err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kdev->kgd,
+               err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kdev->adev,
                                (struct kgd_mem *)*mem, kptr, NULL);
                if (err) {
                        pr_debug("Map GTT BO to kernel failed\n");
@@ -742,10 +742,10 @@ static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd,
        return err;
 
 sync_memory_failed:
-       amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(kdev->kgd, *mem, pdd->drm_priv);
+       amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(kdev->adev, *mem, pdd->drm_priv);
 
 err_map_mem:
-       amdgpu_amdkfd_gpuvm_free_memory_of_gpu(kdev->kgd, *mem, pdd->drm_priv,
+       amdgpu_amdkfd_gpuvm_free_memory_of_gpu(kdev->adev, *mem, pdd->drm_priv,
                                               NULL);
 err_alloc_mem:
        *mem = NULL;
@@ -940,10 +940,10 @@ static void kfd_process_device_free_bos(struct kfd_process_device *pdd)
                        if (!peer_pdd->drm_priv)
                                continue;
                        amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
-                               peer_pdd->dev->kgd, mem, peer_pdd->drm_priv);
+                               peer_pdd->dev->adev, mem, peer_pdd->drm_priv);
                }
 
-               amdgpu_amdkfd_gpuvm_free_memory_of_gpu(pdd->dev->kgd, mem,
+               amdgpu_amdkfd_gpuvm_free_memory_of_gpu(pdd->dev->adev, mem,
                                                       pdd->drm_priv, NULL);
                kfd_process_device_remove_obj_handle(pdd, id);
        }
@@ -974,7 +974,7 @@ static void kfd_process_kunmap_signal_bo(struct kfd_process *p)
        if (!mem)
                goto out;
 
-       amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kdev->kgd, mem);
+       amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kdev->adev, mem);
 
 out:
        mutex_unlock(&p->mutex);
@@ -1003,7 +1003,7 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
 
                if (pdd->drm_file) {
                        amdgpu_amdkfd_gpuvm_release_process_vm(
-                                       pdd->dev->kgd, pdd->drm_priv);
+                                       pdd->dev->adev, pdd->drm_priv);
                        fput(pdd->drm_file);
                }
 
@@ -1317,14 +1317,13 @@ bool kfd_process_xnack_mode(struct kfd_process *p, bool supported)
                 * support the SVM APIs and don't need to be considered
                 * for the XNACK mode selection.
                 */
-               if (dev->device_info->asic_family < CHIP_VEGA10)
+               if (!KFD_IS_SOC15(dev))
                        continue;
                /* Aldebaran can always support XNACK because it can support
                 * per-process XNACK mode selection. But let the dev->noretry
                 * setting still influence the default XNACK mode.
                 */
-               if (supported &&
-                   dev->device_info->asic_family == CHIP_ALDEBARAN)
+               if (supported && KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2))
                        continue;
 
                /* GFXv10 and later GPUs do not support shader preemption
@@ -1332,7 +1331,7 @@ bool kfd_process_xnack_mode(struct kfd_process *p, bool supported)
                 * management and memory-manager-related preemptions or
                 * even deadlocks.
                 */
-               if (dev->device_info->asic_family >= CHIP_NAVI10)
+               if (KFD_GC_VERSION(dev) >= IP_VERSION(10, 1, 1))
                        return false;
 
                if (dev->noretry)
@@ -1431,7 +1430,7 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd,
        int range_start = dev->shared_resources.non_cp_doorbells_start;
        int range_end = dev->shared_resources.non_cp_doorbells_end;
 
-       if (!KFD_IS_SOC15(dev->device_info->asic_family))
+       if (!KFD_IS_SOC15(dev))
                return 0;
 
        qpd->doorbell_bitmap =
@@ -1547,7 +1546,7 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
        dev = pdd->dev;
 
        ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(
-               dev->kgd, drm_file, p->pasid,
+               dev->adev, drm_file, p->pasid,
                &p->kgd_process_info, &p->ef);
        if (ret) {
                pr_err("Failed to create process VM object\n");
@@ -1779,14 +1778,13 @@ int kfd_process_gpuidx_from_gpuid(struct kfd_process *p, uint32_t gpu_id)
 }
 
 int
-kfd_process_gpuid_from_kgd(struct kfd_process *p, struct amdgpu_device *adev,
+kfd_process_gpuid_from_adev(struct kfd_process *p, struct amdgpu_device *adev,
                           uint32_t *gpuid, uint32_t *gpuidx)
 {
-       struct kgd_dev *kgd = (struct kgd_dev *)adev;
        int i;
 
        for (i = 0; i < p->n_pdds; i++)
-               if (p->pdds[i] && p->pdds[i]->dev->kgd == kgd) {
+               if (p->pdds[i] && p->pdds[i]->dev->adev == adev) {
                        *gpuid = p->pdds[i]->dev->id;
                        *gpuidx = i;
                        return 0;
@@ -1951,10 +1949,10 @@ void kfd_flush_tlb(struct kfd_process_device *pdd, enum TLB_FLUSH_TYPE type)
                 * only happens when the first queue is created.
                 */
                if (pdd->qpd.vmid)
-                       amdgpu_amdkfd_flush_gpu_tlb_vmid(dev->kgd,
+                       amdgpu_amdkfd_flush_gpu_tlb_vmid(dev->adev,
                                                        pdd->qpd.vmid);
        } else {
-               amdgpu_amdkfd_flush_gpu_tlb_pasid(dev->kgd,
+               amdgpu_amdkfd_flush_gpu_tlb_pasid(dev->adev,
                                        pdd->process->pasid, type);
        }
 }
index 3627e7ac161b657ef274c2d6814f088b0aaa6081..4f8464658dafd47b97f281bf1e4486b37ccb4a4e 100644 (file)
@@ -118,7 +118,7 @@ int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid,
                return ret;
 
        pqn->q->gws = mem;
-       pdd->qpd.num_gws = gws ? amdgpu_amdkfd_get_num_gws(dev->kgd) : 0;
+       pdd->qpd.num_gws = gws ? dev->adev->gds.gws_size : 0;
 
        return pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
                                                        pqn->q, NULL);
index ed4bc5f844ce7675f17937515fbb24d085482b23..deae12dc777d29a23c13f0b92aa776613d2b63c5 100644 (file)
@@ -207,7 +207,6 @@ void kfd_smi_event_update_gpu_reset(struct kfd_dev *dev, bool post_reset)
 void kfd_smi_event_update_thermal_throttling(struct kfd_dev *dev,
                                             uint64_t throttle_bitmask)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)dev->kgd;
        /*
         * ThermalThrottle msg = throttle_bitmask(8):
         *                       thermal_interrupt_count(16):
@@ -223,14 +222,13 @@ void kfd_smi_event_update_thermal_throttling(struct kfd_dev *dev,
 
        len = snprintf(fifo_in, sizeof(fifo_in), "%x %llx:%llx\n",
                       KFD_SMI_EVENT_THERMAL_THROTTLE, throttle_bitmask,
-                      atomic64_read(&adev->smu.throttle_int_counter));
+                      atomic64_read(&dev->adev->smu.throttle_int_counter));
 
        add_event_to_kfifo(dev, KFD_SMI_EVENT_THERMAL_THROTTLE, fifo_in, len);
 }
 
 void kfd_smi_event_update_vmfault(struct kfd_dev *dev, uint16_t pasid)
 {
-       struct amdgpu_device *adev = (struct amdgpu_device *)dev->kgd;
        struct amdgpu_task_info task_info;
        /* VmFault msg = (hex)uint32_pid(8) + :(1) + task name(16) = 25 */
        /* 1 byte event + 1 byte space + 25 bytes msg + 1 byte \n +
@@ -243,7 +241,7 @@ void kfd_smi_event_update_vmfault(struct kfd_dev *dev, uint16_t pasid)
                return;
 
        memset(&task_info, 0, sizeof(struct amdgpu_task_info));
-       amdgpu_vm_get_task_info(adev, pasid, &task_info);
+       amdgpu_vm_get_task_info(dev->adev, pasid, &task_info);
        /* Report VM faults from user applications, not retry from kernel */
        if (!task_info.pid)
                return;
index 16137c4247bbec50b4a2b41fb2af55e04f992dd8..10868d5b549f53efab97563b0d4dabd86906b304 100644 (file)
@@ -193,7 +193,6 @@ svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap,
 
        for_each_set_bit(gpuidx, bitmap, MAX_GPU_INSTANCE) {
                struct kfd_process_device *pdd;
-               struct amdgpu_device *adev;
 
                pr_debug("mapping to gpu idx 0x%x\n", gpuidx);
                pdd = kfd_process_device_from_gpuidx(p, gpuidx);
@@ -201,9 +200,8 @@ svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap,
                        pr_debug("failed to find device idx %d\n", gpuidx);
                        return -EINVAL;
                }
-               adev = (struct amdgpu_device *)pdd->dev->kgd;
 
-               r = svm_range_dma_map_dev(adev, prange, offset, npages,
+               r = svm_range_dma_map_dev(pdd->dev->adev, prange, offset, npages,
                                          hmm_pfns, gpuidx);
                if (r)
                        break;
@@ -581,7 +579,7 @@ svm_range_get_adev_by_id(struct svm_range *prange, uint32_t gpu_id)
                return NULL;
        }
 
-       return (struct amdgpu_device *)pdd->dev->kgd;
+       return pdd->dev->adev;
 }
 
 struct kfd_process_device *
@@ -593,7 +591,7 @@ svm_range_get_pdd_by_adev(struct svm_range *prange, struct amdgpu_device *adev)
 
        p = container_of(prange->svms, struct kfd_process, svms);
 
-       r = kfd_process_gpuid_from_kgd(p, adev, &gpuid, &gpu_idx);
+       r = kfd_process_gpuid_from_adev(p, adev, &gpuid, &gpu_idx);
        if (r) {
                pr_debug("failed to get device id by adev %p\n", adev);
                return NULL;
@@ -1053,8 +1051,8 @@ svm_range_get_pte_flags(struct amdgpu_device *adev, struct svm_range *prange,
        if (domain == SVM_RANGE_VRAM_DOMAIN)
                bo_adev = amdgpu_ttm_adev(prange->svm_bo->bo->tbo.bdev);
 
-       switch (adev->asic_type) {
-       case CHIP_ARCTURUS:
+       switch (KFD_GC_VERSION(adev->kfd.dev)) {
+       case IP_VERSION(9, 4, 1):
                if (domain == SVM_RANGE_VRAM_DOMAIN) {
                        if (bo_adev == adev) {
                                mapping_flags |= coherent ?
@@ -1070,7 +1068,7 @@ svm_range_get_pte_flags(struct amdgpu_device *adev, struct svm_range *prange,
                                AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
                }
                break;
-       case CHIP_ALDEBARAN:
+       case IP_VERSION(9, 4, 2):
                if (domain == SVM_RANGE_VRAM_DOMAIN) {
                        if (bo_adev == adev) {
                                mapping_flags |= coherent ?
@@ -1129,7 +1127,6 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start,
        DECLARE_BITMAP(bitmap, MAX_GPU_INSTANCE);
        struct kfd_process_device *pdd;
        struct dma_fence *fence = NULL;
-       struct amdgpu_device *adev;
        struct kfd_process *p;
        uint32_t gpuidx;
        int r = 0;
@@ -1145,9 +1142,9 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start,
                        pr_debug("failed to find device idx %d\n", gpuidx);
                        return -EINVAL;
                }
-               adev = (struct amdgpu_device *)pdd->dev->kgd;
 
-               r = svm_range_unmap_from_gpu(adev, drm_priv_to_vm(pdd->drm_priv),
+               r = svm_range_unmap_from_gpu(pdd->dev->adev,
+                                            drm_priv_to_vm(pdd->drm_priv),
                                             start, last, &fence);
                if (r)
                        break;
@@ -1159,7 +1156,7 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start,
                        if (r)
                                break;
                }
-               amdgpu_amdkfd_flush_gpu_tlb_pasid((struct kgd_dev *)adev,
+               amdgpu_amdkfd_flush_gpu_tlb_pasid(pdd->dev->adev,
                                        p->pasid, TLB_FLUSH_HEAVYWEIGHT);
        }
 
@@ -1243,8 +1240,7 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                struct kfd_process *p;
 
                p = container_of(prange->svms, struct kfd_process, svms);
-               amdgpu_amdkfd_flush_gpu_tlb_pasid((struct kgd_dev *)adev,
-                                               p->pasid, TLB_FLUSH_LEGACY);
+               amdgpu_amdkfd_flush_gpu_tlb_pasid(adev, p->pasid, TLB_FLUSH_LEGACY);
        }
 out:
        return r;
@@ -1257,7 +1253,6 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset,
 {
        struct kfd_process_device *pdd;
        struct amdgpu_device *bo_adev;
-       struct amdgpu_device *adev;
        struct kfd_process *p;
        struct dma_fence *fence = NULL;
        uint32_t gpuidx;
@@ -1276,19 +1271,18 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset,
                        pr_debug("failed to find device idx %d\n", gpuidx);
                        return -EINVAL;
                }
-               adev = (struct amdgpu_device *)pdd->dev->kgd;
 
                pdd = kfd_bind_process_to_device(pdd->dev, p);
                if (IS_ERR(pdd))
                        return -EINVAL;
 
-               if (bo_adev && adev != bo_adev &&
-                   !amdgpu_xgmi_same_hive(adev, bo_adev)) {
+               if (bo_adev && pdd->dev->adev != bo_adev &&
+                   !amdgpu_xgmi_same_hive(pdd->dev->adev, bo_adev)) {
                        pr_debug("cannot map to device idx %d\n", gpuidx);
                        continue;
                }
 
-               r = svm_range_map_to_gpu(adev, drm_priv_to_vm(pdd->drm_priv),
+               r = svm_range_map_to_gpu(pdd->dev->adev, drm_priv_to_vm(pdd->drm_priv),
                                         prange, offset, npages, readonly,
                                         prange->dma_addr[gpuidx],
                                         bo_adev, wait ? &fence : NULL);
@@ -1322,7 +1316,6 @@ struct svm_validate_context {
 static int svm_range_reserve_bos(struct svm_validate_context *ctx)
 {
        struct kfd_process_device *pdd;
-       struct amdgpu_device *adev;
        struct amdgpu_vm *vm;
        uint32_t gpuidx;
        int r;
@@ -1334,7 +1327,6 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx)
                        pr_debug("failed to find device idx %d\n", gpuidx);
                        return -EINVAL;
                }
-               adev = (struct amdgpu_device *)pdd->dev->kgd;
                vm = drm_priv_to_vm(pdd->drm_priv);
 
                ctx->tv[gpuidx].bo = &vm->root.bo->tbo;
@@ -1356,9 +1348,9 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx)
                        r = -EINVAL;
                        goto unreserve_out;
                }
-               adev = (struct amdgpu_device *)pdd->dev->kgd;
 
-               r = amdgpu_vm_validate_pt_bos(adev, drm_priv_to_vm(pdd->drm_priv),
+               r = amdgpu_vm_validate_pt_bos(pdd->dev->adev,
+                                             drm_priv_to_vm(pdd->drm_priv),
                                              svm_range_bo_validate, NULL);
                if (r) {
                        pr_debug("failed %d validate pt bos\n", r);
@@ -1381,12 +1373,10 @@ static void svm_range_unreserve_bos(struct svm_validate_context *ctx)
 static void *kfd_svm_page_owner(struct kfd_process *p, int32_t gpuidx)
 {
        struct kfd_process_device *pdd;
-       struct amdgpu_device *adev;
 
        pdd = kfd_process_device_from_gpuidx(p, gpuidx);
-       adev = (struct amdgpu_device *)pdd->dev->kgd;
 
-       return SVM_ADEV_PGMAP_OWNER(adev);
+       return SVM_ADEV_PGMAP_OWNER(pdd->dev->adev);
 }
 
 /*
@@ -1966,23 +1956,30 @@ svm_range_handle_list_op(struct svm_range_list *svms, struct svm_range *prange)
 static void svm_range_drain_retry_fault(struct svm_range_list *svms)
 {
        struct kfd_process_device *pdd;
-       struct amdgpu_device *adev;
        struct kfd_process *p;
+       int drain;
        uint32_t i;
 
        p = container_of(svms, struct kfd_process, svms);
 
+restart:
+       drain = atomic_read(&svms->drain_pagefaults);
+       if (!drain)
+               return;
+
        for_each_set_bit(i, svms->bitmap_supported, p->n_pdds) {
                pdd = p->pdds[i];
                if (!pdd)
                        continue;
 
                pr_debug("drain retry fault gpu %d svms %p\n", i, svms);
-               adev = (struct amdgpu_device *)pdd->dev->kgd;
 
-               amdgpu_ih_wait_on_checkpoint_process(adev, &adev->irq.ih1);
+               amdgpu_ih_wait_on_checkpoint_process(pdd->dev->adev,
+                                                    &pdd->dev->adev->irq.ih1);
                pr_debug("drain retry fault gpu %d svms 0x%p done\n", i, svms);
        }
+       if (atomic_cmpxchg(&svms->drain_pagefaults, drain, 0) != drain)
+               goto restart;
 }
 
 static void svm_range_deferred_list_work(struct work_struct *work)
@@ -1990,43 +1987,41 @@ static void svm_range_deferred_list_work(struct work_struct *work)
        struct svm_range_list *svms;
        struct svm_range *prange;
        struct mm_struct *mm;
+       struct kfd_process *p;
 
        svms = container_of(work, struct svm_range_list, deferred_list_work);
        pr_debug("enter svms 0x%p\n", svms);
 
+       p = container_of(svms, struct kfd_process, svms);
+       /* Avoid mm is gone when inserting mmu notifier */
+       mm = get_task_mm(p->lead_thread);
+       if (!mm) {
+               pr_debug("svms 0x%p process mm gone\n", svms);
+               return;
+       }
+retry:
+       mmap_write_lock(mm);
+
+       /* Checking for the need to drain retry faults must be inside
+        * mmap write lock to serialize with munmap notifiers.
+        */
+       if (unlikely(atomic_read(&svms->drain_pagefaults))) {
+               mmap_write_unlock(mm);
+               svm_range_drain_retry_fault(svms);
+               goto retry;
+       }
+
        spin_lock(&svms->deferred_list_lock);
        while (!list_empty(&svms->deferred_range_list)) {
                prange = list_first_entry(&svms->deferred_range_list,
                                          struct svm_range, deferred_list);
+               list_del_init(&prange->deferred_list);
                spin_unlock(&svms->deferred_list_lock);
+
                pr_debug("prange 0x%p [0x%lx 0x%lx] op %d\n", prange,
                         prange->start, prange->last, prange->work_item.op);
 
-               mm = prange->work_item.mm;
-retry:
-               mmap_write_lock(mm);
                mutex_lock(&svms->lock);
-
-               /* Checking for the need to drain retry faults must be in
-                * mmap write lock to serialize with munmap notifiers.
-                *
-                * Remove from deferred_list must be inside mmap write lock,
-                * otherwise, svm_range_list_lock_and_flush_work may hold mmap
-                * write lock, and continue because deferred_list is empty, then
-                * deferred_list handle is blocked by mmap write lock.
-                */
-               spin_lock(&svms->deferred_list_lock);
-               if (unlikely(svms->drain_pagefaults)) {
-                       svms->drain_pagefaults = false;
-                       spin_unlock(&svms->deferred_list_lock);
-                       mutex_unlock(&svms->lock);
-                       mmap_write_unlock(mm);
-                       svm_range_drain_retry_fault(svms);
-                       goto retry;
-               }
-               list_del_init(&prange->deferred_list);
-               spin_unlock(&svms->deferred_list_lock);
-
                mutex_lock(&prange->migrate_mutex);
                while (!list_empty(&prange->child_list)) {
                        struct svm_range *pchild;
@@ -2042,12 +2037,13 @@ retry:
 
                svm_range_handle_list_op(svms, prange);
                mutex_unlock(&svms->lock);
-               mmap_write_unlock(mm);
 
                spin_lock(&svms->deferred_list_lock);
        }
        spin_unlock(&svms->deferred_list_lock);
 
+       mmap_write_unlock(mm);
+       mmput(mm);
        pr_debug("exit svms 0x%p\n", svms);
 }
 
@@ -2056,12 +2052,6 @@ svm_range_add_list_work(struct svm_range_list *svms, struct svm_range *prange,
                        struct mm_struct *mm, enum svm_work_list_ops op)
 {
        spin_lock(&svms->deferred_list_lock);
-       /* Make sure pending page faults are drained in the deferred worker
-        * before the range is freed to avoid straggler interrupts on
-        * unmapped memory causing "phantom faults".
-        */
-       if (op == SVM_OP_UNMAP_RANGE)
-               svms->drain_pagefaults = true;
        /* if prange is on the deferred list */
        if (!list_empty(&prange->deferred_list)) {
                pr_debug("update exist prange 0x%p work op %d\n", prange, op);
@@ -2140,6 +2130,12 @@ svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange,
        pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] [0x%lx 0x%lx]\n", svms,
                 prange, prange->start, prange->last, start, last);
 
+       /* Make sure pending page faults are drained in the deferred worker
+        * before the range is freed to avoid straggler interrupts on
+        * unmapped memory causing "phantom faults".
+        */
+       atomic_inc(&svms->drain_pagefaults);
+
        unmap_parent = start <= prange->start && last >= prange->last;
 
        list_for_each_entry(pchild, &prange->child_list, child_list) {
@@ -2301,7 +2297,7 @@ svm_range_best_restore_location(struct svm_range *prange,
 
        p = container_of(prange->svms, struct kfd_process, svms);
 
-       r = kfd_process_gpuid_from_kgd(p, adev, &gpuid, gpuidx);
+       r = kfd_process_gpuid_from_adev(p, adev, &gpuid, gpuidx);
        if (r < 0) {
                pr_debug("failed to get gpuid from kgd\n");
                return -1;
@@ -2478,7 +2474,7 @@ svm_range *svm_range_create_unregistered_range(struct amdgpu_device *adev,
                pr_debug("Failed to create prange in address [0x%llx]\n", addr);
                return NULL;
        }
-       if (kfd_process_gpuid_from_kgd(p, adev, &gpuid, &gpuidx)) {
+       if (kfd_process_gpuid_from_adev(p, adev, &gpuid, &gpuidx)) {
                pr_debug("failed to get gpuid from kgd\n");
                svm_range_free(prange);
                return NULL;
@@ -2545,7 +2541,7 @@ svm_range_count_fault(struct amdgpu_device *adev, struct kfd_process *p,
                uint32_t gpuid;
                int r;
 
-               r = kfd_process_gpuid_from_kgd(p, adev, &gpuid, &gpuidx);
+               r = kfd_process_gpuid_from_adev(p, adev, &gpuid, &gpuidx);
                if (r < 0)
                        return;
        }
@@ -2559,20 +2555,13 @@ svm_range_count_fault(struct amdgpu_device *adev, struct kfd_process *p,
 }
 
 static bool
-svm_fault_allowed(struct mm_struct *mm, uint64_t addr, bool write_fault)
+svm_fault_allowed(struct vm_area_struct *vma, bool write_fault)
 {
        unsigned long requested = VM_READ;
-       struct vm_area_struct *vma;
 
        if (write_fault)
                requested |= VM_WRITE;
 
-       vma = find_vma(mm, addr << PAGE_SHIFT);
-       if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) {
-               pr_debug("address 0x%llx VMA is removed\n", addr);
-               return true;
-       }
-
        pr_debug("requested 0x%lx, vma permission flags 0x%lx\n", requested,
                vma->vm_flags);
        return (vma->vm_flags & requested) == requested;
@@ -2590,6 +2579,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
        int32_t best_loc;
        int32_t gpuidx = MAX_GPU_INSTANCE;
        bool write_locked = false;
+       struct vm_area_struct *vma;
        int r = 0;
 
        if (!KFD_IS_SVM_API_SUPPORTED(adev->kfd.dev)) {
@@ -2600,7 +2590,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
        p = kfd_lookup_process_by_pasid(pasid);
        if (!p) {
                pr_debug("kfd process not founded pasid 0x%x\n", pasid);
-               return -ESRCH;
+               return 0;
        }
        if (!p->xnack_enabled) {
                pr_debug("XNACK not enabled for pasid 0x%x\n", pasid);
@@ -2611,10 +2601,17 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
 
        pr_debug("restoring svms 0x%p fault address 0x%llx\n", svms, addr);
 
+       if (atomic_read(&svms->drain_pagefaults)) {
+               pr_debug("draining retry fault, drop fault 0x%llx\n", addr);
+               goto out;
+       }
+
+       /* p->lead_thread is available as kfd_process_wq_release flush the work
+        * before releasing task ref.
+        */
        mm = get_task_mm(p->lead_thread);
        if (!mm) {
                pr_debug("svms 0x%p failed to get mm\n", svms);
-               r = -ESRCH;
                goto out;
        }
 
@@ -2663,7 +2660,17 @@ retry_write_locked:
                goto out_unlock_range;
        }
 
-       if (!svm_fault_allowed(mm, addr, write_fault)) {
+       /* __do_munmap removed VMA, return success as we are handling stale
+        * retry fault.
+        */
+       vma = find_vma(mm, addr << PAGE_SHIFT);
+       if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) {
+               pr_debug("address 0x%llx VMA is removed\n", addr);
+               r = 0;
+               goto out_unlock_range;
+       }
+
+       if (!svm_fault_allowed(vma, write_fault)) {
                pr_debug("fault addr 0x%llx no %s permission\n", addr,
                        write_fault ? "write" : "read");
                r = -EPERM;
@@ -2741,6 +2748,14 @@ void svm_range_list_fini(struct kfd_process *p)
        /* Ensure list work is finished before process is destroyed */
        flush_work(&p->svms.deferred_list_work);
 
+       /*
+        * Ensure no retry fault comes in afterwards, as page fault handler will
+        * not find kfd process and take mm lock to recover fault.
+        */
+       atomic_inc(&p->svms.drain_pagefaults);
+       svm_range_drain_retry_fault(&p->svms);
+
+
        list_for_each_entry_safe(prange, next, &p->svms.list, list) {
                svm_range_unlink(prange);
                svm_range_remove_notifier(prange);
@@ -2761,6 +2776,7 @@ int svm_range_list_init(struct kfd_process *p)
        mutex_init(&svms->lock);
        INIT_LIST_HEAD(&svms->list);
        atomic_set(&svms->evicted_ranges, 0);
+       atomic_set(&svms->drain_pagefaults, 0);
        INIT_DELAYED_WORK(&svms->restore_work, svm_range_restore_work);
        INIT_WORK(&svms->deferred_list_work, svm_range_deferred_list_work);
        INIT_LIST_HEAD(&svms->deferred_range_list);
@@ -2953,7 +2969,6 @@ svm_range_best_prefetch_location(struct svm_range *prange)
        uint32_t best_loc = prange->prefetch_loc;
        struct kfd_process_device *pdd;
        struct amdgpu_device *bo_adev;
-       struct amdgpu_device *adev;
        struct kfd_process *p;
        uint32_t gpuidx;
 
@@ -2981,12 +2996,11 @@ svm_range_best_prefetch_location(struct svm_range *prange)
                        pr_debug("failed to get device by idx 0x%x\n", gpuidx);
                        continue;
                }
-               adev = (struct amdgpu_device *)pdd->dev->kgd;
 
-               if (adev == bo_adev)
+               if (pdd->dev->adev == bo_adev)
                        continue;
 
-               if (!amdgpu_xgmi_same_hive(adev, bo_adev)) {
+               if (!amdgpu_xgmi_same_hive(pdd->dev->adev, bo_adev)) {
                        best_loc = 0;
                        break;
                }
index dd593ad0614a153b4ba567cc478d2f2f06e70fc0..2d44b26b66576fbbc83dfd3f5d0b386a089e6819 100644 (file)
@@ -113,7 +113,7 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev)
        return device;
 }
 
-struct kfd_dev *kfd_device_by_kgd(const struct kgd_dev *kgd)
+struct kfd_dev *kfd_device_by_adev(const struct amdgpu_device *adev)
 {
        struct kfd_topology_device *top_dev;
        struct kfd_dev *device = NULL;
@@ -121,7 +121,7 @@ struct kfd_dev *kfd_device_by_kgd(const struct kgd_dev *kgd)
        down_read(&topology_lock);
 
        list_for_each_entry(top_dev, &topology_device_list, list)
-               if (top_dev->gpu && top_dev->gpu->kgd == kgd) {
+               if (top_dev->gpu && top_dev->gpu->adev == adev) {
                        device = top_dev->gpu;
                        break;
                }
@@ -515,7 +515,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
                                HSA_CAP_WATCH_POINTS_TOTALBITS_MASK);
                }
 
-               if (dev->gpu->device_info->asic_family == CHIP_TONGA)
+               if (dev->gpu->adev->asic_type == CHIP_TONGA)
                        dev->node_props.capability |=
                                        HSA_CAP_AQL_QUEUE_DOUBLE_MAP;
 
@@ -531,7 +531,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
                sysfs_show_32bit_prop(buffer, offs, "sdma_fw_version",
                                      dev->gpu->sdma_fw_version);
                sysfs_show_64bit_prop(buffer, offs, "unique_id",
-                                     amdgpu_amdkfd_get_unique_id(dev->gpu->kgd));
+                                     dev->gpu->adev->unique_id);
 
        }
 
@@ -1106,7 +1106,7 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu)
        if (!gpu)
                return 0;
 
-       amdgpu_amdkfd_get_local_mem_info(gpu->kgd, &local_mem_info);
+       amdgpu_amdkfd_get_local_mem_info(gpu->adev, &local_mem_info);
 
        local_mem_size = local_mem_info.local_mem_size_private +
                        local_mem_info.local_mem_size_public;
@@ -1189,7 +1189,7 @@ static void kfd_fill_mem_clk_max_info(struct kfd_topology_device *dev)
         * for APUs - If CRAT from ACPI reports more than one bank, then
         *      all the banks will report the same mem_clk_max information
         */
-       amdgpu_amdkfd_get_local_mem_info(dev->gpu->kgd, &local_mem_info);
+       amdgpu_amdkfd_get_local_mem_info(dev->gpu->adev, &local_mem_info);
 
        list_for_each_entry(mem, &dev->mem_props, list)
                mem->mem_clk_max = local_mem_info.mem_clk_max;
@@ -1217,8 +1217,7 @@ static void kfd_set_iolink_no_atomics(struct kfd_topology_device *dev,
        /* set gpu (dev) flags. */
        } else {
                if (!dev->gpu->pci_atomic_requested ||
-                               dev->gpu->device_info->asic_family ==
-                                                       CHIP_HAWAII)
+                               dev->gpu->adev->asic_type == CHIP_HAWAII)
                        link->flags |= CRAT_IOLINK_FLAGS_NO_ATOMICS_32_BIT |
                                CRAT_IOLINK_FLAGS_NO_ATOMICS_64_BIT;
        }
@@ -1239,7 +1238,7 @@ static void kfd_set_iolink_non_coherent(struct kfd_topology_device *to_dev,
                 */
                if (inbound_link->iolink_type == CRAT_IOLINK_TYPE_PCIEXPRESS ||
                    (inbound_link->iolink_type == CRAT_IOLINK_TYPE_XGMI &&
-                   to_dev->gpu->device_info->asic_family == CHIP_VEGA20)) {
+                   KFD_GC_VERSION(to_dev->gpu) == IP_VERSION(9, 4, 0))) {
                        outbound_link->flags |= CRAT_IOLINK_FLAGS_NON_COHERENT;
                        inbound_link->flags |= CRAT_IOLINK_FLAGS_NON_COHERENT;
                }
@@ -1286,7 +1285,6 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
        void *crat_image = NULL;
        size_t image_size = 0;
        int proximity_domain;
-       struct amdgpu_device *adev;
 
        INIT_LIST_HEAD(&temp_topology_device_list);
 
@@ -1296,10 +1294,8 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
 
        proximity_domain = atomic_inc_return(&topology_crat_proximity_domain);
 
-       adev = (struct amdgpu_device *)(gpu->kgd);
-
        /* Include the CPU in xGMI hive if xGMI connected by assigning it the hive ID. */
-       if (gpu->hive_id && adev->gmc.xgmi.connected_to_cpu) {
+       if (gpu->hive_id && gpu->adev->gmc.xgmi.connected_to_cpu) {
                struct kfd_topology_device *top_dev;
 
                down_read(&topology_lock);
@@ -1372,7 +1368,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
         * needed for the topology
         */
 
-       amdgpu_amdkfd_get_cu_info(dev->gpu->kgd, &cu_info);
+       amdgpu_amdkfd_get_cu_info(dev->gpu->adev, &cu_info);
 
        strncpy(dev->node_props.name, gpu->device_info->asic_name,
                        KFD_TOPOLOGY_PUBLIC_NAME_SIZE);
@@ -1384,33 +1380,32 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
        dev->node_props.vendor_id = gpu->pdev->vendor;
        dev->node_props.device_id = gpu->pdev->device;
        dev->node_props.capability |=
-               ((amdgpu_amdkfd_get_asic_rev_id(dev->gpu->kgd) <<
-                       HSA_CAP_ASIC_REVISION_SHIFT) &
+               ((dev->gpu->adev->rev_id << HSA_CAP_ASIC_REVISION_SHIFT) &
                        HSA_CAP_ASIC_REVISION_MASK);
        dev->node_props.location_id = pci_dev_id(gpu->pdev);
        dev->node_props.domain = pci_domain_nr(gpu->pdev->bus);
        dev->node_props.max_engine_clk_fcompute =
-               amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->kgd);
+               amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->adev);
        dev->node_props.max_engine_clk_ccompute =
                cpufreq_quick_get_max(0) / 1000;
        dev->node_props.drm_render_minor =
                gpu->shared_resources.drm_render_minor;
 
        dev->node_props.hive_id = gpu->hive_id;
-       dev->node_props.num_sdma_engines = gpu->device_info->num_sdma_engines;
+       dev->node_props.num_sdma_engines = kfd_get_num_sdma_engines(gpu);
        dev->node_props.num_sdma_xgmi_engines =
-                               gpu->device_info->num_xgmi_sdma_engines;
+                                       kfd_get_num_xgmi_sdma_engines(gpu);
        dev->node_props.num_sdma_queues_per_engine =
                                gpu->device_info->num_sdma_queues_per_engine;
        dev->node_props.num_gws = (dev->gpu->gws &&
                dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ?
-               amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0;
+               dev->gpu->adev->gds.gws_size : 0;
        dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm);
 
        kfd_fill_mem_clk_max_info(dev);
        kfd_fill_iolink_non_crat_info(dev);
 
-       switch (dev->gpu->device_info->asic_family) {
+       switch (dev->gpu->adev->asic_type) {
        case CHIP_KAVERI:
        case CHIP_HAWAII:
        case CHIP_TONGA:
@@ -1429,30 +1424,14 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
                        HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) &
                        HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK);
                break;
-       case CHIP_VEGA10:
-       case CHIP_VEGA12:
-       case CHIP_VEGA20:
-       case CHIP_RAVEN:
-       case CHIP_RENOIR:
-       case CHIP_ARCTURUS:
-       case CHIP_ALDEBARAN:
-       case CHIP_NAVI10:
-       case CHIP_NAVI12:
-       case CHIP_NAVI14:
-       case CHIP_SIENNA_CICHLID:
-       case CHIP_NAVY_FLOUNDER:
-       case CHIP_VANGOGH:
-       case CHIP_DIMGREY_CAVEFISH:
-       case CHIP_BEIGE_GOBY:
-       case CHIP_YELLOW_CARP:
-       case CHIP_CYAN_SKILLFISH:
-               dev->node_props.capability |= ((HSA_CAP_DOORBELL_TYPE_2_0 <<
-                       HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) &
-                       HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK);
-               break;
        default:
-               WARN(1, "Unexpected ASIC family %u",
-                    dev->gpu->device_info->asic_family);
+               if (KFD_GC_VERSION(dev->gpu) >= IP_VERSION(9, 0, 1))
+                       dev->node_props.capability |= ((HSA_CAP_DOORBELL_TYPE_2_0 <<
+                               HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) &
+                               HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK);
+               else
+                       WARN(1, "Unexpected ASIC family %u",
+                            dev->gpu->adev->asic_type);
        }
 
        /*
@@ -1469,7 +1448,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
         *              because it doesn't consider masked out CUs
         * max_waves_per_simd: Carrizo reports wrong max_waves_per_simd
         */
-       if (dev->gpu->device_info->asic_family == CHIP_CARRIZO) {
+       if (dev->gpu->adev->asic_type == CHIP_CARRIZO) {
                dev->node_props.simd_count =
                        cu_info.simd_per_cu * cu_info.cu_active_number;
                dev->node_props.max_waves_per_simd = 10;
@@ -1477,16 +1456,17 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
 
        /* kfd only concerns sram ecc on GFX and HBM ecc on UMC */
        dev->node_props.capability |=
-               ((adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__GFX)) != 0) ?
+               ((dev->gpu->adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__GFX)) != 0) ?
                HSA_CAP_SRAM_EDCSUPPORTED : 0;
-       dev->node_props.capability |= ((adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__UMC)) != 0) ?
+       dev->node_props.capability |=
+               ((dev->gpu->adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__UMC)) != 0) ?
                HSA_CAP_MEM_EDCSUPPORTED : 0;
 
-       if (adev->asic_type != CHIP_VEGA10)
-               dev->node_props.capability |= (adev->ras_enabled != 0) ?
+       if (KFD_GC_VERSION(dev->gpu) != IP_VERSION(9, 0, 1))
+               dev->node_props.capability |= (dev->gpu->adev->ras_enabled != 0) ?
                        HSA_CAP_RASEVENTNOTIFY : 0;
 
-       if (KFD_IS_SVM_API_SUPPORTED(adev->kfd.dev))
+       if (KFD_IS_SVM_API_SUPPORTED(dev->gpu->adev->kfd.dev))
                dev->node_props.capability |= HSA_CAP_SVMAPI_SUPPORTED;
 
        kfd_debug_print_topology();
index a8db017c9b8edac9af0332dff5fd5865235bc977..f0cc59d2fd5db792768b3e475c19b0f08c4b25e7 100644 (file)
 
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/kfd_sysfs.h>
 #include "kfd_crat.h"
 
 #define KFD_TOPOLOGY_PUBLIC_NAME_SIZE 32
 
-#define HSA_CAP_HOT_PLUGGABLE                  0x00000001
-#define HSA_CAP_ATS_PRESENT                    0x00000002
-#define HSA_CAP_SHARED_WITH_GRAPHICS           0x00000004
-#define HSA_CAP_QUEUE_SIZE_POW2                        0x00000008
-#define HSA_CAP_QUEUE_SIZE_32BIT               0x00000010
-#define HSA_CAP_QUEUE_IDLE_EVENT               0x00000020
-#define HSA_CAP_VA_LIMIT                       0x00000040
-#define HSA_CAP_WATCH_POINTS_SUPPORTED         0x00000080
-#define HSA_CAP_WATCH_POINTS_TOTALBITS_MASK    0x00000f00
-#define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT   8
-#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK   0x00003000
-#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT  12
-
-#define HSA_CAP_DOORBELL_TYPE_PRE_1_0          0x0
-#define HSA_CAP_DOORBELL_TYPE_1_0              0x1
-#define HSA_CAP_DOORBELL_TYPE_2_0              0x2
-#define HSA_CAP_AQL_QUEUE_DOUBLE_MAP           0x00004000
-
-#define HSA_CAP_RESERVED_WAS_SRAM_EDCSUPPORTED 0x00080000 /* Old buggy user mode depends on this being 0 */
-#define HSA_CAP_MEM_EDCSUPPORTED               0x00100000
-#define HSA_CAP_RASEVENTNOTIFY                 0x00200000
-#define HSA_CAP_ASIC_REVISION_MASK             0x03c00000
-#define HSA_CAP_ASIC_REVISION_SHIFT            22
-#define HSA_CAP_SRAM_EDCSUPPORTED              0x04000000
-#define HSA_CAP_SVMAPI_SUPPORTED               0x08000000
-#define HSA_CAP_FLAGS_COHERENTHOSTACCESS       0x10000000
-#define HSA_CAP_RESERVED                       0xe00f8000
-
 struct kfd_node_properties {
        uint64_t hive_id;
        uint32_t cpu_cores_count;
@@ -93,17 +66,6 @@ struct kfd_node_properties {
        char name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE];
 };
 
-#define HSA_MEM_HEAP_TYPE_SYSTEM       0
-#define HSA_MEM_HEAP_TYPE_FB_PUBLIC    1
-#define HSA_MEM_HEAP_TYPE_FB_PRIVATE   2
-#define HSA_MEM_HEAP_TYPE_GPU_GDS      3
-#define HSA_MEM_HEAP_TYPE_GPU_LDS      4
-#define HSA_MEM_HEAP_TYPE_GPU_SCRATCH  5
-
-#define HSA_MEM_FLAGS_HOT_PLUGGABLE            0x00000001
-#define HSA_MEM_FLAGS_NON_VOLATILE             0x00000002
-#define HSA_MEM_FLAGS_RESERVED                 0xfffffffc
-
 struct kfd_mem_properties {
        struct list_head        list;
        uint32_t                heap_type;
@@ -116,12 +78,6 @@ struct kfd_mem_properties {
        struct attribute        attr;
 };
 
-#define HSA_CACHE_TYPE_DATA            0x00000001
-#define HSA_CACHE_TYPE_INSTRUCTION     0x00000002
-#define HSA_CACHE_TYPE_CPU             0x00000004
-#define HSA_CACHE_TYPE_HSACU           0x00000008
-#define HSA_CACHE_TYPE_RESERVED                0xfffffff0
-
 struct kfd_cache_properties {
        struct list_head        list;
        uint32_t                processor_id_low;
index 4595c59f2bf0ba437ba2c0b4e0cf9b888daa2bdb..3fcf911c8b618cb47e02bb87c72fd52a84020acd 100644 (file)
@@ -51,6 +51,7 @@
 #include <drm/drm_hdcp.h>
 #endif
 #include "amdgpu_pm.h"
+#include "amdgpu_atombios.h"
 
 #include "amd_shared.h"
 #include "amdgpu_dm_irq.h"
@@ -789,8 +790,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
                                        plink = adev->dm.dc->links[notify.link_index];
                                        if (plink) {
                                                plink->hpd_status =
-                                                       notify.hpd_status ==
-                                                       DP_HPD_PLUG ? true : false;
+                                                       notify.hpd_status == DP_HPD_PLUG;
                                        }
                                }
                                queue_work(adev->dm.delayed_hpd_wq, &dmub_hpd_wrk->handle_hpd_work);
@@ -1455,6 +1455,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
 
        init_data.flags.power_down_display_on_boot = true;
 
+       if (check_seamless_boot_capability(adev)) {
+               init_data.flags.power_down_display_on_boot = false;
+               init_data.flags.allow_seamless_boot_optimization = true;
+               DRM_INFO("Seamless boot condition check passed\n");
+       }
+
        INIT_LIST_HEAD(&adev->dm.da_list);
        /* Display Core create. */
        adev->dm.dc = dc_create(&init_data);
@@ -1479,8 +1485,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
        if (amdgpu_dc_debug_mask & DC_DISABLE_STUTTER)
                adev->dm.dc->debug.disable_stutter = true;
 
-       if (amdgpu_dc_debug_mask & DC_DISABLE_DSC)
+       if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) {
                adev->dm.dc->debug.disable_dsc = true;
+               adev->dm.dc->debug.disable_dsc_edp = true;
+       }
 
        if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING)
                adev->dm.dc->debug.disable_clock_gate = true;
@@ -2303,14 +2311,6 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc)
                        goto fail;
        }
 
-
-       res = dc_validate_global_state(dc, context, false);
-
-       if (res != DC_OK) {
-               DRM_ERROR("%s:resource validation failed, dc_status:%d\n", __func__, res);
-               goto fail;
-       }
-
        res = dc_commit_state(dc, context);
 
 fail:
@@ -2561,6 +2561,22 @@ static int dm_resume(void *handle)
        if (amdgpu_in_reset(adev)) {
                dc_state = dm->cached_dc_state;
 
+               /*
+                * The dc->current_state is backed up into dm->cached_dc_state
+                * before we commit 0 streams.
+                *
+                * DC will clear link encoder assignments on the real state
+                * but the changes won't propagate over to the copy we made
+                * before the 0 streams commit.
+                *
+                * DC expects that link encoder assignments are *not* valid
+                * when committing a state, so as a workaround it needs to be
+                * cleared here.
+                */
+               link_enc_cfg_init(dm->dc, dc_state);
+
+               amdgpu_dm_outbox_init(adev);
+
                r = dm_dmub_hw_init(adev);
                if (r)
                        DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
@@ -2572,20 +2588,11 @@ static int dm_resume(void *handle)
 
                for (i = 0; i < dc_state->stream_count; i++) {
                        dc_state->streams[i]->mode_changed = true;
-                       for (j = 0; j < dc_state->stream_status->plane_count; j++) {
-                               dc_state->stream_status->plane_states[j]->update_flags.raw
+                       for (j = 0; j < dc_state->stream_status[i].plane_count; j++) {
+                               dc_state->stream_status[i].plane_states[j]->update_flags.raw
                                        = 0xffffffff;
                        }
                }
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-               /*
-                * Resource allocation happens for link encoders for newer ASIC in
-                * dc_validate_global_state, so we need to revalidate it.
-                *
-                * This shouldn't fail (it passed once before), so warn if it does.
-                */
-               WARN_ON(dc_validate_global_state(dm->dc, dc_state, false) != DC_OK);
-#endif
 
                WARN_ON(!dc_commit_state(dm->dc, dc_state));
 
@@ -3909,6 +3916,9 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
        caps = dm->backlight_caps[bl_idx];
 
        dm->brightness[bl_idx] = user_brightness;
+       /* update scratch register */
+       if (bl_idx == 0)
+               amdgpu_atombios_scratch_regs_set_backlight_level(dm->adev, dm->brightness[bl_idx]);
        brightness = convert_brightness_from_user(&caps, dm->brightness[bl_idx]);
        link = (struct dc_link *)dm->backlight_link[bl_idx];
 
@@ -4251,6 +4261,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 
        }
 
+       /*
+        * Disable vblank IRQs aggressively for power-saving.
+        *
+        * TODO: Fix vblank control helpers to delay PSR entry to allow this when PSR
+        * is also supported.
+        */
+       adev_to_drm(adev)->vblank_disable_immediate = !psr_feature_enabled;
+
        /* Software is initialized. Now we can register interrupt handlers. */
        switch (adev->asic_type) {
 #if defined(CONFIG_DRM_AMD_DC_SI)
@@ -6036,7 +6054,8 @@ static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
 {
        stream->timing.flags.DSC = 0;
 
-       if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
+       if (aconnector->dc_link && (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT ||
+               sink->sink_signal == SIGNAL_TYPE_EDP)) {
                dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc,
                                      aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
                                      aconnector->dc_link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
@@ -6044,6 +6063,64 @@ static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
        }
 }
 
+static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
+                                   struct dc_sink *sink, struct dc_stream_state *stream,
+                                   struct dsc_dec_dpcd_caps *dsc_caps,
+                                   uint32_t max_dsc_target_bpp_limit_override)
+{
+       const struct dc_link_settings *verified_link_cap = NULL;
+       uint32_t link_bw_in_kbps;
+       uint32_t edp_min_bpp_x16, edp_max_bpp_x16;
+       struct dc *dc = sink->ctx->dc;
+       struct dc_dsc_bw_range bw_range = {0};
+       struct dc_dsc_config dsc_cfg = {0};
+
+       verified_link_cap = dc_link_get_link_cap(stream->link);
+       link_bw_in_kbps = dc_link_bandwidth_kbps(stream->link, verified_link_cap);
+       edp_min_bpp_x16 = 8 * 16;
+       edp_max_bpp_x16 = 8 * 16;
+
+       if (edp_max_bpp_x16 > dsc_caps->edp_max_bits_per_pixel)
+               edp_max_bpp_x16 = dsc_caps->edp_max_bits_per_pixel;
+
+       if (edp_max_bpp_x16 < edp_min_bpp_x16)
+               edp_min_bpp_x16 = edp_max_bpp_x16;
+
+       if (dc_dsc_compute_bandwidth_range(dc->res_pool->dscs[0],
+                               dc->debug.dsc_min_slice_height_override,
+                               edp_min_bpp_x16, edp_max_bpp_x16,
+                               dsc_caps,
+                               &stream->timing,
+                               &bw_range)) {
+
+               if (bw_range.max_kbps < link_bw_in_kbps) {
+                       if (dc_dsc_compute_config(dc->res_pool->dscs[0],
+                                       dsc_caps,
+                                       dc->debug.dsc_min_slice_height_override,
+                                       max_dsc_target_bpp_limit_override,
+                                       0,
+                                       &stream->timing,
+                                       &dsc_cfg)) {
+                               stream->timing.dsc_cfg = dsc_cfg;
+                               stream->timing.flags.DSC = 1;
+                               stream->timing.dsc_cfg.bits_per_pixel = edp_max_bpp_x16;
+                       }
+                       return;
+               }
+       }
+
+       if (dc_dsc_compute_config(dc->res_pool->dscs[0],
+                               dsc_caps,
+                               dc->debug.dsc_min_slice_height_override,
+                               max_dsc_target_bpp_limit_override,
+                               link_bw_in_kbps,
+                               &stream->timing,
+                               &dsc_cfg)) {
+               stream->timing.dsc_cfg = dsc_cfg;
+               stream->timing.flags.DSC = 1;
+       }
+}
+
 static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
                                                                                struct dc_sink *sink, struct dc_stream_state *stream,
                                                                                struct dsc_dec_dpcd_caps *dsc_caps)
@@ -6051,6 +6128,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
        struct drm_connector *drm_connector = &aconnector->base;
        uint32_t link_bandwidth_kbps;
        uint32_t max_dsc_target_bpp_limit_override = 0;
+       struct dc *dc = sink->ctx->dc;
 
        link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
                                                        dc_link_get_link_cap(aconnector->dc_link));
@@ -6063,7 +6141,12 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
        dc_dsc_policy_set_enable_dsc_when_not_needed(
                aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
 
-       if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
+       if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP && !dc->debug.disable_dsc_edp &&
+           dc->caps.edp_dsc_support && aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE) {
+
+               apply_dsc_policy_for_edp(aconnector, sink, stream, dsc_caps, max_dsc_target_bpp_limit_override);
+
+       } else if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
 
                if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
                                                dsc_caps,
@@ -10759,8 +10842,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
        trace_amdgpu_dm_atomic_check_begin(state);
 
        ret = drm_atomic_helper_check_modeset(dev, state);
-       if (ret)
+       if (ret) {
+               DRM_DEBUG_DRIVER("drm_atomic_helper_check_modeset() failed\n");
                goto fail;
+       }
 
        /* Check connector changes */
        for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
@@ -10776,6 +10861,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 
                new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc);
                if (IS_ERR(new_crtc_state)) {
+                       DRM_DEBUG_DRIVER("drm_atomic_get_crtc_state() failed\n");
                        ret = PTR_ERR(new_crtc_state);
                        goto fail;
                }
@@ -10790,8 +10876,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
                        if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
                                ret = add_affected_mst_dsc_crtcs(state, crtc);
-                               if (ret)
+                               if (ret) {
+                                       DRM_DEBUG_DRIVER("add_affected_mst_dsc_crtcs() failed\n");
                                        goto fail;
+                               }
                        }
                }
        }
@@ -10806,19 +10894,25 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                        continue;
 
                ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n");
                        goto fail;
+               }
 
                if (!new_crtc_state->enable)
                        continue;
 
                ret = drm_atomic_add_affected_connectors(state, crtc);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("drm_atomic_add_affected_connectors() failed\n");
                        goto fail;
+               }
 
                ret = drm_atomic_add_affected_planes(state, crtc);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("drm_atomic_add_affected_planes() failed\n");
                        goto fail;
+               }
 
                if (dm_old_crtc_state->dsc_force_changed)
                        new_crtc_state->mode_changed = true;
@@ -10855,6 +10949,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 
                        if (IS_ERR(new_plane_state)) {
                                ret = PTR_ERR(new_plane_state);
+                               DRM_DEBUG_DRIVER("new_plane_state is BAD\n");
                                goto fail;
                        }
                }
@@ -10867,8 +10962,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                            new_plane_state,
                                            false,
                                            &lock_and_validation_needed);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n");
                        goto fail;
+               }
        }
 
        /* Disable all crtcs which require disable */
@@ -10878,8 +10975,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                           new_crtc_state,
                                           false,
                                           &lock_and_validation_needed);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("DISABLE: dm_update_crtc_state() failed\n");
                        goto fail;
+               }
        }
 
        /* Enable all crtcs which require enable */
@@ -10889,8 +10988,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                           new_crtc_state,
                                           true,
                                           &lock_and_validation_needed);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("ENABLE: dm_update_crtc_state() failed\n");
                        goto fail;
+               }
        }
 
        /* Add new/modified planes */
@@ -10900,20 +11001,26 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                            new_plane_state,
                                            true,
                                            &lock_and_validation_needed);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n");
                        goto fail;
+               }
        }
 
        /* Run this here since we want to validate the streams we created */
        ret = drm_atomic_helper_check_planes(dev, state);
-       if (ret)
+       if (ret) {
+               DRM_DEBUG_DRIVER("drm_atomic_helper_check_planes() failed\n");
                goto fail;
+       }
 
        /* Check cursor planes scaling */
        for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
                ret = dm_check_crtc_cursor(state, crtc, new_crtc_state);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("dm_check_crtc_cursor() failed\n");
                        goto fail;
+               }
        }
 
        if (state->legacy_cursor_update) {
@@ -11000,20 +11107,28 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
         */
        if (lock_and_validation_needed) {
                ret = dm_atomic_get_state(state, &dm_state);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("dm_atomic_get_state() failed\n");
                        goto fail;
+               }
 
                ret = do_aquire_global_lock(dev, state);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("do_aquire_global_lock() failed\n");
                        goto fail;
+               }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-               if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars))
+               if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars)) {
+                       DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n");
                        goto fail;
+               }
 
                ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("dm_update_mst_vcpi_slots_for_dsc() failed\n");
                        goto fail;
+               }
 #endif
 
                /*
@@ -11023,12 +11138,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                 * to get stuck in an infinite loop and hang eventually.
                 */
                ret = drm_dp_mst_atomic_check(state);
-               if (ret)
+               if (ret) {
+                       DRM_DEBUG_DRIVER("drm_dp_mst_atomic_check() failed\n");
                        goto fail;
-               status = dc_validate_global_state(dc, dm_state->context, false);
+               }
+               status = dc_validate_global_state(dc, dm_state->context, true);
                if (status != DC_OK) {
-                       drm_dbg_atomic(dev,
-                                      "DC global validation failure: %s (%d)",
+                       DRM_DEBUG_DRIVER("DC global validation failure: %s (%d)",
                                       dc_status_to_str(status), status);
                        ret = -EINVAL;
                        goto fail;
@@ -11529,3 +11645,24 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context
                        ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS,
                        (uint32_t *)operation_result);
 }
+
+/*
+ * Check whether seamless boot is supported.
+ *
+ * So far we only support seamless boot on CHIP_VANGOGH.
+ * If everything goes well, we may consider expanding
+ * seamless boot to other ASICs.
+ */
+bool check_seamless_boot_capability(struct amdgpu_device *adev)
+{
+       switch (adev->asic_type) {
+       case CHIP_VANGOGH:
+               if (!adev->mman.keep_stolen_vga_memory)
+                       return true;
+               break;
+       default:
+               break;
+       }
+
+       return false;
+}
index 37e61a88d49e287a8a489370f3dfe854dd29920c..bb65f41d1a59a1ff8bf038eaaae6349b8bb8601e 100644 (file)
@@ -731,4 +731,7 @@ extern const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs;
 int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux,
                                        struct dc_context *ctx, unsigned int link_index,
                                        void *payload, void *operation_result);
+
+bool check_seamless_boot_capability(struct amdgpu_device *adev);
+
 #endif /* __AMDGPU_DM_H__ */
index 8cbeeb7c986d03d3f1144bda5ef40c3b18a531bb..72a2e84645df2933c1b2a256a4e2c8768911707f 100644 (file)
@@ -584,7 +584,7 @@ bool dm_helpers_dp_write_dsc_enable(
                ret = drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1);
        }
 
-       if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
+       if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) {
                ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1);
                DC_LOG_DC("Send DSC %s to sst display\n", enable_dsc ? "enable" : "disable");
        }
index a4bef4364afd8d65688ba400c3c84a0aa6d683c6..1e385d55e7fbba5f0fe80f471518faa2aafbaa74 100644 (file)
@@ -2995,7 +2995,7 @@ static bool bios_parser2_construct(
                &bp->object_info_tbl.revision);
 
        if (bp->object_info_tbl.revision.major == 1
-               && bp->object_info_tbl.revision.minor >= 4) {
+               && bp->object_info_tbl.revision.minor == 4) {
                struct display_object_info_table_v1_4 *tbl_v1_4;
 
                tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
@@ -3004,8 +3004,10 @@ static bool bios_parser2_construct(
                        return false;
 
                bp->object_info_tbl.v1_4 = tbl_v1_4;
-       } else
+       } else {
+               ASSERT(0);
                return false;
+       }
 
        dal_firmware_parser_init_cmd_tbl(bp);
        dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
index 6b248cd2a461c686a2b0305cc49237a25dba70ba..c8b0a2f05b4d4bfd9bd9a95522451412d43b139d 100644 (file)
@@ -763,7 +763,7 @@ unsigned int get_highest_allowed_voltage_level(uint32_t chip_family, uint32_t hw
        return 4;
 }
 
-bool dcn_validate_bandwidth(
+bool dcn10_validate_bandwidth(
                struct dc *dc,
                struct dc_state *context,
                bool fast_validate)
index 26f96ee324729b4dec05a5055533b48164a0cabf..9200c8ce02ba917d6dc2a8b71645d2cf3776f9fa 100644 (file)
@@ -308,8 +308,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
        case FAMILY_NV:
                if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
                        dcn3_clk_mgr_destroy(clk_mgr);
-               }
-               if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
+               } else if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
                        dcn3_clk_mgr_destroy(clk_mgr);
                }
                if (ASICREV_IS_BEIGE_GOBY_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
index f4c9a458ace80d357f8ea18c2a4ca92b9d8641d5..a13ff1783b9b0367ac3b630debd9a944b9c40f7e 100644 (file)
@@ -66,7 +66,7 @@
 #define TO_CLK_MGR_DCN31(clk_mgr)\
        container_of(clk_mgr, struct clk_mgr_dcn31, base)
 
-int dcn31_get_active_display_cnt_wa(
+static int dcn31_get_active_display_cnt_wa(
                struct dc *dc,
                struct dc_state *context)
 {
@@ -118,7 +118,7 @@ static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
        }
 }
 
-static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
+void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
                        struct dc_state *context,
                        bool safe_to_lower)
 {
@@ -284,7 +284,7 @@ static void dcn31_enable_pme_wa(struct clk_mgr *clk_mgr_base)
        dcn31_smu_enable_pme_wa(clk_mgr);
 }
 
-static void dcn31_init_clocks(struct clk_mgr *clk_mgr)
+void dcn31_init_clocks(struct clk_mgr *clk_mgr)
 {
        memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
        // Assumption is that boot state always supports pstate
@@ -294,7 +294,7 @@ static void dcn31_init_clocks(struct clk_mgr *clk_mgr)
        clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
 }
 
-static bool dcn31_are_clock_states_equal(struct dc_clocks *a,
+bool dcn31_are_clock_states_equal(struct dc_clocks *a,
                struct dc_clocks *b)
 {
        if (a->dispclk_khz != b->dispclk_khz)
index f8f100535526df86985c4fb4d4ae1857e68e812a..961b10a494863e76fe80310ee99eadb036099ca3 100644 (file)
@@ -39,6 +39,13 @@ struct clk_mgr_dcn31 {
        struct dcn31_smu_watermark_set smu_wm_set;
 };
 
+bool dcn31_are_clock_states_equal(struct dc_clocks *a,
+               struct dc_clocks *b);
+void dcn31_init_clocks(struct clk_mgr *clk_mgr);
+void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
+                       struct dc_state *context,
+                       bool safe_to_lower);
+
 void dcn31_clk_mgr_construct(struct dc_context *ctx,
                struct clk_mgr_dcn31 *clk_mgr,
                struct pp_smu_funcs *pp_smu,
index 0ded4decee05fdc8a7149ab952453cf4135a4bc6..17b7408d84b70e1ac39c70675fa154be05cd9c0a 100644 (file)
@@ -221,9 +221,9 @@ static bool create_links(
                link = link_create(&link_init_params);
 
                if (link) {
-                               dc->links[dc->link_count] = link;
-                               link->dc = dc;
-                               ++dc->link_count;
+                       dc->links[dc->link_count] = link;
+                       link->dc = dc;
+                       ++dc->link_count;
                }
        }
 
@@ -808,6 +808,10 @@ void dc_stream_set_static_screen_params(struct dc *dc,
 
 static void dc_destruct(struct dc *dc)
 {
+       // reset link encoder assignment table on destruct
+       if (dc->res_pool->funcs->link_encs_assign)
+               link_enc_cfg_init(dc, dc->current_state);
+
        if (dc->current_state) {
                dc_release_state(dc->current_state);
                dc->current_state = NULL;
@@ -1016,8 +1020,6 @@ static bool dc_construct(struct dc *dc,
                goto fail;
        }
 
-       dc_resource_state_construct(dc, dc->current_state);
-
        if (!create_links(dc, init_params->num_virtual_links))
                goto fail;
 
@@ -1027,8 +1029,7 @@ static bool dc_construct(struct dc *dc,
        if (!create_link_encoders(dc))
                goto fail;
 
-       /* Initialise DIG link encoder resource tracking variables. */
-       link_enc_cfg_init(dc, dc->current_state);
+       dc_resource_state_construct(dc, dc->current_state);
 
        return true;
 
@@ -1830,6 +1831,19 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context)
                dc_stream_log(dc, stream);
        }
 
+       /*
+        * Previous validation was perfomred with fast_validation = true and
+        * the full DML state required for hardware programming was skipped.
+        *
+        * Re-validate here to calculate these parameters / watermarks.
+        */
+       result = dc_validate_global_state(dc, context, false);
+       if (result != DC_OK) {
+               DC_LOG_ERROR("DC commit global validation failure: %s (%d)",
+                            dc_status_to_str(result), result);
+               return result;
+       }
+
        result = dc_commit_state_no_check(dc, context);
 
        return (result == DC_OK);
@@ -2870,7 +2884,8 @@ static void commit_planes_for_stream(struct dc *dc,
 #endif
 
        if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
-               if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
+               if (top_pipe_to_program &&
+                       top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
                        if (should_use_dmub_lock(stream->link)) {
                                union dmub_hw_lock_flags hw_locks = { 0 };
                                struct dmub_hw_lock_inst_flags inst_flags = { 0 };
index 60544788e911ee15969e0cefa1aeb630cf1f3f44..3d08f8eba402e67614a240f09fd58fe70cece860 100644 (file)
@@ -270,10 +270,10 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
 
        /* Link may not have physical HPD pin. */
        if (link->ep_type != DISPLAY_ENDPOINT_PHY) {
-               if (link->hpd_status)
-                       *type = dc_connection_single;
-               else
+               if (link->is_hpd_pending || !link->hpd_status)
                        *type = dc_connection_none;
+               else
+                       *type = dc_connection_single;
 
                return true;
        }
@@ -1999,6 +1999,57 @@ static enum dc_status enable_link_dp_mst(
        return enable_link_dp(state, pipe_ctx);
 }
 
+void dc_link_blank_all_dp_displays(struct dc *dc)
+{
+       unsigned int i;
+       uint8_t dpcd_power_state = '\0';
+       enum dc_status status = DC_ERROR_UNEXPECTED;
+
+       for (i = 0; i < dc->link_count; i++) {
+               if ((dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) ||
+                       (dc->links[i]->priv == NULL) || (dc->links[i]->local_sink == NULL))
+                       continue;
+
+               /* DP 2.0 spec requires that we read LTTPR caps first */
+               dp_retrieve_lttpr_cap(dc->links[i]);
+               /* if any of the displays are lit up turn them off */
+               status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
+                                                       &dpcd_power_state, sizeof(dpcd_power_state));
+
+               if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0)
+                       dc_link_blank_dp_stream(dc->links[i], true);
+       }
+
+}
+
+void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init)
+{
+       unsigned int j;
+       struct dc  *dc = link->ctx->dc;
+       enum signal_type signal = link->connector_signal;
+
+       if ((signal == SIGNAL_TYPE_EDP) ||
+               (signal == SIGNAL_TYPE_DISPLAY_PORT)) {
+               if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
+                       link->link_enc->funcs->get_dig_frontend &&
+                       link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
+                       unsigned int fe = link->link_enc->funcs->get_dig_frontend(link->link_enc);
+
+                       if (fe != ENGINE_ID_UNKNOWN)
+                               for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
+                                       if (fe == dc->res_pool->stream_enc[j]->id) {
+                                               dc->res_pool->stream_enc[j]->funcs->dp_blank(link,
+                                                                       dc->res_pool->stream_enc[j]);
+                                               break;
+                                       }
+                               }
+               }
+
+               if ((!link->wa_flags.dp_keep_receiver_powered) || hw_init)
+                       dp_receiver_power_ctrl(link, false);
+       }
+}
+
 static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
                enum engine_id eng_id,
                struct ext_hdmi_settings *settings)
@@ -2946,7 +2997,7 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active
                link->psr_settings.psr_power_opt = *power_opts;
 
                if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt)
-                       psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt);
+                       psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt, panel_inst);
        }
 
        /* Enable or Disable PSR */
@@ -3913,9 +3964,6 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
        struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
        struct link_encoder *link_enc = NULL;
-       struct dc_state *state = pipe_ctx->stream->ctx->dc->current_state;
-       struct link_enc_assignment link_enc_assign;
-       int i;
 #endif
 
        if (cp_psp && cp_psp->funcs.update_stream_config) {
@@ -3943,18 +3991,15 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
                                                        pipe_ctx->stream->ctx->dc,
                                                        pipe_ctx->stream);
                        }
+                       ASSERT(link_enc);
+
                        // Initialize PHY ID with ABCDE - 01234 mapping except when it is B0
                        config.phy_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
 
-                       //look up the link_enc_assignment for the current pipe_ctx
-                       for (i = 0; i < state->stream_count; i++) {
-                               if (pipe_ctx->stream == state->streams[i]) {
-                                       link_enc_assign = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
-                               }
-                       }
                        // Add flag to guard new A0 DIG mapping
-                       if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 == true) {
-                               config.dig_be = link_enc_assign.eng_id;
+                       if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 == true &&
+                                       pipe_ctx->stream->link->dc->ctx->dce_version == DCN_VERSION_3_1) {
+                               config.dig_be = link_enc->preferred_engine;
                                config.dio_output_type = pipe_ctx->stream->link->ep_type;
                                config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
                        } else {
@@ -3966,10 +4011,8 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
                        if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 == true &&
                                        link_enc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
                                if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
-                                       link_enc = link_enc_assign.stream->link_enc;
-
                                        // enum ID 1-4 maps to DPIA PHY ID 0-3
-                                       config.phy_idx = link_enc_assign.ep_id.link_id.enum_id - ENUM_ID_1;
+                                       config.phy_idx = pipe_ctx->stream->link->link_id.enum_id - ENUM_ID_1;
                                } else {  // for non DPIA mode over B0, ABCDE maps to 01564
 
                                        switch (link_enc->transmitter) {
@@ -4242,7 +4285,8 @@ void core_link_enable_stream(
                /* eDP lit up by bios already, no need to enable again. */
                if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
                                        apply_edp_fast_boot_optimization &&
-                                       !pipe_ctx->stream->timing.flags.DSC) {
+                                       !pipe_ctx->stream->timing.flags.DSC &&
+                                       !pipe_ctx->next_odm_pipe) {
                        pipe_ctx->stream->dpms_off = false;
 #if defined(CONFIG_DRM_AMD_DC_HDCP)
                        update_psp_stream_config(pipe_ctx, false);
@@ -4749,6 +4793,8 @@ bool dc_link_should_enable_fec(const struct dc_link *link)
                        link->local_sink &&
                        link->local_sink->edid_caps.panel_patch.disable_fec) ||
                        (link->connector_signal == SIGNAL_TYPE_EDP
+                               // enable FEC for EDP if DSC is supported
+                               && link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT == false
                                ))
                is_fec_disable = true;
 
index 60539b1f2a80a155d2927f0d8693dc8fc823bf1e..24dc662ec3e4523880a000b1625ebf0b6b123c0c 100644 (file)
@@ -626,7 +626,7 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
        do {
                struct aux_payload current_payload;
                bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) >=
-                               payload->length ? true : false;
+                               payload->length;
                uint32_t payload_length = is_end_of_payload ?
                                payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE;
 
index cb7bf9148904edb02534b01db8ca1e8f90b966c8..84f3545c3032996dbdffa18064902a2502b4b0d4 100644 (file)
@@ -430,7 +430,7 @@ enum dc_status dpcd_set_link_settings(
        status = core_link_write_dpcd(link, DP_LANE_COUNT_SET,
                &lane_count_set.raw, 1);
 
-       if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
+       if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_13 &&
                        lt_settings->link_settings.use_link_rate_set == true) {
                rate = 0;
                /* WA for some MUX chips that will power down with eDP and lose supported
@@ -3346,6 +3346,148 @@ bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settings *lin
        return false;
 }
 
+static bool decide_edp_link_settings_with_dsc(struct dc_link *link,
+               struct dc_link_settings *link_setting,
+               uint32_t req_bw,
+               enum dc_link_rate max_link_rate)
+{
+       struct dc_link_settings initial_link_setting;
+       struct dc_link_settings current_link_setting;
+       uint32_t link_bw;
+
+       unsigned int policy = 0;
+
+       policy = link->ctx->dc->debug.force_dsc_edp_policy;
+       if (max_link_rate == LINK_RATE_UNKNOWN)
+               max_link_rate = link->verified_link_cap.link_rate;
+       /*
+        * edp_supported_link_rates_count is only valid for eDP v1.4 or higher.
+        * Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h"
+        */
+       if ((link->dpcd_caps.dpcd_rev.raw < DPCD_REV_13 ||
+                       link->dpcd_caps.edp_supported_link_rates_count == 0)) {
+               /* for DSC enabled case, we search for minimum lane count */
+               memset(&initial_link_setting, 0, sizeof(initial_link_setting));
+               initial_link_setting.lane_count = LANE_COUNT_ONE;
+               initial_link_setting.link_rate = LINK_RATE_LOW;
+               initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
+               initial_link_setting.use_link_rate_set = false;
+               initial_link_setting.link_rate_set = 0;
+               current_link_setting = initial_link_setting;
+               if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap))
+                       return false;
+
+               /* search for the minimum link setting that:
+                * 1. is supported according to the link training result
+                * 2. could support the b/w requested by the timing
+                */
+               while (current_link_setting.link_rate <=
+                               max_link_rate) {
+                       link_bw = dc_link_bandwidth_kbps(
+                                       link,
+                                       &current_link_setting);
+                       if (req_bw <= link_bw) {
+                               *link_setting = current_link_setting;
+                               return true;
+                       }
+                       if (policy) {
+                               /* minimize lane */
+                               if (current_link_setting.link_rate < max_link_rate) {
+                                       current_link_setting.link_rate =
+                                                       increase_link_rate(
+                                                                       current_link_setting.link_rate);
+                               } else {
+                                       if (current_link_setting.lane_count <
+                                                                       link->verified_link_cap.lane_count) {
+                                               current_link_setting.lane_count =
+                                                               increase_lane_count(
+                                                                               current_link_setting.lane_count);
+                                               current_link_setting.link_rate = initial_link_setting.link_rate;
+                                       } else
+                                               break;
+                               }
+                       } else {
+                               /* minimize link rate */
+                               if (current_link_setting.lane_count <
+                                               link->verified_link_cap.lane_count) {
+                                       current_link_setting.lane_count =
+                                                       increase_lane_count(
+                                                                       current_link_setting.lane_count);
+                               } else {
+                                       current_link_setting.link_rate =
+                                                       increase_link_rate(
+                                                                       current_link_setting.link_rate);
+                                       current_link_setting.lane_count =
+                                                       initial_link_setting.lane_count;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       /* if optimize edp link is supported */
+       memset(&initial_link_setting, 0, sizeof(initial_link_setting));
+       initial_link_setting.lane_count = LANE_COUNT_ONE;
+       initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0];
+       initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
+       initial_link_setting.use_link_rate_set = true;
+       initial_link_setting.link_rate_set = 0;
+       current_link_setting = initial_link_setting;
+
+       /* search for the minimum link setting that:
+        * 1. is supported according to the link training result
+        * 2. could support the b/w requested by the timing
+        */
+       while (current_link_setting.link_rate <=
+                       max_link_rate) {
+               link_bw = dc_link_bandwidth_kbps(
+                               link,
+                               &current_link_setting);
+               if (req_bw <= link_bw) {
+                       *link_setting = current_link_setting;
+                       return true;
+               }
+               if (policy) {
+                       /* minimize lane */
+                       if (current_link_setting.link_rate_set <
+                                       link->dpcd_caps.edp_supported_link_rates_count
+                                       && current_link_setting.link_rate < max_link_rate) {
+                               current_link_setting.link_rate_set++;
+                               current_link_setting.link_rate =
+                                       link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
+                       } else {
+                               if (current_link_setting.lane_count < link->verified_link_cap.lane_count) {
+                                       current_link_setting.lane_count =
+                                                       increase_lane_count(
+                                                                       current_link_setting.lane_count);
+                                       current_link_setting.link_rate_set = initial_link_setting.link_rate_set;
+                                       current_link_setting.link_rate =
+                                               link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
+                               } else
+                                       break;
+                       }
+               } else {
+                       /* minimize link rate */
+                       if (current_link_setting.lane_count <
+                                       link->verified_link_cap.lane_count) {
+                               current_link_setting.lane_count =
+                                               increase_lane_count(
+                                                               current_link_setting.lane_count);
+                       } else {
+                               if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
+                                       current_link_setting.link_rate_set++;
+                                       current_link_setting.link_rate =
+                                               link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
+                                       current_link_setting.lane_count =
+                                               initial_link_setting.lane_count;
+                               } else
+                                       break;
+                       }
+               }
+       }
+       return false;
+}
+
 static bool decide_mst_link_settings(const struct dc_link *link, struct dc_link_settings *link_setting)
 {
        *link_setting = link->verified_link_cap;
@@ -3380,7 +3522,25 @@ void decide_link_settings(struct dc_stream_state *stream,
                if (decide_mst_link_settings(link, link_setting))
                        return;
        } else if (link->connector_signal == SIGNAL_TYPE_EDP) {
-               if (decide_edp_link_settings(link, link_setting, req_bw))
+               /* enable edp link optimization for DSC eDP case */
+               if (stream->timing.flags.DSC) {
+                       enum dc_link_rate max_link_rate = LINK_RATE_UNKNOWN;
+
+                       if (link->ctx->dc->debug.force_dsc_edp_policy) {
+                               /* calculate link max link rate cap*/
+                               struct dc_link_settings tmp_link_setting;
+                               struct dc_crtc_timing tmp_timing = stream->timing;
+                               uint32_t orig_req_bw;
+
+                               tmp_link_setting.link_rate = LINK_RATE_UNKNOWN;
+                               tmp_timing.flags.DSC = 0;
+                               orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing);
+                               decide_edp_link_settings(link, &tmp_link_setting, orig_req_bw);
+                               max_link_rate = tmp_link_setting.link_rate;
+                       }
+                       if (decide_edp_link_settings_with_dsc(link, link_setting, req_bw, max_link_rate))
+                               return;
+               } else if (decide_edp_link_settings(link, link_setting, req_bw))
                        return;
        } else if (decide_dp_link_settings(link, link_setting, req_bw))
                return;
@@ -4454,7 +4614,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
                                lttpr_dpcd_data,
                                sizeof(lttpr_dpcd_data));
                if (status != DC_OK) {
-                       dm_error("%s: Read LTTPR caps data failed.\n", __func__);
+                       DC_LOG_DP2("%s: Read LTTPR caps data failed.\n", __func__);
                        return false;
                }
 
@@ -5885,7 +6045,10 @@ bool is_edp_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timin
 
        req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing);
 
-       decide_edp_link_settings(link, &link_setting, req_bw);
+       if (!crtc_timing->flags.DSC)
+               decide_edp_link_settings(link, &link_setting, req_bw);
+       else
+               decide_edp_link_settings_with_dsc(link, &link_setting, req_bw, LINK_RATE_UNKNOWN);
 
        if (link->dpcd_caps.edp_supported_link_rates[link_rate_set] != link_setting.link_rate ||
                        lane_count_set.bits.LANE_COUNT_SET != link_setting.lane_count) {
index b1c9f77d6bf4331681b1b4dc7592c7257275fce2..d721225939594028b539daa089b9d2c798c5c449 100644 (file)
@@ -94,17 +94,17 @@ static enum link_training_result dpia_configure_link(struct dc_link *link,
                lt_settings);
 
        status = dpcd_configure_channel_coding(link, lt_settings);
-       if (status != DC_OK && !link->hpd_status)
+       if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
        /* Configure lttpr mode */
        status = dpcd_configure_lttpr_mode(link, lt_settings);
-       if (status != DC_OK && !link->hpd_status)
+       if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
        /* Set link rate, lane count and spread. */
        status = dpcd_set_link_settings(link, lt_settings);
-       if (status != DC_OK && !link->hpd_status)
+       if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
        if (link->preferred_training_settings.fec_enable)
@@ -112,7 +112,7 @@ static enum link_training_result dpia_configure_link(struct dc_link *link,
        else
                fec_enable = true;
        status = dp_set_fec_ready(link, fec_enable);
-       if (status != DC_OK && !link->hpd_status)
+       if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
        return LINK_TRAINING_SUCCESS;
@@ -388,7 +388,7 @@ static enum link_training_result dpia_training_cr_non_transparent(struct dc_link
        }
 
        /* Abort link training if clock recovery failed due to HPD unplug. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                result = LINK_TRAINING_ABORT;
 
        DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) clock recovery\n"
@@ -490,7 +490,7 @@ static enum link_training_result dpia_training_cr_transparent(struct dc_link *li
        }
 
        /* Abort link training if clock recovery failed due to HPD unplug. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                result = LINK_TRAINING_ABORT;
 
        DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) clock recovery\n"
@@ -675,7 +675,7 @@ static enum link_training_result dpia_training_eq_non_transparent(struct dc_link
        }
 
        /* Abort link training if equalization failed due to HPD unplug. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                result = LINK_TRAINING_ABORT;
 
        DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) equalization\n"
@@ -758,7 +758,7 @@ static enum link_training_result dpia_training_eq_transparent(struct dc_link *li
        }
 
        /* Abort link training if equalization failed due to HPD unplug. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                result = LINK_TRAINING_ABORT;
 
        DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) equalization\n"
@@ -892,10 +892,10 @@ static void dpia_training_abort(struct dc_link *link, uint32_t hop)
                                __func__,
                                link->link_id.enum_id - ENUM_ID_1,
                                link->lttpr_mode,
-                               link->hpd_status);
+                               link->is_hpd_pending);
 
        /* Abandon clean-up if sink unplugged. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                return;
 
        if (hop != DPRX)
index 25e48a8cbb78d21db02169612c64b4320fc39f7f..a55944da8d53fbb18da1d9e237c21b9234163e09 100644 (file)
@@ -118,7 +118,10 @@ static void remove_link_enc_assignment(
                                 */
                                if (get_stream_using_link_enc(state, eng_id) == NULL)
                                        state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] = eng_id;
+
                                stream->link_enc = NULL;
+                               state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id = ENGINE_ID_UNKNOWN;
+                               state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream = NULL;
                                break;
                        }
                }
@@ -148,6 +151,7 @@ static void add_link_enc_assignment(
                                                .ep_type = stream->link->ep_type},
                                        .eng_id = eng_id,
                                        .stream = stream};
+                               dc_stream_retain(stream);
                                state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] = ENGINE_ID_UNKNOWN;
                                stream->link_enc = stream->ctx->dc->res_pool->link_encoders[eng_idx];
                                break;
@@ -227,7 +231,7 @@ static struct link_encoder *get_link_enc_used_by_link(
                .link_id = link->link_id,
                .ep_type = link->ep_type};
 
-       for (i = 0; i < state->stream_count; i++) {
+       for (i = 0; i < MAX_PIPES; i++) {
                struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
 
                if (assignment.valid == true && are_ep_ids_equal(&assignment.ep_id, &ep_id))
@@ -237,28 +241,18 @@ static struct link_encoder *get_link_enc_used_by_link(
        return link_enc;
 }
 /* Clear all link encoder assignments. */
-static void clear_enc_assignments(struct dc_state *state)
+static void clear_enc_assignments(const struct dc *dc, struct dc_state *state)
 {
        int i;
-       enum engine_id eng_id;
-       struct dc_stream_state *stream;
 
        for (i = 0; i < MAX_PIPES; i++) {
                state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid = false;
-               eng_id = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id;
-               stream = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream;
-               if (eng_id != ENGINE_ID_UNKNOWN)
-                       state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_id - ENGINE_ID_DIGA] = eng_id;
-               if (stream)
-                       stream->link_enc = NULL;
+               state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id = ENGINE_ID_UNKNOWN;
+               if (state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream != NULL) {
+                       dc_stream_release(state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream);
+                       state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream = NULL;
+               }
        }
-}
-
-void link_enc_cfg_init(
-               struct dc *dc,
-               struct dc_state *state)
-{
-       int i;
 
        for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) {
                if (dc->res_pool->link_encoders[i])
@@ -266,8 +260,13 @@ void link_enc_cfg_init(
                else
                        state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i] = ENGINE_ID_UNKNOWN;
        }
+}
 
-       clear_enc_assignments(state);
+void link_enc_cfg_init(
+               const struct dc *dc,
+               struct dc_state *state)
+{
+       clear_enc_assignments(dc, state);
 
        state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY;
 }
@@ -284,12 +283,9 @@ void link_enc_cfg_link_encs_assign(
 
        ASSERT(state->stream_count == stream_count);
 
-       if (stream_count == 0)
-               clear_enc_assignments(state);
-
        /* Release DIG link encoder resources before running assignment algorithm. */
-       for (i = 0; i < stream_count; i++)
-               dc->res_pool->funcs->link_enc_unassign(state, streams[i]);
+       for (i = 0; i < dc->current_state->stream_count; i++)
+               dc->res_pool->funcs->link_enc_unassign(state, dc->current_state->streams[i]);
 
        for (i = 0; i < MAX_PIPES; i++)
                ASSERT(state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid == false);
@@ -544,6 +540,7 @@ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state)
        uint8_t dig_stream_count = 0;
        int matching_stream_ptrs = 0;
        int eng_ids_per_ep_id[MAX_PIPES] = {0};
+       int valid_bitmap = 0;
 
        /* (1) No. valid entries same as stream count. */
        for (i = 0; i < MAX_PIPES; i++) {
@@ -625,5 +622,15 @@ bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state)
        is_valid = valid_entries && valid_stream_ptrs && valid_uniqueness && valid_avail && valid_streams;
        ASSERT(is_valid);
 
+       if (is_valid == false) {
+               valid_bitmap =
+                       (valid_entries & 0x1) |
+                       ((valid_stream_ptrs & 0x1) << 1) |
+                       ((valid_uniqueness & 0x1) << 2) |
+                       ((valid_avail & 0x1) << 3) |
+                       ((valid_streams & 0x1) << 4);
+               dm_error("Invalid link encoder assignments: 0x%x\n", valid_bitmap);
+       }
+
        return is_valid;
 }
index c32fdccd4d925c96b4f1bda165453d29a0340feb..1da91f250afa050b8e4df9e01b30d96cfbe4213f 100644 (file)
@@ -2078,7 +2078,6 @@ static void mark_seamless_boot_stream(
 {
        struct dc_bios *dcb = dc->ctx->dc_bios;
 
-       /* TODO: Check Linux */
        if (dc->config.allow_seamless_boot_optimization &&
                        !dcb->funcs->is_accelerated_mode(dcb)) {
                if (dc_validate_seamless_boot_timing(dc, stream->sink, &stream->timing))
@@ -2224,6 +2223,9 @@ void dc_resource_state_construct(
                struct dc_state *dst_ctx)
 {
        dst_ctx->clk_mgr = dc->clk_mgr;
+
+       /* Initialise DIG link encoder resource tracking variables. */
+       link_enc_cfg_init(dc, dst_ctx);
 }
 
 
@@ -2506,17 +2508,7 @@ static void set_avi_info_frame(
 
        /* TODO : We should handle YCC quantization */
        /* but we do not have matrix calculation */
-       if (stream->qy_bit == 1) {
-               if (color_space == COLOR_SPACE_SRGB ||
-                       color_space == COLOR_SPACE_2020_RGB_FULLRANGE)
-                       hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
-               else if (color_space == COLOR_SPACE_SRGB_LIMITED ||
-                                       color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE)
-                       hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
-               else
-                       hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
-       } else
-               hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
+       hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
 
        ///VIC
        format = stream->timing.timing_3d_format;
index a249a0e5edd0ff6b67894af5b557c561ac8f6200..4b5e4d8e7735e5b2e2e4d2e7447c719405d904cf 100644 (file)
  * Private functions
  ******************************************************************************/
 
-static void dc_sink_destruct(struct dc_sink *sink)
-{
-       if (sink->dc_container_id) {
-               kfree(sink->dc_container_id);
-               sink->dc_container_id = NULL;
-       }
-}
-
 static bool dc_sink_construct(struct dc_sink *sink, const struct dc_sink_init_data *init_params)
 {
 
@@ -75,7 +67,7 @@ void dc_sink_retain(struct dc_sink *sink)
 static void dc_sink_free(struct kref *kref)
 {
        struct dc_sink *sink = container_of(kref, struct dc_sink, refcount);
-       dc_sink_destruct(sink);
+       kfree(sink->dc_container_id);
        kfree(sink);
 }
 
index 3aac3f4a28525623382f21dd934dd39851baf1af..c14e7db3f69d14aa954dd657606f409203de1e48 100644 (file)
@@ -47,7 +47,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.160"
+#define DC_VER "3.2.163"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
@@ -188,6 +188,7 @@ struct dc_caps {
 #if defined(CONFIG_DRM_AMD_DC_DCN)
        bool dp_hpo;
 #endif
+       bool edp_dsc_support;
        bool vbios_lttpr_aware;
        bool vbios_lttpr_enable;
 };
@@ -573,6 +574,8 @@ struct dc_debug_options {
        bool native422_support;
        bool disable_dsc;
        enum visual_confirm visual_confirm;
+       int visual_confirm_rect_height;
+
        bool sanity_checks;
        bool max_disp_clk;
        bool surface_trace;
@@ -667,6 +670,8 @@ struct dc_debug_options {
        bool validate_dml_output;
        bool enable_dmcub_surface_flip;
        bool usbc_combo_phy_reset_wa;
+       bool disable_dsc_edp;
+       unsigned int  force_dsc_edp_policy;
        bool enable_dram_clock_change_one_display_vactive;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
        /* TODO - remove once tested */
index 360f3199ea6fa1d41c526091ddb8d2f3c19061b4..541376fabbef16a3ecbdf828bc6f09fa32ab87c3 100644 (file)
@@ -115,13 +115,44 @@ void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv)
        }
 }
 
+void dc_dmub_srv_clear_inbox0_ack(struct dc_dmub_srv *dmub_srv)
+{
+       struct dmub_srv *dmub = dmub_srv->dmub;
+       struct dc_context *dc_ctx = dmub_srv->ctx;
+       enum dmub_status status = DMUB_STATUS_OK;
+
+       status = dmub_srv_clear_inbox0_ack(dmub);
+       if (status != DMUB_STATUS_OK) {
+               DC_ERROR("Error clearing INBOX0 ack: status=%d\n", status);
+               dc_dmub_srv_log_diagnostic_data(dmub_srv);
+       }
+}
+
+void dc_dmub_srv_wait_for_inbox0_ack(struct dc_dmub_srv *dmub_srv)
+{
+       struct dmub_srv *dmub = dmub_srv->dmub;
+       struct dc_context *dc_ctx = dmub_srv->ctx;
+       enum dmub_status status = DMUB_STATUS_OK;
+
+       status = dmub_srv_wait_for_inbox0_ack(dmub, 100000);
+       if (status != DMUB_STATUS_OK) {
+               DC_ERROR("Error waiting for INBOX0 HW Lock Ack\n");
+               dc_dmub_srv_log_diagnostic_data(dmub_srv);
+       }
+}
+
 void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
                union dmub_inbox0_data_register data)
 {
        struct dmub_srv *dmub = dmub_srv->dmub;
-       if (dmub->hw_funcs.send_inbox0_cmd)
-               dmub->hw_funcs.send_inbox0_cmd(dmub, data);
-       // TODO: Add wait command -- poll register for ACK
+       struct dc_context *dc_ctx = dmub_srv->ctx;
+       enum dmub_status status = DMUB_STATUS_OK;
+
+       status = dmub_srv_send_inbox0_cmd(dmub, data);
+       if (status != DMUB_STATUS_OK) {
+               DC_ERROR("Error sending INBOX0 cmd\n");
+               dc_dmub_srv_log_diagnostic_data(dmub_srv);
+       }
 }
 
 bool dc_dmub_srv_cmd_with_reply_data(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd)
index 3e35eee7188c539e11e39c61bad99f811a7374ce..7e4e2ec5915d27d3f84095869aedbe8c119c0eed 100644 (file)
@@ -68,6 +68,8 @@ bool dc_dmub_srv_get_dmub_outbox0_msg(const struct dc *dc, struct dmcub_trace_bu
 
 void dc_dmub_trace_event_control(struct dc *dc, bool enable);
 
+void dc_dmub_srv_clear_inbox0_ack(struct dc_dmub_srv *dmub_srv);
+void dc_dmub_srv_wait_for_inbox0_ack(struct dc_dmub_srv *dmub_srv);
 void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv, union dmub_inbox0_data_register data);
 
 bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmub_diagnostic_data *dmub_oca);
index 180ecd860296b250fe40f6d040d6a2a33bb88817..d449e72a4e2a92c675d4034b8a059749d0206953 100644 (file)
@@ -113,6 +113,7 @@ struct dc_link {
         * DIG encoder. */
        bool is_dig_mapping_flexible;
        bool hpd_status; /* HPD status of link without physical HPD pin. */
+       bool is_hpd_pending; /* Indicates a new received hpd */
 
        bool edp_sink_present;
 
@@ -287,6 +288,10 @@ bool dc_link_setup_psr(struct dc_link *dc_link,
 
 void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency);
 
+void dc_link_blank_all_dp_displays(struct dc *dc);
+
+void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init);
+
 /* Request DC to detect if there is a Panel connected.
  * boot - If this call is during initial boot.
  * Return false for any type of detection failure or MST detection
@@ -298,7 +303,7 @@ enum dc_detect_reason {
        DETECT_REASON_HPD,
        DETECT_REASON_HPDRX,
        DETECT_REASON_FALLBACK,
-       DETECT_REASON_RETRAIN
+       DETECT_REASON_RETRAIN,
 };
 
 bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
index 27218ede150a9368b25bedfd56a69ad8075ab7f3..70eaac0176242c86bd7afeba431e856f86915bd0 100644 (file)
@@ -67,9 +67,6 @@ static void write_indirect_azalia_reg(struct audio *audio,
        /* AZALIA_F0_CODEC_ENDPOINT_DATA  endpoint data  */
        REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0,
                        AZALIA_ENDPOINT_REG_DATA, reg_data);
-
-       DC_LOG_HW_AUDIO("AUDIO:write_indirect_azalia_reg: index: %u  data: %u\n",
-               reg_index, reg_data);
 }
 
 static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index)
@@ -85,9 +82,6 @@ static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index
        /* AZALIA_F0_CODEC_ENDPOINT_DATA  endpoint data  */
        value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA);
 
-       DC_LOG_HW_AUDIO("AUDIO:read_indirect_azalia_reg: index: %u  data: %u\n",
-               reg_index, value);
-
        return value;
 }
 
index 5622d5e32d81896fa545b4cbe51695343f415988..dbd2cfed0603085f25a67ca3700588716afb6cc0 100644 (file)
@@ -113,6 +113,7 @@ struct dce_audio_shift {
        uint8_t DCCG_AUDIO_DTO2_USE_512FBR_DTO;
        uint32_t DCCG_AUDIO_DTO0_USE_512FBR_DTO;
        uint32_t DCCG_AUDIO_DTO1_USE_512FBR_DTO;
+       uint32_t CLOCK_GATING_DISABLE;
 };
 
 struct dce_audio_mask {
@@ -132,6 +133,7 @@ struct dce_audio_mask {
        uint32_t DCCG_AUDIO_DTO2_USE_512FBR_DTO;
        uint32_t DCCG_AUDIO_DTO0_USE_512FBR_DTO;
        uint32_t DCCG_AUDIO_DTO1_USE_512FBR_DTO;
+       uint32_t CLOCK_GATING_DISABLE;
 
 };
 
index 9baf8ca0a920f82d4efcd318c332cb62423e4da5..b1b2e3c6f379d13c75ff7075a884c70e45ed29a6 100644 (file)
@@ -56,8 +56,11 @@ void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
                union dmub_inbox0_cmd_lock_hw hw_lock_cmd)
 {
        union dmub_inbox0_data_register data = { 0 };
+
        data.inbox0_cmd_lock_hw = hw_lock_cmd;
+       dc_dmub_srv_clear_inbox0_ack(dmub_srv);
        dc_dmub_srv_send_inbox0_cmd(dmub_srv, data);
+       dc_dmub_srv_wait_for_inbox0_ack(dmub_srv);
 }
 
 bool should_use_dmub_lock(struct dc_link *link)
index 90eb8eedacf2a7dae7ea439d4e2177f124559136..87ed48d5530dc7b51507350d26d0f8f2bc4efa40 100644 (file)
@@ -230,7 +230,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_
 /**
  * Set PSR power optimization flags.
  */
-static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt)
+static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt, uint8_t panel_inst)
 {
        union dmub_rb_cmd cmd;
        struct dc_context *dc = dmub->ctx;
@@ -239,7 +239,9 @@ static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt
        cmd.psr_set_power_opt.header.type = DMUB_CMD__PSR;
        cmd.psr_set_power_opt.header.sub_type = DMUB_CMD__SET_PSR_POWER_OPT;
        cmd.psr_set_power_opt.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_power_opt_data);
+       cmd.psr_set_power_opt.psr_set_power_opt_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
        cmd.psr_set_power_opt.psr_set_power_opt_data.power_opt = power_opt;
+       cmd.psr_set_power_opt.psr_set_power_opt_data.panel_inst = panel_inst;
 
        dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
        dc_dmub_srv_cmd_execute(dc->dmub_srv);
@@ -327,6 +329,16 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
        copy_settings_data->fec_enable_delay_in100us = link->dc->debug.fec_enable_delay_in100us;
        copy_settings_data->cmd_version =  DMUB_CMD_PSR_CONTROL_VERSION_1;
        copy_settings_data->panel_inst = panel_inst;
+       copy_settings_data->dsc_enable_status = (pipe_ctx->stream->timing.flags.DSC == 1);
+
+       if (link->fec_state == dc_link_fec_enabled &&
+               (!memcmp(link->dpcd_caps.sink_dev_id_str, DP_SINK_DEVICE_STR_ID_1,
+                       sizeof(link->dpcd_caps.sink_dev_id_str)) ||
+               !memcmp(link->dpcd_caps.sink_dev_id_str, DP_SINK_DEVICE_STR_ID_2,
+                       sizeof(link->dpcd_caps.sink_dev_id_str))))
+               copy_settings_data->debug.bitfields.force_wakeup_by_tps3 = 1;
+       else
+               copy_settings_data->debug.bitfields.force_wakeup_by_tps3 = 0;
 
        dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
        dc_dmub_srv_cmd_execute(dc->dmub_srv);
index 5dbd479660f1aff522987ab8e8c6d4800c946504..01acc01cc191127d2ea47010b4141edf4ff77d4c 100644 (file)
@@ -46,7 +46,7 @@ struct dmub_psr_funcs {
        void (*psr_force_static)(struct dmub_psr *dmub, uint8_t panel_inst);
        void (*psr_get_residency)(struct dmub_psr *dmub, uint32_t *residency,
        uint8_t panel_inst);
-       void (*psr_set_power_opt)(struct dmub_psr *dmub, unsigned int power_opt);
+       void (*psr_set_power_opt)(struct dmub_psr *dmub, unsigned int power_opt, uint8_t panel_inst);
 };
 
 struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
index 24e47df526f6a08c3a56556d1d030c2834f00a71..3d421583e9ca3821cd122976e3ab7b38c36a42b3 100644 (file)
@@ -1602,6 +1602,11 @@ static enum dc_status apply_single_controller_ctx_to_hw(
                        pipe_ctx->stream_res.stream_enc,
                        pipe_ctx->stream_res.tg->inst);
 
+       if (dc_is_dp_signal(pipe_ctx->stream->signal) &&
+               pipe_ctx->stream_res.stream_enc->funcs->reset_fifo)
+               pipe_ctx->stream_res.stream_enc->funcs->reset_fifo(
+                       pipe_ctx->stream_res.stream_enc);
+
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
                dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
 
@@ -1655,30 +1660,12 @@ static enum dc_status apply_single_controller_ctx_to_hw(
 
 static void power_down_encoders(struct dc *dc)
 {
-       int i, j;
+       int i;
 
        for (i = 0; i < dc->link_count; i++) {
                enum signal_type signal = dc->links[i]->connector_signal;
 
-               if ((signal == SIGNAL_TYPE_EDP) ||
-                       (signal == SIGNAL_TYPE_DISPLAY_PORT)) {
-                       if (dc->links[i]->link_enc->funcs->get_dig_frontend &&
-                               dc->links[i]->link_enc->funcs->is_dig_enabled(dc->links[i]->link_enc)) {
-                               unsigned int fe = dc->links[i]->link_enc->funcs->get_dig_frontend(
-                                                                       dc->links[i]->link_enc);
-
-                               for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
-                                       if (fe == dc->res_pool->stream_enc[j]->id) {
-                                               dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
-                                                                       dc->res_pool->stream_enc[j]);
-                                               break;
-                                       }
-                               }
-                       }
-
-                       if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
-                               dp_receiver_power_ctrl(dc->links[i], false);
-               }
+               dc_link_blank_dp_stream(dc->links[i], false);
 
                if (signal != SIGNAL_TYPE_EDP)
                        signal = SIGNAL_TYPE_NONE;
@@ -1846,7 +1833,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
                        }
                }
                // We are trying to enable eDP, don't power down VDD
-               if (edp_stream_num)
+               if (edp_stream_num && can_apply_edp_fast_boot)
                        keep_edp_vdd_on = true;
        }
 
index 44293d66b46bd66d7e28290da78a23996f7203f4..e31a6f1516bb50462d490041a72b8b0cd6294578 100644 (file)
 #define BLACK_OFFSET_RGB_Y 0x0
 #define BLACK_OFFSET_CBCR  0x8000
 
+#define VISUAL_CONFIRM_RECT_HEIGHT_DEFAULT 3
+#define VISUAL_CONFIRM_RECT_HEIGHT_MIN 1
+#define VISUAL_CONFIRM_RECT_HEIGHT_MAX 10
+
 #define REG(reg)\
        dpp->tf_regs->reg
 
@@ -685,9 +689,17 @@ static void dpp1_dscl_set_recout(struct dcn10_dpp *dpp,
                                 const struct rect *recout)
 {
        int visual_confirm_on = 0;
+       unsigned short visual_confirm_rect_height = VISUAL_CONFIRM_RECT_HEIGHT_DEFAULT;
+
        if (dpp->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE)
                visual_confirm_on = 1;
 
+       /* Check bounds to ensure the VC bar height was set to a sane value */
+       if ((dpp->base.ctx->dc->debug.visual_confirm_rect_height >= VISUAL_CONFIRM_RECT_HEIGHT_MIN) &&
+                       (dpp->base.ctx->dc->debug.visual_confirm_rect_height <= VISUAL_CONFIRM_RECT_HEIGHT_MAX)) {
+               visual_confirm_rect_height = dpp->base.ctx->dc->debug.visual_confirm_rect_height;
+       }
+
        REG_SET_2(RECOUT_START, 0,
                  /* First pixel of RECOUT in the active OTG area */
                  RECOUT_START_X, recout->x,
@@ -699,7 +711,7 @@ static void dpp1_dscl_set_recout(struct dcn10_dpp *dpp,
                  RECOUT_WIDTH, recout->width,
                  /* Number of RECOUT vertical lines */
                  RECOUT_HEIGHT, recout->height
-                        - visual_confirm_on * 2 * (dpp->base.inst + 1));
+                        - visual_confirm_on * 2 * (dpp->base.inst + visual_confirm_rect_height));
 }
 
 /**
index 0b788d794fb334e0fc9e66fc67e919936bbec6f1..a2b925cc41322985c11b5abb7aa6b2a304f94c74 100644 (file)
@@ -1362,11 +1362,48 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
 
                tg->funcs->tg_init(tg);
        }
+
+       /* Power gate DSCs */
+       if (hws->funcs.dsc_pg_control != NULL) {
+               uint32_t num_opps = 0;
+               uint32_t opp_id_src0 = OPP_ID_INVALID;
+               uint32_t opp_id_src1 = OPP_ID_INVALID;
+
+               // Step 1: To find out which OPTC is running & OPTC DSC is ON
+               for (i = 0; i < dc->res_pool->res_cap->num_timing_generator; i++) {
+                       uint32_t optc_dsc_state = 0;
+                       struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+                       if (tg->funcs->is_tg_enabled(tg)) {
+                               if (tg->funcs->get_dsc_status)
+                                       tg->funcs->get_dsc_status(tg, &optc_dsc_state);
+                               // Only one OPTC with DSC is ON, so if we got one result, we would exit this block.
+                               // non-zero value is DSC enabled
+                               if (optc_dsc_state != 0) {
+                                       tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
+                                       break;
+                               }
+                       }
+               }
+
+               // Step 2: To power down DSC but skip DSC  of running OPTC
+               for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
+                       struct dcn_dsc_state s  = {0};
+
+                       dc->res_pool->dscs[i]->funcs->dsc_read_state(dc->res_pool->dscs[i], &s);
+
+                       if ((s.dsc_opp_source == opp_id_src0 || s.dsc_opp_source == opp_id_src1) &&
+                               s.dsc_clock_en && s.dsc_fw_en)
+                               continue;
+
+                       hws->funcs.dsc_pg_control(hws, dc->res_pool->dscs[i]->inst, false);
+               }
+       }
 }
 
 void dcn10_init_hw(struct dc *dc)
 {
-       int i, j;
+       int i;
        struct abm *abm = dc->res_pool->abm;
        struct dmcu *dmcu = dc->res_pool->dmcu;
        struct dce_hwseq *hws = dc->hwseq;
@@ -1468,43 +1505,8 @@ void dcn10_init_hw(struct dc *dc)
                dmub_enable_outbox_notification(dc);
 
        /* we want to turn off all dp displays before doing detection */
-       if (dc->config.power_down_display_on_boot) {
-               uint8_t dpcd_power_state = '\0';
-               enum dc_status status = DC_ERROR_UNEXPECTED;
-
-               for (i = 0; i < dc->link_count; i++) {
-                       if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)
-                               continue;
-
-                       /* DP 2.0 requires that LTTPR Caps be read first */
-                       dp_retrieve_lttpr_cap(dc->links[i]);
-
-                       /*
-                        * If any of the displays are lit up turn them off.
-                        * The reason is that some MST hubs cannot be turned off
-                        * completely until we tell them to do so.
-                        * If not turned off, then displays connected to MST hub
-                        * won't light up.
-                        */
-                       status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
-                                                       &dpcd_power_state, sizeof(dpcd_power_state));
-                       if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
-                               /* blank dp stream before power off receiver*/
-                               if (dc->links[i]->link_enc->funcs->get_dig_frontend) {
-                                       unsigned int fe = dc->links[i]->link_enc->funcs->get_dig_frontend(dc->links[i]->link_enc);
-
-                                       for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
-                                               if (fe == dc->res_pool->stream_enc[j]->id) {
-                                                       dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
-                                                                               dc->res_pool->stream_enc[j]);
-                                                       break;
-                                               }
-                                       }
-                               }
-                               dp_receiver_power_ctrl(dc->links[i], false);
-                       }
-               }
-       }
+       if (dc->config.power_down_display_on_boot)
+               dc_link_blank_all_dp_displays(dc);
 
        /* If taking control over from VBIOS, we may want to optimize our first
         * mode set, so we need to skip powering down pipes until we know which
@@ -1637,7 +1639,7 @@ void dcn10_reset_hw_ctx_wrap(
 
                        dcn10_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
                        if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx);
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
                        if (old_clk)
                                old_clk->funcs->cs_power_down(old_clk);
                }
@@ -2624,7 +2626,7 @@ static void dcn10_update_dchubp_dpp(
                /* new calculated dispclk, dppclk are stored in
                 * context->bw_ctx.bw.dcn.clk.dispclk_khz / dppclk_khz. current
                 * dispclk, dppclk are from dc->clk_mgr->clks.dispclk_khz.
-                * dcn_validate_bandwidth compute new dispclk, dppclk.
+                * dcn10_validate_bandwidth compute new dispclk, dppclk.
                 * dispclk will put in use after optimize_bandwidth when
                 * ramp_up_dispclk_with_dpp is called.
                 * there are two places for dppclk be put in use. One location
@@ -2638,7 +2640,7 @@ static void dcn10_update_dchubp_dpp(
                 * for example, eDP + external dp,  change resolution of DP from
                 * 1920x1080x144hz to 1280x960x60hz.
                 * before change: dispclk = 337889 dppclk = 337889
-                * change mode, dcn_validate_bandwidth calculate
+                * change mode, dcn10_validate_bandwidth calculate
                 *                dispclk = 143122 dppclk = 143122
                 * update_dchubp_dpp be executed before dispclk be updated,
                 * dispclk = 337889, but dppclk use new value dispclk /2 =
index f37551e00023fa11c8ab1b2a2e11ef8ed59f8f9f..19a2dd619ec75d4876e03c598efe06746b7a8d0d 100644 (file)
@@ -978,10 +978,8 @@ static void dcn10_resource_destruct(struct dcn10_resource_pool *pool)
                pool->base.mpc = NULL;
        }
 
-       if (pool->base.hubbub != NULL) {
-               kfree(pool->base.hubbub);
-               pool->base.hubbub = NULL;
-       }
+       kfree(pool->base.hubbub);
+       pool->base.hubbub = NULL;
 
        for (i = 0; i < pool->base.pipe_count; i++) {
                if (pool->base.opps[i] != NULL)
@@ -1011,14 +1009,10 @@ static void dcn10_resource_destruct(struct dcn10_resource_pool *pool)
        for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
                if (pool->base.engines[i] != NULL)
                        dce110_engine_destroy(&pool->base.engines[i]);
-               if (pool->base.hw_i2cs[i] != NULL) {
-                       kfree(pool->base.hw_i2cs[i]);
-                       pool->base.hw_i2cs[i] = NULL;
-               }
-               if (pool->base.sw_i2cs[i] != NULL) {
-                       kfree(pool->base.sw_i2cs[i]);
-                       pool->base.sw_i2cs[i] = NULL;
-               }
+               kfree(pool->base.hw_i2cs[i]);
+               pool->base.hw_i2cs[i] = NULL;
+               kfree(pool->base.sw_i2cs[i]);
+               pool->base.sw_i2cs[i] = NULL;
        }
 
        for (i = 0; i < pool->base.audio_count; i++) {
@@ -1320,7 +1314,7 @@ static const struct resource_funcs dcn10_res_pool_funcs = {
        .destroy = dcn10_destroy_resource_pool,
        .link_enc_create = dcn10_link_encoder_create,
        .panel_cntl_create = dcn10_panel_cntl_create,
-       .validate_bandwidth = dcn_validate_bandwidth,
+       .validate_bandwidth = dcn10_validate_bandwidth,
        .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
        .validate_plane = dcn10_validate_plane,
        .validate_global = dcn10_validate_global,
index b0c08ee6bc2cb316663bde8e5265a36a479785c9..bf4436d7aaab95e8c11c18fa9ca0cd817fa23633 100644 (file)
@@ -902,6 +902,19 @@ void enc1_stream_encoder_stop_dp_info_packets(
 
 }
 
+void enc1_stream_encoder_reset_fifo(
+       struct stream_encoder *enc)
+{
+       struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+
+       /* set DIG_START to 0x1 to reset FIFO */
+       REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
+       udelay(100);
+
+       /* write 0 to take the FIFO out of reset */
+       REG_UPDATE(DIG_FE_CNTL, DIG_START, 0);
+}
+
 void enc1_stream_encoder_dp_blank(
        struct dc_link *link,
        struct stream_encoder *enc)
@@ -1587,6 +1600,8 @@ static const struct stream_encoder_funcs dcn10_str_enc_funcs = {
                enc1_stream_encoder_send_immediate_sdp_message,
        .stop_dp_info_packets =
                enc1_stream_encoder_stop_dp_info_packets,
+       .reset_fifo =
+               enc1_stream_encoder_reset_fifo,
        .dp_blank =
                enc1_stream_encoder_dp_blank,
        .dp_unblank =
index 687d7e4bf7cadd2129b458aaabedaa4d70fbcaa7..a146a41f68e9ef786bbac83da31447d646043060 100644 (file)
@@ -626,6 +626,9 @@ void enc1_stream_encoder_send_immediate_sdp_message(
 void enc1_stream_encoder_stop_dp_info_packets(
        struct stream_encoder *enc);
 
+void enc1_stream_encoder_reset_fifo(
+       struct stream_encoder *enc);
+
 void enc1_stream_encoder_dp_blank(
        struct dc_link *link,
        struct stream_encoder *enc);
index 79b640e202eb4752dccbb2f59d526200a7736d63..ef5c4c0f4d6c242c5e6c60708f8d7c9875563108 100644 (file)
@@ -162,6 +162,8 @@ static void dsc2_read_state(struct display_stream_compressor *dsc, struct dcn_ds
        REG_GET(DSCC_PPS_CONFIG2, PIC_WIDTH, &s->dsc_pic_width);
        REG_GET(DSCC_PPS_CONFIG2, PIC_HEIGHT, &s->dsc_pic_height);
        REG_GET(DSCC_PPS_CONFIG7, SLICE_BPG_OFFSET, &s->dsc_slice_bpg_offset);
+       REG_GET_2(DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN, &s->dsc_fw_en,
+               DSCRM_DSC_OPP_PIPE_SOURCE, &s->dsc_opp_source);
 }
 
 
index 4f88376a118f8169093f1032007a9c12e7fb8c71..e6af99ae3d9f54f691b48bea363d0e0eead8d3b6 100644 (file)
@@ -2270,7 +2270,7 @@ void dcn20_reset_hw_ctx_wrap(
 
                        dcn20_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
                        if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx);
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
                        if (old_clk)
                                old_clk->funcs->cs_power_down(old_clk);
                }
index c90b8516dcc128d95a3ba67ddfc2c80858863d93..8c34751b0e582c81b01f9be72fadd6251bd45cbe 100644 (file)
@@ -190,6 +190,19 @@ void optc2_set_dsc_config(struct timing_generator *optc,
                OPTC_DSC_SLICE_WIDTH, dsc_slice_width);
 }
 
+/* Get DSC-related configuration.
+ *   dsc_mode: 0 disables DSC, other values enable DSC in specified format
+ */
+void optc2_get_dsc_status(struct timing_generator *optc,
+                                       uint32_t *dsc_mode)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+
+       REG_GET(OPTC_DATA_FORMAT_CONTROL,
+               OPTC_DSC_MODE, dsc_mode);
+}
+
+
 /*TEMP: Need to figure out inheritance model here.*/
 bool optc2_is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
 {
@@ -579,6 +592,7 @@ static struct timing_generator_funcs dcn20_tg_funcs = {
                .get_crc = optc1_get_crc,
                .configure_crc = optc2_configure_crc,
                .set_dsc_config = optc2_set_dsc_config,
+               .get_dsc_status = optc2_get_dsc_status,
                .set_dwb_source = optc2_set_dwb_source,
                .set_odm_bypass = optc2_set_odm_bypass,
                .set_odm_combine = optc2_set_odm_combine,
index be19a6885fbfd23fa135973b921d9b4c2b898dbf..f7968b9ca16eb41fcce68fff662fd59a6e271905 100644 (file)
@@ -98,6 +98,9 @@ void optc2_set_dsc_config(struct timing_generator *optc,
                                        uint32_t dsc_bytes_per_pixel,
                                        uint32_t dsc_slice_width);
 
+void optc2_get_dsc_status(struct timing_generator *optc,
+                                       uint32_t *dsc_mode);
+
 void optc2_set_odm_bypass(struct timing_generator *optc,
                const struct dc_crtc_timing *dc_crtc_timing);
 
index aab25ca8343abe4275fc7aa379cf47210a08592f..8a70f92795c2aa80fbc9f33b13f1c561f1ff2575 100644 (file)
@@ -593,6 +593,8 @@ static const struct stream_encoder_funcs dcn20_str_enc_funcs = {
                enc1_stream_encoder_send_immediate_sdp_message,
        .stop_dp_info_packets =
                enc1_stream_encoder_stop_dp_info_packets,
+       .reset_fifo =
+               enc1_stream_encoder_reset_fifo,
        .dp_blank =
                enc1_stream_encoder_dp_blank,
        .dp_unblank =
index ebd9c35c914f26352e5fc522f972c6e5eed2dd13..7aa9aaf5db4cbb10788288b91fc4ed10f0ae3d3d 100644 (file)
@@ -805,6 +805,8 @@ static const struct stream_encoder_funcs dcn30_str_enc_funcs = {
                enc3_stream_encoder_update_dp_info_packets,
        .stop_dp_info_packets =
                enc1_stream_encoder_stop_dp_info_packets,
+       .reset_fifo =
+               enc1_stream_encoder_reset_fifo,
        .dp_blank =
                enc1_stream_encoder_dp_blank,
        .dp_unblank =
index df27171166044f2d6eb388b16eca87bfa965a849..3e99bb9c70ab8e3dcaa099cad2c45655302e857d 100644 (file)
@@ -437,7 +437,7 @@ void dcn30_init_hw(struct dc *dc)
        struct dce_hwseq *hws = dc->hwseq;
        struct dc_bios *dcb = dc->ctx->dc_bios;
        struct resource_pool *res_pool = dc->res_pool;
-       int i, j;
+       int i;
        int edp_num;
        uint32_t backlight = MAX_BACKLIGHT_LEVEL;
 
@@ -534,41 +534,8 @@ void dcn30_init_hw(struct dc *dc)
                        hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
 
        /* we want to turn off all dp displays before doing detection */
-       if (dc->config.power_down_display_on_boot) {
-               uint8_t dpcd_power_state = '\0';
-               enum dc_status status = DC_ERROR_UNEXPECTED;
-
-               for (i = 0; i < dc->link_count; i++) {
-                       if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)
-                               continue;
-                       /* DP 2.0 states that LTTPR regs must be read first */
-                       dp_retrieve_lttpr_cap(dc->links[i]);
-
-                       /* if any of the displays are lit up turn them off */
-                       status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
-                                                    &dpcd_power_state, sizeof(dpcd_power_state));
-                       if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
-                               /* blank dp stream before power off receiver*/
-                               if (dc->links[i]->link_enc->funcs->get_dig_frontend) {
-                                       unsigned int fe;
-
-                                       fe = dc->links[i]->link_enc->funcs->get_dig_frontend(
-                                                                               dc->links[i]->link_enc);
-                                       if (fe == ENGINE_ID_UNKNOWN)
-                                               continue;
-
-                                       for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
-                                               if (fe == dc->res_pool->stream_enc[j]->id) {
-                                                       dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
-                                                                               dc->res_pool->stream_enc[j]);
-                                                       break;
-                                               }
-                                       }
-                               }
-                               dp_receiver_power_ctrl(dc->links[i], false);
-                       }
-               }
-       }
+       if (dc->config.power_down_display_on_boot)
+               dc_link_blank_all_dp_displays(dc);
 
        /* If taking control over from VBIOS, we may want to optimize our first
         * mode set, so we need to skip powering down pipes until we know which
index 5d9e6413d67a2e3b46ff936f00e4d23be8fab586..f5e8916601d3d65a7c3828a9aa5f1a695dd60b52 100644 (file)
@@ -332,6 +332,7 @@ static struct timing_generator_funcs dcn30_tg_funcs = {
                .get_crc = optc1_get_crc,
                .configure_crc = optc2_configure_crc,
                .set_dsc_config = optc3_set_dsc_config,
+               .get_dsc_status = optc2_get_dsc_status,
                .set_dwb_source = NULL,
                .set_odm_bypass = optc3_set_odm_bypass,
                .set_odm_combine = optc3_set_odm_combine,
index fbaa03f26d8bfac7b11a94dc527abe6fdc9b63b2..7abc36a4ff76b5f9e320544ea4a822453399ed7e 100644 (file)
@@ -686,7 +686,7 @@ static const struct dc_debug_options debug_defaults_drv = {
        .disable_clock_gate = true,
        .disable_pplib_clock_request = true,
        .disable_pplib_wm_range = true,
-       .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
+       .pipe_split_policy = MPC_SPLIT_AVOID,
        .force_single_disp_pipe_split = false,
        .disable_dcc = DCC_ENABLE,
        .vsr_support = true,
@@ -1449,9 +1449,7 @@ static bool dcn301_resource_construct(
        dc->caps.post_blend_color_processing = true;
        dc->caps.force_dp_tps4_for_cp2520 = true;
        dc->caps.extended_aux_timeout_support = true;
-#ifdef CONFIG_DRM_AMD_DC_DMUB
        dc->caps.dmcub_support = true;
-#endif
 
        /* Color pipeline capabilities */
        dc->caps.color.dpp.dcn_arch = 1;
@@ -1487,6 +1485,23 @@ static bool dcn301_resource_construct(
        dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
        dc->caps.color.mpc.ocsc = 1;
 
+       /* read VBIOS LTTPR caps */
+       if (ctx->dc_bios->funcs->get_lttpr_caps) {
+               enum bp_result bp_query_result;
+               uint8_t is_vbios_lttpr_enable = 0;
+
+               bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
+               dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
+       }
+
+       if (ctx->dc_bios->funcs->get_lttpr_interop) {
+               enum bp_result bp_query_result;
+               uint8_t is_vbios_interop_enabled = 0;
+
+               bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios, &is_vbios_interop_enabled);
+               dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled;
+       }
+
        if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
                dc->debug = debug_defaults_drv;
        else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
index fcf96cf08c761ae1c7fb8fd658ca041b9afd7277..058f5d71e037ab6e4d80ae3b8884c4f35d14003c 100644 (file)
@@ -1557,6 +1557,24 @@ static bool dcn302_resource_construct(
        dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
        dc->caps.color.mpc.ocsc = 1;
 
+       /* read VBIOS LTTPR caps */
+       if (ctx->dc_bios->funcs->get_lttpr_caps) {
+               enum bp_result bp_query_result;
+               uint8_t is_vbios_lttpr_enable = 0;
+
+               bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
+               dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
+       }
+
+       if (ctx->dc_bios->funcs->get_lttpr_interop) {
+               enum bp_result bp_query_result;
+               uint8_t is_vbios_interop_enabled = 0;
+
+               bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios,
+                               &is_vbios_interop_enabled);
+               dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled;
+       }
+
        if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
                dc->debug = debug_defaults_drv;
        else
index 4a9b64023675573e4c4ed80fbf40ac58499d7f23..7024aeb0884cf155a8839448069ff7a8b4a83a47 100644 (file)
@@ -1500,6 +1500,23 @@ static bool dcn303_resource_construct(
        dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
        dc->caps.color.mpc.ocsc = 1;
 
+       /* read VBIOS LTTPR caps */
+       if (ctx->dc_bios->funcs->get_lttpr_caps) {
+               enum bp_result bp_query_result;
+               uint8_t is_vbios_lttpr_enable = 0;
+
+               bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
+               dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
+       }
+
+       if (ctx->dc_bios->funcs->get_lttpr_interop) {
+               enum bp_result bp_query_result;
+               uint8_t is_vbios_interop_enabled = 0;
+
+               bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios, &is_vbios_interop_enabled);
+               dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled;
+       }
+
        if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
                dc->debug = debug_defaults_drv;
        else
index 565f12dd179a8338fbfe4955d9089978f1e474bf..5065904c78335743e92551f12d636772d5714723 100644 (file)
@@ -358,8 +358,8 @@ static void dcn31_hpo_dp_stream_enc_set_stream_attribute(
 
        h_width = hw_crtc_timing.h_border_left + hw_crtc_timing.h_addressable + hw_crtc_timing.h_border_right;
        v_height = hw_crtc_timing.v_border_top + hw_crtc_timing.v_addressable + hw_crtc_timing.v_border_bottom;
-       hsp = hw_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ? 0x80 : 0;
-       vsp = hw_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ? 0x80 : 0;
+       hsp = hw_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ? 0 : 0x80;
+       vsp = hw_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ? 0 : 0x80;
        v_freq = hw_crtc_timing.pix_clk_100hz * 100;
 
        /*   MSA Packet Mapping to 32-bit Link Symbols - DP2 spec, section 2.7.4.1
index 5dd1ce9ddb539afb2aa1dbfb16f6550086402ecd..4206ce5bf9a92dc68d42c054b48eb9575f8f893a 100644 (file)
@@ -112,7 +112,7 @@ void dcn31_init_hw(struct dc *dc)
        struct dc_bios *dcb = dc->ctx->dc_bios;
        struct resource_pool *res_pool = dc->res_pool;
        uint32_t backlight = MAX_BACKLIGHT_LEVEL;
-       int i, j;
+       int i;
 
        if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
                dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
@@ -192,50 +192,13 @@ void dcn31_init_hw(struct dc *dc)
                        link->link_status.link_active = true;
        }
 
-       /* Power gate DSCs */
-       for (i = 0; i < res_pool->res_cap->num_dsc; i++)
-               if (hws->funcs.dsc_pg_control != NULL)
-                       hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
-
        /* Enables outbox notifications for usb4 dpia */
        if (dc->res_pool->usb4_dpia_count)
                dmub_enable_outbox_notification(dc);
 
        /* we want to turn off all dp displays before doing detection */
-       if (dc->config.power_down_display_on_boot) {
-               uint8_t dpcd_power_state = '\0';
-               enum dc_status status = DC_ERROR_UNEXPECTED;
-
-               for (i = 0; i < dc->link_count; i++) {
-                       if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)
-                               continue;
-
-                       /* if any of the displays are lit up turn them off */
-                       status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
-                                                    &dpcd_power_state, sizeof(dpcd_power_state));
-                       if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
-                               /* blank dp stream before power off receiver*/
-                               if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY &&
-                                               dc->links[i]->link_enc->funcs->get_dig_frontend) {
-                                       unsigned int fe;
-
-                                       fe = dc->links[i]->link_enc->funcs->get_dig_frontend(
-                                                                               dc->links[i]->link_enc);
-                                       if (fe == ENGINE_ID_UNKNOWN)
-                                               continue;
-
-                                       for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
-                                               if (fe == dc->res_pool->stream_enc[j]->id) {
-                                                       dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
-                                                                               dc->res_pool->stream_enc[j]);
-                                                       break;
-                                               }
-                                       }
-                               }
-                               dp_receiver_power_ctrl(dc->links[i], false);
-                       }
-               }
-       }
+       if (dc->config.power_down_display_on_boot)
+               dc_link_blank_all_dp_displays(dc);
 
        /* If taking control over from VBIOS, we may want to optimize our first
         * mode set, so we need to skip powering down pipes until we know which
@@ -602,7 +565,7 @@ void dcn31_reset_hw_ctx_wrap(
 
                        dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
                        if (hws->funcs.enable_stream_gating)
-                               hws->funcs.enable_stream_gating(dc, pipe_ctx);
+                               hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
                        if (old_clk)
                                old_clk->funcs->cs_power_down(old_clk);
                }
index 05335a8c3c2dcffe54bb55bfebd9ba2a126e01a9..e175b6cc01254a965ba81eb27e9c711182fb4f99 100644 (file)
@@ -149,4 +149,9 @@ void dcn31_hw_sequencer_construct(struct dc *dc)
                dc->hwss.init_hw = dcn20_fpga_init_hw;
                dc->hwseq->funcs.init_pipes = NULL;
        }
+       if (dc->debug.disable_z10) {
+               /*hw not support z10 or sw disable it*/
+               dc->hwss.z10_restore = NULL;
+               dc->hwss.z10_save_init = NULL;
+       }
 }
index a4b1d98f00077dde0a8ea86baac10d7bb2441715..e8562fa11366a481133ba9073bf3cee2954ef547 100644 (file)
@@ -256,6 +256,7 @@ static struct timing_generator_funcs dcn31_tg_funcs = {
                .get_crc = optc1_get_crc,
                .configure_crc = optc2_configure_crc,
                .set_dsc_config = optc3_set_dsc_config,
+               .get_dsc_status = optc2_get_dsc_status,
                .set_dwb_source = NULL,
                .set_odm_bypass = optc3_set_odm_bypass,
                .set_odm_combine = optc31_set_odm_combine,
index 18896294ae12e7e2562ca89de9edc7edd151f63e..88e04068794005132026c673dc1f3564762b2b67 100644 (file)
@@ -2199,6 +2199,7 @@ static bool dcn31_resource_construct(
        dc->caps.post_blend_color_processing = true;
        dc->caps.force_dp_tps4_for_cp2520 = true;
        dc->caps.dp_hpo = true;
+       dc->caps.edp_dsc_support = true;
        dc->caps.extended_aux_timeout_support = true;
        dc->caps.dmcub_support = true;
        dc->caps.is_apu = true;
index 6905ef1e75a627bc8a2f71774d60ef6be5b24477..d76251fd15669f1948e6a81a12958187287dd70d 100644 (file)
@@ -73,6 +73,7 @@ struct display_mode_lib {
        struct vba_vars_st vba;
        struct dal_logger *logger;
        struct dml_funcs funcs;
+       struct _vcs_dpi_display_e2e_pipe_params_st dml_pipe_state[6];
 };
 
 void dml_init_instance(struct display_mode_lib *lib,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c
new file mode 100644 (file)
index 0000000..ece34b0
--- /dev/null
@@ -0,0 +1,1889 @@
+/*
+ * Copyright 2017 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 "dml_wrapper.h"
+#include "resource.h"
+#include "core_types.h"
+#include "dsc.h"
+#include "clk_mgr.h"
+
+#ifndef DC_LOGGER_INIT
+#define DC_LOGGER_INIT
+#undef DC_LOG_WARNING
+#define DC_LOG_WARNING
+#endif
+
+#define DML_WRAPPER_TRANSLATION_
+#include "dml_wrapper_translation.c"
+#undef DML_WRAPPER_TRANSLATION_
+
+static bool is_dual_plane(enum surface_pixel_format format)
+{
+       return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
+}
+
+static void build_clamping_params(struct dc_stream_state *stream)
+{
+       stream->clamping.clamping_level = CLAMPING_FULL_RANGE;
+       stream->clamping.c_depth = stream->timing.display_color_depth;
+       stream->clamping.pixel_encoding = stream->timing.pixel_encoding;
+}
+
+static void get_pixel_clock_parameters(
+       const struct pipe_ctx *pipe_ctx,
+       struct pixel_clk_params *pixel_clk_params)
+{
+       const struct dc_stream_state *stream = pipe_ctx->stream;
+
+       /*TODO: is this halved for YCbCr 420? in that case we might want to move
+        * the pixel clock normalization for hdmi up to here instead of doing it
+        * in pll_adjust_pix_clk
+        */
+       pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
+       pixel_clk_params->encoder_object_id = stream->link->link_enc->id;
+       pixel_clk_params->signal_type = pipe_ctx->stream->signal;
+       pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
+       /* TODO: un-hardcode*/
+       pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
+                                               LINK_RATE_REF_FREQ_IN_KHZ;
+       pixel_clk_params->flags.ENABLE_SS = 0;
+       pixel_clk_params->color_depth =
+               stream->timing.display_color_depth;
+       pixel_clk_params->flags.DISPLAY_BLANKED = 1;
+       pixel_clk_params->flags.SUPPORT_YCBCR420 = (stream->timing.pixel_encoding ==
+                       PIXEL_ENCODING_YCBCR420);
+       pixel_clk_params->pixel_encoding = stream->timing.pixel_encoding;
+       if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) {
+               pixel_clk_params->color_depth = COLOR_DEPTH_888;
+       }
+       if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
+               pixel_clk_params->requested_pix_clk_100hz  = pixel_clk_params->requested_pix_clk_100hz / 2;
+       }
+       if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
+               pixel_clk_params->requested_pix_clk_100hz *= 2;
+
+}
+
+static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
+{
+       get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->stream_res.pix_clk_params);
+
+       if (pipe_ctx->clock_source)
+               pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
+                       pipe_ctx->clock_source,
+                       &pipe_ctx->stream_res.pix_clk_params,
+                       &pipe_ctx->pll_settings);
+
+       pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->timing.pixel_encoding;
+
+       resource_build_bit_depth_reduction_params(pipe_ctx->stream,
+                                       &pipe_ctx->stream->bit_depth_params);
+       build_clamping_params(pipe_ctx->stream);
+
+       return DC_OK;
+}
+
+static void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
+               struct bit_depth_reduction_params *fmt_bit_depth)
+{
+       enum dc_dither_option option = stream->dither_option;
+       enum dc_pixel_encoding pixel_encoding =
+                       stream->timing.pixel_encoding;
+
+       memset(fmt_bit_depth, 0, sizeof(*fmt_bit_depth));
+
+       if (option == DITHER_OPTION_DEFAULT) {
+               switch (stream->timing.display_color_depth) {
+               case COLOR_DEPTH_666:
+                       option = DITHER_OPTION_SPATIAL6;
+                       break;
+               case COLOR_DEPTH_888:
+                       option = DITHER_OPTION_SPATIAL8;
+                       break;
+               case COLOR_DEPTH_101010:
+                       option = DITHER_OPTION_SPATIAL10;
+                       break;
+               default:
+                       option = DITHER_OPTION_DISABLE;
+               }
+       }
+
+       if (option == DITHER_OPTION_DISABLE)
+               return;
+
+       if (option == DITHER_OPTION_TRUN6) {
+               fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
+               fmt_bit_depth->flags.TRUNCATE_DEPTH = 0;
+       } else if (option == DITHER_OPTION_TRUN8 ||
+                       option == DITHER_OPTION_TRUN8_SPATIAL6 ||
+                       option == DITHER_OPTION_TRUN8_FM6) {
+               fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
+               fmt_bit_depth->flags.TRUNCATE_DEPTH = 1;
+       } else if (option == DITHER_OPTION_TRUN10        ||
+                       option == DITHER_OPTION_TRUN10_SPATIAL6   ||
+                       option == DITHER_OPTION_TRUN10_SPATIAL8   ||
+                       option == DITHER_OPTION_TRUN10_FM8     ||
+                       option == DITHER_OPTION_TRUN10_FM6     ||
+                       option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) {
+               fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
+               fmt_bit_depth->flags.TRUNCATE_DEPTH = 2;
+       }
+
+       /* special case - Formatter can only reduce by 4 bits at most.
+        * When reducing from 12 to 6 bits,
+        * HW recommends we use trunc with round mode
+        * (if we did nothing, trunc to 10 bits would be used)
+        * note that any 12->10 bit reduction is ignored prior to DCE8,
+        * as the input was 10 bits.
+        */
+       if (option == DITHER_OPTION_SPATIAL6_FRAME_RANDOM ||
+                       option == DITHER_OPTION_SPATIAL6 ||
+                       option == DITHER_OPTION_FM6) {
+               fmt_bit_depth->flags.TRUNCATE_ENABLED = 1;
+               fmt_bit_depth->flags.TRUNCATE_DEPTH = 2;
+               fmt_bit_depth->flags.TRUNCATE_MODE = 1;
+       }
+
+       /* spatial dither
+        * note that spatial modes 1-3 are never used
+        */
+       if (option == DITHER_OPTION_SPATIAL6_FRAME_RANDOM            ||
+                       option == DITHER_OPTION_SPATIAL6 ||
+                       option == DITHER_OPTION_TRUN10_SPATIAL6      ||
+                       option == DITHER_OPTION_TRUN8_SPATIAL6) {
+               fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1;
+               fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 0;
+               fmt_bit_depth->flags.HIGHPASS_RANDOM = 1;
+               fmt_bit_depth->flags.RGB_RANDOM =
+                               (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0;
+       } else if (option == DITHER_OPTION_SPATIAL8_FRAME_RANDOM            ||
+                       option == DITHER_OPTION_SPATIAL8 ||
+                       option == DITHER_OPTION_SPATIAL8_FM6        ||
+                       option == DITHER_OPTION_TRUN10_SPATIAL8      ||
+                       option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) {
+               fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1;
+               fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 1;
+               fmt_bit_depth->flags.HIGHPASS_RANDOM = 1;
+               fmt_bit_depth->flags.RGB_RANDOM =
+                               (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0;
+       } else if (option == DITHER_OPTION_SPATIAL10_FRAME_RANDOM ||
+                       option == DITHER_OPTION_SPATIAL10 ||
+                       option == DITHER_OPTION_SPATIAL10_FM8 ||
+                       option == DITHER_OPTION_SPATIAL10_FM6) {
+               fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1;
+               fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 2;
+               fmt_bit_depth->flags.HIGHPASS_RANDOM = 1;
+               fmt_bit_depth->flags.RGB_RANDOM =
+                               (pixel_encoding == PIXEL_ENCODING_RGB) ? 1 : 0;
+       }
+
+       if (option == DITHER_OPTION_SPATIAL6 ||
+                       option == DITHER_OPTION_SPATIAL8 ||
+                       option == DITHER_OPTION_SPATIAL10) {
+               fmt_bit_depth->flags.FRAME_RANDOM = 0;
+       } else {
+               fmt_bit_depth->flags.FRAME_RANDOM = 1;
+       }
+
+       //////////////////////
+       //// temporal dither
+       //////////////////////
+       if (option == DITHER_OPTION_FM6           ||
+                       option == DITHER_OPTION_SPATIAL8_FM6     ||
+                       option == DITHER_OPTION_SPATIAL10_FM6     ||
+                       option == DITHER_OPTION_TRUN10_FM6     ||
+                       option == DITHER_OPTION_TRUN8_FM6      ||
+                       option == DITHER_OPTION_TRUN10_SPATIAL8_FM6) {
+               fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1;
+               fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 0;
+       } else if (option == DITHER_OPTION_FM8        ||
+                       option == DITHER_OPTION_SPATIAL10_FM8  ||
+                       option == DITHER_OPTION_TRUN10_FM8) {
+               fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1;
+               fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 1;
+       } else if (option == DITHER_OPTION_FM10) {
+               fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 1;
+               fmt_bit_depth->flags.FRAME_MODULATION_DEPTH = 2;
+       }
+
+       fmt_bit_depth->pixel_encoding = pixel_encoding;
+}
+
+bool dml_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
+{
+       int i;
+
+       /* Validate DSC config, dsc count validation is already done */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i];
+               struct dc_stream_state *stream = pipe_ctx->stream;
+               struct dsc_config dsc_cfg;
+               struct pipe_ctx *odm_pipe;
+               int opp_cnt = 1;
+
+               for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+                       opp_cnt++;
+
+               /* Only need to validate top pipe */
+               if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe || !stream || !stream->timing.flags.DSC)
+                       continue;
+
+               dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left
+                               + stream->timing.h_border_right) / opp_cnt;
+               dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top
+                               + stream->timing.v_border_bottom;
+               dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
+               dsc_cfg.color_depth = stream->timing.display_color_depth;
+               dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
+               dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+               dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+
+               if (pipe_ctx->stream_res.dsc && !pipe_ctx->stream_res.dsc->funcs->dsc_validate_stream(pipe_ctx->stream_res.dsc, &dsc_cfg))
+                       return false;
+       }
+       return true;
+}
+
+enum dc_status dml_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream)
+{
+       enum dc_status status = DC_OK;
+       struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
+
+       if (!pipe_ctx)
+               return DC_ERROR_UNEXPECTED;
+
+
+       status = build_pipe_hw_param(pipe_ctx);
+
+       return status;
+}
+
+void dml_acquire_dsc(const struct dc *dc,
+                       struct resource_context *res_ctx,
+                       struct display_stream_compressor **dsc,
+                       int pipe_idx)
+{
+       int i;
+       const struct resource_pool *pool = dc->res_pool;
+       struct display_stream_compressor *dsc_old = dc->current_state->res_ctx.pipe_ctx[pipe_idx].stream_res.dsc;
+
+       ASSERT(*dsc == NULL); /* If this ASSERT fails, dsc was not released properly */
+       *dsc = NULL;
+
+       /* Always do 1-to-1 mapping when number of DSCs is same as number of pipes */
+       if (pool->res_cap->num_dsc == pool->res_cap->num_opp) {
+               *dsc = pool->dscs[pipe_idx];
+               res_ctx->is_dsc_acquired[pipe_idx] = true;
+               return;
+       }
+
+       /* Return old DSC to avoid the need for redo it */
+       if (dsc_old && !res_ctx->is_dsc_acquired[dsc_old->inst]) {
+               *dsc = dsc_old;
+               res_ctx->is_dsc_acquired[dsc_old->inst] = true;
+               return ;
+       }
+
+       /* Find first free DSC */
+       for (i = 0; i < pool->res_cap->num_dsc; i++)
+               if (!res_ctx->is_dsc_acquired[i]) {
+                       *dsc = pool->dscs[i];
+                       res_ctx->is_dsc_acquired[i] = true;
+                       break;
+               }
+}
+
+static bool dml_split_stream_for_mpc_or_odm(
+               const struct dc *dc,
+               struct resource_context *res_ctx,
+               struct pipe_ctx *pri_pipe,
+               struct pipe_ctx *sec_pipe,
+               bool odm)
+{
+       int pipe_idx = sec_pipe->pipe_idx;
+       const struct resource_pool *pool = dc->res_pool;
+
+       *sec_pipe = *pri_pipe;
+
+       sec_pipe->pipe_idx = pipe_idx;
+       sec_pipe->plane_res.mi = pool->mis[pipe_idx];
+       sec_pipe->plane_res.hubp = pool->hubps[pipe_idx];
+       sec_pipe->plane_res.ipp = pool->ipps[pipe_idx];
+       sec_pipe->plane_res.xfm = pool->transforms[pipe_idx];
+       sec_pipe->plane_res.dpp = pool->dpps[pipe_idx];
+       sec_pipe->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst;
+       sec_pipe->stream_res.dsc = NULL;
+       if (odm) {
+               if (pri_pipe->next_odm_pipe) {
+                       ASSERT(pri_pipe->next_odm_pipe != sec_pipe);
+                       sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe;
+                       sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe;
+               }
+               if (pri_pipe->top_pipe && pri_pipe->top_pipe->next_odm_pipe) {
+                       pri_pipe->top_pipe->next_odm_pipe->bottom_pipe = sec_pipe;
+                       sec_pipe->top_pipe = pri_pipe->top_pipe->next_odm_pipe;
+               }
+               if (pri_pipe->bottom_pipe && pri_pipe->bottom_pipe->next_odm_pipe) {
+                       pri_pipe->bottom_pipe->next_odm_pipe->top_pipe = sec_pipe;
+                       sec_pipe->bottom_pipe = pri_pipe->bottom_pipe->next_odm_pipe;
+               }
+               pri_pipe->next_odm_pipe = sec_pipe;
+               sec_pipe->prev_odm_pipe = pri_pipe;
+               ASSERT(sec_pipe->top_pipe == NULL);
+
+               if (!sec_pipe->top_pipe)
+                       sec_pipe->stream_res.opp = pool->opps[pipe_idx];
+               else
+                       sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp;
+               if (sec_pipe->stream->timing.flags.DSC == 1) {
+                       dml_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx);
+                       ASSERT(sec_pipe->stream_res.dsc);
+                       if (sec_pipe->stream_res.dsc == NULL)
+                               return false;
+               }
+       } else {
+               if (pri_pipe->bottom_pipe) {
+                       ASSERT(pri_pipe->bottom_pipe != sec_pipe);
+                       sec_pipe->bottom_pipe = pri_pipe->bottom_pipe;
+                       sec_pipe->bottom_pipe->top_pipe = sec_pipe;
+               }
+               pri_pipe->bottom_pipe = sec_pipe;
+               sec_pipe->top_pipe = pri_pipe;
+
+               ASSERT(pri_pipe->plane_state);
+       }
+
+       return true;
+}
+
+static struct pipe_ctx *dml_find_split_pipe(
+               struct dc *dc,
+               struct dc_state *context,
+               int old_index)
+{
+       struct pipe_ctx *pipe = NULL;
+       int i;
+
+       if (old_index >= 0 && context->res_ctx.pipe_ctx[old_index].stream == NULL) {
+               pipe = &context->res_ctx.pipe_ctx[old_index];
+               pipe->pipe_idx = old_index;
+       }
+
+       if (!pipe)
+               for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+                       if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL
+                                       && dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) {
+                               if (context->res_ctx.pipe_ctx[i].stream == NULL) {
+                                       pipe = &context->res_ctx.pipe_ctx[i];
+                                       pipe->pipe_idx = i;
+                                       break;
+                               }
+                       }
+               }
+
+       /*
+        * May need to fix pipes getting tossed from 1 opp to another on flip
+        * Add for debugging transient underflow during topology updates:
+        * ASSERT(pipe);
+        */
+       if (!pipe)
+               for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+                       if (context->res_ctx.pipe_ctx[i].stream == NULL) {
+                               pipe = &context->res_ctx.pipe_ctx[i];
+                               pipe->pipe_idx = i;
+                               break;
+                       }
+               }
+
+       return pipe;
+}
+
+static void dml_release_dsc(struct resource_context *res_ctx,
+                       const struct resource_pool *pool,
+                       struct display_stream_compressor **dsc)
+{
+       int i;
+
+       for (i = 0; i < pool->res_cap->num_dsc; i++)
+               if (pool->dscs[i] == *dsc) {
+                       res_ctx->is_dsc_acquired[i] = false;
+                       *dsc = NULL;
+                       break;
+               }
+}
+
+static int dml_get_num_mpc_splits(struct pipe_ctx *pipe)
+{
+       int mpc_split_count = 0;
+       struct pipe_ctx *other_pipe = pipe->bottom_pipe;
+
+       while (other_pipe && other_pipe->plane_state == pipe->plane_state) {
+               mpc_split_count++;
+               other_pipe = other_pipe->bottom_pipe;
+       }
+       other_pipe = pipe->top_pipe;
+       while (other_pipe && other_pipe->plane_state == pipe->plane_state) {
+               mpc_split_count++;
+               other_pipe = other_pipe->top_pipe;
+       }
+
+       return mpc_split_count;
+}
+
+static bool dml_enough_pipes_for_subvp(struct dc *dc,
+               struct dc_state *context)
+{
+       int i = 0;
+       int num_pipes = 0;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->stream && pipe->plane_state)
+                       num_pipes++;
+       }
+
+       // Sub-VP only possible if the number of "real" pipes is
+       // less than or equal to half the number of available pipes
+       if (num_pipes * 2 > dc->res_pool->pipe_count)
+               return false;
+
+       return true;
+}
+
+static int dml_validate_apply_pipe_split_flags(
+               struct dc *dc,
+               struct dc_state *context,
+               int vlevel,
+               int *split,
+               bool *merge)
+{
+       int i, pipe_idx, vlevel_split;
+       int plane_count = 0;
+       bool force_split = false;
+       bool avoid_split = dc->debug.pipe_split_policy == MPC_SPLIT_AVOID;
+       struct vba_vars_st *v = &context->bw_ctx.dml.vba;
+       int max_mpc_comb = v->maxMpcComb;
+
+       if (context->stream_count > 1) {
+               if (dc->debug.pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP)
+                       avoid_split = true;
+       } else if (dc->debug.force_single_disp_pipe_split)
+                       force_split = true;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               /**
+                * Workaround for avoiding pipe-split in cases where we'd split
+                * planes that are too small, resulting in splits that aren't
+                * valid for the scaler.
+                */
+               if (pipe->plane_state &&
+                   (pipe->plane_state->dst_rect.width <= 16 ||
+                    pipe->plane_state->dst_rect.height <= 16 ||
+                    pipe->plane_state->src_rect.width <= 16 ||
+                    pipe->plane_state->src_rect.height <= 16))
+                       avoid_split = true;
+
+               /* TODO: fix dc bugs and remove this split threshold thing */
+               if (pipe->stream && !pipe->prev_odm_pipe &&
+                               (!pipe->top_pipe || pipe->top_pipe->plane_state != pipe->plane_state))
+                       ++plane_count;
+       }
+       if (plane_count > dc->res_pool->pipe_count / 2)
+               avoid_split = true;
+
+       /* W/A: Mode timing with borders may not work well with pipe split, avoid for this corner case */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct dc_crtc_timing timing;
+
+               if (!pipe->stream)
+                       continue;
+               else {
+                       timing = pipe->stream->timing;
+                       if (timing.h_border_left + timing.h_border_right
+                                       + timing.v_border_top + timing.v_border_bottom > 0) {
+                               avoid_split = true;
+                               break;
+                       }
+               }
+       }
+
+       /* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */
+       if (avoid_split) {
+               for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+                       if (!context->res_ctx.pipe_ctx[i].stream)
+                               continue;
+
+                       for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++)
+                               if (v->NoOfDPP[vlevel][0][pipe_idx] == 1 &&
+                                               v->ModeSupport[vlevel][0])
+                                       break;
+                       /* Impossible to not split this pipe */
+                       if (vlevel > context->bw_ctx.dml.soc.num_states)
+                               vlevel = vlevel_split;
+                       else
+                               max_mpc_comb = 0;
+                       pipe_idx++;
+               }
+               v->maxMpcComb = max_mpc_comb;
+       }
+
+       /* Split loop sets which pipe should be split based on dml outputs and dc flags */
+       for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               int pipe_plane = v->pipe_plane[pipe_idx];
+               bool split4mpc = context->stream_count == 1 && plane_count == 1
+                               && dc->config.enable_4to1MPC && dc->res_pool->pipe_count >= 4;
+
+               if (!context->res_ctx.pipe_ctx[i].stream)
+                       continue;
+
+               if (split4mpc || v->NoOfDPP[vlevel][max_mpc_comb][pipe_plane] == 4)
+                       split[i] = 4;
+               else if (force_split || v->NoOfDPP[vlevel][max_mpc_comb][pipe_plane] == 2)
+                               split[i] = 2;
+
+               if ((pipe->stream->view_format ==
+                               VIEW_3D_FORMAT_SIDE_BY_SIDE ||
+                               pipe->stream->view_format ==
+                               VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
+                               (pipe->stream->timing.timing_3d_format ==
+                               TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
+                                pipe->stream->timing.timing_3d_format ==
+                               TIMING_3D_FORMAT_SIDE_BY_SIDE))
+                       split[i] = 2;
+               if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
+                       split[i] = 2;
+                       v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_2to1;
+               }
+               if (dc->debug.force_odm_combine_4to1 & (1 << pipe->stream_res.tg->inst)) {
+                       split[i] = 4;
+                       v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_4to1;
+               }
+               /*420 format workaround*/
+               if (pipe->stream->timing.h_addressable > 7680 &&
+                               pipe->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
+                       split[i] = 4;
+               }
+
+               v->ODMCombineEnabled[pipe_plane] =
+                       v->ODMCombineEnablePerState[vlevel][pipe_plane];
+
+               if (v->ODMCombineEnabled[pipe_plane] == dm_odm_combine_mode_disabled) {
+                       if (dml_get_num_mpc_splits(pipe) == 1) {
+                               /*If need split for mpc but 2 way split already*/
+                               if (split[i] == 4)
+                                       split[i] = 2; /* 2 -> 4 MPC */
+                               else if (split[i] == 2)
+                                       split[i] = 0; /* 2 -> 2 MPC */
+                               else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state)
+                                       merge[i] = true; /* 2 -> 1 MPC */
+                       } else if (dml_get_num_mpc_splits(pipe) == 3) {
+                               /*If need split for mpc but 4 way split already*/
+                               if (split[i] == 2 && ((pipe->top_pipe && !pipe->top_pipe->top_pipe)
+                                               || !pipe->bottom_pipe)) {
+                                       merge[i] = true; /* 4 -> 2 MPC */
+                               } else if (split[i] == 0 && pipe->top_pipe &&
+                                               pipe->top_pipe->plane_state == pipe->plane_state)
+                                       merge[i] = true; /* 4 -> 1 MPC */
+                               split[i] = 0;
+                       } else if (dml_get_num_mpc_splits(pipe)) {
+                               /* ODM -> MPC transition */
+                               if (pipe->prev_odm_pipe) {
+                                       split[i] = 0;
+                                       merge[i] = true;
+                               }
+                       }
+               } else {
+                       if (dml_get_num_mpc_splits(pipe) == 1) {
+                               /*If need split for odm but 2 way split already*/
+                               if (split[i] == 4)
+                                       split[i] = 2; /* 2 -> 4 ODM */
+                               else if (split[i] == 2)
+                                       split[i] = 0; /* 2 -> 2 ODM */
+                               else if (pipe->prev_odm_pipe) {
+                                       ASSERT(0); /* NOT expected yet */
+                                       merge[i] = true; /* exit ODM */
+                               }
+                       } else if (dml_get_num_mpc_splits(pipe) == 3) {
+                               /*If need split for odm but 4 way split already*/
+                               if (split[i] == 2 && ((pipe->prev_odm_pipe && !pipe->prev_odm_pipe->prev_odm_pipe)
+                                               || !pipe->next_odm_pipe)) {
+                                       ASSERT(0); /* NOT expected yet */
+                                       merge[i] = true; /* 4 -> 2 ODM */
+                               } else if (split[i] == 0 && pipe->prev_odm_pipe) {
+                                       ASSERT(0); /* NOT expected yet */
+                                       merge[i] = true; /* exit ODM */
+                               }
+                               split[i] = 0;
+                       } else if (dml_get_num_mpc_splits(pipe)) {
+                               /* MPC -> ODM transition */
+                               ASSERT(0); /* NOT expected yet */
+                               if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) {
+                                       split[i] = 0;
+                                       merge[i] = true;
+                               }
+                       }
+               }
+
+               /* Adjust dppclk when split is forced, do not bother with dispclk */
+               if (split[i] != 0 && v->NoOfDPP[vlevel][max_mpc_comb][pipe_idx] == 1)
+                       v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2;
+               pipe_idx++;
+       }
+
+       return vlevel;
+}
+
+static void dml_set_phantom_stream_timing(struct dc *dc,
+               struct dc_state *context,
+               struct pipe_ctx *ref_pipe,
+               struct dc_stream_state *phantom_stream)
+{
+       // phantom_vactive = blackout (latency + margin) + fw_processing_delays + pstate allow width
+       uint32_t phantom_vactive_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us + 60 +
+                                       dc->caps.subvp_fw_processing_delay_us +
+                                       dc->caps.subvp_pstate_allow_width_us;
+       uint32_t phantom_vactive = ((double)phantom_vactive_us/1000000) *
+                                       (ref_pipe->stream->timing.pix_clk_100hz * 100) /
+                                       (double)ref_pipe->stream->timing.h_total;
+       uint32_t phantom_bp = ref_pipe->pipe_dlg_param.vstartup_start;
+
+       phantom_stream->dst.y = 0;
+       phantom_stream->dst.height = phantom_vactive;
+       phantom_stream->src.y = 0;
+       phantom_stream->src.height = phantom_vactive;
+
+       phantom_stream->timing.v_addressable = phantom_vactive;
+       phantom_stream->timing.v_front_porch = 1;
+       phantom_stream->timing.v_total = phantom_stream->timing.v_addressable +
+                                               phantom_stream->timing.v_front_porch +
+                                               phantom_stream->timing.v_sync_width +
+                                               phantom_bp;
+}
+
+static struct dc_stream_state *dml_enable_phantom_stream(struct dc *dc,
+               struct dc_state *context,
+               struct pipe_ctx *ref_pipe)
+{
+       struct dc_stream_state *phantom_stream = NULL;
+
+       phantom_stream = dc_create_stream_for_sink(ref_pipe->stream->sink);
+       phantom_stream->signal = SIGNAL_TYPE_VIRTUAL;
+       phantom_stream->dpms_off = true;
+       phantom_stream->mall_stream_config.type = SUBVP_PHANTOM;
+       phantom_stream->mall_stream_config.paired_stream = ref_pipe->stream;
+       ref_pipe->stream->mall_stream_config.type = SUBVP_MAIN;
+       ref_pipe->stream->mall_stream_config.paired_stream = phantom_stream;
+
+       /* stream has limited viewport and small timing */
+       memcpy(&phantom_stream->timing, &ref_pipe->stream->timing, sizeof(phantom_stream->timing));
+       memcpy(&phantom_stream->src, &ref_pipe->stream->src, sizeof(phantom_stream->src));
+       memcpy(&phantom_stream->dst, &ref_pipe->stream->dst, sizeof(phantom_stream->dst));
+       dml_set_phantom_stream_timing(dc, context, ref_pipe, phantom_stream);
+
+       dc_add_stream_to_ctx(dc, context, phantom_stream);
+       dc->hwss.apply_ctx_to_hw(dc, context);
+       return phantom_stream;
+}
+
+static void dml_enable_phantom_plane(struct dc *dc,
+               struct dc_state *context,
+               struct dc_stream_state *phantom_stream,
+               struct pipe_ctx *main_pipe)
+{
+       struct dc_plane_state *phantom_plane = NULL;
+       struct dc_plane_state *prev_phantom_plane = NULL;
+       struct pipe_ctx *curr_pipe = main_pipe;
+
+       while (curr_pipe) {
+               if (curr_pipe->top_pipe && curr_pipe->top_pipe->plane_state == curr_pipe->plane_state)
+                       phantom_plane = prev_phantom_plane;
+               else
+                       phantom_plane = dc_create_plane_state(dc);
+
+               memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address));
+               memcpy(&phantom_plane->scaling_quality, &curr_pipe->plane_state->scaling_quality,
+                               sizeof(phantom_plane->scaling_quality));
+               memcpy(&phantom_plane->src_rect, &curr_pipe->plane_state->src_rect, sizeof(phantom_plane->src_rect));
+               memcpy(&phantom_plane->dst_rect, &curr_pipe->plane_state->dst_rect, sizeof(phantom_plane->dst_rect));
+               memcpy(&phantom_plane->clip_rect, &curr_pipe->plane_state->clip_rect, sizeof(phantom_plane->clip_rect));
+               memcpy(&phantom_plane->plane_size, &curr_pipe->plane_state->plane_size,
+                               sizeof(phantom_plane->plane_size));
+               memcpy(&phantom_plane->tiling_info, &curr_pipe->plane_state->tiling_info,
+                               sizeof(phantom_plane->tiling_info));
+               memcpy(&phantom_plane->dcc, &curr_pipe->plane_state->dcc, sizeof(phantom_plane->dcc));
+               /* Currently compat_level is undefined in dc_state
+               * phantom_plane->compat_level = curr_pipe->plane_state->compat_level;
+               */
+               phantom_plane->format = curr_pipe->plane_state->format;
+               phantom_plane->rotation = curr_pipe->plane_state->rotation;
+               phantom_plane->visible = curr_pipe->plane_state->visible;
+
+               /* Shadow pipe has small viewport. */
+               phantom_plane->clip_rect.y = 0;
+               phantom_plane->clip_rect.height = phantom_stream->timing.v_addressable;
+
+               dc_add_plane_to_context(dc, phantom_stream, phantom_plane, context);
+
+               curr_pipe = curr_pipe->bottom_pipe;
+               prev_phantom_plane = phantom_plane;
+       }
+}
+
+static void dml_add_phantom_pipes(struct dc *dc, struct dc_state *context)
+{
+       int i = 0;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct dc_stream_state *ref_stream = pipe->stream;
+               // Only construct phantom stream for top pipes that have plane enabled
+               if (!pipe->top_pipe && pipe->plane_state && pipe->stream &&
+                               pipe->stream->mall_stream_config.type == SUBVP_NONE) {
+                       struct dc_stream_state *phantom_stream = NULL;
+
+                       phantom_stream = dml_enable_phantom_stream(dc, context, pipe);
+                       dml_enable_phantom_plane(dc, context, phantom_stream, pipe);
+               }
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->plane_state && pipe->stream &&
+                               pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                       pipe->stream->use_dynamic_meta = false;
+                       pipe->plane_state->flip_immediate = false;
+                       if (!resource_build_scaling_params(pipe)) {
+                               // Log / remove phantom pipes since failed to build scaling params
+                       }
+               }
+       }
+}
+
+static void dml_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       bool removed_pipe = false;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               // build scaling params for phantom pipes
+               if (pipe->plane_state && pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                       dc_rem_all_planes_for_stream(dc, pipe->stream, context);
+                       dc_remove_stream_from_ctx(dc, context, pipe->stream);
+                       removed_pipe = true;
+               }
+
+               // Clear all phantom stream info
+               if (pipe->stream) {
+                       pipe->stream->mall_stream_config.type = SUBVP_NONE;
+                       pipe->stream->mall_stream_config.paired_stream = NULL;
+               }
+       }
+       if (removed_pipe)
+               dc->hwss.apply_ctx_to_hw(dc, context);
+}
+
+/*
+ * If the input state contains no upstream planes for a particular pipe (i.e. only timing)
+ * we need to populate some "conservative" plane information as DML cannot handle "no planes"
+ */
+static void populate_default_plane_from_timing(const struct dc_crtc_timing *timing, struct _vcs_dpi_display_pipe_params_st *pipe)
+{
+       pipe->src.is_hsplit = pipe->dest.odm_combine != dm_odm_combine_mode_disabled;
+       pipe->src.source_scan = dm_horz;
+       pipe->src.sw_mode = dm_sw_4kb_s;
+       pipe->src.macro_tile_size = dm_64k_tile;
+       pipe->src.viewport_width = timing->h_addressable;
+       if (pipe->src.viewport_width > 1920)
+               pipe->src.viewport_width = 1920;
+       pipe->src.viewport_height = timing->v_addressable;
+       if (pipe->src.viewport_height > 1080)
+               pipe->src.viewport_height = 1080;
+       pipe->src.surface_height_y = pipe->src.viewport_height;
+       pipe->src.surface_width_y = pipe->src.viewport_width;
+       pipe->src.surface_height_c = pipe->src.viewport_height;
+       pipe->src.surface_width_c = pipe->src.viewport_width;
+       pipe->src.data_pitch = ((pipe->src.viewport_width + 255) / 256) * 256;
+       pipe->src.source_format = dm_444_32;
+       pipe->dest.recout_width = pipe->src.viewport_width;
+       pipe->dest.recout_height = pipe->src.viewport_height;
+       pipe->dest.full_recout_width = pipe->dest.recout_width;
+       pipe->dest.full_recout_height = pipe->dest.recout_height;
+       pipe->scale_ratio_depth.lb_depth = dm_lb_16;
+       pipe->scale_ratio_depth.hscl_ratio = 1.0;
+       pipe->scale_ratio_depth.vscl_ratio = 1.0;
+       pipe->scale_ratio_depth.scl_enable = 0;
+       pipe->scale_taps.htaps = 1;
+       pipe->scale_taps.vtaps = 1;
+       pipe->dest.vtotal_min = timing->v_total;
+       pipe->dest.vtotal_max = timing->v_total;
+
+       if (pipe->dest.odm_combine == dm_odm_combine_mode_2to1) {
+               pipe->src.viewport_width /= 2;
+               pipe->dest.recout_width /= 2;
+       } else if (pipe->dest.odm_combine == dm_odm_combine_mode_4to1) {
+               pipe->src.viewport_width /= 4;
+               pipe->dest.recout_width /= 4;
+       }
+
+       pipe->src.dcc = false;
+       pipe->src.dcc_rate = 1;
+}
+
+/*
+ * If the pipe is not blending (i.e. pipe_ctx->top pipe == null) then its
+ * hsplit group is equal to its own pipe ID
+ * Otherwise, all pipes part of the same blending tree have the same hsplit group
+ * ID as the top most pipe
+ *
+ * If the pipe ctx is ODM combined, then similar logic follows
+ */
+static void populate_hsplit_group_from_dc_pipe_ctx (const struct pipe_ctx *dc_pipe_ctx, struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe)
+{
+       e2e_pipe->pipe.src.hsplit_grp = dc_pipe_ctx->pipe_idx;
+
+       if (dc_pipe_ctx->top_pipe && dc_pipe_ctx->top_pipe->plane_state
+                       == dc_pipe_ctx->plane_state) {
+               struct pipe_ctx *first_pipe = dc_pipe_ctx->top_pipe;
+               int split_idx = 0;
+
+               while (first_pipe->top_pipe && first_pipe->top_pipe->plane_state
+                               == dc_pipe_ctx->plane_state) {
+                       first_pipe = first_pipe->top_pipe;
+                       split_idx++;
+               }
+
+               /* Treat 4to1 mpc combine as an mpo of 2 2-to-1 combines */
+               if (split_idx == 0)
+                       e2e_pipe->pipe.src.hsplit_grp = first_pipe->pipe_idx;
+               else if (split_idx == 1)
+                       e2e_pipe->pipe.src.hsplit_grp = dc_pipe_ctx->pipe_idx;
+               else if (split_idx == 2)
+                       e2e_pipe->pipe.src.hsplit_grp = dc_pipe_ctx->top_pipe->pipe_idx;
+
+       } else if (dc_pipe_ctx->prev_odm_pipe) {
+               struct pipe_ctx *first_pipe = dc_pipe_ctx->prev_odm_pipe;
+
+               while (first_pipe->prev_odm_pipe)
+                       first_pipe = first_pipe->prev_odm_pipe;
+               e2e_pipe->pipe.src.hsplit_grp = first_pipe->pipe_idx;
+       }
+}
+
+static void populate_dml_from_dc_pipe_ctx (const struct pipe_ctx *dc_pipe_ctx, struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe, int always_scale)
+{
+       const struct dc_plane_state *pln = dc_pipe_ctx->plane_state;
+       const struct scaler_data *scl = &dc_pipe_ctx->plane_res.scl_data;
+
+       e2e_pipe->pipe.src.immediate_flip = pln->flip_immediate;
+       e2e_pipe->pipe.src.is_hsplit = (dc_pipe_ctx->bottom_pipe && dc_pipe_ctx->bottom_pipe->plane_state == pln)
+                       || (dc_pipe_ctx->top_pipe && dc_pipe_ctx->top_pipe->plane_state == pln)
+                       || e2e_pipe->pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
+
+       /* stereo is not split */
+       if (pln->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE ||
+               pln->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) {
+               e2e_pipe->pipe.src.is_hsplit = false;
+               e2e_pipe->pipe.src.hsplit_grp = dc_pipe_ctx->pipe_idx;
+       }
+
+       e2e_pipe->pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
+                       || pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
+       e2e_pipe->pipe.src.viewport_y_y = scl->viewport.y;
+       e2e_pipe->pipe.src.viewport_y_c = scl->viewport_c.y;
+       e2e_pipe->pipe.src.viewport_width = scl->viewport.width;
+       e2e_pipe->pipe.src.viewport_width_c = scl->viewport_c.width;
+       e2e_pipe->pipe.src.viewport_height = scl->viewport.height;
+       e2e_pipe->pipe.src.viewport_height_c = scl->viewport_c.height;
+       e2e_pipe->pipe.src.viewport_width_max = pln->src_rect.width;
+       e2e_pipe->pipe.src.viewport_height_max = pln->src_rect.height;
+       e2e_pipe->pipe.src.surface_width_y = pln->plane_size.surface_size.width;
+       e2e_pipe->pipe.src.surface_height_y = pln->plane_size.surface_size.height;
+       e2e_pipe->pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
+       e2e_pipe->pipe.src.surface_height_c = pln->plane_size.chroma_size.height;
+
+       if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA
+                       || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+               e2e_pipe->pipe.src.data_pitch = pln->plane_size.surface_pitch;
+               e2e_pipe->pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
+               e2e_pipe->pipe.src.meta_pitch = pln->dcc.meta_pitch;
+               e2e_pipe->pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c;
+       } else {
+               e2e_pipe->pipe.src.data_pitch = pln->plane_size.surface_pitch;
+               e2e_pipe->pipe.src.meta_pitch = pln->dcc.meta_pitch;
+       }
+       e2e_pipe->pipe.src.dcc = pln->dcc.enable;
+       e2e_pipe->pipe.src.dcc_rate = 1;
+       e2e_pipe->pipe.dest.recout_width = scl->recout.width;
+       e2e_pipe->pipe.dest.recout_height = scl->recout.height;
+       e2e_pipe->pipe.dest.full_recout_height = scl->recout.height;
+       e2e_pipe->pipe.dest.full_recout_width = scl->recout.width;
+       if (e2e_pipe->pipe.dest.odm_combine == dm_odm_combine_mode_2to1)
+               e2e_pipe->pipe.dest.full_recout_width *= 2;
+       else if (e2e_pipe->pipe.dest.odm_combine == dm_odm_combine_mode_4to1)
+               e2e_pipe->pipe.dest.full_recout_width *= 4;
+       else {
+               struct pipe_ctx *split_pipe = dc_pipe_ctx->bottom_pipe;
+
+               while (split_pipe && split_pipe->plane_state == pln) {
+                       e2e_pipe->pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
+                       split_pipe = split_pipe->bottom_pipe;
+               }
+               split_pipe = dc_pipe_ctx->top_pipe;
+               while (split_pipe && split_pipe->plane_state == pln) {
+                       e2e_pipe->pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
+                       split_pipe = split_pipe->top_pipe;
+               }
+       }
+
+       e2e_pipe->pipe.scale_ratio_depth.lb_depth = dm_lb_16;
+       e2e_pipe->pipe.scale_ratio_depth.hscl_ratio = (double) scl->ratios.horz.value / (1ULL<<32);
+       e2e_pipe->pipe.scale_ratio_depth.hscl_ratio_c = (double) scl->ratios.horz_c.value / (1ULL<<32);
+       e2e_pipe->pipe.scale_ratio_depth.vscl_ratio = (double) scl->ratios.vert.value / (1ULL<<32);
+       e2e_pipe->pipe.scale_ratio_depth.vscl_ratio_c = (double) scl->ratios.vert_c.value / (1ULL<<32);
+       e2e_pipe->pipe.scale_ratio_depth.scl_enable =
+                       scl->ratios.vert.value != dc_fixpt_one.value
+                       || scl->ratios.horz.value != dc_fixpt_one.value
+                       || scl->ratios.vert_c.value != dc_fixpt_one.value
+                       || scl->ratios.horz_c.value != dc_fixpt_one.value /*Lb only or Full scl*/
+                       || always_scale; /*support always scale*/
+       e2e_pipe->pipe.scale_taps.htaps = scl->taps.h_taps;
+       e2e_pipe->pipe.scale_taps.htaps_c = scl->taps.h_taps_c;
+       e2e_pipe->pipe.scale_taps.vtaps = scl->taps.v_taps;
+       e2e_pipe->pipe.scale_taps.vtaps_c = scl->taps.v_taps_c;
+
+       /* Currently compat_level is not defined. Commenting it until further resolution
+        * if (pln->compat_level == DC_LEGACY_TILING_ADDR_GEN_TWO) {
+               swizzle_to_dml_params(pln->tiling_info.gfx9.swizzle,
+                               &e2e_pipe->pipe.src.sw_mode);
+               e2e_pipe->pipe.src.macro_tile_size =
+                               swizzle_mode_to_macro_tile_size(pln->tiling_info.gfx9.swizzle);
+       } else {
+               gfx10array_mode_to_dml_params(pln->tiling_info.gfx10compatible.array_mode,
+                               pln->compat_level,
+                               &e2e_pipe->pipe.src.sw_mode);
+               e2e_pipe->pipe.src.macro_tile_size = dm_4k_tile;
+       }*/
+
+       e2e_pipe->pipe.src.source_format = dc_source_format_to_dml_source_format(pln->format);
+}
+
+static void populate_dml_cursor_parameters_from_dc_pipe_ctx (const struct pipe_ctx *dc_pipe_ctx, struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe)
+{
+       /*
+       * For graphic plane, cursor number is 1, nv12 is 0
+       * bw calculations due to cursor on/off
+       */
+       if (dc_pipe_ctx->plane_state &&
+                       (dc_pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ||
+                       dc_pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM))
+               e2e_pipe->pipe.src.num_cursors = 0;
+       else
+               e2e_pipe->pipe.src.num_cursors = 1;
+
+       e2e_pipe->pipe.src.cur0_src_width = 256;
+       e2e_pipe->pipe.src.cur0_bpp = dm_cur_32bit;
+}
+
+static int populate_dml_pipes_from_context_base(
+               struct dc *dc,
+               struct dc_state *context,
+               display_e2e_pipe_params_st *pipes,
+               bool fast_validate)
+{
+       int pipe_cnt, i;
+       bool synchronized_vblank = true;
+       struct resource_context *res_ctx = &context->res_ctx;
+
+       for (i = 0, pipe_cnt = -1; i < dc->res_pool->pipe_count; i++) {
+               if (!res_ctx->pipe_ctx[i].stream)
+                       continue;
+
+               if (pipe_cnt < 0) {
+                       pipe_cnt = i;
+                       continue;
+               }
+
+               if (res_ctx->pipe_ctx[pipe_cnt].stream == res_ctx->pipe_ctx[i].stream)
+                       continue;
+
+               if (dc->debug.disable_timing_sync ||
+                       (!resource_are_streams_timing_synchronizable(
+                               res_ctx->pipe_ctx[pipe_cnt].stream,
+                               res_ctx->pipe_ctx[i].stream) &&
+                       !resource_are_vblanks_synchronizable(
+                               res_ctx->pipe_ctx[pipe_cnt].stream,
+                               res_ctx->pipe_ctx[i].stream))) {
+                       synchronized_vblank = false;
+                       break;
+               }
+       }
+
+       for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+               struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing;
+
+               struct audio_check aud_check = {0};
+               if (!res_ctx->pipe_ctx[i].stream)
+                       continue;
+
+               /* todo:
+               pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0;
+               pipes[pipe_cnt].pipe.src.dcc = 0;
+               pipes[pipe_cnt].pipe.src.vm = 0;*/
+
+               pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
+
+               pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC;
+               /* todo: rotation?*/
+               pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h;
+               if (res_ctx->pipe_ctx[i].stream->use_dynamic_meta) {
+                       pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = true;
+                       /* 1/2 vblank */
+                       pipes[pipe_cnt].pipe.src.dynamic_metadata_lines_before_active =
+                               (timing->v_total - timing->v_addressable
+                                       - timing->v_border_top - timing->v_border_bottom) / 2;
+                       /* 36 bytes dp, 32 hdmi */
+                       pipes[pipe_cnt].pipe.src.dynamic_metadata_xmit_bytes =
+                               dc_is_dp_signal(res_ctx->pipe_ctx[i].stream->signal) ? 36 : 32;
+               }
+               pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;
+
+               dc_timing_to_dml_timing(timing, &pipes[pipe_cnt].pipe.dest);
+               pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;
+               pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;
+
+               pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst;
+
+               pipes[pipe_cnt].pipe.dest.odm_combine = get_dml_odm_combine(&res_ctx->pipe_ctx[i]);
+
+               populate_hsplit_group_from_dc_pipe_ctx(&res_ctx->pipe_ctx[i], &pipes[pipe_cnt]);
+
+               pipes[pipe_cnt].dout.dp_lanes = 4;
+               pipes[pipe_cnt].dout.is_virtual = 0;
+               pipes[pipe_cnt].dout.output_type = get_dml_output_type(res_ctx->pipe_ctx[i].stream->signal);
+               if (pipes[pipe_cnt].dout.output_type < 0) {
+                       pipes[pipe_cnt].dout.output_type = dm_dp;
+                       pipes[pipe_cnt].dout.is_virtual = 1;
+               }
+
+               populate_color_depth_and_encoding_from_timing(&res_ctx->pipe_ctx[i].stream->timing, &pipes[pipe_cnt].dout);
+
+               if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC)
+                       pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0;
+
+               /* todo: default max for now, until there is logic reflecting this in dc*/
+               pipes[pipe_cnt].dout.dsc_input_bpc = 12;
+               /*fill up the audio sample rate (unit in kHz)*/
+               get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check);
+               pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000;
+
+               populate_dml_cursor_parameters_from_dc_pipe_ctx(&res_ctx->pipe_ctx[i], &pipes[pipe_cnt]);
+
+               if (!res_ctx->pipe_ctx[i].plane_state) {
+                       populate_default_plane_from_timing(timing, &pipes[pipe_cnt].pipe);
+               } else {
+                       populate_dml_from_dc_pipe_ctx(&res_ctx->pipe_ctx[i], &pipes[pipe_cnt], dc->debug.always_scale);
+               }
+
+               pipe_cnt++;
+       }
+
+       /* populate writeback information */
+       if (dc->res_pool)
+               dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes);
+
+       return pipe_cnt;
+}
+
+static int dml_populate_dml_pipes_from_context(
+       struct dc *dc, struct dc_state *context,
+       display_e2e_pipe_params_st *pipes,
+       bool fast_validate)
+{
+       int i, pipe_cnt;
+       struct resource_context *res_ctx = &context->res_ctx;
+       struct pipe_ctx *pipe;
+
+       populate_dml_pipes_from_context_base(dc, context, pipes, fast_validate);
+
+       for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+               struct dc_crtc_timing *timing;
+
+               if (!res_ctx->pipe_ctx[i].stream)
+                       continue;
+               pipe = &res_ctx->pipe_ctx[i];
+               timing = &pipe->stream->timing;
+
+               pipes[pipe_cnt].pipe.src.gpuvm = true;
+               pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
+               pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
+               pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
+
+               pipes[pipe_cnt].dout.dsc_input_bpc = 0;
+               if (pipes[pipe_cnt].dout.dsc_enable) {
+                       switch (timing->display_color_depth) {
+                       case COLOR_DEPTH_888:
+                               pipes[pipe_cnt].dout.dsc_input_bpc = 8;
+                               break;
+                       case COLOR_DEPTH_101010:
+                               pipes[pipe_cnt].dout.dsc_input_bpc = 10;
+                               break;
+                       case COLOR_DEPTH_121212:
+                               pipes[pipe_cnt].dout.dsc_input_bpc = 12;
+                               break;
+                       default:
+                               ASSERT(0);
+                               break;
+                       }
+               }
+               pipe_cnt++;
+       }
+       dc->config.enable_4to1MPC = false;
+       if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
+               if (is_dual_plane(pipe->plane_state->format)
+                               && pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) {
+                       dc->config.enable_4to1MPC = true;
+               } else if (!is_dual_plane(pipe->plane_state->format)) {
+                       context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
+                       pipes[0].pipe.src.unbounded_req_mode = true;
+               }
+       }
+
+       return pipe_cnt;
+}
+
+static void dml_full_validate_bw_helper(struct dc *dc,
+               struct dc_state *context,
+               display_e2e_pipe_params_st *pipes,
+               int *vlevel,
+               int *split,
+               bool *merge,
+               int *pipe_cnt)
+{
+       struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
+
+       /*
+        * DML favors voltage over p-state, but we're more interested in
+        * supporting p-state over voltage. We can't support p-state in
+        * prefetch mode > 0 so try capping the prefetch mode to start.
+        */
+       context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank =
+               dm_allow_self_refresh_and_mclk_switch;
+       *vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, *pipe_cnt);
+       /* This may adjust vlevel and maxMpcComb */
+       if (*vlevel < context->bw_ctx.dml.soc.num_states)
+               *vlevel = dml_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge);
+
+       /* Conditions for setting up phantom pipes for SubVP:
+        * 1. Not force disable SubVP
+        * 2. Full update (i.e. !fast_validate)
+        * 3. Enough pipes are available to support SubVP (TODO: Which pipes will use VACTIVE / VBLANK / SUBVP?)
+        * 4. Display configuration passes validation
+        * 5. (Config doesn't support MCLK in VACTIVE/VBLANK || dc->debug.force_subvp_mclk_switch)
+        */
+       if (!dc->debug.force_disable_subvp &&
+                       dml_enough_pipes_for_subvp(dc, context) &&
+                       *vlevel < context->bw_ctx.dml.soc.num_states &&
+                       (vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported ||
+                       dc->debug.force_subvp_mclk_switch)) {
+
+               dml_add_phantom_pipes(dc, context);
+
+                /* Create input to DML based on new context which includes phantom pipes
+                 * TODO: Input to DML should mark which pipes are phantom
+                 */
+               *pipe_cnt = dml_populate_dml_pipes_from_context(dc, context, pipes, false);
+               *vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, *pipe_cnt);
+               if (*vlevel < context->bw_ctx.dml.soc.num_states) {
+                       memset(split, 0, sizeof(split));
+                       memset(merge, 0, sizeof(merge));
+                       *vlevel = dml_validate_apply_pipe_split_flags(dc, context, *vlevel, split, merge);
+               }
+
+               // If SubVP pipe config is unsupported (or cannot be used for UCLK switching)
+               // remove phantom pipes and repopulate dml pipes
+               if (*vlevel == context->bw_ctx.dml.soc.num_states ||
+                               vba->DRAMClockChangeSupport[*vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
+                       dml_remove_phantom_pipes(dc, context);
+                       *pipe_cnt = dml_populate_dml_pipes_from_context(dc, context, pipes, false);
+               }
+       }
+}
+
+static void dcn20_adjust_adaptive_sync_v_startup(
+               const struct dc_crtc_timing *dc_crtc_timing, int *vstartup_start)
+{
+       struct dc_crtc_timing patched_crtc_timing;
+       uint32_t asic_blank_end   = 0;
+       uint32_t asic_blank_start = 0;
+       uint32_t newVstartup      = 0;
+
+       patched_crtc_timing = *dc_crtc_timing;
+
+       if (patched_crtc_timing.flags.INTERLACE == 1) {
+               if (patched_crtc_timing.v_front_porch < 2)
+                       patched_crtc_timing.v_front_porch = 2;
+       } else {
+               if (patched_crtc_timing.v_front_porch < 1)
+                       patched_crtc_timing.v_front_porch = 1;
+       }
+
+       /* blank_start = frame end - front porch */
+       asic_blank_start = patched_crtc_timing.v_total -
+                                       patched_crtc_timing.v_front_porch;
+
+       /* blank_end = blank_start - active */
+       asic_blank_end = asic_blank_start -
+                                       patched_crtc_timing.v_border_bottom -
+                                       patched_crtc_timing.v_addressable -
+                                       patched_crtc_timing.v_border_top;
+
+       newVstartup = asic_blank_end + (patched_crtc_timing.v_total - asic_blank_start);
+
+       *vstartup_start = ((newVstartup > *vstartup_start) ? newVstartup : *vstartup_start);
+}
+
+static bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx)
+{
+       return (pipe_ctx->stream_res.hpo_dp_stream_enc &&
+                       pipe_ctx->stream->link->hpo_dp_link_enc &&
+                       dc_is_dp_signal(pipe_ctx->stream->signal));
+}
+
+static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (!context->res_ctx.pipe_ctx[i].stream)
+                       continue;
+#if defined (CONFIG_DRM_AMD_DC_DP2_0)
+               if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
+                       return true;
+#endif
+       }
+       return false;
+}
+
+static void dml_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
+{
+       if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid) {
+               context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
+               context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us;
+               context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us;
+       }
+}
+
+static bool dml_internal_validate(
+               struct dc *dc,
+               struct dc_state *context,
+               display_e2e_pipe_params_st *pipes,
+               int *pipe_cnt_out,
+               int *vlevel_out,
+               bool fast_validate)
+{
+       bool out = false;
+       bool repopulate_pipes = false;
+       int split[MAX_PIPES] = { 0 };
+       bool merge[MAX_PIPES] = { false };
+       bool newly_split[MAX_PIPES] = { false };
+       int pipe_cnt, i, pipe_idx, vlevel;
+       struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
+
+       ASSERT(pipes);
+       if (!pipes)
+               return false;
+
+       // For each full update, remove all existing phantom pipes first
+       dml_remove_phantom_pipes(dc, context);
+
+       dml_update_soc_for_wm_a(dc, context);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->plane_state) {
+                       // On initial pass through DML, we intend to use MALL for SS on all
+                       // (non-PSR) surfaces with none using MALL for P-State
+                       // 'mall_plane_config': is not a member of 'dc_plane_state' - commenting it out till mall_plane_config gets supported in dc_plant_state
+                       //if (pipe->stream && pipe->stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED)
+                       //      pipe->plane_state->mall_plane_config.use_mall_for_ss = true;
+               }
+       }
+       pipe_cnt = dml_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
+
+       if (!pipe_cnt) {
+               out = true;
+               goto validate_out;
+       }
+
+       dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
+
+       if (!fast_validate) {
+               dml_full_validate_bw_helper(dc, context, pipes, &vlevel, split, merge, &pipe_cnt);
+       }
+
+       if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
+                       vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
+               /*
+                * If mode is unsupported or there's still no p-state support then
+                * fall back to favoring voltage.
+                *
+                * We don't actually support prefetch mode 2, so require that we
+                * at least support prefetch mode 1.
+                */
+               context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank =
+                       dm_allow_self_refresh;
+
+               vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
+               if (vlevel < context->bw_ctx.dml.soc.num_states) {
+                       memset(split, 0, sizeof(split));
+                       memset(merge, 0, sizeof(merge));
+                       vlevel = dml_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
+               }
+       }
+
+       dml_log_mode_support_params(&context->bw_ctx.dml);
+
+       if (vlevel == context->bw_ctx.dml.soc.num_states)
+               goto validate_fail;
+
+       for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *mpo_pipe = pipe->bottom_pipe;
+
+               if (!pipe->stream)
+                       continue;
+
+               /* We only support full screen mpo with ODM */
+               if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled
+                               && pipe->plane_state && mpo_pipe
+                               && memcmp(&mpo_pipe->plane_res.scl_data.recout,
+                                               &pipe->plane_res.scl_data.recout,
+                                               sizeof(struct rect)) != 0) {
+                       ASSERT(mpo_pipe->plane_state != pipe->plane_state);
+                       goto validate_fail;
+               }
+               pipe_idx++;
+       }
+
+       /* merge pipes if necessary */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               /*skip pipes that don't need merging*/
+               if (!merge[i])
+                       continue;
+
+               /* if ODM merge we ignore mpc tree, mpo pipes will have their own flags */
+               if (pipe->prev_odm_pipe) {
+                       /*split off odm pipe*/
+                       pipe->prev_odm_pipe->next_odm_pipe = pipe->next_odm_pipe;
+                       if (pipe->next_odm_pipe)
+                               pipe->next_odm_pipe->prev_odm_pipe = pipe->prev_odm_pipe;
+
+                       pipe->bottom_pipe = NULL;
+                       pipe->next_odm_pipe = NULL;
+                       pipe->plane_state = NULL;
+                       pipe->stream = NULL;
+                       pipe->top_pipe = NULL;
+                       pipe->prev_odm_pipe = NULL;
+                       if (pipe->stream_res.dsc)
+                               dml_release_dsc(&context->res_ctx, dc->res_pool, &pipe->stream_res.dsc);
+                       memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
+                       memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
+                       repopulate_pipes = true;
+               } else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) {
+                       struct pipe_ctx *top_pipe = pipe->top_pipe;
+                       struct pipe_ctx *bottom_pipe = pipe->bottom_pipe;
+
+                       top_pipe->bottom_pipe = bottom_pipe;
+                       if (bottom_pipe)
+                               bottom_pipe->top_pipe = top_pipe;
+
+                       pipe->top_pipe = NULL;
+                       pipe->bottom_pipe = NULL;
+                       pipe->plane_state = NULL;
+                       pipe->stream = NULL;
+                       memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
+                       memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
+                       repopulate_pipes = true;
+               } else
+                       ASSERT(0); /* Should never try to merge master pipe */
+
+       }
+
+       for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+               struct pipe_ctx *hsplit_pipe = NULL;
+               bool odm;
+               int old_index = -1;
+
+               if (!pipe->stream || newly_split[i])
+                       continue;
+
+               pipe_idx++;
+               odm = vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled;
+
+               if (!pipe->plane_state && !odm)
+                       continue;
+
+               if (split[i]) {
+                       if (odm) {
+                               if (split[i] == 4 && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe)
+                                       old_index = old_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
+                               else if (old_pipe->next_odm_pipe)
+                                       old_index = old_pipe->next_odm_pipe->pipe_idx;
+                       } else {
+                               if (split[i] == 4 && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe &&
+                                               old_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
+                                       old_index = old_pipe->bottom_pipe->bottom_pipe->pipe_idx;
+                               else if (old_pipe->bottom_pipe &&
+                                               old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
+                                       old_index = old_pipe->bottom_pipe->pipe_idx;
+                       }
+                       hsplit_pipe = dml_find_split_pipe(dc, context, old_index);
+                       ASSERT(hsplit_pipe);
+                       if (!hsplit_pipe)
+                               goto validate_fail;
+
+                       if (!dml_split_stream_for_mpc_or_odm(
+                                       dc, &context->res_ctx,
+                                       pipe, hsplit_pipe, odm))
+                               goto validate_fail;
+
+                       newly_split[hsplit_pipe->pipe_idx] = true;
+                       repopulate_pipes = true;
+               }
+               if (split[i] == 4) {
+                       struct pipe_ctx *pipe_4to1;
+
+                       if (odm && old_pipe->next_odm_pipe)
+                               old_index = old_pipe->next_odm_pipe->pipe_idx;
+                       else if (!odm && old_pipe->bottom_pipe &&
+                                               old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
+                               old_index = old_pipe->bottom_pipe->pipe_idx;
+                       else
+                               old_index = -1;
+                       pipe_4to1 = dml_find_split_pipe(dc, context, old_index);
+                       ASSERT(pipe_4to1);
+                       if (!pipe_4to1)
+                               goto validate_fail;
+                       if (!dml_split_stream_for_mpc_or_odm(
+                                       dc, &context->res_ctx,
+                                       pipe, pipe_4to1, odm))
+                               goto validate_fail;
+                       newly_split[pipe_4to1->pipe_idx] = true;
+
+                       if (odm && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe
+                                       && old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe)
+                               old_index = old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
+                       else if (!odm && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe &&
+                                       old_pipe->bottom_pipe->bottom_pipe->bottom_pipe &&
+                                       old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
+                               old_index = old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx;
+                       else
+                               old_index = -1;
+                       pipe_4to1 = dml_find_split_pipe(dc, context, old_index);
+                       ASSERT(pipe_4to1);
+                       if (!pipe_4to1)
+                               goto validate_fail;
+                       if (!dml_split_stream_for_mpc_or_odm(
+                                       dc, &context->res_ctx,
+                                       hsplit_pipe, pipe_4to1, odm))
+                               goto validate_fail;
+                       newly_split[pipe_4to1->pipe_idx] = true;
+               }
+               if (odm)
+                       dml_build_mapped_resource(dc, context, pipe->stream);
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->plane_state) {
+                       if (!resource_build_scaling_params(pipe))
+                               goto validate_fail;
+               }
+       }
+
+       /* Actual dsc count per stream dsc validation*/
+       if (!dml_validate_dsc(dc, context)) {
+               vba->ValidationStatus[vba->soc.num_states] = DML_FAIL_DSC_VALIDATION_FAILURE;
+               goto validate_fail;
+       }
+
+       if (repopulate_pipes)
+               pipe_cnt = dml_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
+       *vlevel_out = vlevel;
+       *pipe_cnt_out = pipe_cnt;
+
+       out = true;
+       goto validate_out;
+
+validate_fail:
+       out = false;
+
+validate_out:
+       return out;
+}
+
+static void dml_calculate_dlg_params(
+               struct dc *dc, struct dc_state *context,
+               display_e2e_pipe_params_st *pipes,
+               int pipe_cnt,
+               int vlevel)
+{
+       int i, pipe_idx;
+       int plane_count;
+
+       /* Writeback MCIF_WB arbitration parameters */
+       if (dc->res_pool)
+               dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);
+
+       context->bw_ctx.bw.dcn.clk.dispclk_khz = context->bw_ctx.dml.vba.DISPCLK * 1000;
+       context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000;
+       context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000;
+       context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16;
+       context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000;
+       context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000;
+       context->bw_ctx.bw.dcn.clk.p_state_change_support =
+               context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]
+                                                       != dm_dram_clock_change_unsupported;
+
+       context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
+       /* 'z9_support': is not a member of 'dc_clocks' - Commenting out till we have this support in dc_clocks
+        * context->bw_ctx.bw.dcn.clk.z9_support = (context->bw_ctx.dml.vba.StutterPeriod > 5000.0) ?
+                       DCN_Z9_SUPPORT_ALLOW : DCN_Z9_SUPPORT_DISALLOW;
+       */
+       plane_count = 0;
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (context->res_ctx.pipe_ctx[i].plane_state)
+                       plane_count++;
+       }
+
+       /* Commented out as per above error for now.
+       if (plane_count == 0)
+               context->bw_ctx.bw.dcn.clk.z9_support = DCN_Z9_SUPPORT_ALLOW;
+       */
+       context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context);
+       /* TODO : Uncomment the below line and make changes
+        * as per DML nomenclature once it is available.
+        * context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = context->bw_ctx.dml.vba.fclk_pstate_support;
+        */
+
+       if (context->bw_ctx.bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz)
+               context->bw_ctx.bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz;
+
+       for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+               if (!context->res_ctx.pipe_ctx[i].stream)
+                       continue;
+               pipes[pipe_idx].pipe.dest.vstartup_start = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+               pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+               pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+               pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+               if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                       // Phantom pipe requires that DET_SIZE = 0 and no unbounded requests
+                       context->res_ctx.pipe_ctx[i].det_buffer_size_kb = 0;
+                       context->res_ctx.pipe_ctx[i].unbounded_req = false;
+               } else {
+                       context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes;
+                       context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode;
+               }
+
+               if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
+                       context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
+               context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =
+                                               pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
+               context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest;
+               pipe_idx++;
+       }
+       /*save a original dppclock copy*/
+       context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz;
+       context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz;
+       context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz * 1000;
+       context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz * 1000;
+       context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes
+                                               - context->bw_ctx.dml.ip.det_buffer_size_kbytes * pipe_idx;
+
+       for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+               bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2;
+
+               if (!context->res_ctx.pipe_ctx[i].stream)
+                       continue;
+
+               context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml,
+                               &context->res_ctx.pipe_ctx[i].dlg_regs,
+                               &context->res_ctx.pipe_ctx[i].ttu_regs,
+                               pipes,
+                               pipe_cnt,
+                               pipe_idx,
+                               cstate_en,
+                               context->bw_ctx.bw.dcn.clk.p_state_change_support,
+                               false, false, true);
+
+               context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,
+                               &context->res_ctx.pipe_ctx[i].rq_regs,
+                               &pipes[pipe_idx].pipe);
+               pipe_idx++;
+       }
+}
+
+static void dml_calculate_wm_and_dlg(
+               struct dc *dc, struct dc_state *context,
+               display_e2e_pipe_params_st *pipes,
+               int pipe_cnt,
+               int vlevel)
+{
+       int i, pipe_idx, vlevel_temp = 0;
+
+       double dcfclk = context->bw_ctx.dml.soc.clock_limits[0].dcfclk_mhz;
+       double dcfclk_from_validation = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+       unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed;
+       bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] !=
+                       dm_dram_clock_change_unsupported;
+
+       /* Set B:
+        * For Set B calculations use clocks from clock_limits[2] when available i.e. when SMU is present,
+        * otherwise use arbitrary low value from spreadsheet for DCFCLK as lower is safer for watermark
+        * calculations to cover bootup clocks.
+        * DCFCLK: soc.clock_limits[2] when available
+        * UCLK: soc.clock_limits[2] when available
+        */
+       if (context->bw_ctx.dml.soc.num_states > 2) {
+               vlevel_temp = 2;
+               dcfclk = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
+       } else
+               dcfclk = 615; //DCFCLK Vmin_lv
+
+       pipes[0].clks_cfg.voltage = vlevel_temp;
+       pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
+       pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel_temp].socclk_mhz;
+
+       if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].valid) {
+               context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us;
+               context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us;
+               context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us;
+       }
+       context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       //context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.fclk_pstate_change_ns = get_wm_fclk_pstate(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       //context->bw_ctx.bw.dcn.watermarks.b.usr_retraining_ns = get_wm_usr_retraining(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+       /* Temporary, to have some fclk_pstate_change_ns and usr_retraining_ns wm values until DML is implemented */
+       context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.fclk_pstate_change_ns = context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns / 4;
+       context->bw_ctx.bw.dcn.watermarks.b.usr_retraining_ns = context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns / 8;
+
+       /* Set D:
+        * All clocks min.
+        * DCFCLK: Min, as reported by PM FW when available
+        * UCLK  : Min, as reported by PM FW when available
+        * sr_enter_exit/sr_exit should be lower than used for DRAM (TBD after bringup or later, use as decided in Clk Mgr)
+        */
+
+       if (context->bw_ctx.dml.soc.num_states > 2) {
+               vlevel_temp = 0;
+               dcfclk = dc->clk_mgr->bw_params->clk_table.entries[0].dcfclk_mhz;
+       } else
+               dcfclk = 615; //DCFCLK Vmin_lv
+
+       pipes[0].clks_cfg.voltage = vlevel_temp;
+       pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
+       pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel_temp].socclk_mhz;
+
+       if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) {
+               context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us;
+               context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us;
+               context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us;
+       }
+       context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       //context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.fclk_pstate_change_ns = get_wm_fclk_pstate(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       //context->bw_ctx.bw.dcn.watermarks.d.usr_retraining_ns = get_wm_usr_retraining(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+       /* Temporary, to have some fclk_pstate_change_ns and usr_retraining_ns wm values until DML is implemented */
+       context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.fclk_pstate_change_ns = context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns / 4;
+       context->bw_ctx.bw.dcn.watermarks.d.usr_retraining_ns = context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns / 8;
+
+       /* Set C, for Dummy P-State:
+        * All clocks min.
+        * DCFCLK: Min, as reported by PM FW, when available
+        * UCLK  : Min,  as reported by PM FW, when available
+        * pstate latency as per UCLK state dummy pstate latency
+        */
+       if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) {
+               unsigned int min_dram_speed_mts_margin = 160;
+
+               if ((!pstate_en))
+                       min_dram_speed_mts = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz * 16;
+
+               /* find largest table entry that is lower than dram speed, but lower than DPM0 still uses DPM0 */
+               for (i = 3; i > 0; i--)
+                       if (min_dram_speed_mts + min_dram_speed_mts_margin > dc->clk_mgr->bw_params->dummy_pstate_table[i].dram_speed_mts)
+                               break;
+
+               context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us;
+               context->bw_ctx.dml.soc.dummy_pstate_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us;
+               context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us;
+               context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us;
+       }
+       context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       //context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.fclk_pstate_change_ns = get_wm_fclk_pstate(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       //context->bw_ctx.bw.dcn.watermarks.c.usr_retraining_ns = get_wm_usr_retraining(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+       /* Temporary, to have some fclk_pstate_change_ns and usr_retraining_ns wm values until DML is implemented */
+       context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.fclk_pstate_change_ns = context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns / 4;
+       context->bw_ctx.bw.dcn.watermarks.c.usr_retraining_ns = context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns / 8;
+
+       if ((!pstate_en) && (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid)) {
+               /* The only difference between A and C is p-state latency, if p-state is not supported
+                * with full p-state latency we want to calculate DLG based on dummy p-state latency,
+                * Set A p-state watermark set to 0 previously, when p-state unsupported, for now keep as previous implementation.
+                */
+               context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c;
+               context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0;
+       } else {
+               /* Set A:
+                * All clocks min.
+                * DCFCLK: Min, as reported by PM FW, when available
+                * UCLK: Min, as reported by PM FW, when available
+                */
+               dml_update_soc_for_wm_a(dc, context);
+               context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+               context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+               context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+               context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+               context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+               context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+               context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+               context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+       }
+
+       pipes[0].clks_cfg.voltage = vlevel;
+       pipes[0].clks_cfg.dcfclk_mhz = dcfclk_from_validation;
+       pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
+
+       for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+               if (!context->res_ctx.pipe_ctx[i].stream)
+                       continue;
+
+               pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
+               pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+
+               if (dc->config.forced_clocks) {
+                       pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
+                       pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
+               }
+               if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
+                       pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
+               if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
+                       pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
+
+               pipe_idx++;
+       }
+
+       context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod;
+
+       dml_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+
+       if (!pstate_en)
+               /* Restore full p-state latency */
+               context->bw_ctx.dml.soc.dram_clock_change_latency_us =
+                               dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
+}
+
+bool dml_validate(struct dc *dc,
+               struct dc_state *context,
+               bool fast_validate)
+{
+       bool out = false;
+
+       BW_VAL_TRACE_SETUP();
+
+       int vlevel = 0;
+       int pipe_cnt = 0;
+       display_e2e_pipe_params_st *pipes = context->bw_ctx.dml.dml_pipe_state;
+       DC_LOGGER_INIT(dc->ctx->logger);
+
+       BW_VAL_TRACE_COUNT();
+
+       out = dml_internal_validate(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
+
+       if (pipe_cnt == 0)
+               goto validate_out;
+
+       if (!out)
+               goto validate_fail;
+
+       BW_VAL_TRACE_END_VOLTAGE_LEVEL();
+
+       if (fast_validate) {
+               BW_VAL_TRACE_SKIP(fast);
+               goto validate_out;
+       }
+
+       dml_calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
+
+       BW_VAL_TRACE_END_WATERMARKS();
+
+       goto validate_out;
+
+validate_fail:
+       DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
+               dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
+
+       BW_VAL_TRACE_SKIP(fail);
+       out = false;
+
+validate_out:
+       BW_VAL_TRACE_FINISH();
+
+       return out;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper_translation.c b/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper_translation.c
new file mode 100644 (file)
index 0000000..4ec5310
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2017 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
+ *
+ */
+
+#ifdef DML_WRAPPER_TRANSLATION_
+
+static void gfx10array_mode_to_dml_params(
+               enum array_mode_values array_mode,
+               enum legacy_tiling_compat_level compat_level,
+               unsigned int *sw_mode)
+{
+       switch (array_mode) {
+       case DC_ARRAY_LINEAR_ALLIGNED:
+       case DC_ARRAY_LINEAR_GENERAL:
+               *sw_mode = dm_sw_linear;
+               break;
+       case DC_ARRAY_2D_TILED_THIN1:
+// DC_LEGACY_TILING_ADDR_GEN_ZERO - undefined as per current code hence removed
+#if 0
+               if (compat_level == DC_LEGACY_TILING_ADDR_GEN_ZERO)
+                       *sw_mode = dm_sw_gfx7_2d_thin_l_vp;
+               else
+                       *sw_mode = dm_sw_gfx7_2d_thin_gl;
+#endif
+               break;
+       default:
+               ASSERT(0); /* Not supported */
+               break;
+       }
+}
+
+static void swizzle_to_dml_params(
+               enum swizzle_mode_values swizzle,
+               unsigned int *sw_mode)
+{
+       switch (swizzle) {
+       case DC_SW_LINEAR:
+               *sw_mode = dm_sw_linear;
+               break;
+       case DC_SW_4KB_S:
+               *sw_mode = dm_sw_4kb_s;
+               break;
+       case DC_SW_4KB_S_X:
+               *sw_mode = dm_sw_4kb_s_x;
+               break;
+       case DC_SW_4KB_D:
+               *sw_mode = dm_sw_4kb_d;
+               break;
+       case DC_SW_4KB_D_X:
+               *sw_mode = dm_sw_4kb_d_x;
+               break;
+       case DC_SW_64KB_S:
+               *sw_mode = dm_sw_64kb_s;
+               break;
+       case DC_SW_64KB_S_X:
+               *sw_mode = dm_sw_64kb_s_x;
+               break;
+       case DC_SW_64KB_S_T:
+               *sw_mode = dm_sw_64kb_s_t;
+               break;
+       case DC_SW_64KB_D:
+               *sw_mode = dm_sw_64kb_d;
+               break;
+       case DC_SW_64KB_D_X:
+               *sw_mode = dm_sw_64kb_d_x;
+               break;
+       case DC_SW_64KB_D_T:
+               *sw_mode = dm_sw_64kb_d_t;
+               break;
+       case DC_SW_64KB_R_X:
+               *sw_mode = dm_sw_64kb_r_x;
+               break;
+       case DC_SW_VAR_S:
+               *sw_mode = dm_sw_var_s;
+               break;
+       case DC_SW_VAR_S_X:
+               *sw_mode = dm_sw_var_s_x;
+               break;
+       case DC_SW_VAR_D:
+               *sw_mode = dm_sw_var_d;
+               break;
+       case DC_SW_VAR_D_X:
+               *sw_mode = dm_sw_var_d_x;
+               break;
+
+       default:
+               ASSERT(0); /* Not supported */
+               break;
+       }
+}
+
+static void dc_timing_to_dml_timing(const struct dc_crtc_timing *timing, struct _vcs_dpi_display_pipe_dest_params_st *dest)
+{
+       dest->hblank_start = timing->h_total - timing->h_front_porch;
+       dest->hblank_end = dest->hblank_start
+                       - timing->h_addressable
+                       - timing->h_border_left
+                       - timing->h_border_right;
+       dest->vblank_start = timing->v_total - timing->v_front_porch;
+       dest->vblank_end = dest->vblank_start
+                       - timing->v_addressable
+                       - timing->v_border_top
+                       - timing->v_border_bottom;
+       dest->htotal = timing->h_total;
+       dest->vtotal = timing->v_total;
+       dest->hactive = timing->h_addressable;
+       dest->vactive = timing->v_addressable;
+       dest->interlaced = timing->flags.INTERLACE;
+       dest->pixel_rate_mhz = timing->pix_clk_100hz/10000.0;
+       if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
+               dest->pixel_rate_mhz *= 2;
+}
+
+static enum odm_combine_mode get_dml_odm_combine(const struct pipe_ctx *pipe)
+{
+       int odm_split_count = 0;
+       enum odm_combine_mode combine_mode = dm_odm_combine_mode_disabled;
+       struct pipe_ctx *next_pipe = pipe->next_odm_pipe;
+
+       // Traverse pipe tree to determine odm split count
+       while (next_pipe) {
+               odm_split_count++;
+               next_pipe = next_pipe->next_odm_pipe;
+       }
+       pipe = pipe->prev_odm_pipe;
+       while (pipe) {
+               odm_split_count++;
+               pipe = pipe->prev_odm_pipe;
+       }
+
+       // Translate split to DML odm combine factor
+       switch (odm_split_count) {
+       case 1:
+               combine_mode = dm_odm_combine_mode_2to1;
+               break;
+       case 3:
+               combine_mode = dm_odm_combine_mode_4to1;
+               break;
+       default:
+               combine_mode = dm_odm_combine_mode_disabled;
+       }
+
+       return combine_mode;
+}
+
+static int get_dml_output_type(enum signal_type dc_signal)
+{
+       int dml_output_type = -1;
+
+       switch (dc_signal) {
+       case SIGNAL_TYPE_DISPLAY_PORT_MST:
+       case SIGNAL_TYPE_DISPLAY_PORT:
+               dml_output_type = dm_dp;
+               break;
+       case SIGNAL_TYPE_EDP:
+               dml_output_type = dm_edp;
+               break;
+       case SIGNAL_TYPE_HDMI_TYPE_A:
+       case SIGNAL_TYPE_DVI_SINGLE_LINK:
+       case SIGNAL_TYPE_DVI_DUAL_LINK:
+               dml_output_type = dm_hdmi;
+               break;
+       default:
+               break;
+       }
+
+       return dml_output_type;
+}
+
+static void populate_color_depth_and_encoding_from_timing(const struct dc_crtc_timing *timing, struct _vcs_dpi_display_output_params_st *dout)
+{
+       int output_bpc = 0;
+
+       switch (timing->display_color_depth) {
+       case COLOR_DEPTH_666:
+               output_bpc = 6;
+               break;
+       case COLOR_DEPTH_888:
+               output_bpc = 8;
+               break;
+       case COLOR_DEPTH_101010:
+               output_bpc = 10;
+               break;
+       case COLOR_DEPTH_121212:
+               output_bpc = 12;
+               break;
+       case COLOR_DEPTH_141414:
+               output_bpc = 14;
+               break;
+       case COLOR_DEPTH_161616:
+               output_bpc = 16;
+               break;
+       case COLOR_DEPTH_999:
+               output_bpc = 9;
+               break;
+       case COLOR_DEPTH_111111:
+               output_bpc = 11;
+               break;
+       default:
+               output_bpc = 8;
+               break;
+       }
+
+       switch (timing->pixel_encoding) {
+       case PIXEL_ENCODING_RGB:
+       case PIXEL_ENCODING_YCBCR444:
+               dout->output_format = dm_444;
+               dout->output_bpp = output_bpc * 3;
+               break;
+       case PIXEL_ENCODING_YCBCR420:
+               dout->output_format = dm_420;
+               dout->output_bpp = (output_bpc * 3.0) / 2;
+               break;
+       case PIXEL_ENCODING_YCBCR422:
+               if (timing->flags.DSC && !timing->dsc_cfg.ycbcr422_simple)
+                       dout->output_format = dm_n422;
+               else
+                       dout->output_format = dm_s422;
+               dout->output_bpp = output_bpc * 2;
+               break;
+       default:
+               dout->output_format = dm_444;
+               dout->output_bpp = output_bpc * 3;
+       }
+}
+
+static enum source_format_class dc_source_format_to_dml_source_format(enum surface_pixel_format dc_format)
+{
+       enum source_format_class dml_format = dm_444_32;
+
+       switch (dc_format) {
+       case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
+       case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
+               dml_format = dm_420_8;
+               break;
+       case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
+       case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
+               dml_format = dm_420_10;
+               break;
+       case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+       case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
+       case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
+               dml_format = dm_444_64;
+               break;
+       case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
+       case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
+               dml_format = dm_444_16;
+               break;
+       case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
+               dml_format = dm_444_8;
+               break;
+       case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
+               dml_format = dm_rgbe_alpha;
+               break;
+       default:
+               dml_format = dm_444_32;
+               break;
+       }
+
+       return dml_format;
+}
+
+#endif
index 3ee858f311d12a85679bca6500a7fa82688d0efd..122ba291a7efa9b576f092c5e553c465819018c8 100644 (file)
@@ -61,16 +61,6 @@ static double dsc_roundf(double num)
        return (int)(num);
 }
 
-static double dsc_ceil(double num)
-{
-       double retval = (int)num;
-
-       if (retval != num && num > 0)
-               retval = num + 1;
-
-       return (int)retval;
-}
-
 static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc,
                       enum max_min max_min, float bpp)
 {
@@ -268,24 +258,3 @@ void _do_calc_rc_params(struct rc_params *rc,
        rc->rc_buf_thresh[13] = 8064;
 }
 
-u32 _do_bytes_per_pixel_calc(int slice_width,
-               u16 drm_bpp,
-               bool is_navite_422_or_420)
-{
-       float bpp;
-       u32 bytes_per_pixel;
-       double d_bytes_per_pixel;
-
-       dc_assert_fp_enabled();
-
-       bpp = ((float)drm_bpp / 16.0);
-       d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width;
-       // TODO: Make sure the formula for calculating this is precise (ceiling
-       // vs. floor, and at what point they should be applied)
-       if (is_navite_422_or_420)
-               d_bytes_per_pixel /= 2;
-
-       bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000);
-
-       return bytes_per_pixel;
-}
index b93b95409fbe2d391f432324d0f21701403d2f5d..cad244c023cd3032b81b3d32c5f46ffbd0e8677a 100644 (file)
@@ -78,10 +78,6 @@ struct qp_entry {
 
 typedef struct qp_entry qp_table[];
 
-u32 _do_bytes_per_pixel_calc(int slice_width,
-               u16 drm_bpp,
-               bool is_navite_422_or_420);
-
 void _do_calc_rc_params(struct rc_params *rc,
                enum colour_mode cm,
                enum bits_per_comp bpc,
index 0321b4446e0563f92f473809ef0d7226396eff1a..9c74564cbd8dee637bebb02aadc3a7c30062c0a7 100644 (file)
@@ -455,6 +455,7 @@ static bool intersect_dsc_caps(
        if (pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420)
                dsc_common_caps->bpp_increment_div = min(dsc_common_caps->bpp_increment_div, (uint32_t)8);
 
+       dsc_common_caps->edp_sink_max_bits_per_pixel = dsc_sink_caps->edp_max_bits_per_pixel;
        dsc_common_caps->is_dp = dsc_sink_caps->is_dp;
        return true;
 }
@@ -513,6 +514,13 @@ static bool decide_dsc_bandwidth_range(
                        range->min_target_bpp_x16 = preferred_bpp_x16;
                }
        }
+       /* TODO - make this value generic to all signal types */
+       else if (dsc_caps->edp_sink_max_bits_per_pixel) {
+               /* apply max bpp limitation from edp sink */
+               range->max_target_bpp_x16 = MIN(dsc_caps->edp_sink_max_bits_per_pixel,
+                               max_bpp_x16);
+               range->min_target_bpp_x16 = min_bpp_x16;
+       }
        else {
                range->max_target_bpp_x16 = max_bpp_x16;
                range->min_target_bpp_x16 = min_bpp_x16;
@@ -574,7 +582,7 @@ static bool decide_dsc_target_bpp_x16(
        return *target_bpp_x16 != 0;
 }
 
-#define MIN_AVAILABLE_SLICES_SIZE  4
+#define MIN_AVAILABLE_SLICES_SIZE  6
 
 static int get_available_dsc_slices(union dsc_enc_slice_caps slice_caps, int *available_slices)
 {
@@ -860,6 +868,10 @@ static bool setup_dsc_config(
                min_slices_h = 0; // DSC TODO: Maybe try increasing the number of slices first?
 
        is_dsc_possible = (min_slices_h <= max_slices_h);
+
+       if (min_slices_h == 0 && max_slices_h == 0)
+               is_dsc_possible = false;
+
        if (!is_dsc_possible)
                goto done;
 
index b19d3aeb5962cec8ebf25c6db42eeb69bae9abfc..e97cf09be9d51955eb7a64a6ec91a2aa363b8917 100644 (file)
@@ -60,31 +60,3 @@ void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps)
                           pps->dsc_version_minor);
        DC_FP_END();
 }
-
-/**
- * calc_dsc_bytes_per_pixel - calculate bytes per pixel
- * @pps: DRM struct with all required DSC values
- *
- * Based on the information inside drm_dsc_config, this function calculates the
- * total of bytes per pixel.
- *
- * @note This calculation requires float point operation, most of it executes
- * under kernel_fpu_{begin,end}.
- *
- * Return:
- * Return the number of bytes per pixel
- */
-u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps)
-
-{
-       u32 ret;
-       u16 drm_bpp = pps->bits_per_pixel;
-       int slice_width  = pps->slice_width;
-       bool is_navite_422_or_420 = pps->native_422 || pps->native_420;
-
-       DC_FP_START();
-       ret = _do_bytes_per_pixel_calc(slice_width, drm_bpp,
-                                      is_navite_422_or_420);
-       DC_FP_END();
-       return ret;
-}
index c2340e001b57842bea854a3cb51cef999902c45d..80921c1c0d53cc9cc59286f1bee0efed3650ed23 100644 (file)
@@ -30,7 +30,6 @@
 #include "dml/dsc/rc_calc_fpu.h"
 
 void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps);
-u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps);
 
 #endif
 
index 1e19dd674e5a215a0b53e778f3008f27e21fbac4..7e306aa3e2b95c9f20aeafa6c6f2cd225fdd9884 100644 (file)
@@ -100,8 +100,7 @@ int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_par
        int              ret;
        struct rc_params rc;
        struct drm_dsc_config   dsc_cfg;
-
-       dsc_params->bytes_per_pixel = calc_dsc_bytes_per_pixel(pps);
+       unsigned long long tmp;
 
        calc_rc_params(&rc, pps);
        dsc_params->pps = *pps;
@@ -113,6 +112,9 @@ int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_par
        dsc_cfg.mux_word_size = dsc_params->pps.bits_per_component <= 10 ? 48 : 64;
 
        ret = drm_dsc_compute_rc_parameters(&dsc_cfg);
+       tmp = (unsigned long long)dsc_cfg.slice_chunk_size * 0x10000000 + (dsc_cfg.slice_width - 1);
+       do_div(tmp, (uint32_t)dsc_cfg.slice_width);  //ROUND-UP
+       dsc_params->bytes_per_pixel = (uint32_t)tmp;
 
        copy_pps_fields(&dsc_params->pps, &dsc_cfg);
        dsc_params->rc_buffer_model_size = dsc_cfg.rc_bits;
index 806f3041db1419ca505c5b842768f22f1da289c3..337c0161e72da17e2fbb1355e7f5f93ba0d9f0eb 100644 (file)
@@ -619,7 +619,7 @@ struct dcn_ip_params {
 };
 extern const struct dcn_ip_params dcn10_ip_defaults;
 
-bool dcn_validate_bandwidth(
+bool dcn10_validate_bandwidth(
                struct dc *dc,
                struct dc_state *context,
                bool fast_validate);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dml_wrapper.h b/drivers/gpu/drm/amd/display/dc/inc/dml_wrapper.h
new file mode 100644 (file)
index 0000000..5dcfbd8
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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
+ *
+ */
+
+#ifndef DML_WRAPPER_H_
+#define DML_WRAPPER_H_
+
+#include "dc.h"
+#include "dml/display_mode_vba.h"
+
+bool dml_validate(struct dc *dc, struct dc_state *context, bool fast_validate);
+
+#endif
index f94135c6e3c222b1ccb54f58825949581e548ce7..346f0ba73e864397f69e7ce933d98a863b31fa07 100644 (file)
@@ -61,6 +61,8 @@ struct dcn_dsc_state {
        uint32_t dsc_pic_height;
        uint32_t dsc_slice_bpg_offset;
        uint32_t dsc_chunk_size;
+       uint32_t dsc_fw_en;
+       uint32_t dsc_opp_source;
 };
 
 
@@ -88,6 +90,7 @@ struct dsc_enc_caps {
        int32_t max_total_throughput_mps; /* Maximum total throughput with all the slices combined */
        int32_t max_slice_width;
        uint32_t bpp_increment_div; /* bpp increment divisor, e.g. if 16, it's 1/16th of a bit */
+       uint32_t edp_sink_max_bits_per_pixel;
        bool is_dp;
 };
 
index c88e113b94d1204038b9680f17c35bb8bdfc6c19..073f8b667eff56ab3249d2214e94a9a88b25604c 100644 (file)
@@ -164,6 +164,10 @@ struct stream_encoder_funcs {
        void (*stop_dp_info_packets)(
                struct stream_encoder *enc);
 
+       void (*reset_fifo)(
+               struct stream_encoder *enc
+       );
+
        void (*dp_blank)(
                struct dc_link *link,
                struct stream_encoder *enc);
index 7390baf916b58451a3e490a4ef402286e327204a..c29320b3855da4da5ed5403e48fa0bfa32cced0e 100644 (file)
@@ -290,6 +290,8 @@ struct timing_generator_funcs {
                               enum optc_dsc_mode dsc_mode,
                               uint32_t dsc_bytes_per_pixel,
                               uint32_t dsc_slice_width);
+       void (*get_dsc_status)(struct timing_generator *optc,
+                                       uint32_t *dsc_mode);
        void (*set_odm_bypass)(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing);
        void (*set_odm_combine)(struct timing_generator *optc, int *opp_id, int opp_cnt,
                        struct dc_crtc_timing *timing);
index 10dcf6a5e9b15715ebed95702294cfce8bd822e7..a4e43b4826e0e7b9fde11d2c4091bb9f71fe5fbf 100644 (file)
@@ -36,7 +36,7 @@
  * Initialise link encoder resource tracking.
  */
 void link_enc_cfg_init(
-               struct dc *dc,
+               const struct dc *dc,
                struct dc_state *state);
 
 /*
index cd204eef073b0b8f06ebf97d3b69728d6859c176..83855b8a32e9077c66bc5249c178f2fa52e075a4 100644 (file)
@@ -360,6 +360,8 @@ struct dmub_srv_hw_funcs {
 
        uint32_t (*get_gpint_dataout)(struct dmub_srv *dmub);
 
+       void (*clear_inbox0_ack_register)(struct dmub_srv *dmub);
+       uint32_t (*read_inbox0_ack_register)(struct dmub_srv *dmub);
        void (*send_inbox0_cmd)(struct dmub_srv *dmub, union dmub_inbox0_data_register data);
        uint32_t (*get_current_time)(struct dmub_srv *dmub);
 
@@ -409,6 +411,7 @@ struct dmub_srv {
        struct dmub_srv_base_funcs funcs;
        struct dmub_srv_hw_funcs hw_funcs;
        struct dmub_rb inbox1_rb;
+       uint32_t inbox1_last_wptr;
        /**
         * outbox1_rb is accessed without locks (dal & dc)
         * and to be used only in dmub_srv_stat_get_notification()
@@ -735,6 +738,45 @@ bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_
 
 bool dmub_srv_should_detect(struct dmub_srv *dmub);
 
+/**
+ * dmub_srv_send_inbox0_cmd() - Send command to DMUB using INBOX0
+ * @dmub: the dmub service
+ * @data: the data to be sent in the INBOX0 command
+ *
+ * Send command by writing directly to INBOX0 WPTR
+ *
+ * Return:
+ *   DMUB_STATUS_OK - success
+ *   DMUB_STATUS_INVALID - hw_init false or hw function does not exist
+ */
+enum dmub_status dmub_srv_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data);
+
+/**
+ * dmub_srv_wait_for_inbox0_ack() - wait for DMUB to ACK INBOX0 command
+ * @dmub: the dmub service
+ * @timeout_us: the maximum number of microseconds to wait
+ *
+ * Wait for DMUB to ACK the INBOX0 message
+ *
+ * Return:
+ *   DMUB_STATUS_OK - success
+ *   DMUB_STATUS_INVALID - hw_init false or hw function does not exist
+ *   DMUB_STATUS_TIMEOUT - wait for ack timed out
+ */
+enum dmub_status dmub_srv_wait_for_inbox0_ack(struct dmub_srv *dmub, uint32_t timeout_us);
+
+/**
+ * dmub_srv_wait_for_inbox0_ack() - clear ACK register for INBOX0
+ * @dmub: the dmub service
+ *
+ * Clear ACK register for INBOX0
+ *
+ * Return:
+ *   DMUB_STATUS_OK - success
+ *   DMUB_STATUS_INVALID - hw_init false or hw function does not exist
+ */
+enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub);
+
 #if defined(__cplusplus)
 }
 #endif
index c29a67ccef17a3411fc1223e2edd6badb1a6b752..7eec6509086248dff2f3e3732e42b6c9f4c29c42 100644 (file)
 
 /* Firmware versioning. */
 #ifdef DMUB_EXPOSE_VERSION
-#define DMUB_FW_VERSION_GIT_HASH 0x1d82d23e
+#define DMUB_FW_VERSION_GIT_HASH 0x465e619a
 #define DMUB_FW_VERSION_MAJOR 0
 #define DMUB_FW_VERSION_MINOR 0
-#define DMUB_FW_VERSION_REVISION 91
+#define DMUB_FW_VERSION_REVISION 94
 #define DMUB_FW_VERSION_TEST 0
 #define DMUB_FW_VERSION_VBIOS 0
 #define DMUB_FW_VERSION_HOTFIX 0
@@ -172,13 +172,6 @@ extern "C" {
 #define dmub_udelay(microseconds) udelay(microseconds)
 #endif
 
-/**
- * Number of nanoseconds per DMUB tick.
- * DMCUB_TIMER_CURRENT increments in DMUB ticks, which are 10ns by default.
- * If DMCUB_TIMER_WINDOW is non-zero this will no longer be true.
- */
-#define NS_PER_DMUB_TICK 10
-
 /**
  * union dmub_addr - DMUB physical/virtual 64-bit address.
  */
@@ -208,10 +201,9 @@ union dmub_psr_debug_flags {
                uint32_t use_hw_lock_mgr : 1;
 
                /**
-                * Unused.
-                * TODO: Remove.
+                * Use TPS3 signal when restore main link.
                 */
-               uint32_t log_line_nums : 1;
+               uint32_t force_wakeup_by_tps3 : 1;
        } bitfields;
 
        /**
@@ -1550,10 +1542,14 @@ struct dmub_cmd_psr_copy_settings_data {
         * Currently the support is only for 0 or 1
         */
        uint8_t panel_inst;
+       /*
+        * DSC enable status in driver
+        */
+       uint8_t dsc_enable_status;
        /**
-        * Explicit padding to 4 byte boundary.
+        * Explicit padding to 3 byte boundary.
         */
-       uint8_t pad3[4];
+       uint8_t pad3[3];
 };
 
 /**
@@ -2722,7 +2718,7 @@ static inline bool dmub_rb_full(struct dmub_rb *rb)
 static inline bool dmub_rb_push_front(struct dmub_rb *rb,
                                      const union dmub_rb_cmd *cmd)
 {
-       uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t);
+       uint64_t volatile *dst = (uint64_t volatile *)((uint8_t *)(rb->base_address) + rb->wrpt);
        const uint64_t *src = (const uint64_t *)cmd;
        uint8_t i;
 
@@ -2840,7 +2836,7 @@ static inline bool dmub_rb_peek_offset(struct dmub_rb *rb,
 static inline bool dmub_rb_out_front(struct dmub_rb *rb,
                                 union dmub_rb_out_cmd *cmd)
 {
-       const uint64_t volatile *src = (const uint64_t volatile *)(rb->base_address) + rb->rptr / sizeof(uint64_t);
+       const uint64_t volatile *src = (const uint64_t volatile *)((uint8_t *)(rb->base_address) + rb->rptr);
        uint64_t *dst = (uint64_t *)cmd;
        uint8_t i;
 
@@ -2888,7 +2884,7 @@ static inline void dmub_rb_flush_pending(const struct dmub_rb *rb)
        uint32_t wptr = rb->wrpt;
 
        while (rptr != wptr) {
-               uint64_t volatile *data = (uint64_t volatile *)rb->base_address + rptr / sizeof(uint64_t);
+               uint64_t volatile *data = (uint64_t volatile *)((uint8_t *)(rb->base_address) + rptr);
                //uint64_t volatile *p = (uint64_t volatile *)data;
                uint64_t temp;
                uint8_t i;
index 56d400ffa7ace54ee67095f950e1878c8e63111a..f673a1c1777a7fe32dbafecf0c566a88678e4cea 100644 (file)
@@ -100,24 +100,9 @@ void dmub_flush_buffer_mem(const struct dmub_fb *fb)
 }
 
 static const struct dmub_fw_meta_info *
-dmub_get_fw_meta_info(const struct dmub_srv_region_params *params)
+dmub_get_fw_meta_info_from_blob(const uint8_t *blob, uint32_t blob_size, uint32_t meta_offset)
 {
        const union dmub_fw_meta *meta;
-       const uint8_t *blob = NULL;
-       uint32_t blob_size = 0;
-       uint32_t meta_offset = 0;
-
-       if (params->fw_bss_data && params->bss_data_size) {
-               /* Legacy metadata region. */
-               blob = params->fw_bss_data;
-               blob_size = params->bss_data_size;
-               meta_offset = DMUB_FW_META_OFFSET;
-       } else if (params->fw_inst_const && params->inst_const_size) {
-               /* Combined metadata region. */
-               blob = params->fw_inst_const;
-               blob_size = params->inst_const_size;
-               meta_offset = 0;
-       }
 
        if (!blob || !blob_size)
                return NULL;
@@ -134,6 +119,32 @@ dmub_get_fw_meta_info(const struct dmub_srv_region_params *params)
        return &meta->info;
 }
 
+static const struct dmub_fw_meta_info *
+dmub_get_fw_meta_info(const struct dmub_srv_region_params *params)
+{
+       const struct dmub_fw_meta_info *info = NULL;
+
+       if (params->fw_bss_data && params->bss_data_size) {
+               /* Legacy metadata region. */
+               info = dmub_get_fw_meta_info_from_blob(params->fw_bss_data,
+                                                      params->bss_data_size,
+                                                      DMUB_FW_META_OFFSET);
+       } else if (params->fw_inst_const && params->inst_const_size) {
+               /* Combined metadata region - can be aligned to 16-bytes. */
+               uint32_t i;
+
+               for (i = 0; i < 16; ++i) {
+                       info = dmub_get_fw_meta_info_from_blob(
+                               params->fw_inst_const, params->inst_const_size, i);
+
+                       if (info)
+                               break;
+               }
+       }
+
+       return info;
+}
+
 static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
 {
        struct dmub_srv_hw_funcs *funcs = &dmub->hw_funcs;
@@ -598,6 +609,8 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
 
 enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)
 {
+       struct dmub_rb flush_rb;
+
        if (!dmub->hw_init)
                return DMUB_STATUS_INVALID;
 
@@ -606,9 +619,14 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)
         * been flushed to framebuffer memory. Otherwise DMCUB might
         * read back stale, fully invalid or partially invalid data.
         */
-       dmub_rb_flush_pending(&dmub->inbox1_rb);
+       flush_rb = dmub->inbox1_rb;
+       flush_rb.rptr = dmub->inbox1_last_wptr;
+       dmub_rb_flush_pending(&flush_rb);
+
+       dmub->hw_funcs.set_inbox1_wptr(dmub, dmub->inbox1_rb.wrpt);
+
+       dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
 
-               dmub->hw_funcs.set_inbox1_wptr(dmub, dmub->inbox1_rb.wrpt);
        return DMUB_STATUS_OK;
 }
 
@@ -831,3 +849,38 @@ bool dmub_srv_should_detect(struct dmub_srv *dmub)
 
        return dmub->hw_funcs.should_detect(dmub);
 }
+
+enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub)
+{
+       if (!dmub->hw_init || dmub->hw_funcs.clear_inbox0_ack_register)
+               return DMUB_STATUS_INVALID;
+
+       dmub->hw_funcs.clear_inbox0_ack_register(dmub);
+       return DMUB_STATUS_OK;
+}
+
+enum dmub_status dmub_srv_wait_for_inbox0_ack(struct dmub_srv *dmub, uint32_t timeout_us)
+{
+       uint32_t i = 0;
+       uint32_t ack = 0;
+
+       if (!dmub->hw_init || !dmub->hw_funcs.read_inbox0_ack_register)
+               return DMUB_STATUS_INVALID;
+
+       for (i = 0; i <= timeout_us; i++) {
+               ack = dmub->hw_funcs.read_inbox0_ack_register(dmub);
+               if (ack)
+                       return DMUB_STATUS_OK;
+       }
+       return DMUB_STATUS_TIMEOUT;
+}
+
+enum dmub_status dmub_srv_send_inbox0_cmd(struct dmub_srv *dmub,
+               union dmub_inbox0_data_register data)
+{
+       if (!dmub->hw_init || dmub->hw_funcs.send_inbox0_cmd)
+               return DMUB_STATUS_INVALID;
+
+       dmub->hw_funcs.send_inbox0_cmd(dmub, data);
+       return DMUB_STATUS_OK;
+}
index 4de59b66bb1a388f60d349970055132fd4bb8f6d..a2b80514d83ebb239e06225825955d105120984f 100644 (file)
@@ -35,6 +35,7 @@
 #define DP_BRANCH_DEVICE_ID_00E04C 0x00E04C
 #define DP_BRANCH_DEVICE_ID_006037 0x006037
 
+#define DP_DEVICE_ID_38EC11 0x38EC11
 enum ddc_result {
        DDC_RESULT_UNKNOWN = 0,
        DDC_RESULT_SUCESSFULL,
@@ -117,4 +118,7 @@ struct av_sync_data {
        uint8_t aud_del_ins3;/* DPCD 0002Dh */
 };
 
+static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0};
+static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0};
+
 #endif /* __DAL_DDC_SERVICE_TYPES_H__ */
index 370fad883e338c2a2a8f2d0587d32d614862d413..f093b49c5e6e6143cf0d658514d78fd75f7e6cd0 100644 (file)
@@ -72,9 +72,7 @@
 #define DC_LOG_DSC(...) DRM_DEBUG_KMS(__VA_ARGS__)
 #define DC_LOG_SMU(...) pr_debug("[SMU_MSG]:"__VA_ARGS__)
 #define DC_LOG_DWB(...) DRM_DEBUG_KMS(__VA_ARGS__)
-#if defined(CONFIG_DRM_AMD_DC_DCN)
 #define DC_LOG_DP2(...) DRM_DEBUG_KMS(__VA_ARGS__)
-#endif
 
 struct dal_logger;
 
@@ -126,9 +124,7 @@ enum dc_log_type {
        LOG_MAX_HW_POINTS,
        LOG_ALL_TF_CHANNELS,
        LOG_SAMPLE_1DLUT,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
        LOG_DP2,
-#endif
        LOG_SECTION_TOTAL_COUNT
 };
 
index 6d0052ce6bed483f7922aeb5d68479b4d3900bfd..da6d380c948bbfece4c99feedc41f8516b67337a 100644 (file)
 #define mmMP1_SMN_EXT_SCRATCH7                                                                         0x03c7
 #define mmMP1_SMN_EXT_SCRATCH7_BASE_IDX                                                                0
 
+/*
+ * addressBlock: mp_SmuMp1Pub_MmuDec
+ * base address: 0x0
+ */
+#define smnMP1_PMI_3_START                                                                              0x3030204
+#define smnMP1_PMI_3_FIFO                                                                               0x3030208
+#define smnMP1_PMI_3                                                                                    0x3030600
 
 #endif
index 136fb5de6a4c162e14f253fda885a877f7993da0..a5ae2a8012544e90b88890bc8952e3da24a2d32e 100644 (file)
 #define MP1_SMN_EXT_SCRATCH7__DATA__SHIFT                                                                     0x0
 #define MP1_SMN_EXT_SCRATCH7__DATA_MASK                                                                       0xFFFFFFFFL
 
+// MP1_PMI_3_START
+#define MP1_PMI_3_START__ENABLE_MASK                       0x80000000L
+// MP1_PMI_3_FIFO
+#define MP1_PMI_3_FIFO__DEPTH_MASK                         0x00000fffL
+
+// MP1_PMI_3_START
+#define MP1_PMI_3_START__ENABLE__SHIFT                     0x0000001f
+// MP1_PMI_3_FIFO
+#define MP1_PMI_3_FIFO__DEPTH__SHIFT                       0x00000000
+
+
+
 
 #endif
index c84bd7b2cf59ff1bdbe6e09ac7d889a67cf538ab..ac941f62cbed13dae4686b8779aa2da931b06b9f 100644 (file)
 #include <linux/dma-fence.h>
 
 struct pci_dev;
+struct amdgpu_device;
 
 #define KGD_MAX_QUEUES 128
 
 struct kfd_dev;
-struct kgd_dev;
-
 struct kgd_mem;
 
 enum kfd_preempt_type {
@@ -228,61 +227,61 @@ struct tile_config {
  */
 struct kfd2kgd_calls {
        /* Register access functions */
-       void (*program_sh_mem_settings)(struct kgd_dev *kgd, uint32_t vmid,
+       void (*program_sh_mem_settings)(struct amdgpu_device *adev, uint32_t vmid,
                        uint32_t sh_mem_config, uint32_t sh_mem_ape1_base,
                        uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases);
 
-       int (*set_pasid_vmid_mapping)(struct kgd_dev *kgd, u32 pasid,
+       int (*set_pasid_vmid_mapping)(struct amdgpu_device *adev, u32 pasid,
                                        unsigned int vmid);
 
-       int (*init_interrupts)(struct kgd_dev *kgd, uint32_t pipe_id);
+       int (*init_interrupts)(struct amdgpu_device *adev, uint32_t pipe_id);
 
-       int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
+       int (*hqd_load)(struct amdgpu_device *adev, void *mqd, uint32_t pipe_id,
                        uint32_t queue_id, uint32_t __user *wptr,
                        uint32_t wptr_shift, uint32_t wptr_mask,
                        struct mm_struct *mm);
 
-       int (*hiq_mqd_load)(struct kgd_dev *kgd, void *mqd,
+       int (*hiq_mqd_load)(struct amdgpu_device *adev, void *mqd,
                            uint32_t pipe_id, uint32_t queue_id,
                            uint32_t doorbell_off);
 
-       int (*hqd_sdma_load)(struct kgd_dev *kgd, void *mqd,
+       int (*hqd_sdma_load)(struct amdgpu_device *adev, void *mqd,
                             uint32_t __user *wptr, struct mm_struct *mm);
 
-       int (*hqd_dump)(struct kgd_dev *kgd,
+       int (*hqd_dump)(struct amdgpu_device *adev,
                        uint32_t pipe_id, uint32_t queue_id,
                        uint32_t (**dump)[2], uint32_t *n_regs);
 
-       int (*hqd_sdma_dump)(struct kgd_dev *kgd,
+       int (*hqd_sdma_dump)(struct amdgpu_device *adev,
                             uint32_t engine_id, uint32_t queue_id,
                             uint32_t (**dump)[2], uint32_t *n_regs);
 
-       bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,
-                               uint32_t pipe_id, uint32_t queue_id);
-
-       int (*hqd_destroy)(struct kgd_dev *kgd, void *mqd, uint32_t reset_type,
-                               unsigned int timeout, uint32_t pipe_id,
+       bool (*hqd_is_occupied)(struct amdgpu_device *adev,
+                               uint64_t queue_address, uint32_t pipe_id,
                                uint32_t queue_id);
 
-       bool (*hqd_sdma_is_occupied)(struct kgd_dev *kgd, void *mqd);
+       int (*hqd_destroy)(struct amdgpu_device *adev, void *mqd,
+                               uint32_t reset_type, unsigned int timeout,
+                               uint32_t pipe_id, uint32_t queue_id);
+
+       bool (*hqd_sdma_is_occupied)(struct amdgpu_device *adev, void *mqd);
 
-       int (*hqd_sdma_destroy)(struct kgd_dev *kgd, void *mqd,
+       int (*hqd_sdma_destroy)(struct amdgpu_device *adev, void *mqd,
                                unsigned int timeout);
 
-       int (*address_watch_disable)(struct kgd_dev *kgd);
-       int (*address_watch_execute)(struct kgd_dev *kgd,
+       int (*address_watch_disable)(struct amdgpu_device *adev);
+       int (*address_watch_execute)(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        uint32_t cntl_val,
                                        uint32_t addr_hi,
                                        uint32_t addr_lo);
-       int (*wave_control_execute)(struct kgd_dev *kgd,
+       int (*wave_control_execute)(struct amdgpu_device *adev,
                                        uint32_t gfx_index_val,
                                        uint32_t sq_cmd);
-       uint32_t (*address_watch_get_offset)(struct kgd_dev *kgd,
+       uint32_t (*address_watch_get_offset)(struct amdgpu_device *adev,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset);
-       bool (*get_atc_vmid_pasid_mapping_info)(
-                                       struct kgd_dev *kgd,
+       bool (*get_atc_vmid_pasid_mapping_info)(struct amdgpu_device *adev,
                                        uint8_t vmid,
                                        uint16_t *p_pasid);
 
@@ -290,16 +289,16 @@ struct kfd2kgd_calls {
         * passed to the shader by the CP. It's the user mode driver's
         * responsibility.
         */
-       void (*set_scratch_backing_va)(struct kgd_dev *kgd,
+       void (*set_scratch_backing_va)(struct amdgpu_device *adev,
                                uint64_t va, uint32_t vmid);
 
-       void (*set_vm_context_page_table_base)(struct kgd_dev *kgd,
+       void (*set_vm_context_page_table_base)(struct amdgpu_device *adev,
                        uint32_t vmid, uint64_t page_table_base);
-       uint32_t (*read_vmid_from_vmfault_reg)(struct kgd_dev *kgd);
+       uint32_t (*read_vmid_from_vmfault_reg)(struct amdgpu_device *adev);
 
-       void (*get_cu_occupancy)(struct kgd_dev *kgd, int pasid, int *wave_cnt,
-                       int *max_waves_per_cu);
-       void (*program_trap_handler_settings)(struct kgd_dev *kgd,
+       void (*get_cu_occupancy)(struct amdgpu_device *adev, int pasid,
+                       int *wave_cnt, int *max_waves_per_cu);
+       void (*program_trap_handler_settings)(struct amdgpu_device *adev,
                        uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr);
 };
 
index 41472ed992530c8c4caa14fb63b1cc69188e7203..49df4c20f09ecdeff222dbd9a02f3f22b75e9a27 100644 (file)
@@ -3759,5 +3759,7 @@ void amdgpu_debugfs_pm_init(struct amdgpu_device *adev)
                                         adev,
                                         &amdgpu_debugfs_pm_prv_buffer_fops,
                                         adev->pm.smu_prv_buffer_size);
+
+       amdgpu_smu_stb_debug_fs_init(adev);
 #endif
 }
index 3557f4e7fc306a75e85fb420d7bd65533ab3453d..f738f7dc20c90c52ab8c9272266834efec9124d7 100644 (file)
@@ -324,6 +324,7 @@ enum smu_table_id
        SMU_TABLE_OVERDRIVE,
        SMU_TABLE_I2C_COMMANDS,
        SMU_TABLE_PACE,
+       SMU_TABLE_ECCINFO,
        SMU_TABLE_COUNT,
 };
 
@@ -340,6 +341,7 @@ struct smu_table_context
        void                            *max_sustainable_clocks;
        struct smu_bios_boot_up_values  boot_values;
        void                            *driver_pptable;
+       void                            *ecc_table;
        struct smu_table                tables[SMU_TABLE_COUNT];
        /*
         * The driver table is just a staging buffer for
@@ -472,6 +474,12 @@ struct cmn2asic_mapping {
        int     map_to;
 };
 
+struct stb_context {
+       uint32_t stb_buf_size;
+       bool enabled;
+       spinlock_t lock;
+};
+
 #define WORKLOAD_POLICY_MAX 7
 struct smu_context
 {
@@ -559,6 +567,8 @@ struct smu_context
        uint16_t cpu_core_num;
 
        struct smu_user_dpm_profile user_dpm_profile;
+
+       struct stb_context stb_context;
 };
 
 struct i2c_adapter;
@@ -1261,6 +1271,17 @@ struct pptable_funcs {
         *                                                                              of SMUBUS table.
         */
        int (*send_hbm_bad_pages_num)(struct smu_context *smu, uint32_t size);
+
+       /**
+        * @get_ecc_table:  message SMU to get ECC INFO table.
+        */
+       ssize_t (*get_ecc_info)(struct smu_context *smu, void *table);
+       
+       
+       /**
+        * @stb_collect_info: Collects Smart Trace Buffers data.
+        */
+       int (*stb_collect_info)(struct smu_context *smu, void *buf, uint32_t size);
 };
 
 typedef enum {
@@ -1397,6 +1418,9 @@ int smu_set_light_sbr(struct smu_context *smu, bool enable);
 
 int smu_wait_for_event(struct amdgpu_device *adev, enum smu_event_type event,
                       uint64_t event_arg);
+int smu_get_ecc_info(struct smu_context *smu, void *umc_ecc);
+int smu_stb_collect_info(struct smu_context *smu, void *buff, uint32_t size);
+void amdgpu_smu_stb_debug_fs_init(struct amdgpu_device *adev);
 
 #endif
 #endif
index a017983ff1fabe82180c37caa0a9914f9e668b12..0f67c56c2863abcd6161ba679954565068b8346c 100644 (file)
 
 #define MAX_SW_I2C_COMMANDS                24
 
+#define ALDEBARAN_UMC_CHANNEL_NUM    32
+
 typedef enum {
   I2C_CONTROLLER_PORT_0, //CKSVII2C0
   I2C_CONTROLLER_PORT_1, //CKSVII2C1
@@ -507,6 +509,19 @@ typedef struct {
   uint32_t MmHubPadding[8]; // SMU internal use
 } AvfsDebugTable_t;
 
+typedef struct {
+       uint64_t mca_umc_status;
+       uint64_t mca_umc_addr;
+       uint16_t ce_count_lo_chip;
+       uint16_t ce_count_hi_chip;
+
+       uint32_t eccPadding;
+} EccInfo_t;
+
+typedef struct {
+       EccInfo_t  EccInfo[ALDEBARAN_UMC_CHANNEL_NUM];
+} EccInfoTable_t;
+
 // These defines are used with the following messages:
 // SMC_MSG_TransferTableDram2Smu
 // SMC_MSG_TransferTableSmu2Dram
@@ -517,6 +532,7 @@ typedef struct {
 #define TABLE_SMU_METRICS             4
 #define TABLE_DRIVER_SMU_CONFIG       5
 #define TABLE_I2C_COMMANDS            6
-#define TABLE_COUNT                   7
+#define TABLE_ECCINFO                 7
+#define TABLE_COUNT                   8
 
 #endif
index e5d3b0d1a032aa0e4e8e6dd2997609f377367885..44af23ae059ee409b5821124df59fa6f22d104fe 100644 (file)
@@ -27,7 +27,9 @@
 
 #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
 #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
-#define SMU13_DRIVER_IF_VERSION_ALDE 0x07
+#define SMU13_DRIVER_IF_VERSION_ALDE 0x08
+
+#define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500  //500ms
 
 /* MP Apertures */
 #define MP0_Public                     0x03800000
@@ -216,7 +218,6 @@ int smu_v13_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
 int smu_v13_0_baco_enter(struct smu_context *smu);
 int smu_v13_0_baco_exit(struct smu_context *smu);
 
-int smu_v13_0_mode1_reset(struct smu_context *smu);
 int smu_v13_0_mode2_reset(struct smu_context *smu);
 
 int smu_v13_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
index 8d796ed3b7d16f40369363969499caf7bbb1bf94..20cb234d506113f3fc0ccde5013d730edd504610 100644 (file)
@@ -1551,7 +1551,7 @@ static int pp_set_ppfeature_status(void *handle, uint64_t ppfeature_masks)
 static int pp_asic_reset_mode_2(void *handle)
 {
        struct pp_hwmgr *hwmgr = handle;
-               int ret = 0;
+       int ret = 0;
 
        if (!hwmgr || !hwmgr->pm_en)
                return -EINVAL;
index 258c573acc979849a25b67b9d27a8acdf357bfa2..1f406f21b452fa4241d849421900127dd51a0379 100644 (file)
@@ -1024,8 +1024,6 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
        uint32_t min_freq, max_freq = 0;
        uint32_t ret = 0;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now);
@@ -1038,13 +1036,13 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
                else
                        i = 1;
 
-               size += sysfs_emit_at(buf, size, "0: %uMhz %s\n",
+               size += sprintf(buf + size, "0: %uMhz %s\n",
                                        data->gfx_min_freq_limit/100,
                                        i == 0 ? "*" : "");
-               size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
+               size += sprintf(buf + size, "1: %uMhz %s\n",
                                        i == 1 ? now : SMU10_UMD_PSTATE_GFXCLK,
                                        i == 1 ? "*" : "");
-               size += sysfs_emit_at(buf, size, "2: %uMhz %s\n",
+               size += sprintf(buf + size, "2: %uMhz %s\n",
                                        data->gfx_max_freq_limit/100,
                                        i == 2 ? "*" : "");
                break;
@@ -1052,7 +1050,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now);
 
                for (i = 0; i < mclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i,
                                        mclk_table->entries[i].clk / 100,
                                        ((mclk_table->entries[i].clk / 100)
@@ -1067,10 +1065,10 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
                        if (ret)
                                return ret;
 
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
-                       size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_SCLK");
+                       size += sprintf(buf + size, "0: %10uMhz\n",
                        (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq);
-                       size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
+                       size += sprintf(buf + size, "1: %10uMhz\n",
                        (data->gfx_actual_soft_max_freq > 0) ? data->gfx_actual_soft_max_freq : max_freq);
                }
                break;
@@ -1083,8 +1081,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
                        if (ret)
                                return ret;
 
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_RANGE");
+                       size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
                                min_freq, max_freq);
                }
                break;
index aceebf58422530e7d946a397eb699830a92aa888..611969bf452077c87c4c10f7c6d4b7e7f52e24bc 100644 (file)
@@ -4914,8 +4914,6 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
        int size = 0;
        uint32_t i, now, clock, pcie_speed;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency, &clock);
@@ -4928,7 +4926,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
                now = i;
 
                for (i = 0; i < sclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, sclk_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4943,7 +4941,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
                now = i;
 
                for (i = 0; i < mclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, mclk_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4957,7 +4955,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
                now = i;
 
                for (i = 0; i < pcie_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %s %s\n", i,
+                       size += sprintf(buf + size, "%d: %s %s\n", i,
                                        (pcie_table->dpm_levels[i].value == 0) ? "2.5GT/s, x8" :
                                        (pcie_table->dpm_levels[i].value == 1) ? "5.0GT/s, x16" :
                                        (pcie_table->dpm_levels[i].value == 2) ? "8.0GT/s, x16" : "",
@@ -4965,32 +4963,32 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr,
                break;
        case OD_SCLK:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
+                       size += sprintf(buf + size, "%s:\n", "OD_SCLK");
                        for (i = 0; i < odn_sclk_table->num_of_pl; i++)
-                               size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n",
+                               size += sprintf(buf + size, "%d: %10uMHz %10umV\n",
                                        i, odn_sclk_table->entries[i].clock/100,
                                        odn_sclk_table->entries[i].vddc);
                }
                break;
        case OD_MCLK:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
+                       size += sprintf(buf + size, "%s:\n", "OD_MCLK");
                        for (i = 0; i < odn_mclk_table->num_of_pl; i++)
-                               size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n",
+                               size += sprintf(buf + size, "%d: %10uMHz %10umV\n",
                                        i, odn_mclk_table->entries[i].clock/100,
                                        odn_mclk_table->entries[i].vddc);
                }
                break;
        case OD_RANGE:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_RANGE");
+                       size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
                                data->golden_dpm_table.sclk_table.dpm_levels[0].value/100,
                                hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
-                       size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
                                data->golden_dpm_table.mclk_table.dpm_levels[0].value/100,
                                hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
-                       size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n",
+                       size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
                                data->odn_dpm_table.min_vddc,
                                data->odn_dpm_table.max_vddc);
                }
index 8e28a8eecefc641c435c5b8549a29792cd56f1ae..03bf8f0692228d48de0b9776fb3fe9205f7ee2ce 100644 (file)
@@ -1550,8 +1550,6 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
        uint32_t i, now;
        int size = 0;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                now = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device,
@@ -1561,7 +1559,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
                                CURR_SCLK_INDEX);
 
                for (i = 0; i < sclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, sclk_table->entries[i].clk / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -1573,7 +1571,7 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr,
                                CURR_MCLK_INDEX);
 
                for (i = SMU8_NUM_NBPMEMORYCLOCK; i > 0; i--)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        SMU8_NUM_NBPMEMORYCLOCK-i, data->sys_info.nbp_memory_clock[i-1] / 100,
                                        (SMU8_NUM_NBPMEMORYCLOCK-i == now) ? "*" : "");
                break;
index c981fc2882f017eb3be21a4e4a47c2f5ea9876ea..e6336654c5655eeca69113dda4b1fc06b5fecf65 100644 (file)
@@ -4639,8 +4639,6 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 
        int i, now, size = 0, count = 0;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                if (data->registry_data.sclk_dpm_key_disabled)
@@ -4654,7 +4652,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                else
                        count = sclk_table->count;
                for (i = 0; i < count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, sclk_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4665,7 +4663,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now);
 
                for (i = 0; i < mclk_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, mclk_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4676,7 +4674,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now);
 
                for (i = 0; i < soc_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, soc_table->dpm_levels[i].value / 100,
                                        (i == now) ? "*" : "");
                break;
@@ -4688,7 +4686,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                                PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now);
 
                for (i = 0; i < dcef_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                        i, dcef_table->dpm_levels[i].value / 100,
                                        (dcef_table->dpm_levels[i].value / 100 == now) ?
                                        "*" : "");
@@ -4702,7 +4700,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
                        gen_speed = pptable->PcieGenSpeed[i];
                        lane_width = pptable->PcieLaneCount[i];
 
-                       size += sysfs_emit_at(buf, size, "%d: %s %s %s\n", i,
+                       size += sprintf(buf + size, "%d: %s %s %s\n", i,
                                        (gen_speed == 0) ? "2.5GT/s," :
                                        (gen_speed == 1) ? "5.0GT/s," :
                                        (gen_speed == 2) ? "8.0GT/s," :
@@ -4721,34 +4719,34 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
 
        case OD_SCLK:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
+                       size += sprintf(buf + size, "%s:\n", "OD_SCLK");
                        podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
                        for (i = 0; i < podn_vdd_dep->count; i++)
-                               size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n",
+                               size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
                                        i, podn_vdd_dep->entries[i].clk / 100,
                                                podn_vdd_dep->entries[i].vddc);
                }
                break;
        case OD_MCLK:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
+                       size += sprintf(buf + size, "%s:\n", "OD_MCLK");
                        podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
                        for (i = 0; i < podn_vdd_dep->count; i++)
-                               size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n",
+                               size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
                                        i, podn_vdd_dep->entries[i].clk/100,
                                                podn_vdd_dep->entries[i].vddc);
                }
                break;
        case OD_RANGE:
                if (hwmgr->od_enabled) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_RANGE");
+                       size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
                                data->golden_dpm_table.gfx_table.dpm_levels[0].value/100,
                                hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
-                       size += sysfs_emit_at(buf, size, "MCLK: %7uMHz %10uMHz\n",
+                       size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
                                data->golden_dpm_table.mem_table.dpm_levels[0].value/100,
                                hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
-                       size += sysfs_emit_at(buf, size, "VDDC: %7umV %11umV\n",
+                       size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
                                data->odn_dpm_table.min_vddc,
                                data->odn_dpm_table.max_vddc);
                }
index f7e783e1c888f3442ef3bdfbcfbf3be658a777e2..a2f4d6773d458cd8e988dac3162945281e8bd300 100644 (file)
@@ -2246,8 +2246,6 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
        int i, now, size = 0;
        struct pp_clock_levels_with_latency clocks;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                PP_ASSERT_WITH_CODE(
@@ -2260,7 +2258,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
                                "Attempt to get gfx clk levels Failed!",
                                return -1);
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : "");
                break;
@@ -2276,7 +2274,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
                                "Attempt to get memory clk levels Failed!",
                                return -1);
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : "");
                break;
@@ -2294,7 +2292,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
                                "Attempt to get soc clk levels Failed!",
                                return -1);
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : "");
                break;
@@ -2312,7 +2310,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
                                "Attempt to get dcef clk levels Failed!",
                                return -1);
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : "");
                break;
index 03e63be4ee2756832b2bce8ddb3ed37523a5c8fd..85d55ab4e369fccbb3fd0c03343b16eee63f3eb1 100644 (file)
@@ -3366,8 +3366,6 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
        int ret = 0;
        uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;
 
-       phm_get_sysfs_buf(&buf, &size);
-
        switch (type) {
        case PP_SCLK:
                ret = vega20_get_current_clk_freq(hwmgr, PPCLK_GFXCLK, &now);
@@ -3376,13 +3374,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                if (vega20_get_sclks(hwmgr, &clocks)) {
-                       size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n",
+                       size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
                                now / 100);
                        break;
                }
 
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");
                break;
@@ -3394,13 +3392,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                if (vega20_get_memclocks(hwmgr, &clocks)) {
-                       size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n",
+                       size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
                                now / 100);
                        break;
                }
 
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");
                break;
@@ -3412,13 +3410,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                if (vega20_get_socclocks(hwmgr, &clocks)) {
-                       size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n",
+                       size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
                                now / 100);
                        break;
                }
 
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");
                break;
@@ -3430,7 +3428,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                for (i = 0; i < fclk_dpm_table->count; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, fclk_dpm_table->dpm_levels[i].value,
                                fclk_dpm_table->dpm_levels[i].value == (now / 100) ? "*" : "");
                break;
@@ -3442,13 +3440,13 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                return ret);
 
                if (vega20_get_dcefclocks(hwmgr, &clocks)) {
-                       size += sysfs_emit_at(buf, size, "0: %uMhz * (DPM disabled)\n",
+                       size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
                                now / 100);
                        break;
                }
 
                for (i = 0; i < clocks.num_levels; i++)
-                       size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
+                       size += sprintf(buf + size, "%d: %uMhz %s\n",
                                i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");
                break;
@@ -3462,7 +3460,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                        gen_speed = pptable->PcieGenSpeed[i];
                        lane_width = pptable->PcieLaneCount[i];
 
-                       size += sysfs_emit_at(buf, size, "%d: %s %s %dMhz %s\n", i,
+                       size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
                                        (gen_speed == 0) ? "2.5GT/s," :
                                        (gen_speed == 1) ? "5.0GT/s," :
                                        (gen_speed == 2) ? "8.0GT/s," :
@@ -3483,18 +3481,18 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
        case OD_SCLK:
                if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
-                       size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_SCLK");
+                       size += sprintf(buf + size, "0: %10uMhz\n",
                                od_table->GfxclkFmin);
-                       size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
+                       size += sprintf(buf + size, "1: %10uMhz\n",
                                od_table->GfxclkFmax);
                }
                break;
 
        case OD_MCLK:
                if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
-                       size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_MCLK");
+                       size += sprintf(buf + size, "1: %10uMhz\n",
                                od_table->UclkFmax);
                }
 
@@ -3507,14 +3505,14 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) {
-                       size += sysfs_emit_at(buf, size, "%s:\n", "OD_VDDC_CURVE");
-                       size += sysfs_emit_at(buf, size, "0: %10uMhz %10dmV\n",
+                       size += sprintf(buf + size, "%s:\n", "OD_VDDC_CURVE");
+                       size += sprintf(buf + size, "0: %10uMhz %10dmV\n",
                                od_table->GfxclkFreq1,
                                od_table->GfxclkVolt1 / VOLTAGE_SCALE);
-                       size += sysfs_emit_at(buf, size, "1: %10uMhz %10dmV\n",
+                       size += sprintf(buf + size, "1: %10uMhz %10dmV\n",
                                od_table->GfxclkFreq2,
                                od_table->GfxclkVolt2 / VOLTAGE_SCALE);
-                       size += sysfs_emit_at(buf, size, "2: %10uMhz %10dmV\n",
+                       size += sprintf(buf + size, "2: %10uMhz %10dmV\n",
                                od_table->GfxclkFreq3,
                                od_table->GfxclkVolt3 / VOLTAGE_SCALE);
                }
@@ -3522,17 +3520,17 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                break;
 
        case OD_RANGE:
-               size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+               size += sprintf(buf + size, "%s:\n", "OD_RANGE");
 
                if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) {
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_GFXCLK_FMIN].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_FMAX].max_value);
                }
 
                if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) {
-                       size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_UCLK_FMAX].min_value,
                                od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
                }
@@ -3543,22 +3541,22 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id &&
                    od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) {
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_GFXCLK_FREQ1].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_FREQ1].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n",
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_GFXCLK_FREQ2].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_FREQ2].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n",
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n",
                                od8_settings[OD8_SETTING_GFXCLK_FREQ3].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_FREQ3].max_value);
-                       size += sysfs_emit_at(buf, size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n",
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n",
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].min_value,
                                od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].max_value);
                }
index 01168b8955bff3ce80b1c7a6e6df04b050a9bcab..e156add7b5609feee6cfd6060e0853dd28d3f3ca 100644 (file)
@@ -1153,6 +1153,8 @@ static int smu_smc_hw_setup(struct smu_context *smu)
                case IP_VERSION(11, 5, 0):
                case IP_VERSION(11, 0, 12):
                        ret = smu_system_features_control(smu, true);
+                       if (ret)
+                               dev_err(adev->dev, "Failed system features control!\n");
                        break;
                default:
                        break;
@@ -1277,8 +1279,10 @@ static int smu_smc_hw_setup(struct smu_context *smu)
        }
 
        ret = smu_notify_display_change(smu);
-       if (ret)
+       if (ret) {
+               dev_err(adev->dev, "Failed to notify display change!\n");
                return ret;
+       }
 
        /*
         * Set min deep sleep dce fclk with bootup value from vbios via
@@ -1286,8 +1290,6 @@ static int smu_smc_hw_setup(struct smu_context *smu)
         */
        ret = smu_set_min_dcef_deep_sleep(smu,
                                          smu->smu_table.boot_values.dcefclk / 100);
-       if (ret)
-               return ret;
 
        return ret;
 }
@@ -3072,6 +3074,20 @@ int smu_set_light_sbr(struct smu_context *smu, bool enable)
        return ret;
 }
 
+int smu_get_ecc_info(struct smu_context *smu, void *umc_ecc)
+{
+       int ret = -EOPNOTSUPP;
+
+       mutex_lock(&smu->mutex);
+       if (smu->ppt_funcs &&
+               smu->ppt_funcs->get_ecc_info)
+               ret = smu->ppt_funcs->get_ecc_info(smu, umc_ecc);
+       mutex_unlock(&smu->mutex);
+
+       return ret;
+
+}
+
 static int smu_get_prv_buffer_details(void *handle, void **addr, size_t *size)
 {
        struct smu_context *smu = handle;
@@ -3161,3 +3177,107 @@ int smu_wait_for_event(struct amdgpu_device *adev, enum smu_event_type event,
 
        return ret;
 }
+
+int smu_stb_collect_info(struct smu_context *smu, void *buf, uint32_t size)
+{
+
+       if (!smu->ppt_funcs->stb_collect_info || !smu->stb_context.enabled)
+               return -EOPNOTSUPP;
+
+       /* Confirm the buffer allocated is of correct size */
+       if (size != smu->stb_context.stb_buf_size)
+               return -EINVAL;
+
+       /*
+        * No need to lock smu mutex as we access STB directly through MMIO
+        * and not going through SMU messaging route (for now at least).
+        * For registers access rely on implementation internal locking.
+        */
+       return smu->ppt_funcs->stb_collect_info(smu, buf, size);
+}
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int smu_stb_debugfs_open(struct inode *inode, struct file *filp)
+{
+       struct amdgpu_device *adev = filp->f_inode->i_private;
+       struct smu_context *smu = &adev->smu;
+       unsigned char *buf;
+       int r;
+
+       buf = kvmalloc_array(smu->stb_context.stb_buf_size, sizeof(*buf), GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       r = smu_stb_collect_info(smu, buf, smu->stb_context.stb_buf_size);
+       if (r)
+               goto out;
+
+       filp->private_data = buf;
+
+       return 0;
+
+out:
+       kvfree(buf);
+       return r;
+}
+
+static ssize_t smu_stb_debugfs_read(struct file *filp, char __user *buf, size_t size,
+                               loff_t *pos)
+{
+       struct amdgpu_device *adev = filp->f_inode->i_private;
+       struct smu_context *smu = &adev->smu;
+
+
+       if (!filp->private_data)
+               return -EINVAL;
+
+       return simple_read_from_buffer(buf,
+                                      size,
+                                      pos, filp->private_data,
+                                      smu->stb_context.stb_buf_size);
+}
+
+static int smu_stb_debugfs_release(struct inode *inode, struct file *filp)
+{
+       kvfree(filp->private_data);
+       filp->private_data = NULL;
+
+       return 0;
+}
+
+/*
+ * We have to define not only read method but also
+ * open and release because .read takes up to PAGE_SIZE
+ * data each time so and so is invoked multiple times.
+ *  We allocate the STB buffer in .open and release it
+ *  in .release
+ */
+static const struct file_operations smu_stb_debugfs_fops = {
+       .owner = THIS_MODULE,
+       .open = smu_stb_debugfs_open,
+       .read = smu_stb_debugfs_read,
+       .release = smu_stb_debugfs_release,
+       .llseek = default_llseek,
+};
+
+#endif
+
+void amdgpu_smu_stb_debug_fs_init(struct amdgpu_device *adev)
+{
+#if defined(CONFIG_DEBUG_FS)
+
+       struct smu_context *smu = &adev->smu;
+
+       if (!smu->stb_context.stb_buf_size)
+               return;
+
+       debugfs_create_file_size("amdgpu_smu_stb_dump",
+                           S_IRUSR,
+                           adev_to_drm(adev)->primary->debugfs_root,
+                           adev,
+                           &smu_stb_debugfs_fops,
+                           smu->stb_context.stb_buf_size);
+#endif
+
+}
index a4108025fe29944873f937e68eb4724537f33e2b..a673e05853fecebcf79ae269df2ee5ab515b0233 100644 (file)
@@ -80,6 +80,9 @@
                (*member) = (smu->smu_table.driver_pptable + offsetof(PPTable_t, field));\
 } while(0)
 
+/* STB FIFO depth is in 64bit units */
+#define SIENNA_CICHLID_STB_DEPTH_UNIT_BYTES 8
+
 static int get_table_size(struct smu_context *smu)
 {
        if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13))
@@ -650,6 +653,8 @@ static int sienna_cichlid_allocate_dpm_context(struct smu_context *smu)
        return 0;
 }
 
+static void sienna_cichlid_stb_init(struct smu_context *smu);
+
 static int sienna_cichlid_init_smc_tables(struct smu_context *smu)
 {
        int ret = 0;
@@ -662,6 +667,8 @@ static int sienna_cichlid_init_smc_tables(struct smu_context *smu)
        if (ret)
                return ret;
 
+       sienna_cichlid_stb_init(smu);
+
        return smu_v11_0_init_smc_tables(smu);
 }
 
@@ -1171,7 +1178,7 @@ static int sienna_cichlid_force_clk_levels(struct smu_context *smu,
                                   enum smu_clk_type clk_type, uint32_t mask)
 {
        struct amdgpu_device *adev = smu->adev;
-       int ret = 0, size = 0;
+       int ret = 0;
        uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0;
 
        soft_min_level = mask ? (ffs(mask) - 1) : 0;
@@ -1216,7 +1223,7 @@ forec_level_out:
        if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK))
                amdgpu_gfx_off_ctrl(adev, true);
 
-       return size;
+       return 0;
 }
 
 static int sienna_cichlid_populate_umd_state_clk(struct smu_context *smu)
@@ -2135,7 +2142,13 @@ static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu,
 
 static int sienna_cichlid_run_btc(struct smu_context *smu)
 {
-       return smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
+       int res;
+
+       res = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
+       if (res)
+               dev_err(smu->adev->dev, "RunDcBtc failed!\n");
+
+       return res;
 }
 
 static int sienna_cichlid_baco_enter(struct smu_context *smu)
@@ -3619,6 +3632,16 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu,
        gpu_metrics->energy_accumulator =
                use_metrics_v2 ? metrics_v2->EnergyAccumulator : metrics->EnergyAccumulator;
 
+       if (metrics->CurrGfxVoltageOffset)
+               gpu_metrics->voltage_gfx =
+                       (155000 - 625 * metrics->CurrGfxVoltageOffset) / 100;
+       if (metrics->CurrMemVidOffset)
+               gpu_metrics->voltage_mem =
+                       (155000 - 625 * metrics->CurrMemVidOffset) / 100;
+       if (metrics->CurrSocVoltageOffset)
+               gpu_metrics->voltage_soc =
+                       (155000 - 625 * metrics->CurrSocVoltageOffset) / 100;
+
        average_gfx_activity = use_metrics_v2 ? metrics_v2->AverageGfxActivity : metrics->AverageGfxActivity;
        if (average_gfx_activity <= SMU_11_0_7_GFX_BUSY_THRESHOLD)
                gpu_metrics->average_gfxclk_frequency =
@@ -3793,6 +3816,53 @@ static int sienna_cichlid_set_mp1_state(struct smu_context *smu,
        return ret;
 }
 
+static void sienna_cichlid_stb_init(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+       uint32_t reg;
+
+       reg = RREG32_PCIE(MP1_Public | smnMP1_PMI_3_START);
+       smu->stb_context.enabled = REG_GET_FIELD(reg, MP1_PMI_3_START, ENABLE);
+
+       /* STB is disabled */
+       if (!smu->stb_context.enabled)
+               return;
+
+       spin_lock_init(&smu->stb_context.lock);
+
+       /* STB buffer size in bytes as function of FIFO depth */
+       reg = RREG32_PCIE(MP1_Public | smnMP1_PMI_3_FIFO);
+       smu->stb_context.stb_buf_size = 1 << REG_GET_FIELD(reg, MP1_PMI_3_FIFO, DEPTH);
+       smu->stb_context.stb_buf_size *=  SIENNA_CICHLID_STB_DEPTH_UNIT_BYTES;
+
+       dev_info(smu->adev->dev, "STB initialized to %d entries",
+                smu->stb_context.stb_buf_size / SIENNA_CICHLID_STB_DEPTH_UNIT_BYTES);
+
+}
+
+int sienna_cichlid_stb_get_data_direct(struct smu_context *smu,
+                                      void *buf,
+                                      uint32_t size)
+{
+       uint32_t *p = buf;
+       struct amdgpu_device *adev = smu->adev;
+
+       /* No need to disable interrupts for now as we don't lock it yet from ISR */
+       spin_lock(&smu->stb_context.lock);
+
+       /*
+        * Read the STB FIFO in units of 32bit since this is the accessor window
+        * (register width) we have.
+        */
+       buf = ((char *) buf) + size;
+       while ((void *)p < buf)
+               *p++ = cpu_to_le32(RREG32_PCIE(MP1_Public | smnMP1_PMI_3));
+
+       spin_unlock(&smu->stb_context.lock);
+
+       return 0;
+}
+
 static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
        .get_allowed_feature_mask = sienna_cichlid_get_allowed_feature_mask,
        .set_default_dpm_table = sienna_cichlid_set_default_dpm_table,
@@ -3882,6 +3952,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
        .interrupt_work = smu_v11_0_interrupt_work,
        .gpo_control = sienna_cichlid_gpo_control,
        .set_mp1_state = sienna_cichlid_set_mp1_state,
+       .stb_collect_info = sienna_cichlid_stb_get_data_direct,
 };
 
 void sienna_cichlid_set_ppt_funcs(struct smu_context *smu)
index 59a7d276541de7824b3a5f0519bbcd4a83f55874..6e781cee8bb642c17547a4b4b5ebe5c3642b8921 100644 (file)
 
 #define smnPCIE_ESM_CTRL                       0x111003D0
 
+/*
+ * SMU support ECCTABLE since version 68.42.0,
+ * use this to check ECCTALE feature whether support
+ */
+#define SUPPORT_ECCTABLE_SMU_VERSION 0x00442a00
+
 static const struct smu_temperature_range smu13_thermal_policy[] =
 {
        {-273150,  99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000},
@@ -190,6 +196,7 @@ static const struct cmn2asic_mapping aldebaran_table_map[SMU_TABLE_COUNT] = {
        TAB_MAP(SMU_METRICS),
        TAB_MAP(DRIVER_SMU_CONFIG),
        TAB_MAP(I2C_COMMANDS),
+       TAB_MAP(ECCINFO),
 };
 
 static const uint8_t aldebaran_throttler_map[] = {
@@ -223,6 +230,9 @@ static int aldebaran_tables_init(struct smu_context *smu)
        SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
                       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
 
+       SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t),
+                      PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
+
        smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
        if (!smu_table->metrics_table)
                return -ENOMEM;
@@ -235,6 +245,10 @@ static int aldebaran_tables_init(struct smu_context *smu)
                return -ENOMEM;
        }
 
+       smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL);
+       if (!smu_table->ecc_table)
+               return -ENOMEM;
+
        return 0;
 }
 
@@ -1765,6 +1779,98 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu,
        return sizeof(struct gpu_metrics_v1_3);
 }
 
+static int aldebaran_check_ecc_table_support(struct smu_context *smu)
+{
+       uint32_t if_version = 0xff, smu_version = 0xff;
+       int ret = 0;
+
+       ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version);
+       if (ret) {
+               /* return not support if failed get smu_version */
+               ret = -EOPNOTSUPP;
+       }
+
+       if (smu_version < SUPPORT_ECCTABLE_SMU_VERSION)
+               ret = -EOPNOTSUPP;
+
+       return ret;
+}
+
+static ssize_t aldebaran_get_ecc_info(struct smu_context *smu,
+                                        void *table)
+{
+       struct smu_table_context *smu_table = &smu->smu_table;
+       EccInfoTable_t *ecc_table = NULL;
+       struct ecc_info_per_ch *ecc_info_per_channel = NULL;
+       int i, ret = 0;
+       struct umc_ecc_info *eccinfo = (struct umc_ecc_info *)table;
+
+       ret = aldebaran_check_ecc_table_support(smu);
+       if (ret)
+               return ret;
+
+       ret = smu_cmn_update_table(smu,
+                              SMU_TABLE_ECCINFO,
+                              0,
+                              smu_table->ecc_table,
+                              false);
+       if (ret) {
+               dev_info(smu->adev->dev, "Failed to export SMU ecc table!\n");
+               return ret;
+       }
+
+       ecc_table = (EccInfoTable_t *)smu_table->ecc_table;
+
+       for (i = 0; i < ALDEBARAN_UMC_CHANNEL_NUM; i++) {
+               ecc_info_per_channel = &(eccinfo->ecc[i]);
+               ecc_info_per_channel->ce_count_lo_chip =
+                       ecc_table->EccInfo[i].ce_count_lo_chip;
+               ecc_info_per_channel->ce_count_hi_chip =
+                       ecc_table->EccInfo[i].ce_count_hi_chip;
+               ecc_info_per_channel->mca_umc_status =
+                       ecc_table->EccInfo[i].mca_umc_status;
+               ecc_info_per_channel->mca_umc_addr =
+                       ecc_table->EccInfo[i].mca_umc_addr;
+       }
+
+       return ret;
+}
+
+static int aldebaran_mode1_reset(struct smu_context *smu)
+{
+       u32 smu_version, fatal_err, param;
+       int ret = 0;
+       struct amdgpu_device *adev = smu->adev;
+       struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+       fatal_err = 0;
+       param = SMU_RESET_MODE_1;
+
+       /*
+       * PM FW support SMU_MSG_GfxDeviceDriverReset from 68.07
+       */
+       smu_cmn_get_smc_version(smu, NULL, &smu_version);
+       if (smu_version < 0x00440700) {
+               ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL);
+       }
+       else {
+               /* fatal error triggered by ras, PMFW supports the flag
+                  from 68.44.0 */
+               if ((smu_version >= 0x00442c00) && ras &&
+                   atomic_read(&ras->in_recovery))
+                       fatal_err = 1;
+
+               param |= (fatal_err << 16);
+               ret = smu_cmn_send_smc_msg_with_param(smu,
+                                       SMU_MSG_GfxDeviceDriverReset, param, NULL);
+       }
+
+       if (!ret)
+               msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS);
+
+       return ret;
+}
+
 static int aldebaran_mode2_reset(struct smu_context *smu)
 {
        u32 smu_version;
@@ -1925,13 +2031,14 @@ static const struct pptable_funcs aldebaran_ppt_funcs = {
        .get_gpu_metrics = aldebaran_get_gpu_metrics,
        .mode1_reset_is_support = aldebaran_is_mode1_reset_supported,
        .mode2_reset_is_support = aldebaran_is_mode2_reset_supported,
-       .mode1_reset = smu_v13_0_mode1_reset,
+       .mode1_reset = aldebaran_mode1_reset,
        .set_mp1_state = aldebaran_set_mp1_state,
        .mode2_reset = aldebaran_mode2_reset,
        .wait_for_event = smu_v13_0_wait_for_event,
        .i2c_init = aldebaran_i2c_control_init,
        .i2c_fini = aldebaran_i2c_control_fini,
        .send_hbm_bad_pages_num = aldebaran_smu_send_hbm_bad_page_num,
+       .get_ecc_info = aldebaran_get_ecc_info,
 };
 
 void aldebaran_set_ppt_funcs(struct smu_context *smu)
index 35145db6eedfc9e23df68d2ff71c11bd5a7e04d7..55421ea622fbc4ec6438f0108e96f742cd2f8aa8 100644 (file)
@@ -60,8 +60,6 @@ MODULE_FIRMWARE("amdgpu/aldebaran_smc.bin");
 
 #define SMU13_VOLTAGE_SCALE 4
 
-#define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500  //500ms
-
 #define LINK_WIDTH_MAX                         6
 #define LINK_SPEED_MAX                         3
 
@@ -430,8 +428,10 @@ int smu_v13_0_fini_smc_tables(struct smu_context *smu)
        kfree(smu_table->hardcode_pptable);
        smu_table->hardcode_pptable = NULL;
 
+       kfree(smu_table->ecc_table);
        kfree(smu_table->metrics_table);
        kfree(smu_table->watermarks_table);
+       smu_table->ecc_table = NULL;
        smu_table->metrics_table = NULL;
        smu_table->watermarks_table = NULL;
        smu_table->metrics_time = 0;
@@ -1424,25 +1424,6 @@ int smu_v13_0_set_azalia_d3_pme(struct smu_context *smu)
        return ret;
 }
 
-int smu_v13_0_mode1_reset(struct smu_context *smu)
-{
-       u32 smu_version;
-       int ret = 0;
-       /*
-       * PM FW support SMU_MSG_GfxDeviceDriverReset from 68.07
-       */
-       smu_cmn_get_smc_version(smu, NULL, &smu_version);
-       if (smu_version < 0x00440700)
-               ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL);
-       else
-               ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, SMU_RESET_MODE_1, NULL);
-
-       if (!ret)
-               msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS);
-
-       return ret;
-}
-
 static int smu_v13_0_wait_for_reset_complete(struct smu_context *smu,
                                             uint64_t event_arg)
 {
index ea6f50c08c5f3b838ed40669998af18a47ea4c37..500af6f8adcbb8087e0e5064876a32eb8c9699e7 100644 (file)
@@ -97,7 +97,7 @@ static void smu_cmn_read_arg(struct smu_context *smu,
  * smu: a pointer to SMU context
  *
  * Returns the status of the SMU, which could be,
- *    0, the SMU is busy with your previous command;
+ *    0, the SMU is busy with your command;
  *    1, execution status: success, execution result: success;
  * 0xFF, execution status: success, execution result: failure;
  * 0xFE, unknown command;
@@ -352,7 +352,7 @@ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu,
        __smu_cmn_send_msg(smu, (uint16_t) index, param);
        reg = __smu_cmn_poll_stat(smu);
        res = __smu_cmn_reg2errno(smu, reg);
-       if (res == -EREMOTEIO)
+       if (res != 0)
                __smu_cmn_reg_print_error(smu, reg, index, param, msg);
        if (read_arg)
                smu_cmn_read_arg(smu, read_arg);
index 482fb0ae6cb5db1f6a6723798171924bdf7c15bf..7afe2840808539ffc0090d63613b1a95f4e403a7 100644 (file)
@@ -168,7 +168,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
        if (!r) {
                acpi_status = radeon_acpi_init(rdev);
                if (acpi_status)
-               dev_dbg(dev->dev, "Error during ACPI methods call\n");
+                       dev_dbg(dev->dev, "Error during ACPI methods call\n");
        }
 
        if (radeon_is_px(dev)) {
diff --git a/include/uapi/linux/kfd_sysfs.h b/include/uapi/linux/kfd_sysfs.h
new file mode 100644 (file)
index 0000000..e1fb78b
--- /dev/null
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT WITH Linux-syscall-note */
+/*
+ * Copyright 2021 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 KFD_SYSFS_H_INCLUDED
+#define KFD_SYSFS_H_INCLUDED
+
+/* Capability bits in node properties */
+#define HSA_CAP_HOT_PLUGGABLE                  0x00000001
+#define HSA_CAP_ATS_PRESENT                    0x00000002
+#define HSA_CAP_SHARED_WITH_GRAPHICS           0x00000004
+#define HSA_CAP_QUEUE_SIZE_POW2                        0x00000008
+#define HSA_CAP_QUEUE_SIZE_32BIT               0x00000010
+#define HSA_CAP_QUEUE_IDLE_EVENT               0x00000020
+#define HSA_CAP_VA_LIMIT                       0x00000040
+#define HSA_CAP_WATCH_POINTS_SUPPORTED         0x00000080
+#define HSA_CAP_WATCH_POINTS_TOTALBITS_MASK    0x00000f00
+#define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT   8
+#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK   0x00003000
+#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT  12
+
+#define HSA_CAP_DOORBELL_TYPE_PRE_1_0          0x0
+#define HSA_CAP_DOORBELL_TYPE_1_0              0x1
+#define HSA_CAP_DOORBELL_TYPE_2_0              0x2
+#define HSA_CAP_AQL_QUEUE_DOUBLE_MAP           0x00004000
+
+/* Old buggy user mode depends on this being 0 */
+#define HSA_CAP_RESERVED_WAS_SRAM_EDCSUPPORTED 0x00080000
+
+#define HSA_CAP_MEM_EDCSUPPORTED               0x00100000
+#define HSA_CAP_RASEVENTNOTIFY                 0x00200000
+#define HSA_CAP_ASIC_REVISION_MASK             0x03c00000
+#define HSA_CAP_ASIC_REVISION_SHIFT            22
+#define HSA_CAP_SRAM_EDCSUPPORTED              0x04000000
+#define HSA_CAP_SVMAPI_SUPPORTED               0x08000000
+#define HSA_CAP_FLAGS_COHERENTHOSTACCESS       0x10000000
+#define HSA_CAP_RESERVED                       0xe00f8000
+
+/* Heap types in memory properties */
+#define HSA_MEM_HEAP_TYPE_SYSTEM       0
+#define HSA_MEM_HEAP_TYPE_FB_PUBLIC    1
+#define HSA_MEM_HEAP_TYPE_FB_PRIVATE   2
+#define HSA_MEM_HEAP_TYPE_GPU_GDS      3
+#define HSA_MEM_HEAP_TYPE_GPU_LDS      4
+#define HSA_MEM_HEAP_TYPE_GPU_SCRATCH  5
+
+/* Flag bits in memory properties */
+#define HSA_MEM_FLAGS_HOT_PLUGGABLE            0x00000001
+#define HSA_MEM_FLAGS_NON_VOLATILE             0x00000002
+#define HSA_MEM_FLAGS_RESERVED                 0xfffffffc
+
+/* Cache types in cache properties */
+#define HSA_CACHE_TYPE_DATA            0x00000001
+#define HSA_CACHE_TYPE_INSTRUCTION     0x00000002
+#define HSA_CACHE_TYPE_CPU             0x00000004
+#define HSA_CACHE_TYPE_HSACU           0x00000008
+#define HSA_CACHE_TYPE_RESERVED                0xfffffff0
+
+/* Link types in IO link properties (matches CRAT link types) */
+#define HSA_IOLINK_TYPE_UNDEFINED      0
+#define HSA_IOLINK_TYPE_HYPERTRANSPORT 1
+#define HSA_IOLINK_TYPE_PCIEXPRESS     2
+#define HSA_IOLINK_TYPE_AMBA           3
+#define HSA_IOLINK_TYPE_MIPI           4
+#define HSA_IOLINK_TYPE_QPI_1_1        5
+#define HSA_IOLINK_TYPE_RESERVED1      6
+#define HSA_IOLINK_TYPE_RESERVED2      7
+#define HSA_IOLINK_TYPE_RAPID_IO       8
+#define HSA_IOLINK_TYPE_INFINIBAND     9
+#define HSA_IOLINK_TYPE_RESERVED3      10
+#define HSA_IOLINK_TYPE_XGMI           11
+#define HSA_IOLINK_TYPE_XGOP           12
+#define HSA_IOLINK_TYPE_GZ             13
+#define HSA_IOLINK_TYPE_ETHERNET_RDMA  14
+#define HSA_IOLINK_TYPE_RDMA_OTHER     15
+#define HSA_IOLINK_TYPE_OTHER          16
+
+/* Flag bits in IO link properties (matches CRAT flags, excluding the
+ * bi-directional flag, which is not offially part of the CRAT spec, and
+ * only used internally in KFD)
+ */
+#define HSA_IOLINK_FLAGS_ENABLED               (1 << 0)
+#define HSA_IOLINK_FLAGS_NON_COHERENT          (1 << 1)
+#define HSA_IOLINK_FLAGS_NO_ATOMICS_32_BIT     (1 << 2)
+#define HSA_IOLINK_FLAGS_NO_ATOMICS_64_BIT     (1 << 3)
+#define HSA_IOLINK_FLAGS_NO_PEER_TO_PEER_DMA   (1 << 4)
+#define HSA_IOLINK_FLAGS_RESERVED              0xffffffe0
+
+#endif